Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(esm): allow import from mocha in parallel #4574

Merged
merged 4 commits into from Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
63 changes: 48 additions & 15 deletions lib/mocha.js
Expand Up @@ -96,6 +96,52 @@ exports.Suite = Suite;
exports.Hook = require('./hook');
exports.Test = require('./test');

let currentContext;
exports.afterEach = function(...args) {
(currentContext.afterEach || currentContext.teardown).apply(this, args);
};
exports.after = function(...args) {
(currentContext.after || currentContext.suiteTeardown).apply(this, args);
};
exports.beforeEach = function(...args) {
(currentContext.beforeEach || currentContext.setup).apply(this, args);
};
exports.before = function(...args) {
(currentContext.before || currentContext.suiteSetup).apply(this, args);
};
exports.describe = function(...args) {
nicojs marked this conversation as resolved.
Show resolved Hide resolved
(currentContext.describe || currentContext.suite).apply(this, args);
};
exports.describe.only = function(...args) {
(currentContext.describe || currentContext.suite).only.apply(this, args);
};
exports.describe.skip = function(...args) {
(currentContext.describe || currentContext.suite).skip.apply(this, args);
};
exports.it = function(...args) {
(currentContext.it || currentContext.test).apply(this, args);
};
exports.it.only = function(...args) {
(currentContext.it || currentContext.test).only.apply(this, args);
};
exports.it.skip = function(...args) {
(
currentContext.xit ||
(currentContext.test && currentContext.test.skip)
).apply(this, args);
};
exports.xdescribe = exports.describe.skip;
exports.xit = exports.it.skip;
exports.setup = exports.beforeEach;
exports.suiteSetup = exports.before;
exports.suiteTeardown = exports.after;
exports.suite = exports.describe;
exports.teardown = exports.afterEach;
exports.test = exports.it;
exports.run = function(...args) {
currentContext.run.apply(this, args);
};

/**
* Constructs a new Mocha instance with `options`.
*
Expand Down Expand Up @@ -351,20 +397,7 @@ Mocha.prototype.ui = function(ui) {
bindInterface(this.suite);

this.suite.on(EVENT_FILE_PRE_REQUIRE, function(context) {
exports.afterEach = context.afterEach || context.teardown;
exports.after = context.after || context.suiteTeardown;
exports.beforeEach = context.beforeEach || context.setup;
exports.before = context.before || context.suiteSetup;
exports.describe = context.describe || context.suite;
exports.it = context.it || context.test;
exports.xit = context.xit || (context.test && context.test.skip);
exports.setup = context.setup || context.beforeEach;
exports.suiteSetup = context.suiteSetup || context.before;
exports.suiteTeardown = context.suiteTeardown || context.after;
exports.suite = context.suite || context.describe;
exports.teardown = context.teardown || context.afterEach;
exports.test = context.test || context.it;
exports.run = context.run;
currentContext = context;
});

return this;
Expand Down Expand Up @@ -1299,7 +1332,7 @@ Mocha.prototype.hasGlobalTeardownFixtures = function hasGlobalTeardownFixtures()
* A (sync) function to assert a user-supplied plugin implementation is valid.
*
* Defined in a {@link PluginDefinition}.

* @callback PluginValidator
* @param {*} value - Value to check
* @this {PluginDefinition}
Expand Down
20 changes: 20 additions & 0 deletions test/integration/common-js-require.spec.js
@@ -0,0 +1,20 @@
'use strict';

const {runMochaAsync} = require('./helpers');

describe('common js require', () => {
it('should be able to run a test where all mocha exports are used', async () => {
const result = await runMochaAsync('common-js-require.fixture.js', [
'--delay'
]);
expect(result.output, 'to contain', 'running before');
expect(result.output, 'to contain', 'running suiteSetup');
expect(result.output, 'to contain', 'running setup');
expect(result.output, 'to contain', 'running beforeEach');
expect(result.output, 'to contain', 'running it');
expect(result.output, 'to contain', 'running afterEach');
expect(result.output, 'to contain', 'running teardown');
expect(result.output, 'to contain', 'running suiteTeardown');
expect(result.output, 'to contain', 'running after');
});
});
76 changes: 76 additions & 0 deletions test/integration/fixtures/common-js-require.fixture.js
@@ -0,0 +1,76 @@
const { afterEach,
after,
beforeEach,
before,
describe,
xdescribe,
it,
xit,
setup,
suiteSetup,
suiteTeardown,
suite,
teardown,
test,
run } = require('../../..');


suite('root suite', () => {
setup(() => {
console.log('running setup');
})
before(() => {
console.log('running before');
});
beforeEach(() => {
console.log('running beforeEach');
});
afterEach(() => {
console.log('running afterEach');
});
after(() => {
console.log('running after');
});
teardown(() => {
console.log('running teardown');
});
suiteSetup(() => {
console.log('running suiteSetup');
});
suiteTeardown(() => {
console.log('running suiteTeardown');
});

describe.only('describe only', () => {
it('it', () => {
console.log('running it');
});
xit('it', () => {
console.log('running xit');
});
it.only('it.only', () => {
console.log('running it.only');
});
it.skip('it.skip', () => {
console.log('running it.skip');
});
test('test', () => {
console.log('running test');
});
});

describe('describe', () => {});

xdescribe('xdescribe', () => {});

describe.skip('describe.skip', () => {});

suite.only('suite only', () => {});

suite.skip('suite.skip', () => {});

});

// using `run` here makes it so this suite needs to be run with `--delay` mode.
// adding it here to test that `run` is correctly exported from mocha.
setTimeout(run, 0);
5 changes: 5 additions & 0 deletions test/integration/fixtures/parallel/test1.mjs
@@ -0,0 +1,5 @@
import {describe,it} from "../../../../index.js";

describe('test1', () => {
it('should pass', () => {});
});
5 changes: 5 additions & 0 deletions test/integration/fixtures/parallel/test2.mjs
@@ -0,0 +1,5 @@
import {describe,it} from "../../../../index.js";

describe('test2', () => {
it('should pass', () => {});
});
7 changes: 7 additions & 0 deletions test/integration/fixtures/parallel/test3.mjs
@@ -0,0 +1,7 @@
import {describe,it} from "../../../../index.js";

describe('test3', () => {
it('should fail', () => {
throw new Error('expecting this error to fail');
Copy link

@joielee09 joielee09 Mar 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicojs hello! I was reviewing your PR, and have a question for this change.
You made three different tests, test1, test2, test3. Can you explain about this tests?
Why test1 and test2 pass whereas test3 fail? Also Why do we need test1 and test2 each, when they have the same dir path and they both pass. Thank you 👩

});
});
28 changes: 28 additions & 0 deletions test/integration/parallel.spec.js
@@ -0,0 +1,28 @@
'use strict';

const assert = require('assert');
const {runMochaJSONAsync} = require('./helpers');
const semver = require('semver');

describe('parallel run', () => {
/**
* @see https://github.com/mochajs/mocha/issues/4559
*/
it('should allow `import {it} from "mocha"` module syntax', async () => {
if (semver.major(process.version) <= 10) {
console.log(
`[SKIPPED] for node ${process.version} (es module syntax isn't supported on node <= 10)`
);
} else {
const result = await runMochaJSONAsync('parallel/test3.mjs', [
'--parallel',
'--jobs',
'2',
require.resolve('./fixtures/parallel/test1.mjs'),
require.resolve('./fixtures/parallel/test2.mjs')
]);
assert.strictEqual(result.stats.failures, 1);
assert.strictEqual(result.stats.passes, 2);
}
});
});