diff --git a/packages/mocha/src/flag.js b/packages/mocha/src/flag.js index 957f84ff8..49c7b0fd2 100644 --- a/packages/mocha/src/flag.js +++ b/packages/mocha/src/flag.js @@ -17,27 +17,46 @@ function areAllFlagsPresent(names, total) { }); } +function infoFor(stringOrObject) { + let name; + let flags = []; + if (typeof stringOrObject === 'string') { + name = stringOrObject; + } else { + name = stringOrObject.name; + if (stringOrObject.flags) { + flags = stringOrObject.flags; + } + } + + return { name, flags }; +} + +function formatName(name, flags, handler) { + if (flags.length) { + name = formatTitle(name); + name += `${handler.titleSeparator || titleSeparator}flags: ${flags.join(', ')}`; + } + + return name; +} + + +function isSkipped({ flags, total, isDeactivated }) { + return !isDeactivated && flags.length && !areAllFlagsPresent(flags, total); +} + function flaggedTest(total, isDeactivated) { return it => { return function flaggedTest(stringOrObject, callback) { - let name; - let flags = []; - if (typeof stringOrObject === 'string') { - name = stringOrObject; - } else { - name = stringOrObject.name; - if (stringOrObject.flags) { - flags = stringOrObject.flags; - } - } + let { name, flags } = infoFor(stringOrObject); - if (!isDeactivated && flags.length) { - name = formatTitle(name); - name += `${it.titleSeparator || titleSeparator}flags: ${flags.join(', ')}`; + if (!isDeactivated) { + name = formatName(name, flags, it); } it(name, async function () { - if (!isDeactivated && flags.length && !areAllFlagsPresent(flags, total)) { + if (isSkipped({ flags, total, isDeactivated })) { this.skip(); return; } @@ -48,6 +67,51 @@ function flaggedTest(total, isDeactivated) { }; } +const mochaBeforeEach = global.beforeEach; +const mochaAfterEach = global.afterEach; + +function flaggedDescribe(total, isDeactivated) { + return (describe) => { + return function _flaggedDescribe(stringOrObjectOrCallback, callback) { + let { name, flags } = infoFor(stringOrObjectOrCallback); + + if (!isDeactivated) { + name = formatName(name, flags, describe); + } + + if (!callback) { + callback = stringOrObjectOrCallback; + } + + describe(name, function() { + function beforeEach(beforeEachCallback) { + return mochaBeforeEach(function (...args) { + if (isSkipped({ flags, total, isDeactivated })) { + this.skip(); + return; + } + + return beforeEachCallback.apply(this, args); + }); + } + + function afterEach(afterEachCallback) { + return mochaAfterEach(function (...args) { + if (isSkipped({ flags, total, isDeactivated })) { + this.skip(); + return; + } + + return afterEachCallback.apply(this, args); + }); + } + + callback.apply(this, [{ beforeEach, afterEach }]); + }); + }; + }; +} + function create(it, flags, isDeactivated) { let _flaggedTest = flaggedTest(flags, isDeactivated); @@ -56,6 +120,15 @@ function create(it, flags, isDeactivated) { return _it; } +function createDescribe(describe, flags, isDeactivated) { + let _flaggedDescribe = flaggedDescribe(flags, isDeactivated); + + let _describe = wrap(describe, _flaggedDescribe); + + return _describe; +} + module.exports = { create, + createDescribe, }; diff --git a/packages/mocha/src/index.js b/packages/mocha/src/index.js index 7d13f05e3..ecd8a7ae0 100644 --- a/packages/mocha/src/index.js +++ b/packages/mocha/src/index.js @@ -4,6 +4,10 @@ const Mocha = require('mocha'); const { promisify } = require('util'); const glob = promisify(require('glob')); const { buildGrep } = require('./tag'); +const { + create: createFlaggedTest, + createDescribe: createFlaggedDescribe, +} = require('./flag'); async function runMocha(mocha) { let runner; @@ -78,5 +82,6 @@ async function runTests({ module.exports = { runTests, createRolesHelper: require('./role').create, - createFlaggedTest: require('./flag').create, + createFlaggedTest, + createFlaggedDescribe, };