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

feat: add opts option and default behavior #119

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
.idea
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var plur = require('plur');
var reqCwd = require('req-cwd');

module.exports = function (opts) {
opts = opts || {};
opts = require('./lib/MochaOptsReader.js').getOpts(opts);

var mocha = new Mocha(opts);
var cache = {};
Expand Down
14 changes: 14 additions & 0 deletions lib/MochaOptionAdapters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
comaStringToArray: function(rawValue) {
return rawValue[0].split(',');
},
toString: function(rawValue) {
return rawValue[0].toString();
},
toBoolean: function(rawValue) {
return rawValue[0] === "true";
},
toNumber: function(rawValue) {
return parseFloat(rawValue[0]);
}
};
120 changes: 120 additions & 0 deletions lib/MochaOptsReader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
var fs = require('fs');
var MochaOptionAdapters = require('./MochaOptionAdapters');

MochaOptsReader.config = {
ui: { args: ['--ui', '-u'], adapter: 'toString' },
reporter: { args: ['--reporter', '-R'], adapter: 'toString' },
globals: { args: ['--globals'], adapter: 'comaStringToArray' },
timeout: { args: ['--timeout', '-t'], adapter: 'toNumber' },
bail: { args: ['--bail', '-b'], adapter: 'toBoolean' },
grep: { args: ['--grep', '-g'], adapter: 'toString' },
require: { args: ['--require', '-r'] }
};

function MochaOptsReader(optsFilePath) {
this.optsPath = optsFilePath ? optsFilePath : 'test/mocha.opts';
}

/**
* @param opts gulp-mocha opts
*/
MochaOptsReader.getOpts = function(opts) {
opts = opts || {};
var fileOpts = (new MochaOptsReader(opts.opts)).getConfig();
Object.keys(fileOpts).forEach(function(optName) {
if(opts[optName] === undefined) {
opts[optName] = fileOpts[optName];
}
});

// delete opts option
if(opts.opts) {
delete opts.opts;
}

return opts;
};

MochaOptsReader.prototype.getConfig = function() {
var opts = this.readOptsFile();
var groupedOpts = MochaOptsReader.groupOpts(opts);
return MochaOptsReader.sanitizeOptions(groupedOpts);
};

// @see https://github.com/mochajs/mocha/blob/master/bin/options.js
MochaOptsReader.prototype.readOptsFile = function() {
try {
return fs.readFileSync(this.optsPath, 'utf8')
.replace(/\\\s/g, '%20')
.split(/\s/)
.filter(Boolean)
.map(function(value) {
return value.replace(/%20/g, ' ');
});
} catch(err) {
}
return [];
};

MochaOptsReader.groupOpts = function(opts) {
var groupOpts = {};
var lastConfigName = null;
for(var i = 0; i < opts.length; i++) {
var curArg = opts[i];
if(MochaOptsReader.isOptKnown(curArg)) {
lastConfigName = MochaOptsReader.getConfigName(curArg);
groupOpts[lastConfigName] === undefined && (groupOpts[lastConfigName] = []);
}
// argument not known
else if(curArg[0] === '-'){
lastConfigName = null;
}
// Values of arguments
else if (lastConfigName !== null){
groupOpts[lastConfigName].push(curArg);
}
}

return groupOpts;
};

MochaOptsReader.isOptKnown = function(optName) {
return MochaOptsReader.getKnownArgs().indexOf(optName) >= 0;
};

MochaOptsReader.getConfigName = function(argName) {
return MochaOptsReader.getArgsConfigNames()[argName];
};


MochaOptsReader.getKnownArgs = function() {
if(!MochaOptsReader.knownArgs) {
MochaOptsReader.knownArgs = Object.keys(MochaOptsReader.getArgsConfigNames())
}
return MochaOptsReader.knownArgs;
};

