Skip to content

Commit

Permalink
feat(mocha-runner): use default mocha.opts file, support relative imp…
Browse files Browse the repository at this point in the history
…orts (#1237)

Check if `test/mocha.opts` exists if the no mocha.opts is specified in the stryker config.
Make sure relative imports when using `--require` (same as mocha does it).

Fixes #1046
  • Loading branch information
bharaninb authored and simondel committed Nov 13, 2018
1 parent 2d532bb commit 2711c2b
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 8 deletions.
1 change: 1 addition & 0 deletions packages/stryker-mocha-framework/src/MochaTestFramework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default class MochaTestFramework implements TestFramework {
public filter(testSelections: TestSelection[]) {
const selectedTestNames = testSelections.map(selection => selection.name);
return `var Mocha = window.Mocha || require('mocha');
var describe = Mocha.describe;
var selectedTestNames = ${JSON.stringify(selectedTestNames)};
if (window.____mochaAddTest) {
Mocha.Suite.prototype.addTest = window.____mochaAddTest;
Expand Down
2 changes: 1 addition & 1 deletion packages/stryker-mocha-runner/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ If you want to load all files recursively: use a globbing expression (`'test/**/

### `mochaOptions.opts` [`string`]

Default: `undefined`
Default: `'test/mocha.opts'`

Specify a ['mocha.opts' file](https://mochajs.org/#mochaopts) to be loaded. Options specified directly in your stryker.conf.js file will overrule options from the 'mocha.opts' file.

Expand Down
16 changes: 12 additions & 4 deletions packages/stryker-mocha-runner/src/MochaOptionsLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,26 @@ import MochaRunnerOptions, { mochaOptionsKey } from './MochaRunnerOptions';
export default class MochaOptionsLoader {

private readonly log = getLogger(MochaOptionsLoader.name);
private readonly DEFAULT_MOCHA_OPTS = 'test/mocha.opts';

public load(config: StrykerOptions): MochaRunnerOptions {
const mochaOptions = Object.assign({}, config[mochaOptionsKey]) as MochaRunnerOptions;
if (mochaOptions && mochaOptions.opts) {
const optsFileName = path.resolve(mochaOptions.opts);
let optsFileName = path.resolve(this.DEFAULT_MOCHA_OPTS);

if (mochaOptions.opts) {
optsFileName = path.resolve(mochaOptions.opts);
}

if (fs.existsSync(optsFileName)) {
this.log.info(`Loading mochaOpts from "${optsFileName}"`);
const options = fs.readFileSync(optsFileName, 'utf8');
return Object.assign(this.parseOptsFile(options), mochaOptions);
} else if (mochaOptions.opts) {
this.log.error(`Could not load opts from "${optsFileName}". Please make sure opts file exists.`);
} else {
this.log.debug('No mocha opts file specified, not loading additional mocha options (%s.opts was not defined).', mochaOptionsKey);
return mochaOptions;
this.log.debug('No mocha opts file found, not loading additional mocha options (%s.opts was not defined).', mochaOptionsKey);
}
return mochaOptions;
}

private parseOptsFile(optsFileContent: string): MochaRunnerOptions {
Expand Down
6 changes: 5 additions & 1 deletion packages/stryker-mocha-runner/src/MochaTestRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ export default class MochaTestRunner implements TestRunner {

private additionalRequires() {
if (this.mochaRunnerOptions.require) {
this.mochaRunnerOptions.require.forEach(LibWrapper.require);
const modulesToRequire = this.mochaRunnerOptions.require
.map(module => {
return module.startsWith('.') ? path.resolve(module) : module;
});
modulesToRequire.forEach(LibWrapper.require);
}
}
}
25 changes: 23 additions & 2 deletions packages/stryker-mocha-runner/test/unit/MochaOptionsLoaderSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { logger, Mock } from '../helpers/mockHelpers';
describe('MochaOptionsLoader', () => {

let readFileStub: sinon.SinonStub;
let existsFileStub: sinon.SinonStub;
let config: Config;
let sut: MochaOptionsLoader;
let log: Mock<logging.Logger>;
Expand All @@ -18,6 +19,7 @@ describe('MochaOptionsLoader', () => {
log = logger();
sandbox.stub(logging, 'getLogger').returns(log);
readFileStub = sandbox.stub(fs, 'readFileSync');
existsFileStub = sandbox.stub(fs, 'existsSync').returns(true);
sut = new MochaOptionsLoader();
config = new Config();
});
Expand All @@ -36,10 +38,29 @@ describe('MochaOptionsLoader', () => {
expect(fs.readFileSync).calledWith(path.resolve('some/mocha.opts/file'));
});

it('should not load a mocha.opts file if not specified', () => {
it('should log an error if specified mocha.opts file doesn\'t exist', () => {
readFileStub.returns('');
existsFileStub.returns(false);
config.mochaOptions = {
opts: 'some/mocha.opts/file'
};

sut.load(config);
expect(log.error).calledWith(`Could not load opts from "${path.resolve('some/mocha.opts/file')}". Please make sure opts file exists.`);
});

it('should load default mocha.opts file if not specified', () => {
readFileStub.returns('');
sut.load(config);
expect(log.info).calledWith(`Loading mochaOpts from "${path.resolve('test/mocha.opts')}"`);
expect(fs.readFileSync).calledWith(path.resolve('test/mocha.opts'));
});

it('should not load default mocha.opts file if not found', () => {
existsFileStub.returns(false);
const options = sut.load(config);
expect(options).deep.eq({});
expect(log.debug).calledWith('No mocha opts file specified, not loading additional mocha options (%s.opts was not defined).', 'mochaOptions');
expect(log.debug).calledWith('No mocha opts file found, not loading additional mocha options (%s.opts was not defined).', 'mochaOptions');
});

it('should load `--require` and `-r` properties if specified in mocha.opts file', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ describe('MochaTestRunner', () => {
expect(requireStub).calledWith('babel-register');
});

it('should pass and resolve relative require options when constructed', () => {
const mochaOptions: MochaRunnerOptions = { require: ['./setup.js', 'babel-register'] };
new MochaTestRunner(runnerOptions({ strykerOptions: { mochaOptions } }));
const resolvedRequire = path.resolve('./setup.js');
expect(requireStub).calledTwice;
expect(requireStub).calledWith(resolvedRequire);
expect(requireStub).calledWith('babel-register');
});

it('should evaluate additional testHooks if required (in global mocha context)', async () => {
multimatchStub.returns(['']);
sut = new MochaTestRunner(runnerOptions());
Expand Down

0 comments on commit 2711c2b

Please sign in to comment.