Skip to content

Commit

Permalink
Refactor out usages of Suite#_onlyTests and Suite#_onlyTests; closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Jan 31, 2019
1 parent a406503 commit ed1406f
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 53 deletions.
4 changes: 2 additions & 2 deletions lib/interfaces/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ module.exports = function(suites, context, mocha) {
throw new Error('`.only` forbidden');
}

suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);
suite.parent.appendOnlySuite(suite);
}
if (suite.pending) {
if (mocha.options.forbidPending && shouldBeTested(suite)) {
Expand Down Expand Up @@ -175,7 +175,7 @@ module.exports = function(suites, context, mocha) {
* @returns {*}
*/
only: function(mocha, test) {
test.parent._onlyTests = test.parent._onlyTests.concat(test);
test.parent.appendOnlyTest(test);
return test;
},

Expand Down
56 changes: 5 additions & 51 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,9 @@ Runner.prototype.runTest = function(fn) {
if (!test) {
return;
}
if (this.forbidOnly && hasOnly(this.parents().reverse()[0] || this.suite)) {

var suite = this.parents().reverse()[0] || this.suite;
if (this.forbidOnly && suite.hasOnly()) {
fn(new Error('`.only` forbidden'));
return;
}
Expand Down Expand Up @@ -853,8 +855,8 @@ Runner.prototype.run = function(fn) {

function start() {
// If there is an `only` filter
if (hasOnly(rootSuite)) {
filterOnly(rootSuite);
if (rootSuite.hasOnly()) {
rootSuite.filterOnly();
}
self.started = true;
Runner.immediately(function() {
Expand Down Expand Up @@ -910,54 +912,6 @@ Runner.prototype.abort = function() {
return this;
};

/**
* Filter suites based on `isOnly` logic.
*
* @param {Array} suite
* @returns {Boolean}
* @private
*/
function filterOnly(suite) {
if (suite._onlyTests.length) {
// If the suite contains `only` tests, run those and ignore any nested suites.
suite.tests = suite._onlyTests;
suite.suites = [];
} else {
// Otherwise, do not run any of the tests in this suite.
suite.tests = [];
suite._onlySuites.forEach(function(onlySuite) {
// If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.
// Otherwise, all of the tests on this `only` suite should be run, so don't filter it.
if (hasOnly(onlySuite)) {
filterOnly(onlySuite);
}
});
// Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.
suite.suites = suite.suites.filter(function(childSuite) {
return (
suite._onlySuites.indexOf(childSuite) !== -1 || filterOnly(childSuite)
);
});
}
// Keep the suite only if there is something to run
return suite.tests.length || suite.suites.length;
}

/**
* Determines whether a suite has an `only` test or suite as a descendant.
*
* @param {Array} suite
* @returns {Boolean}
* @private
*/
function hasOnly(suite) {
return (
suite._onlyTests.length ||
suite._onlySuites.length ||
suite.suites.some(hasOnly)
);
}

/**
* Filter leaks with the given globals flagged as `ok`.
*
Expand Down
63 changes: 63 additions & 0 deletions lib/suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,3 +427,66 @@ Suite.prototype.run = function run() {
this.emit('run');
}
};

/**
* Determines whether a suite has an `only` test or suite as a descendant.
*
* @returns {Boolean}
*/
Suite.prototype.hasOnly = function hasOnly() {
return (
this._onlyTests.length ||
this._onlySuites.length ||
this.suites.some(function(suite) {
return suite.hasOnly();
})
);
};

/**
* Filter suites based on `isOnly` logic.
*
* @returns {Boolean}
*/
Suite.prototype.filterOnly = function filterOnly() {
if (this._onlyTests.length) {
// If the suite contains `only` tests, run those and ignore any nested suites.
this.tests = this._onlyTests;
this.suites = [];
} else {
// Otherwise, do not run any of the tests in this suite.
this.tests = [];
this._onlySuites.forEach(function(onlySuite) {
// If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.
// Otherwise, all of the tests on this `only` suite should be run, so don't filter it.
if (onlySuite.hasOnly()) {
onlySuite.filterOnly();
}
});
// Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.
var onlySuites = this._onlySuites;
this.suites = this.suites.filter(function(childSuite) {
return onlySuites.indexOf(childSuite) !== -1 || childSuite.filterOnly();
});
}
// Keep the suite only if there is something to run
return this.tests.length || this.suites.length;
};

/**
* Adds a suite to the list of subsuites marked `only`.
*
* @param {Suite} suite
*/
Suite.prototype.appendOnlySuite = function(suite) {
this._onlySuites.push(suite);
};

/**
* Adds a test to the list of tests marked `only`.
*
* @param {Test} test
*/
Suite.prototype.appendOnlyTest = function(test) {
this._onlyTests.push(test);
};

0 comments on commit ed1406f

Please sign in to comment.