MochaOptsReader.getArgsConfigNames = function() {
if(!MochaOptsReader.argsConfigNames) {
MochaOptsReader.argsConfigNames = {};

Object.keys(MochaOptsReader.config).forEach(function(configName) {
MochaOptsReader.config[configName].args.forEach(function(arg) {
MochaOptsReader.argsConfigNames[arg] = configName;
});
});
}
return MochaOptsReader.argsConfigNames;
};

MochaOptsReader.sanitizeOptions = function(rawOptions) {
var cleanOptions = {};
Object.keys(rawOptions).forEach(function(optionName) {
var optionValue = rawOptions[optionName];
var adapter = MochaOptsReader.config[optionName].adapter;
cleanOptions[optionName] = adapter ? MochaOptionAdapters[adapter](optionValue) : optionValue;
});
return cleanOptions;
};

module.exports = MochaOptsReader;
7 changes: 7 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ Type: `array`

Require custom modules before tests are run.

##### opts

Type: `string`
Default: `test/mocha.opts`

Path to Mocha opts file.
**The only options used are those described before**. Any option set will override the corresponding one in the `opts` file.

## FAQ

Expand Down
23 changes: 23 additions & 0 deletions test/lib.MochaOptionAdapters.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
(function () {
'use strict';

var assert = require('assert');
var MochaOptionAdapters = require('../lib/MochaOptionAdapters.js');

describe('MochaOptionAdapters', function() {
it('comaStringToArray', function() {
assert.deepEqual(MochaOptionAdapters.comaStringToArray(['a,b,c,d,e', 'foobar']), ['a', 'b', 'c', 'd', 'e']);
});
it('toString', function() {
assert.equal(MochaOptionAdapters.toString(['azerty', 'foobar']), 'azerty');
});
it('toBoolean', function() {
assert.equal(MochaOptionAdapters.toBoolean(['true', 'foobar']), true);
assert.equal(MochaOptionAdapters.toBoolean(['false', 'foobar']), false);
assert.equal(MochaOptionAdapters.toBoolean(['foobar']), false);
});
it('toNumber', function() {
assert.equal(MochaOptionAdapters.toNumber(['123456', 'foobar']), 123456);
});
});
})();
61 changes: 61 additions & 0 deletions test/lib.MochaOptsReader.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
(function () {
'use strict';

var assert = require('assert');
var MochaOptsReader = require('../lib/MochaOptsReader.js');
var fs = require('fs');

describe('MochaOptsReader', function() {
it('gives an empty object if no configration file', function() {
var reader = new MochaOptsReader();
assert.deepEqual(reader.getConfig(), {});
});

it('retrieve information from the default file', function() {
var optsPath = "test/mocha.opts";
fs.writeFileSync(optsPath, "--ui bdd", "utf8");

var reader = new MochaOptsReader();
assert.deepEqual(reader.getConfig(), {ui:'bdd'});

fs.unlinkSync(optsPath);
});

it('retrieve information from a given file', function() {
var opts = [
'--require test',
'--require test2',
'-r test3',
'--bail true',
'--ui tdd',
'--globals a,b,c,d',
'--timeout 40530',
'--ignored',
'--grep azesdf',
'-alsoIgnored'
];
var optsPath = "test/mocha.custom.opts";
fs.writeFileSync(optsPath, opts.join('\n'), "utf8");

var reader = new MochaOptsReader(optsPath);
assert.deepEqual(reader.getConfig(), {ui:'tdd', bail: true, globals: ["a", "b", "c", "d"], grep: "azesdf", require: ["test", "test2", "test3"], timeout: 40530});

fs.unlinkSync(optsPath);
});

it('merge opts with the given one', function() {
var opts = [
'--require test',
'--require test2',
'-t 12345'
];
var optsPath = "test/mocha.custom.opts";
fs.writeFileSync(optsPath, opts.join('\n'), "utf8");

var opts = MochaOptsReader.getOpts({opts: optsPath, bail: false, timeout: 40530});
assert.deepEqual(opts, {bail: false, require: ["test", "test2"], timeout: 40530});

fs.unlinkSync(optsPath);
});
});
})();