src/project.js
import fs from 'fs';
import { assert } from 'chai';
import parsers from './parsers';
import * as testconfig from './testconfig';
import ProjectReport from 'typhonjs-escomplex-commons/src/project/report/ProjectReport';
import escomplexProject from '../../src';
// TODO REMOVE
// import escomplexModule from 'typhonjs-escomplex-module';
if (testconfig.modules['project'])
{
parsers.forEach((Parser) =>
{
// TODO REMOVE
// const s_AST = Parser.parse(fs.readFileSync('./node_modules/typhonjs-escomplex-test-data/files/large-module/src/Collection.js', 'utf8'));
// const moduleReport = escomplexModule.analyze(s_AST);
// fs.writeFileSync(process.cwd() + '/test/fixture/module.json', moduleReport.toFormat('json', { spacing: 3 }), 'utf8');
/**
* Load project source and local test files from NPM module typhonjs-escomplex-commons and
* typhonjs-escomplex-module. The order is purposely out of order to test sorting of `srcPath`.
* @type {string[]}
*/
const s_LOCAL_TEST_FILES =
[
'./node_modules/typhonjs-escomplex-module/src/ESComplexModule.js',
'./node_modules/typhonjs-escomplex-module/src/index.js',
'./node_modules/typhonjs-escomplex-module/src/Plugins.js',
'./node_modules/typhonjs-escomplex-commons/src/utils/Enum.js',
'./node_modules/typhonjs-escomplex-commons/src/utils/MathUtil.js',
'./node_modules/typhonjs-escomplex-commons/src/utils/StringUtil.js',
'./node_modules/typhonjs-escomplex-commons/src/utils/ObjectUtil.js',
'./node_modules/typhonjs-escomplex-commons/src/project/report/ProjectReport.js',
'./node_modules/typhonjs-escomplex-commons/src/types/ReportType.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/TransformFormat.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdown.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownAdjacency.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownMinimal.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownModules.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownVisibility.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/AbstractFormatText.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/AbstractTextMatrix.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatText.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextAdjacency.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextMinimal.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextModules.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextVisibility.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSON.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONCheckstyle.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONMinimal.js',
'./node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONModules.js',
'./node_modules/typhonjs-escomplex-commons/src/module/plugin/syntax/AbstractSyntaxLoader.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/AbstractReport.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/AggregateMethodReport.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/ClassReport.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/HalsteadData.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/MethodReport.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/ModuleReport.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/averages/ModuleAverage.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/averages/HalsteadAverage.js',
'./node_modules/typhonjs-escomplex-commons/src/module/report/averages/MethodAverage.js',
'./node_modules/typhonjs-escomplex-commons/src/module/traits/actualize.js',
'./node_modules/typhonjs-escomplex-commons/src/module/traits/HalsteadArray.js',
'./node_modules/typhonjs-escomplex-commons/src/module/traits/TraitUtil.js',
'./node_modules/typhonjs-escomplex-commons/src/module/traits/Trait.js',
'./node_modules/typhonjs-escomplex-commons/src/module/traits/TraitHalstead.js',
'./node_modules/typhonjs-escomplex-commons/src/analyze/AnalyzeError.js',
'./test/fixture/testImportNPMAlias.js',
'./test/fixture/testRequireNPMAlias.js',
'./src/ESComplexProject.js',
'./src/index.js',
'./src/Plugins.js'
];
const s_LOCAL_TEST_DATA = s_LOCAL_TEST_FILES.map((filePath) =>
{
let srcPath = filePath;
let srcPathAlias = undefined;
// Remove leading `./node_modules/` from file path for the source path which is what is referenced in the code.
if (filePath.startsWith('./node_modules/'))
{
srcPath = filePath.replace(/^\.\/node_modules\//, '');
}
// Add srcPathAlias for typhonjs-escomplex-module NPM main alias.
if (filePath === './node_modules/typhonjs-escomplex-module/src/index.js')
{
srcPathAlias = 'typhonjs-escomplex-module';
}
return {
ast: Parser.parse(fs.readFileSync(filePath, 'utf8')),
filePath,
srcPath,
srcPathAlias
};
});
suite(`(${Parser.name}) project:`, () =>
{
test('require returns object', () =>
{
assert.isObject(escomplexProject);
});
test('analyze function is exported', () =>
{
assert.isFunction(escomplexProject.analyze);
});
test('process function is exported', () =>
{
assert.isFunction(escomplexProject.process);
});
test('analyzeAsync function is exported', () =>
{
assert.isFunction(escomplexProject.analyzeAsync);
});
test('processAsync function is exported', () =>
{
assert.isFunction(escomplexProject.processAsync);
});
test('analyze throws when modules is object', () =>
{
assert.throws(() =>
{
escomplexProject.analyze({
body: [],
loc: {
start: {
line: 0
},
end: {
line: 0
}
}
});
});
});
test('analyze does not throw when modules is array', () =>
{
assert.doesNotThrow(() =>
{
escomplexProject.analyze([]);
});
});
test('analyzeAsync does not throw when modules is array', () =>
{
assert.doesNotThrow(() =>
{
escomplexProject.analyzeAsync([]);
});
});
test('analyze throws when modules is not an array', () =>
{
assert.throws(() =>
{
escomplexProject.analyze({});
});
});
test('analyze throws when `srcPath` is missing', () =>
{
assert.throws(() =>
{
escomplexProject.analyze([{ ast: Parser.parse('if (true) { "foo"; } else { "bar"; }') }]);
});
});
suite('no modules:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze([]);
});
teardown(() =>
{
result = undefined;
});
test('object was returned', () =>
{
assert.isObject(result);
});
test('modules array exists', () =>
{
assert.isArray(result.modules);
});
test('modules array has zero length', () =>
{
assert.lengthOf(result.modules, 0);
});
test('adjacency list exists', () =>
{
assert.isArray(result.adjacencyList);
});
test('adjacency list has zero length', () =>
{
assert.lengthOf(result.adjacencyList, 0);
});
test('first-order density is correct', () =>
{
assert.strictEqual(result.firstOrderDensity, 0);
});
test('change cost is correct', () =>
{
assert.strictEqual(result.changeCost, 0);
});
test('core size is correct', () =>
{
assert.strictEqual(result.coreSize, 0);
});
test('mean per-function logical LOC is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.sloc.logical, 0);
});
test('mean per-function cyclomatic complexity is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.cyclomatic, 0);
});
test('mean per-function Halstead effort is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.halstead.effort, 0);
});
test('mean per-function parameter count is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.params, 0);
});
test('mean per-function maintainability index is correct', () =>
{
assert.strictEqual(result.moduleAverage.maintainability, 0);
});
});
suite('one module:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze([{ ast: Parser.parse('if (true) { "foo"; } else { "bar"; }'), srcPath: 'a' }]);
});
teardown(() =>
{
result = undefined;
});
test('modules is correct length', () =>
{
assert.lengthOf(result.modules, 1);
});
test('first module methodAggregate has correct physical lines of code', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.sloc.physical, 1);
});
test('first module methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.sloc.logical, 4);
});
test('first module methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.cyclomatic, 2);
});
test('first module methodAggregate has correct cyclomatic complexity density', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.cyclomaticDensity, 50);
});
test('first module methods is empty', () =>
{
assert.lengthOf(result.modules[0].methods, 0);
});
test('first module methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.operators.total, 2);
});
test('first module methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.operators.distinct, 2);
});
test('first module methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.operands.total, 3);
});
test('first module methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.operands.distinct, 3);
});
test('first module methodAggregate has correct Halstead operator identifier length', () =>
{
assert.lengthOf(
result.modules[0].methodAggregate.halstead.operators.identifiers,
result.modules[0].methodAggregate.halstead.operators.distinct
);
});
test('first module methodAggregate has correct Halstead operand identifier length', () =>
{
assert.lengthOf(
result.modules[0].methodAggregate.halstead.operands.identifiers,
result.modules[0].methodAggregate.halstead.operands.distinct
);
});
test('first module methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.length, 5);
});
test('first module methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.vocabulary, 5);
});
test('first module methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.difficulty, 1);
});
test('first module methodAggregate has correct Halstead volume', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.volume, 11.61);
});
test('first module methodAggregate has correct Halstead effort', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.effort, 11.61);
});
test('first module methodAggregate has correct Halstead bugs', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.bugs, 0.004);
});
test('first module methodAggregate has correct Halstead time', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.time, 0.645);
});
test('first module has correct srcPath', () =>
{
assert.strictEqual(result.modules[0].srcPath, 'a');
});
test('first-order density is correct', () =>
{
assert.strictEqual(result.firstOrderDensity, 0);
});
test('change cost is correct', () =>
{
assert.strictEqual(result.changeCost, 100);
});
test('core size is correct', () =>
{
assert.strictEqual(result.coreSize, 0);
});
test('mean per-function logical LOC is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.sloc.logical, 4);
});
test('mean per-function cyclomatic complexity is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.cyclomatic, 2);
});
test('mean per-function Halstead effort is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.halstead.effort, 11.61);
});
test('mean per-function parameter count is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.params, 0);
});
test('mean per-function maintainability index is correct', () =>
{
assert.strictEqual(result.moduleAverage.maintainability, 139.997);
});
});
suite('two modules:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze([
{
ast: Parser.parse('function foo (a, b) { if (a) { b(a); } else { a(b); } } function bar (c, d) { var i; for (i = 0; i < c.length; i += 1) { d += 1; } console.log(d); }'),
srcPath: 'b'
},
{ ast: Parser.parse('if (true) { "foo"; } else { "bar"; }'), srcPath: 'a' }
]);
});
teardown(() =>
{
result = undefined;
});
test('modules is correct length', () =>
{
assert.lengthOf(result.modules, 2);
});
test('first module methodAggregate has correct physical lines of code', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.sloc.physical, 1);
});
test('first module methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.sloc.logical, 4);
});
test('first module methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.cyclomatic, 2);
});
test('first module methodAggregate has correct cyclomatic complexity density', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.cyclomaticDensity, 50);
});
test('first module methods is empty', () =>
{
assert.lengthOf(result.modules[0].methods, 0);
});
test('first module methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.operators.total, 2);
});
test('first module methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.operators.distinct, 2);
});
test('first module methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.operands.total, 3);
});
test('first module methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.operands.distinct, 3);
});
test('first module methodAggregate has correct Halstead operator identifier length', () =>
{
assert.lengthOf(
result.modules[0].methodAggregate.halstead.operators.identifiers,
result.modules[0].methodAggregate.halstead.operators.distinct
);
});
test('first module methodAggregate has correct Halstead operand identifier length', () =>
{
assert.lengthOf(
result.modules[0].methodAggregate.halstead.operands.identifiers,
result.modules[0].methodAggregate.halstead.operands.distinct
);
});
test('first module methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.length, 5);
});
test('first module methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.vocabulary, 5);
});
test('first module methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.difficulty, 1);
});
test('first module methodAggregate has correct Halstead volume', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.volume, 11.61);
});
test('first module methodAggregate has correct Halstead effort', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.effort, 11.61);
});
test('first module methodAggregate has correct Halstead bugs', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.bugs, 0.004);
});
test('first module methodAggregate has correct Halstead time', () =>
{
assert.strictEqual(result.modules[0].methodAggregate.halstead.time, 0.645);
});
test('first module has correct srcPath', () =>
{
assert.strictEqual(result.modules[0].srcPath, 'a');
});
test('second module maintainability index is correct', () =>
{
assert.strictEqual(result.modules[1].maintainability, 128.115);
});
test('second module first method has correct parameter count', () =>
{
assert.strictEqual(result.modules[1].methods[0].params, 2);
});
test('second module second method has correct parameter count', () =>
{
assert.strictEqual(result.modules[1].methods[1].params, 2);
});
test('second module methodAggregate has correct parameter count', () =>
{
assert.strictEqual(result.modules[1].methodAggregate.params, 4);
});
test('second module mean parameter count is correct', () =>
{
assert.strictEqual(result.modules[1].methodAverage.params, 2);
});
test('second module has correct srcPath', () =>
{
assert.strictEqual(result.modules[1].srcPath, 'b');
});
test('first-order density is correct', () =>
{
assert.strictEqual(result.firstOrderDensity, 0);
});
test('change cost is correct', () =>
{
assert.strictEqual(result.changeCost, 50);
});
test('core size is correct', () =>
{
assert.strictEqual(result.coreSize, 0);
});
test('mean per-function logical LOC is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.sloc.logical, 4);
});
test('mean per-function cyclomatic complexity is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.cyclomatic, 2);
});
test('mean per-function Halstead effort is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.halstead.effort, 193.162);
});
test('mean per-function parameter count is correct', () =>
{
assert.strictEqual(result.moduleAverage.methodAverage.params, 1);
});
test('mean per-function maintainability index is correct', () =>
{
assert.strictEqual(result.moduleAverage.maintainability, 134.056);
});
});
suite('two modules with different options:', () =>
{
const modules =
[
{
ast: Parser.parse('function foo (a, b) { if (a) { b(a); } else { a(b); } } function bar (c, d) { var i; for (i = 0; i < c.length; i += 1) { d += 1; } console.log(d); }'),
srcPath: 'b'
},
{
ast: Parser.parse('if (true) { "foo"; } else { "bar"; }'),
srcPath: 'a'
}
];
let reportsOnly;
setup(() =>
{
reportsOnly = escomplexProject.analyze(modules, { skipCalculation: true });
});
test('should have default values if we call with skipCalculation', () =>
{
assert.lengthOf(reportsOnly.modules, 2);
assert.strictEqual(reportsOnly.moduleAverage.methodAverage.sloc.logical, 0);
assert.strictEqual(reportsOnly.moduleAverage.maintainability, 0);
assert.strictEqual(reportsOnly.coreSize, 0);
assert.isUndefined(reportsOnly.adjacencyList);
assert.isUndefined(reportsOnly.visibilityList);
});
test('should have default coreSize and visibilityMatrix if we call with noCoreSize', () =>
{
const results = escomplexProject.analyze(modules, { noCoreSize: true });
assert.strictEqual(results.coreSize, 0);
assert.isUndefined(results.visibilityList);
// make sure we still have a few things though
assert.ok(results.adjacencyList);
assert.ok(results.moduleAverage.methodAverage.sloc.logical);
});
test('should be able to run process', () =>
{
const fullReport = escomplexProject.analyze(modules);
const calcReport = escomplexProject.process(reportsOnly);
assert.deepEqual(calcReport, fullReport);
});
test('should be able to run process without calculating coreSize', () =>
{
const results = escomplexProject.process(reportsOnly, { noCoreSize: true });
assert.strictEqual(results.coreSize, 0);
assert.isUndefined(results.visibilityList);
// make sure we still have a few things though
assert.ok(results.adjacencyList);
assert.ok(results.moduleAverage.methodAverage.sloc.logical);
});
test('should be able to run processAsync', () =>
{
const fullReport = escomplexProject.analyze(modules);
escomplexProject.processAsync(reportsOnly).then((calcReport) =>
{
assert.deepEqual(calcReport, fullReport);
});
});
});
suite('local source + NPM module typhonjs-escomplex-commons test w/ serializeModules false:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze(s_LOCAL_TEST_DATA, { serializeModules: false });
});
teardown(() =>
{
result = undefined;
});
test('modules are in correct order', () =>
{
// TODO REMOVE
// fs.writeFileSync(process.cwd() + '/test/fixture/project-no-modules.json', result.toFormat('json', { spacing: 3 }), 'utf8');
// TODO REMOVE
/*
result.modules.forEach((module, index) =>
{
console.log(`assert.strictEqual(result.modules[${index}].filePath, '${module.filePath}');`);
});
result.modules.forEach((module, index) =>
{
console.log(`assert.strictEqual(result.modules[${index}].srcPath, '${module.srcPath}');`);
});
*/
assert.strictEqual(result.modules[0].filePath, './src/ESComplexProject.js');
assert.strictEqual(result.modules[1].filePath, './src/index.js');
assert.strictEqual(result.modules[2].filePath, './src/Plugins.js');
assert.strictEqual(result.modules[3].filePath, './test/fixture/testImportNPMAlias.js');
assert.strictEqual(result.modules[4].filePath, './test/fixture/testRequireNPMAlias.js');
assert.strictEqual(result.modules[5].filePath, './node_modules/typhonjs-escomplex-commons/src/analyze/AnalyzeError.js');
assert.strictEqual(result.modules[6].filePath, './node_modules/typhonjs-escomplex-commons/src/module/plugin/syntax/AbstractSyntaxLoader.js');
assert.strictEqual(result.modules[7].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/AbstractReport.js');
assert.strictEqual(result.modules[8].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/AggregateMethodReport.js');
assert.strictEqual(result.modules[9].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/averages/HalsteadAverage.js');
assert.strictEqual(result.modules[10].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/averages/MethodAverage.js');
assert.strictEqual(result.modules[11].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/averages/ModuleAverage.js');
assert.strictEqual(result.modules[12].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/ClassReport.js');
assert.strictEqual(result.modules[13].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/HalsteadData.js');
assert.strictEqual(result.modules[14].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/MethodReport.js');
assert.strictEqual(result.modules[15].filePath, './node_modules/typhonjs-escomplex-commons/src/module/report/ModuleReport.js');
assert.strictEqual(result.modules[16].filePath, './node_modules/typhonjs-escomplex-commons/src/module/traits/actualize.js');
assert.strictEqual(result.modules[17].filePath, './node_modules/typhonjs-escomplex-commons/src/module/traits/HalsteadArray.js');
assert.strictEqual(result.modules[18].filePath, './node_modules/typhonjs-escomplex-commons/src/module/traits/Trait.js');
assert.strictEqual(result.modules[19].filePath, './node_modules/typhonjs-escomplex-commons/src/module/traits/TraitHalstead.js');
assert.strictEqual(result.modules[20].filePath, './node_modules/typhonjs-escomplex-commons/src/module/traits/TraitUtil.js');
assert.strictEqual(result.modules[21].filePath, './node_modules/typhonjs-escomplex-commons/src/project/report/ProjectReport.js');
assert.strictEqual(result.modules[22].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSON.js');
assert.strictEqual(result.modules[23].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONCheckstyle.js');
assert.strictEqual(result.modules[24].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONMinimal.js');
assert.strictEqual(result.modules[25].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONModules.js');
assert.strictEqual(result.modules[26].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdown.js');
assert.strictEqual(result.modules[27].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownAdjacency.js');
assert.strictEqual(result.modules[28].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownMinimal.js');
assert.strictEqual(result.modules[29].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownModules.js');
assert.strictEqual(result.modules[30].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownVisibility.js');
assert.strictEqual(result.modules[31].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/text/AbstractFormatText.js');
assert.strictEqual(result.modules[32].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/text/AbstractTextMatrix.js');
assert.strictEqual(result.modules[33].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatText.js');
assert.strictEqual(result.modules[34].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextAdjacency.js');
assert.strictEqual(result.modules[35].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextMinimal.js');
assert.strictEqual(result.modules[36].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextModules.js');
assert.strictEqual(result.modules[37].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextVisibility.js');
assert.strictEqual(result.modules[38].filePath, './node_modules/typhonjs-escomplex-commons/src/transform/TransformFormat.js');
assert.strictEqual(result.modules[39].filePath, './node_modules/typhonjs-escomplex-commons/src/types/ReportType.js');
assert.strictEqual(result.modules[40].filePath, './node_modules/typhonjs-escomplex-commons/src/utils/Enum.js');
assert.strictEqual(result.modules[41].filePath, './node_modules/typhonjs-escomplex-commons/src/utils/MathUtil.js');
assert.strictEqual(result.modules[42].filePath, './node_modules/typhonjs-escomplex-commons/src/utils/ObjectUtil.js');
assert.strictEqual(result.modules[43].filePath, './node_modules/typhonjs-escomplex-commons/src/utils/StringUtil.js');
assert.strictEqual(result.modules[44].filePath, './node_modules/typhonjs-escomplex-module/src/ESComplexModule.js');
assert.strictEqual(result.modules[45].filePath, './node_modules/typhonjs-escomplex-module/src/index.js');
assert.strictEqual(result.modules[46].filePath, './node_modules/typhonjs-escomplex-module/src/Plugins.js');
assert.strictEqual(result.modules[0].srcPath, './src/ESComplexProject.js');
assert.strictEqual(result.modules[1].srcPath, './src/index.js');
assert.strictEqual(result.modules[2].srcPath, './src/Plugins.js');
assert.strictEqual(result.modules[3].srcPath, './test/fixture/testImportNPMAlias.js');
assert.strictEqual(result.modules[4].srcPath, './test/fixture/testRequireNPMAlias.js');
assert.strictEqual(result.modules[5].srcPath, 'typhonjs-escomplex-commons/src/analyze/AnalyzeError.js');
assert.strictEqual(result.modules[6].srcPath, 'typhonjs-escomplex-commons/src/module/plugin/syntax/AbstractSyntaxLoader.js');
assert.strictEqual(result.modules[7].srcPath, 'typhonjs-escomplex-commons/src/module/report/AbstractReport.js');
assert.strictEqual(result.modules[8].srcPath, 'typhonjs-escomplex-commons/src/module/report/AggregateMethodReport.js');
assert.strictEqual(result.modules[9].srcPath, 'typhonjs-escomplex-commons/src/module/report/averages/HalsteadAverage.js');
assert.strictEqual(result.modules[10].srcPath, 'typhonjs-escomplex-commons/src/module/report/averages/MethodAverage.js');
assert.strictEqual(result.modules[11].srcPath, 'typhonjs-escomplex-commons/src/module/report/averages/ModuleAverage.js');
assert.strictEqual(result.modules[12].srcPath, 'typhonjs-escomplex-commons/src/module/report/ClassReport.js');
assert.strictEqual(result.modules[13].srcPath, 'typhonjs-escomplex-commons/src/module/report/HalsteadData.js');
assert.strictEqual(result.modules[14].srcPath, 'typhonjs-escomplex-commons/src/module/report/MethodReport.js');
assert.strictEqual(result.modules[15].srcPath, 'typhonjs-escomplex-commons/src/module/report/ModuleReport.js');
assert.strictEqual(result.modules[16].srcPath, 'typhonjs-escomplex-commons/src/module/traits/actualize.js');
assert.strictEqual(result.modules[17].srcPath, 'typhonjs-escomplex-commons/src/module/traits/HalsteadArray.js');
assert.strictEqual(result.modules[18].srcPath, 'typhonjs-escomplex-commons/src/module/traits/Trait.js');
assert.strictEqual(result.modules[19].srcPath, 'typhonjs-escomplex-commons/src/module/traits/TraitHalstead.js');
assert.strictEqual(result.modules[20].srcPath, 'typhonjs-escomplex-commons/src/module/traits/TraitUtil.js');
assert.strictEqual(result.modules[21].srcPath, 'typhonjs-escomplex-commons/src/project/report/ProjectReport.js');
assert.strictEqual(result.modules[22].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/json/FormatJSON.js');
assert.strictEqual(result.modules[23].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONCheckstyle.js');
assert.strictEqual(result.modules[24].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONMinimal.js');
assert.strictEqual(result.modules[25].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONModules.js');
assert.strictEqual(result.modules[26].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdown.js');
assert.strictEqual(result.modules[27].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownAdjacency.js');
assert.strictEqual(result.modules[28].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownMinimal.js');
assert.strictEqual(result.modules[29].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownModules.js');
assert.strictEqual(result.modules[30].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownVisibility.js');
assert.strictEqual(result.modules[31].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/AbstractFormatText.js');
assert.strictEqual(result.modules[32].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/AbstractTextMatrix.js');
assert.strictEqual(result.modules[33].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatText.js');
assert.strictEqual(result.modules[34].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatTextAdjacency.js');
assert.strictEqual(result.modules[35].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatTextMinimal.js');
assert.strictEqual(result.modules[36].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatTextModules.js');
assert.strictEqual(result.modules[37].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatTextVisibility.js');
assert.strictEqual(result.modules[38].srcPath, 'typhonjs-escomplex-commons/src/transform/TransformFormat.js');
assert.strictEqual(result.modules[39].srcPath, 'typhonjs-escomplex-commons/src/types/ReportType.js');
assert.strictEqual(result.modules[40].srcPath, 'typhonjs-escomplex-commons/src/utils/Enum.js');
assert.strictEqual(result.modules[41].srcPath, 'typhonjs-escomplex-commons/src/utils/MathUtil.js');
assert.strictEqual(result.modules[42].srcPath, 'typhonjs-escomplex-commons/src/utils/ObjectUtil.js');
assert.strictEqual(result.modules[43].srcPath, 'typhonjs-escomplex-commons/src/utils/StringUtil.js');
assert.strictEqual(result.modules[44].srcPath, 'typhonjs-escomplex-module/src/ESComplexModule.js');
assert.strictEqual(result.modules[45].srcPath, 'typhonjs-escomplex-module/src/index.js');
assert.strictEqual(result.modules[46].srcPath, 'typhonjs-escomplex-module/src/Plugins.js');
assert.strictEqual(result.modules[45].srcPathAlias, 'typhonjs-escomplex-module');
});
test('modules only contains object hash w/ filePath, srcPath and srcPathAlias entries', () =>
{
const testString = '[{"filePath":"./src/ESComplexProject.js","srcPath":"./src/ESComplexProject.js"},{"filePath":"./src/index.js","srcPath":"./src/index.js"},{"filePath":"./src/Plugins.js","srcPath":"./src/Plugins.js"},{"filePath":"./test/fixture/testImportNPMAlias.js","srcPath":"./test/fixture/testImportNPMAlias.js"},{"filePath":"./test/fixture/testRequireNPMAlias.js","srcPath":"./test/fixture/testRequireNPMAlias.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/analyze/AnalyzeError.js","srcPath":"typhonjs-escomplex-commons/src/analyze/AnalyzeError.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/plugin/syntax/AbstractSyntaxLoader.js","srcPath":"typhonjs-escomplex-commons/src/module/plugin/syntax/AbstractSyntaxLoader.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/AbstractReport.js","srcPath":"typhonjs-escomplex-commons/src/module/report/AbstractReport.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/AggregateMethodReport.js","srcPath":"typhonjs-escomplex-commons/src/module/report/AggregateMethodReport.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/averages/HalsteadAverage.js","srcPath":"typhonjs-escomplex-commons/src/module/report/averages/HalsteadAverage.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/averages/MethodAverage.js","srcPath":"typhonjs-escomplex-commons/src/module/report/averages/MethodAverage.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/averages/ModuleAverage.js","srcPath":"typhonjs-escomplex-commons/src/module/report/averages/ModuleAverage.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/ClassReport.js","srcPath":"typhonjs-escomplex-commons/src/module/report/ClassReport.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/HalsteadData.js","srcPath":"typhonjs-escomplex-commons/src/module/report/HalsteadData.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/MethodReport.js","srcPath":"typhonjs-escomplex-commons/src/module/report/MethodReport.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/report/ModuleReport.js","srcPath":"typhonjs-escomplex-commons/src/module/report/ModuleReport.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/traits/actualize.js","srcPath":"typhonjs-escomplex-commons/src/module/traits/actualize.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/traits/HalsteadArray.js","srcPath":"typhonjs-escomplex-commons/src/module/traits/HalsteadArray.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/traits/Trait.js","srcPath":"typhonjs-escomplex-commons/src/module/traits/Trait.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/traits/TraitHalstead.js","srcPath":"typhonjs-escomplex-commons/src/module/traits/TraitHalstead.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/module/traits/TraitUtil.js","srcPath":"typhonjs-escomplex-commons/src/module/traits/TraitUtil.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/project/report/ProjectReport.js","srcPath":"typhonjs-escomplex-commons/src/project/report/ProjectReport.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSON.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/json/FormatJSON.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONCheckstyle.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONCheckstyle.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONMinimal.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONMinimal.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONModules.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONModules.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdown.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdown.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownAdjacency.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownAdjacency.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownMinimal.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownMinimal.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownModules.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownModules.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownVisibility.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownVisibility.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/AbstractFormatText.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/text/AbstractFormatText.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/AbstractTextMatrix.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/text/AbstractTextMatrix.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatText.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/text/FormatText.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextAdjacency.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/text/FormatTextAdjacency.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextMinimal.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/text/FormatTextMinimal.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextModules.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/text/FormatTextModules.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/formats/text/FormatTextVisibility.js","srcPath":"typhonjs-escomplex-commons/src/transform/formats/text/FormatTextVisibility.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/transform/TransformFormat.js","srcPath":"typhonjs-escomplex-commons/src/transform/TransformFormat.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/types/ReportType.js","srcPath":"typhonjs-escomplex-commons/src/types/ReportType.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/utils/Enum.js","srcPath":"typhonjs-escomplex-commons/src/utils/Enum.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/utils/MathUtil.js","srcPath":"typhonjs-escomplex-commons/src/utils/MathUtil.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/utils/ObjectUtil.js","srcPath":"typhonjs-escomplex-commons/src/utils/ObjectUtil.js"},{"filePath":"./node_modules/typhonjs-escomplex-commons/src/utils/StringUtil.js","srcPath":"typhonjs-escomplex-commons/src/utils/StringUtil.js"},{"filePath":"./node_modules/typhonjs-escomplex-module/src/ESComplexModule.js","srcPath":"typhonjs-escomplex-module/src/ESComplexModule.js"},{"filePath":"./node_modules/typhonjs-escomplex-module/src/index.js","srcPath":"typhonjs-escomplex-module/src/index.js","srcPathAlias":"typhonjs-escomplex-module"},{"filePath":"./node_modules/typhonjs-escomplex-module/src/Plugins.js","srcPath":"typhonjs-escomplex-module/src/Plugins.js"}]';
assert.strictEqual(JSON.stringify(result.modules), testString);
});
});
suite('local source + NPM module typhonjs-escomplex-commons and typhonjs-escomplex-module test w/ dependencies:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze(s_LOCAL_TEST_DATA, { commonjs: true, serializeModules: false });
});
teardown(() =>
{
result = undefined;
});
test('modules are in correct order', () =>
{
assert.strictEqual(result.modules[0].srcPath, './src/ESComplexProject.js');
assert.strictEqual(result.modules[1].srcPath, './src/index.js');
assert.strictEqual(result.modules[2].srcPath, './src/Plugins.js');
assert.strictEqual(result.modules[3].srcPath, './test/fixture/testImportNPMAlias.js');
assert.strictEqual(result.modules[4].srcPath, './test/fixture/testRequireNPMAlias.js');
assert.strictEqual(result.modules[5].srcPath, 'typhonjs-escomplex-commons/src/analyze/AnalyzeError.js');
assert.strictEqual(result.modules[6].srcPath, 'typhonjs-escomplex-commons/src/module/plugin/syntax/AbstractSyntaxLoader.js');
assert.strictEqual(result.modules[7].srcPath, 'typhonjs-escomplex-commons/src/module/report/AbstractReport.js');
assert.strictEqual(result.modules[8].srcPath, 'typhonjs-escomplex-commons/src/module/report/AggregateMethodReport.js');
assert.strictEqual(result.modules[9].srcPath, 'typhonjs-escomplex-commons/src/module/report/averages/HalsteadAverage.js');
assert.strictEqual(result.modules[10].srcPath, 'typhonjs-escomplex-commons/src/module/report/averages/MethodAverage.js');
assert.strictEqual(result.modules[11].srcPath, 'typhonjs-escomplex-commons/src/module/report/averages/ModuleAverage.js');
assert.strictEqual(result.modules[12].srcPath, 'typhonjs-escomplex-commons/src/module/report/ClassReport.js');
assert.strictEqual(result.modules[13].srcPath, 'typhonjs-escomplex-commons/src/module/report/HalsteadData.js');
assert.strictEqual(result.modules[14].srcPath, 'typhonjs-escomplex-commons/src/module/report/MethodReport.js');
assert.strictEqual(result.modules[15].srcPath, 'typhonjs-escomplex-commons/src/module/report/ModuleReport.js');
assert.strictEqual(result.modules[16].srcPath, 'typhonjs-escomplex-commons/src/module/traits/actualize.js');
assert.strictEqual(result.modules[17].srcPath, 'typhonjs-escomplex-commons/src/module/traits/HalsteadArray.js');
assert.strictEqual(result.modules[18].srcPath, 'typhonjs-escomplex-commons/src/module/traits/Trait.js');
assert.strictEqual(result.modules[19].srcPath, 'typhonjs-escomplex-commons/src/module/traits/TraitHalstead.js');
assert.strictEqual(result.modules[20].srcPath, 'typhonjs-escomplex-commons/src/module/traits/TraitUtil.js');
assert.strictEqual(result.modules[21].srcPath, 'typhonjs-escomplex-commons/src/project/report/ProjectReport.js');
assert.strictEqual(result.modules[22].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/json/FormatJSON.js');
assert.strictEqual(result.modules[23].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONCheckstyle.js');
assert.strictEqual(result.modules[24].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONMinimal.js');
assert.strictEqual(result.modules[25].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/json/FormatJSONModules.js');
assert.strictEqual(result.modules[26].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdown.js');
assert.strictEqual(result.modules[27].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownAdjacency.js');
assert.strictEqual(result.modules[28].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownMinimal.js');
assert.strictEqual(result.modules[29].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownModules.js');
assert.strictEqual(result.modules[30].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/markdown/FormatMarkdownVisibility.js');
assert.strictEqual(result.modules[31].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/AbstractFormatText.js');
assert.strictEqual(result.modules[32].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/AbstractTextMatrix.js');
assert.strictEqual(result.modules[33].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatText.js');
assert.strictEqual(result.modules[34].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatTextAdjacency.js');
assert.strictEqual(result.modules[35].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatTextMinimal.js');
assert.strictEqual(result.modules[36].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatTextModules.js');
assert.strictEqual(result.modules[37].srcPath, 'typhonjs-escomplex-commons/src/transform/formats/text/FormatTextVisibility.js');
assert.strictEqual(result.modules[38].srcPath, 'typhonjs-escomplex-commons/src/transform/TransformFormat.js');
assert.strictEqual(result.modules[39].srcPath, 'typhonjs-escomplex-commons/src/types/ReportType.js');
assert.strictEqual(result.modules[40].srcPath, 'typhonjs-escomplex-commons/src/utils/Enum.js');
assert.strictEqual(result.modules[41].srcPath, 'typhonjs-escomplex-commons/src/utils/MathUtil.js');
assert.strictEqual(result.modules[42].srcPath, 'typhonjs-escomplex-commons/src/utils/ObjectUtil.js');
assert.strictEqual(result.modules[43].srcPath, 'typhonjs-escomplex-commons/src/utils/StringUtil.js');
assert.strictEqual(result.modules[44].srcPath, 'typhonjs-escomplex-module/src/ESComplexModule.js');
assert.strictEqual(result.modules[45].srcPath, 'typhonjs-escomplex-module/src/index.js');
assert.strictEqual(result.modules[46].srcPath, 'typhonjs-escomplex-module/src/Plugins.js');
});
test('adjacency list is correct', () =>
{
const testString = '[{"row":0,"cols":[2,15,21,44]},{"row":1,"cols":[0]},{"row":3,"cols":[45]},{"row":4,"cols":[45]},{"row":5,"cols":[39]},{"row":7,"cols":[38]},{"row":8,"cols":[7,13]},{"row":10,"cols":[9]},{"row":11,"cols":[10]},{"row":12,"cols":[5,7,8,10,38,39,42]},{"row":14,"cols":[5,8]},{"row":15,"cols":[5,7,8,10,12,38,39,41,42]},{"row":16,"cols":[17,18,20]},{"row":17,"cols":[19]},{"row":21,"cols":[11,15,38,39,41,42,43]},{"row":23,"cols":[39,42]},{"row":24,"cols":[39,42]},{"row":25,"cols":[39]},{"row":26,"cols":[33,43]},{"row":27,"cols":[34]},{"row":28,"cols":[35,43]},{"row":29,"cols":[36,43]},{"row":30,"cols":[37]},{"row":31,"cols":[39,42,43]},{"row":32,"cols":[39,42]},{"row":33,"cols":[31,38,39,43]},{"row":34,"cols":[32]},{"row":35,"cols":[31,39,43]},{"row":36,"cols":[31,39,43]},{"row":37,"cols":[32]},{"row":38,"cols":[22,23,24,25,26,27,28,29,30,33,34,35,36,37,39]},{"row":39,"cols":[40]},{"row":41,"cols":[42]},{"row":43,"cols":[42]},{"row":44,"cols":[46]},{"row":45,"cols":[44]},{"row":46,"cols":[15]}]';
assert.strictEqual(JSON.stringify(result.adjacencyList), testString);
});
test('visibility list is correct', () =>
{
const testString = '[{"row":0,"cols":[0,2,5,7,8,9,10,11,12,13,15,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46]},{"row":1,"cols":[0,1,2,5,7,8,9,10,11,12,13,15,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46]},{"row":2,"cols":[2]},{"row":3,"cols":[3,5,7,8,9,10,12,13,15,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46]},{"row":4,"cols":[4,5,7,8,9,10,12,13,15,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46]},{"row":5,"cols":[5,39,40]},{"row":6,"cols":[6]},{"row":7,"cols":[7,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,43]},{"row":8,"cols":[7,8,13,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,43]},{"row":9,"cols":[9]},{"row":10,"cols":[9,10]},{"row":11,"cols":[9,10,11]},{"row":12,"cols":[5,7,8,9,10,12,13,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,43]},{"row":13,"cols":[13]},{"row":14,"cols":[5,7,8,13,14,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,43]},{"row":15,"cols":[5,7,8,9,10,12,13,15,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43]},{"row":16,"cols":[16,17,18,19,20]},{"row":17,"cols":[17,19]},{"row":18,"cols":[18]},{"row":19,"cols":[19]},{"row":20,"cols":[20]},{"row":21,"cols":[5,7,8,9,10,11,12,13,15,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43]},{"row":22,"cols":[22]},{"row":23,"cols":[23,39,40,42]},{"row":24,"cols":[24,39,40,42]},{"row":25,"cols":[25,39,40]},{"row":26,"cols":[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,43]},{"row":27,"cols":[27,32,34,39,40,42]},{"row":28,"cols":[28,31,35,39,40,42,43]},{"row":29,"cols":[29,31,36,39,40,42,43]},{"row":30,"cols":[30,32,37,39,40,42]},{"row":31,"cols":[31,39,40,42,43]},{"row":32,"cols":[32,39,40,42]},{"row":33,"cols":[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,43]},{"row":34,"cols":[32,34,39,40,42]},{"row":35,"cols":[31,35,39,40,42,43]},{"row":36,"cols":[31,36,39,40,42,43]},{"row":37,"cols":[32,37,39,40,42]},{"row":38,"cols":[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,43]},{"row":39,"cols":[39,40]},{"row":40,"cols":[40]},{"row":41,"cols":[41,42]},{"row":42,"cols":[42]},{"row":43,"cols":[42,43]},{"row":44,"cols":[5,7,8,9,10,12,13,15,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46]},{"row":45,"cols":[5,7,8,9,10,12,13,15,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46]},{"row":46,"cols":[5,7,8,9,10,12,13,15,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,46]}]';
assert.strictEqual(JSON.stringify(result.visibilityList), testString);
});
});
suite('cjs modules with dependencies:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze([
{ ast: Parser.parse('require("./a");'), srcPath: '/d.js' },
{ ast: Parser.parse('require("./b");'), srcPath: '/a/c.js' },
{ ast: Parser.parse('require("./c");'), srcPath: '/a/b.js' },
{ ast: Parser.parse('require("./a/b");require("./a/c");'), srcPath: '/a.js' }
], { commonjs: true });
});
teardown(() =>
{
result = undefined;
});
test('modules are in correct order', () =>
{
assert.strictEqual(result.modules[0].srcPath, '/a.js');
assert.strictEqual(result.modules[1].srcPath, '/a/b.js');
assert.strictEqual(result.modules[2].srcPath, '/a/c.js');
assert.strictEqual(result.modules[3].srcPath, '/d.js');
});
test('adjacency list is correct', () =>
{
const testString = '[{"row":0,"cols":[1,2]},{"row":1,"cols":[2]},{"row":2,"cols":[1]},{"row":3,"cols":[0]}]';
assert.strictEqual(JSON.stringify(result.adjacencyList), testString);
});
test('visibility list is correct', () =>
{
const testString = '[{"row":0,"cols":[0,1,2]},{"row":1,"cols":[1,2]},{"row":2,"cols":[1,2]},{"row":3,"cols":[0,1,2,3]}]';
assert.strictEqual(JSON.stringify(result.visibilityList), testString);
});
test('first order density is correct', () =>
{
assert.strictEqual(result.firstOrderDensity, 31.25);
});
test('change cost is correct', () =>
{
assert.strictEqual(result.changeCost, 68.75);
});
test('core size is correct', () =>
{
assert.strictEqual(result.coreSize, 0);
});
});
suite('cjs modules with dynamic dependencies:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze([
{ ast: Parser.parse('require("dynamic_a");'), srcPath: '/d.js' },
{ ast: Parser.parse('require("dynamic_b");'), srcPath: '/a/c.js' },
{ ast: Parser.parse('require("dynamic_c");'), srcPath: '/a/b.js' },
{ ast: Parser.parse('require("./a/b");require("./a/c");'), srcPath: '/a.js' }
],
{ commonjs: true, dependencyResolver: (dependency) =>
{
switch (dependency)
{
case 'dynamic_a': return './a';
case 'dynamic_b': return './b';
case 'dynamic_c': return './c';
default: return dependency;
}
}
});
});
teardown(() =>
{
result = undefined;
});
test('modules are in correct order', () =>
{
assert.strictEqual(result.modules[0].srcPath, '/a.js');
assert.strictEqual(result.modules[1].srcPath, '/a/b.js');
assert.strictEqual(result.modules[2].srcPath, '/a/c.js');
assert.strictEqual(result.modules[3].srcPath, '/d.js');
});
test('adjacency list is correct', () =>
{
const testString = '[{"row":0,"cols":[1,2]},{"row":1,"cols":[2]},{"row":2,"cols":[1]},{"row":3,"cols":[0]}]';
assert.strictEqual(JSON.stringify(result.adjacencyList), testString);
});
test('visibility list is correct', () =>
{
const testString = '[{"row":0,"cols":[0,1,2]},{"row":1,"cols":[1,2]},{"row":2,"cols":[1,2]},{"row":3,"cols":[0,1,2,3]}]';
assert.strictEqual(JSON.stringify(result.visibilityList), testString);
});
test('first order density is correct', () =>
{
assert.strictEqual(result.firstOrderDensity, 31.25);
});
test('change cost is correct', () =>
{
assert.strictEqual(result.changeCost, 68.75);
});
test('core size is correct', () =>
{
assert.strictEqual(result.coreSize, 0);
});
});
suite('esm modules with dependencies:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze([
{ ast: Parser.parse('import d from "./a";'), srcPath: '/d.js' },
{ ast: Parser.parse('import c from "./b";'), srcPath: '/a/c.js' },
{ ast: Parser.parse('import b from "./c";'), srcPath: '/a/b.js' },
{ ast: Parser.parse('import a from "./a/b"; import aa from "./a/c";'), srcPath: '/a.js' }
]);
});
teardown(() =>
{
result = undefined;
});
test('modules are in correct order', () =>
{
assert.strictEqual(result.modules[0].srcPath, '/a.js');
assert.strictEqual(result.modules[1].srcPath, '/a/b.js');
assert.strictEqual(result.modules[2].srcPath, '/a/c.js');
assert.strictEqual(result.modules[3].srcPath, '/d.js');
});
test('adjacency list is correct', () =>
{
const testString = '[{"row":0,"cols":[1,2]},{"row":1,"cols":[2]},{"row":2,"cols":[1]},{"row":3,"cols":[0]}]';
assert.strictEqual(JSON.stringify(result.adjacencyList), testString);
});
test('visibility list is correct', () =>
{
const testString = '[{"row":0,"cols":[0,1,2]},{"row":1,"cols":[1,2]},{"row":2,"cols":[1,2]},{"row":3,"cols":[0,1,2,3]}]';
assert.strictEqual(JSON.stringify(result.visibilityList), testString);
});
test('first order density is correct', () =>
{
assert.strictEqual(result.firstOrderDensity, 31.25);
});
test('change cost is correct', () =>
{
assert.strictEqual(result.changeCost, 68.75);
});
test('core size is correct', () =>
{
assert.strictEqual(result.coreSize, 0);
});
});
suite('esm modules with dynamic dependencies:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze([
{ ast: Parser.parse('import d from "dynamic_a";'), srcPath: '/d.js' },
{ ast: Parser.parse('import c from "dynamic_b";'), srcPath: '/a/c.js' },
{ ast: Parser.parse('import b from "dynamic_c";'), srcPath: '/a/b.js' },
{ ast: Parser.parse('import a from "./a/b"; import aa from "./a/c";'), srcPath: '/a.js' }
],
{
dependencyResolver: (dependency) =>
{
switch (dependency)
{
case 'dynamic_a': return './a';
case 'dynamic_b': return './b';
case 'dynamic_c': return './c';
default: return dependency;
}
}
});
});
teardown(() =>
{
result = undefined;
});
test('modules are in correct order', () =>
{
assert.strictEqual(result.modules[0].srcPath, '/a.js');
assert.strictEqual(result.modules[1].srcPath, '/a/b.js');
assert.strictEqual(result.modules[2].srcPath, '/a/c.js');
assert.strictEqual(result.modules[3].srcPath, '/d.js');
});
test('adjacency list is correct', () =>
{
const testString = '[{"row":0,"cols":[1,2]},{"row":1,"cols":[2]},{"row":2,"cols":[1]},{"row":3,"cols":[0]}]';
assert.strictEqual(JSON.stringify(result.adjacencyList), testString);
});
test('visibility list is correct', () =>
{
const testString = '[{"row":0,"cols":[0,1,2]},{"row":1,"cols":[1,2]},{"row":2,"cols":[1,2]},{"row":3,"cols":[0,1,2,3]}]';
assert.strictEqual(JSON.stringify(result.visibilityList), testString);
});
test('first order density is correct', () =>
{
assert.strictEqual(result.firstOrderDensity, 31.25);
});
test('change cost is correct', () =>
{
assert.strictEqual(result.changeCost, 68.75);
});
test('core size is correct', () =>
{
assert.strictEqual(result.coreSize, 0);
});
});
suite('MacCormack, Rusnak & Baldwin example:', () =>
{
let result;
setup(() =>
{
result = escomplexProject.analyze([
{ ast: Parser.parse('"f";'), srcPath: '/a/c/f.js' },
{ ast: Parser.parse('require("./f");"e";'), srcPath: '/a/c/e.js' },
{ ast: Parser.parse('"d";'), srcPath: '/a/b/d.js' },
{ ast: Parser.parse('require("./c/e");"c";'), srcPath: '/a/c.js' },
{ ast: Parser.parse('require("./b/d");"b";'), srcPath: '/a/b.js' },
{ ast: Parser.parse('require("./a/b");require("./a/c");"a";'), srcPath: '/a.js' }
], { commonjs: true });
});
teardown(() =>
{
result = undefined;
});
test('modules are in correct order', () =>
{
assert.strictEqual(result.modules[0].srcPath, '/a.js');
assert.strictEqual(result.modules[1].srcPath, '/a/b.js');
assert.strictEqual(result.modules[2].srcPath, '/a/b/d.js');
assert.strictEqual(result.modules[3].srcPath, '/a/c.js');
assert.strictEqual(result.modules[4].srcPath, '/a/c/e.js');
assert.strictEqual(result.modules[5].srcPath, '/a/c/f.js');
});
test('adjacency list is correct', () =>
{
const testString = '[{"row":0,"cols":[1,3]},{"row":1,"cols":[2]},{"row":3,"cols":[4]},{"row":4,"cols":[5]}]';
assert.strictEqual(JSON.stringify(result.adjacencyList), testString);
});
test('visibility list is correct', () =>
{
const testString = '[{"row":0,"cols":[0,1,2,3,4,5]},{"row":1,"cols":[1,2]},{"row":2,"cols":[2]},{"row":3,"cols":[3,4,5]},{"row":4,"cols":[4,5]},{"row":5,"cols":[5]}]';
assert.strictEqual(JSON.stringify(result.visibilityList), testString);
});
test('first order density is correct', () =>
{
assert.isTrue(result.firstOrderDensity > 13.88);
assert.isTrue(result.firstOrderDensity < 13.89);
});
test('change cost is correct', () =>
{
assert.isTrue(result.changeCost > 41.66);
assert.isTrue(result.changeCost < 41.67);
});
test('core size is correct', () =>
{
assert.isTrue(result.coreSize > 16.66);
assert.isTrue(result.coreSize < 16.67);
});
});
suite('large project calculation performance', () =>
{
const resultFixture = require('typhonjs-escomplex-test-data/files/large-project/json/project-with-errors');
const resultSkipCalc = escomplexProject.analyze(s_LOCAL_TEST_DATA, { skipCalculation: true });
test('deserialize JSON object should be sufficiently fast', function()
{
this.timeout(100);
ProjectReport.parse(resultFixture);
});
test('running calculations should be sufficiently fast', function()
{
this.timeout(150);
escomplexProject.process(resultSkipCalc);
});
test('running analyze should be sufficiently fast', function()
{
this.timeout(450);
escomplexProject.analyze(s_LOCAL_TEST_DATA);
});
});
});
});
}