Skip to content

Commit

Permalink
Extract library to deal with mocha function names
Browse files Browse the repository at this point in the history
  • Loading branch information
lo1tuma committed Jul 31, 2020
1 parent 8fadc3e commit ebf2102
Show file tree
Hide file tree
Showing 4 changed files with 340 additions and 11 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"files": [ "test/**/*.js", "benchmarks/**/*.js" ],
"env": { "mocha": true },
"rules": {
"max-nested-callbacks": [ "error", 8 ]
"max-nested-callbacks": [ "error", 8 ],
"max-statements": [ "error", 30 ]
}
}
]
Expand Down
14 changes: 4 additions & 10 deletions lib/util/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,16 @@ const isNil = require('ramda/src/isNil');
const propEq = require('ramda/src/propEq');
const pathEq = require('ramda/src/pathEq');
const find = require('ramda/src/find');
const { getTestCaseNames, getSuiteNames } = require('./names');

const isDefined = complement(isNil);
const isCallExpression = both(isDefined, propEq('type', 'CallExpression'));

const describeAliases = [
'describe', 'xdescribe', 'describe.only', 'describe.skip',
'context', 'xcontext', 'context.only', 'context.skip',
'suite', 'xsuite', 'suite.only', 'suite.skip'
];
const hooks = [
'before', 'after', 'beforeEach', 'afterEach', 'beforeAll', 'afterAll',
'setup', 'teardown', 'suiteSetup', 'suiteTeardown'
];
const suiteConfig = [ 'timeout', 'slow', 'retries' ];
const testCaseNames = [
'it', 'it.only', 'it.skip', 'xit',
'test', 'test.only', 'test.skip',
'specify', 'specify.only', 'specify.skip', 'xspecify'
];

