src/moduleCore.js
'use strict';
import { assert } from 'chai';
import parsers from './parsers';
import * as testconfig from './testconfig';
if (testconfig.modules['moduleCore'])
{
parsers.forEach((parser) =>
{
suite(`(${parser.name}): module (Core):`, () =>
{
suite('function call:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('parseInt("10", 10);');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct physical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.physical, 1);
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 1);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
test('methodAggregate has correct cyclomatic complexity density', () =>
{
assert.strictEqual(report.methodAggregate.cyclomaticDensity, 100);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 1);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 1);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
test('methodAggregate has correct Halstead operator identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operators.identifiers,
report.methodAggregate.halstead.operators.distinct
);
});
test('methodAggregate has correct Halstead operand identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operands.identifiers,
report.methodAggregate.halstead.operands.distinct
);
});
test('methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(report.methodAggregate.halstead.length, 4);
});
test('methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(report.methodAggregate.halstead.vocabulary, 4);
});
test('methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methodAggregate.halstead.difficulty, 0.5);
});
test('methodAggregate has correct Halstead volume', () =>
{
assert.strictEqual(report.methodAggregate.halstead.volume, 8);
});
test('methodAggregate has correct Halstead effort', () =>
{
assert.strictEqual(report.methodAggregate.halstead.effort, 4);
});
test('methodAggregate has correct Halstead bugs', () =>
{
assert.strictEqual(report.methodAggregate.halstead.bugs, 0.003);
});
test('methodAggregate has correct Halstead time', () =>
{
assert.strictEqual(report.methodAggregate.halstead.time, 0.222);
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 166.259);
});
test('methodAggregate has correct parameter count', () =>
{
assert.strictEqual(report.methodAggregate.params, 0);
});
test('mean logical LOC is correct', () =>
{
assert.strictEqual(report.methodAverage.sloc.logical, 1);
});
test('mean cyclomatic complexity is correct', () =>
{
assert.strictEqual(report.methodAverage.cyclomatic, 1);
});
test('mean Halstead effort is correct', () =>
{
assert.strictEqual(report.methodAverage.halstead.effort, 4);
});
test('mean parameter count is correct', () =>
{
assert.strictEqual(report.methodAverage.params, 0);
});
test('dependencies is correct', () =>
{
assert.lengthOf(report.dependencies, 0);
});
});
suite('condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('if (true) { "foo"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct physical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.physical, 1);
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct cyclomatic complexity density', () =>
{
assert.strictEqual(report.methodAggregate.cyclomaticDensity, 100);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 1);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 1);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 2);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
test('methodAggregate has correct Halstead operator identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operators.identifiers,
report.methodAggregate.halstead.operators.distinct
);
});
test('methodAggregate has correct Halstead operand identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operands.identifiers,
report.methodAggregate.halstead.operands.distinct
);
});
test('methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(report.methodAggregate.halstead.length, 3);
});
test('methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(report.methodAggregate.halstead.vocabulary, 3);
});
test('methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methodAggregate.halstead.difficulty, 0.5);
});
test('methodAggregate has correct Halstead volume', () =>
{
assert.strictEqual(report.methodAggregate.halstead.volume, 4.755);
});
test('methodAggregate has correct Halstead effort', () =>
{
assert.strictEqual(report.methodAggregate.halstead.effort, 2.377);
});
test('methodAggregate has correct Halstead bugs', () =>
{
assert.strictEqual(report.methodAggregate.halstead.bugs, 0.002);
});
test('methodAggregate has correct Halstead time', () =>
{
assert.strictEqual(report.methodAggregate.halstead.time, 0.132);
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 156.65);
});
test('mean logical LOC is correct', () =>
{
assert.strictEqual(report.methodAverage.sloc.logical, 2);
});
test('mean cyclomatic complexity is correct', () =>
{
assert.strictEqual(report.methodAverage.cyclomatic, 2);
});
test('mean Halstead effort is correct', () =>
{
assert.strictEqual(report.methodAverage.halstead.effort, 2.377);
});
test('mean parameter count is correct', () =>
{
assert.strictEqual(report.methodAverage.params, 0);
});
test('dependencies is correct', () =>
{
assert.lengthOf(report.dependencies, 0);
});
});
suite('condition with alternate:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('if (true) { "foo"; } else { "bar"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct physical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.physical, 1);
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 4);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
test('methodAggregate has correct Halstead operator identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operators.identifiers,
report.methodAggregate.halstead.operators.distinct
);
});
test('methodAggregate has correct Halstead operand identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operands.identifiers,
report.methodAggregate.halstead.operands.distinct
);
});
test('methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(report.methodAggregate.halstead.length, 5);
});
test('methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(report.methodAggregate.halstead.vocabulary, 5);
});
test('methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methodAggregate.halstead.difficulty, 1);
});
test('methodAggregate has correct Halstead volume', () =>
{
assert.strictEqual(report.methodAggregate.halstead.volume, 11.61);
});
test('methodAggregate has correct Halstead effort', () =>
{
assert.strictEqual(report.methodAggregate.halstead.effort, 11.61);
});
test('methodAggregate has correct Halstead bugs', () =>
{
assert.strictEqual(report.methodAggregate.halstead.bugs, 0.004);
});
test('methodAggregate has correct Halstead time', () =>
{
assert.strictEqual(report.methodAggregate.halstead.time, 0.645);
});
});
suite('dual condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('if (true) { "foo"; } if (false) { "bar"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 4);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 1);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
test('methodAggregate has correct Halstead operator identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operators.identifiers,
report.methodAggregate.halstead.operators.distinct
);
});
test('methodAggregate has correct Halstead operand identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operands.identifiers,
report.methodAggregate.halstead.operands.distinct
);
});
test('methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(report.methodAggregate.halstead.length, 6);
});
test('methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(report.methodAggregate.halstead.vocabulary, 5);
});
test('methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methodAggregate.halstead.difficulty, 0.5);
});
});
suite('alternate dual condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('if (true) { "foo"; } else if (false) { "bar"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 5);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
test('methodAggregate has correct Halstead operator identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operators.identifiers,
report.methodAggregate.halstead.operators.distinct
);
});
test('methodAggregate has correct Halstead operand identifier length', () =>
{
assert.lengthOf(
report.methodAggregate.halstead.operands.identifiers,
report.methodAggregate.halstead.operands.distinct
);
});
});
suite('nested condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('if (true) { "foo"; if (false) { "bar"; } }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 4);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
});
suite('switch statement:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'switch (Date.now()) { case 1: "foo"; break; case 2: "bar"; break; default: "baz"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 9);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methodAggregate has correct cyclomatic complexity density', () =>
{
assert.isTrue(report.methodAggregate.cyclomaticDensity > 33.3);
assert.isTrue(report.methodAggregate.cyclomaticDensity < 33.4);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 8);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 6);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 7);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 7);
});
});
suite('switch statement with fall-through case:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('switch (Date.now()) { case 1: case 2: "foo"; break; default: "bar"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 7);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 7);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 6);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 6);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 6);
});
});
suite('switch statement containing condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'switch (Date.now()) { '
+ ' case 1: "foo"; break; '
+ ' case 2: "bar"; break; '
+ ' default: if (true) { "baz"; } '
+ '}');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 10);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 4);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 9);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 7);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 8);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 8);
});
});
suite('for loop:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var i; for (i = 0; i < 10; i += 1) { "foo"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 3);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 5);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 5);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 8);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 5);
});
test('methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(report.methodAggregate.halstead.length, 13);
});
test('methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(report.methodAggregate.halstead.vocabulary, 10);
});
test('methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methodAggregate.halstead.difficulty, 4);
});
});
suite('for loop containing condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var i; for (i = 0; i < 10; i += 1) { if (true) { "foo"; } }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 6);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 6);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 9);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 6);
});
});
suite('for...in loop:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var property; for (property in { foo: "bar", baz: "qux" }) { "wibble"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 5);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 5);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 4);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 7);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 6);
});
test('methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(report.methodAggregate.halstead.length, 12);
});
test('methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(report.methodAggregate.halstead.vocabulary, 10);
});
test('methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methodAggregate.halstead.difficulty, 2.333);
});
});
suite('for...in loop containing condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'var property, object = { foo: "bar", baz: "qux" }; '
+ 'for (property in object) { if (object.hasOwnProperty(property)) { "wibble"; } }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 9);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 8);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 12);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 8);
});
});
suite('while loop:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('while (true) { "foo"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 1);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 1);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 2);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
});
suite('while loop containing condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('while (true) { if (true) { "foo"; } }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
});
suite('do...while loop:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('do { "foo"; } while (true)');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 3);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 1);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 1);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 2);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
});
suite('do...while loop containing condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('do { if (true) { "foo"; } } while (true)');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
});
suite('try...catch:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('try { "foo"; } catch (e) { e.message; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 4);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('try containing condition', () =>
{
let report;
setup(() =>
{
report = parser.analyze('try { if (true) { "foo"; } } catch (e) { "bar"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
});
suite('catch containing condition', () =>
{
let report;
setup(() =>
{
report = parser.analyze('try { "foo"; } catch (e) { if (true) { "bar"; } }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
});
suite('catch with finally containing condition', () =>
{
let report;
setup(() =>
{
report = parser.analyze('try { "foo"; } catch (e) { } finally { if (true) { "bar"; } }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 4);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 4);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
});
suite('function declaration:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { "bar"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, 'foo');
});
test('method has correct physical lines of code', () =>
{
assert.strictEqual(report.methods[0].sloc.physical, 1);
});
test('method has correct logical lines of code', () =>
{
assert.strictEqual(report.methods[0].sloc.logical, 1);
});
test('method has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methods[0].cyclomatic, 1);
});
test('method has correct parameter count', () =>
{
assert.strictEqual(report.methods[0].params, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 1);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 1);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 2);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
test('methodAggregate has correct Halstead length', () =>
{
assert.strictEqual(report.methodAggregate.halstead.length, 3);
});
test('methodAggregate has correct Halstead vocabulary', () =>
{
assert.strictEqual(report.methodAggregate.halstead.vocabulary, 3);
});
test('methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methodAggregate.halstead.difficulty, 0.5);
});
test('method has correct Halstead length', () =>
{
assert.strictEqual(report.methods[0].halstead.length, 1);
});
test('method has correct Halstead vocabulary', () =>
{
assert.strictEqual(report.methods[0].halstead.vocabulary, 1);
});
test('method has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methods[0].halstead.difficulty, 0);
});
test('method has correct Halstead volume', () =>
{
assert.strictEqual(report.methods[0].halstead.volume, 0);
});
test('method has correct Halstead effort', () =>
{
assert.strictEqual(report.methods[0].halstead.effort, 0);
});
test('method has correct Halstead bugs', () =>
{
assert.strictEqual(report.methods[0].halstead.bugs, 0);
});
test('method has correct Halstead time', () =>
{
assert.strictEqual(report.methods[0].halstead.time, 0);
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 171);
});
test('methodAggregate has correct parameter count', () =>
{
assert.strictEqual(report.methodAggregate.params, 0);
});
});
suite('nested function declaration:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { bar(); function bar () { "baz"; } }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 4);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 2);
});
test('first method has correct logical lines of code', () =>
{
assert.strictEqual(report.methods[0].sloc.logical, 2);
});
test('second method has correct logical lines of code', () =>
{
assert.strictEqual(report.methods[1].sloc.logical, 1);
});
test('first method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, 'foo');
});
test('second method has correct name', () =>
{
assert.strictEqual(report.methods[1].name, 'bar');
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('function declaration containing condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { if (true) { "bar"; } }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('method has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methods[0].cyclomatic, 2);
});
test('method has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methods[0].cyclomaticDensity, 100);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('assignment expression', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = "bar";');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 1);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
test('methods is empty', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 2);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
});
suite('ternary condtional expression assigned to variable:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = true ? "bar" : "baz";');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 1);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
});
suite('nested ternary condtional expression:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = true ? "bar" : (false ? "baz" : "qux");');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 1);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 4);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 6);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 6);
});
});
suite('logical or expression assigned to variable:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = true || false;');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 1);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('anonymous function assigned to variable:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = function () { "bar"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, '<anonymous>');
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('named function assigned to variable:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = function bar () { "baz"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, 'bar');
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('ternary condtional expression returned from function:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { return true ? "bar" : "baz"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('method has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methods[0].cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
});
suite('logical or expression returned from function:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { return true || false; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('method has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methods[0].cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('anonymous function returned from function:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { return function () { "bar"; }; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 3);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 2);
});
test('first method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, 'foo');
});
test('second method is anonymous', () =>
{
assert.strictEqual(report.methods[1].name, '<anonymous>');
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('named function returned from function:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { return function bar () { "baz"; }; }');
});
teardown(() =>
{
report = undefined;
});
test('second method has correct name', () =>
{
assert.strictEqual(report.methods[1].name, 'bar');
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('ternary condtional expression passed as argument:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('parseInt("10", true ? 10 : 8);');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 5);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 5);
});
});
suite('logical or expression passed as argument:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('parseInt("10", 10 || 8);');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
});
suite('anonymous function passed as argument:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('setTimeout(function () { "foo"; }, 1000);');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('method is anonymous', () =>
{
assert.strictEqual(report.methods[0].name, '<anonymous>');
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
});
suite('named function passed as argument:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('setTimeout(function foo () { "bar"; }, 1000);');
});
teardown(() =>
{
report = undefined;
});
test('method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, 'foo');
});
});
suite('logical AND expression:', () =>
{
test('methodAggregate has correct cyclomatic complexity', () =>
{
const report = parser.analyze('var foo = true && false;', {});
assert.strictEqual(report.methodAverage.cyclomatic, 2);
});
});
suite('logical OR expression with logicalor false:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = true || false;', { logicalor: false });
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
});
suite('switch statement with switchcase false:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'switch (Date.now()) { case 1: "foo"; break; case 2: "bar"; break; default: "baz"; }',
{ switchcase: false });
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
});
suite('for...in loop with forin true:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'var property; for (property in { foo: "bar", baz: "qux" }) { "wibble"; }', { forin: true });
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
});
suite('try...catch with trycatch true:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('try { "foo"; } catch (e) { e.message; }', { trycatch: true });
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
});
suite('IIFE:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'(function (foo) { if (foo === "foo") { console.log(foo); return; } "bar"; }("foo"));');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 6);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('method has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methods[0].cyclomatic, 2);
});
test('method has correct parameter count', () =>
{
assert.strictEqual(report.methods[0].params, 1);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 7);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 6);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 9);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 6);
});
test('methodAggregate has correct parameter count', () =>
{
assert.strictEqual(report.methodAggregate.params, 1);
});
});
suite('logical and condition:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('if ("foo" && "bar") { "baz"; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 3);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 3);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 3);
});
});
suite('call on function object:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('(function () { "foo"; }).call(this);');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 3);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
});
suite('anonymous function assigned to property:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = {}; foo.bar = function () { "foobar"; };');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 3);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, '<anonymous>');
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 6);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 5);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 5);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 4);
});
});
suite('anonymous function assigned to property of literal:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('"".bar = function () { "bar"; };');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 2);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, '<anonymous>');
});
});
suite('empty object literal:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = {};');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 1);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 3);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 3);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 1);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 1);
});
});
suite('function property of literal object:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = { bar: "bar", baz: function () { "baz"; } };');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 4);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, '<anonymous>');
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 6);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 5);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 6);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 6);
});
});
suite('duplicate function properties of literal object:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'var foo = { bar: function () { if (true) { "bar"; } }, bar: function () { "bar"; } };');
});
teardown(() =>
{
report = undefined;
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 2);
});
test('first method has correct name', () =>
{
assert.strictEqual(report.methods[0].name, '<anonymous>');
});
test('second method has correct name', () =>
{
assert.strictEqual(report.methods[1].name, '<anonymous>');
});
test('first method has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methods[0].cyclomatic, 2);
});
test('second method has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methods[1].cyclomatic, 1);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 2);
});
});
suite('throw exception:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('try { throw new Error("foo"); } catch (e) { alert(error.message); }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 4);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 6);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 6);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 6);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 6);
});
});
suite('prefix and postfix increment:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var a = 0; ++a; a++;');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 3);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 4);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 4);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 4);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
});
suite('array literal:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('[ "foo", "bar" ];');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 1);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 0);
});
test('methodAggregate has correct cyclomatic complexity', () =>
{
assert.strictEqual(report.methodAggregate.cyclomatic, 1);
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 1);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 1);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 2);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 2);
});
});
suite('multiple physical lines:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'// This is a\n// multi-line\n// comment.\nparseInt(\n\t(function () {\n\t\t// Moar\n\t\t'
+ '// commentz!\n\t\treturn [\n\t\t\t"1",\n\t\t\t"0"\n\t\t].join("");\n\t}()),\n\t10\n);');
});
teardown(() =>
{
report = undefined;
});
test('report has correct line start / end', () =>
{
switch (parser.name)
{
// acorn & babylon sets the start location at line 1 (first comment) instead of line 4 (first
// line of code).
case 'acorn':
case 'babylon':
assert.strictEqual(report.lineStart, 1);
assert.strictEqual(report.lineEnd, 14);
break;
default:
assert.strictEqual(report.lineStart, 4);
assert.strictEqual(report.lineEnd, 14);
}
});
test('methodAggregate has correct physical lines of code', () =>
{
switch (parser.name)
{
// acorn & babylon sets the start location at line 1 (first comment) instead of line 4 (first
// line of code).
case 'acorn':
case 'babylon':
assert.strictEqual(report.methodAggregate.sloc.physical, 14);
break;
default:
assert.strictEqual(report.methodAggregate.sloc.physical, 11);
}
});
test('methodAggregate has correct logical lines of code', () =>
{
assert.strictEqual(report.methodAggregate.sloc.logical, 4);
});
test('methods has correct length', () =>
{
assert.lengthOf(report.methods, 1);
});
test('method has correct physical lines of code', () =>
{
assert.strictEqual(report.methods[0].sloc.physical, 8);
});
test('method has correct logical lines of code', () =>
{
assert.strictEqual(report.methods[0].sloc.logical, 2);
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 146.532);
});
});
suite('multiple functions:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'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); }');
});
teardown(() =>
{
report = undefined;
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 128.115);
});
test('first method has correct parameter count', () =>
{
assert.strictEqual(report.methods[0].params, 2);
});
test('second method has correct parameter count', () =>
{
assert.strictEqual(report.methods[1].params, 2);
});
test('methodAggregate has correct parameter count', () =>
{
assert.strictEqual(report.methodAggregate.params, 4);
});
test('mean logical LOC is correct', () =>
{
assert.strictEqual(report.methodAverage.sloc.logical, 4);
});
test('mean cyclomatic complexity is correct', () =>
{
assert.strictEqual(report.methodAverage.cyclomatic, 2);
});
test('mean Halstead effort is correct', () =>
{
assert.strictEqual(report.methodAverage.halstead.effort, 374.713);
});
test('mean parameter count is correct', () =>
{
assert.strictEqual(report.methodAverage.params, 2);
});
});
suite('issue 3 / reddit.ISV_Damocles:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'var callback = arguments[arguments.length-1] instanceof Function ? '
+ 'arguments[arguments.length-1] : function() {};');
});
teardown(() =>
{
report = undefined;
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 171);
});
});
suite('empty return:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { return; }');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct Halstead total operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.total, 2);
});
test('methodAggregate has correct Halstead distinct operators', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operators.distinct, 2);
});
test('methodAggregate has correct Halstead total operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.total, 1);
});
test('methodAggregate has correct Halstead distinct operands', () =>
{
assert.strictEqual(report.methodAggregate.halstead.operands.distinct, 1);
});
test('methodAggregate has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methodAggregate.halstead.difficulty, 1);
});
test('method has correct Halstead difficulty', () =>
{
assert.strictEqual(report.methods[0].halstead.difficulty, 0.5);
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 171);
});
});
suite('Empty nested functions', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo () { function bar () {} }');
});
teardown(() =>
{
report = undefined;
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 171);
});
});
suite('Microsoft variant maintainability index:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'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); }',
{ newmi: true }
);
});
teardown(() =>
{
report = undefined;
});
test('maintainability index is correct', () =>
{
assert.strictEqual(report.maintainability, 74.921);
});
});
suite('Functions with consistent parameter counts:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('function foo (a) {} function bar (b) {} function baz (c) {}');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct parameter count', () =>
{
assert.strictEqual(report.methodAggregate.params, 3);
});
test('mean parameter count is correct', () =>
{
assert.strictEqual(report.methodAverage.params, 1);
});
});
suite('Functions with inconsistent parameter counts:', () =>
{
let report;
setup(() =>
{
report = parser.analyze(
'function foo (a, b, c, d, e) {} function bar (a, b, c, d, e) {} function baz (a) {}');
});
teardown(() =>
{
report = undefined;
});
test('methodAggregate has correct parameter count', () =>
{
assert.strictEqual(report.methodAggregate.params, 11);
});
test('mean parameter count is correct', () =>
{
assert.strictEqual(report.methodAverage.params, 3.667);
});
});
suite('CommonJS require literal:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('require("./foo");', { commonjs: true });
});
teardown(() =>
{
report = undefined;
});
test('dependencies has correct length', () =>
{
assert.lengthOf(report.dependencies, 1);
});
test('dependencies are correct', () =>
{
assert.isObject(report.dependencies[0]);
assert.strictEqual(report.dependencies[0].line, 1);
assert.strictEqual(report.dependencies[0].path, './foo');
assert.strictEqual(report.dependencies[0].type, 'cjs');
});
});
suite('alternative CommonJS require literal:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('require("./bar");', { commonjs: true });
});
teardown(() =>
{
report = undefined;
});
test('dependencies are correct', () =>
{
assert.strictEqual(report.dependencies[0].path, './bar');
});
});
suite('CommonJS require multiple:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('require("./foo");\nrequire("./bar");\n\nrequire("./baz");', { commonjs: true });
});
teardown(() =>
{
report = undefined;
});
test('dependencies has correct length', () =>
{
assert.lengthOf(report.dependencies, 3);
});
test('dependencies are correct', () =>
{
assert.strictEqual(report.dependencies[0].line, 1);
assert.strictEqual(report.dependencies[0].path, './foo');
assert.strictEqual(report.dependencies[1].line, 2);
assert.strictEqual(report.dependencies[1].path, './bar');
assert.strictEqual(report.dependencies[2].line, 4);
assert.strictEqual(report.dependencies[2].path, './baz');
});
});
suite('CommonJS require variable:', () =>
{
let report;
setup(() =>
{
report = parser.analyze('var foo = "./foo";require(foo);', { commonjs: true });
});
teardown(() =>
{
report = undefined;
});
test('dependencies has correct length', () =>
{
assert.lengthOf(report.dependencies, 1);
});
test('dependencies are correct', () =>
{
assert.isObject(report.dependencies[0]);
assert.strictEqual(report.dependencies[0].line, 1);
assert.strictEqual(report.dependencies[0].path, '* dynamic dependency *');
assert.strictEqual(report.dependencies[0].type, 'cjs');
});
});
});
});
}