function getPropertyName(property) {
return property.name || property.value;
Expand All @@ -38,6 +29,8 @@ function getNodeName(node) {
}

function isDescribe(node, additionalSuiteNames = []) {
const describeAliases = getSuiteNames({ modifiers: [ 'skip', 'only' ] });

return isCallExpression(node) &&
describeAliases.concat(additionalSuiteNames).indexOf(getNodeName(node.callee)) > -1;
}
Expand All @@ -53,6 +46,7 @@ function isHookCall(node) {
}

function isTestCase(node) {
const testCaseNames = getTestCaseNames({ modifiers: [ 'skip', 'only' ] });
return isCallExpression(node) && testCaseNames.indexOf(getNodeName(node.callee)) > -1;
}

Expand Down
77 changes: 77 additions & 0 deletions lib/util/names.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use strict';

const chain = require('ramda/src/chain');

const suiteNames = [
'describe',
'context',
'suite'
];

const suiteModifiers = {
skip: [
'describe.skip',
'context.skip',
'suite.skip',
'xdescribe',
'xcontext',
'xsuite'
],
only: [
'describe.only',
'context.only',
'suite.only'
]
};

const testCaseNames = [
'it',
'test',
'specify'
];

const testCaseModifiers = {
skip: [
'it.skip',
'test.skip',
'specify.skip',
'xit',
'xspecify'
],
only: [
'it.only',
'test.only',
'specify.only'
]
};

function getTestCaseNames(options = {}) {
const { modifiers = [], baseNames = true } = options;
const names = baseNames ? testCaseNames : [];

return names.concat(chain((modifierName) => {
if (testCaseModifiers[modifierName]) {
return testCaseModifiers[modifierName];
}

return [];
}, modifiers));
}

function getSuiteNames(options = {}) {
const { modifiers = [], baseNames = true, additionalSuiteNames = [] } = options;
const names = baseNames ? suiteNames.concat(additionalSuiteNames) : [];

return names.concat(chain((modifierName) => {
if (suiteModifiers[modifierName]) {
return suiteModifiers[modifierName];
}

return [];
}, modifiers));
}

module.exports = {
getTestCaseNames,
getSuiteNames
};
257 changes: 257 additions & 0 deletions test/util/namesSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
'use strict';

const { expect } = require('chai');
const { getTestCaseNames, getSuiteNames } = require('../../lib/util/names');

describe('mocha names', () => {
describe('test case names', () => {
it('returns the list of basic test case names when no options are provided', () => {
const testCaseNames = getTestCaseNames();

expect(testCaseNames).to.deep.equal([
'it',
'test',
'specify'
]);
});

it('returns an empty list when no modifiers and no base names are wanted', () => {
const testCaseNames = getTestCaseNames({ baseNames: false });

expect(testCaseNames).to.deep.equal([]);
});

it('always returns a new array', () => {
const testCaseNames1 = getTestCaseNames({ baseNames: false });
const testCaseNames2 = getTestCaseNames({ baseNames: false });

expect(testCaseNames1).to.deep.equal(testCaseNames2);
expect(testCaseNames1).to.not.equal(testCaseNames2);
});

it('ignores invalid modifiers', () => {
const testCaseNames = getTestCaseNames({ modifiers: [ 'foo' ], baseNames: false });

expect(testCaseNames).to.deep.equal([]);
});

it('returns the list of test case names with and without "skip" modifiers applied', () => {
const testCaseNames = getTestCaseNames({ modifiers: [ 'skip' ] });

expect(testCaseNames).to.deep.equal([
'it',
'test',
'specify',
'it.skip',
'test.skip',
'specify.skip',
'xit',
'xspecify'
]);
});

it('returns the list of test case names only with "skip" modifiers applied', () => {
const testCaseNames = getTestCaseNames({ modifiers: [ 'skip' ], baseNames: false });

expect(testCaseNames).to.deep.equal([
'it.skip',
'test.skip',
'specify.skip',
'xit',
'xspecify'
]);
});

it('returns the list of test case names with and without "only" modifiers applied', () => {
const testCaseNames = getTestCaseNames({ modifiers: [ 'only' ] });

expect(testCaseNames).to.deep.equal([
'it',
'test',
'specify',
'it.only',
'test.only',
'specify.only'
]);
});

it('returns the list of test case names only with "only" modifiers applied', () => {
const testCaseNames = getTestCaseNames({ modifiers: [ 'only' ], baseNames: false });

expect(testCaseNames).to.deep.equal([
'it.only',
'test.only',
'specify.only'
]);
});

it('returns the list of all test case names', () => {
const testCaseNames = getTestCaseNames({ modifiers: [ 'skip', 'only' ] });

expect(testCaseNames).to.deep.equal([
'it',
'test',
'specify',
'it.skip',
'test.skip',
'specify.skip',
'xit',
'xspecify',
'it.only',
'test.only',
'specify.only'
]);
});

it('returns the list of test case names only with modifiers applied', () => {
const testCaseNames = getTestCaseNames({ modifiers: [ 'skip', 'only' ], baseNames: false });

expect(testCaseNames).to.deep.equal([
'it.skip',
'test.skip',
'specify.skip',
'xit',
'xspecify',
'it.only',
'test.only',
'specify.only'
]);
});
});

describe('suite names', () => {
it('returns the list of basic suite names when no options are provided', () => {
const suiteNames = getSuiteNames();

expect(suiteNames).to.deep.equal([
'describe',
'context',
'suite'
]);
});

it('returns an empty list when no modifiers and no base names are wanted', () => {
const suiteNames = getSuiteNames({ baseNames: false });

expect(suiteNames).to.deep.equal([]);
});

it('always returns a new array', () => {
const suiteNames1 = getSuiteNames({ baseNames: false });
const suiteNames2 = getSuiteNames({ baseNames: false });

expect(suiteNames1).to.deep.equal(suiteNames2);
expect(suiteNames1).to.not.equal(suiteNames2);
});

it('ignores invalid modifiers', () => {
const suiteNames = getSuiteNames({ modifiers: [ 'foo' ], baseNames: false });

expect(suiteNames).to.deep.equal([]);
});

it('returns the list of suite names with and without "skip" modifiers applied', () => {
const suiteNames = getSuiteNames({ modifiers: [ 'skip' ] });

expect(suiteNames).to.deep.equal([
'describe',
'context',
'suite',
'describe.skip',
'context.skip',
'suite.skip',
'xdescribe',
'xcontext',
'xsuite'
]);
});

it('returns the list of suite names only with "skip" modifiers applied', () => {
const suiteNames = getSuiteNames({ modifiers: [ 'skip' ], baseNames: false });

expect(suiteNames).to.deep.equal([
'describe.skip',
'context.skip',
'suite.skip',
'xdescribe',
'xcontext',
'xsuite'
]);
});

it('returns the list of suite names with and without "only" modifiers applied', () => {
const suiteNames = getSuiteNames({ modifiers: [ 'only' ] });

expect(suiteNames).to.deep.equal([
'describe',
'context',
'suite',
'describe.only',
'context.only',
'suite.only'
]);
});

it('returns the list of suite names only with "only" modifiers applied', () => {
const suiteNames = getSuiteNames({ modifiers: [ 'only' ], baseNames: false });

expect(suiteNames).to.deep.equal([
'describe.only',
'context.only',
'suite.only'
]);
});

it('returns the list of all suite names', () => {
const suiteNames = getSuiteNames({ modifiers: [ 'skip', 'only' ] });

expect(suiteNames).to.deep.equal([
'describe',
'context',
'suite',
'describe.skip',
'context.skip',
'suite.skip',
'xdescribe',
'xcontext',
'xsuite',
'describe.only',
'context.only',
'suite.only'
]);
});

it('returns the list of suite names names only with modifiers applied', () => {
const suiteNames = getSuiteNames({ modifiers: [ 'skip', 'only' ], baseNames: false });

expect(suiteNames).to.deep.equal([
'describe.skip',
'context.skip',
'suite.skip',
'xdescribe',
'xcontext',
'xsuite',
'describe.only',
'context.only',
'suite.only'
]);
});

it('returns the additional suite names', () => {
const suiteNames = getSuiteNames({ additionalSuiteNames: [ 'myCustomDescribe' ] });

expect(suiteNames).to.deep.equal([
'describe',
'context',
'suite',
'myCustomDescribe'
]);
});

it('doesn’t return the additional suite names when base names shouldn’t be included', () => {
const suiteNames = getSuiteNames({ additionalSuiteNames: [ 'myCustomDescribe' ], baseNames: false });

expect(suiteNames).to.deep.equal([]);
});
});
});

0 comments on commit ebf2102

Please sign in to comment.