Skip to content

Commit 625523c

Browse files
committed
0.0.1
1 parent b6fc7b4 commit 625523c

File tree

7 files changed

+239
-1
lines changed

7 files changed

+239
-1
lines changed

README.md

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,90 @@
11
# mocha.parallel
2-
Run async mocha specs in parallel
2+
3+
Run async mocha specs in parallel.
4+
5+
```
6+
/**
7+
* Builds the test suite dynamically to allow for parallel execution of the
8+
* individual specs. While each spec is ran in parallel, specs resolve in
9+
* series, leading to deterministic output. Expects an array of names,
10+
* arguments, and a function that returns a Promise.
11+
*
12+
* @example
13+
* parallel(['test1', 'test2'], [[1, 2], [2, 4]], function(x, expected) {
14+
* return Promise.delay(100).then(function() {
15+
* assert.equal(x + x, res);
16+
* });
17+
* });
18+
*
19+
* @param {string[]} names Names to assign the specs
20+
* @param {*[]} args Arguments to pass to the function
21+
* @param {} A function returning a promise
22+
*/
23+
```
24+
25+
## Examples
26+
27+
Rather than taking 3.5s, the specs below run in parallel, completing in just
28+
over 900ms.
29+
30+
``` javascript
31+
var parallel = require('../index.js');
32+
var Promise = require('bluebird');
33+
34+
describe('delays', function() {
35+
var args = [500, 600, 700, 800, 900];
36+
parallel(args, args, function(arg) {
37+
return Promise.delay(arg);
38+
});
39+
});
40+
```
41+
42+
```
43+
delays
44+
✓ 500 (497ms)
45+
✓ 600 (99ms)
46+
✓ 700 (98ms)
47+
✓ 800 (99ms)
48+
✓ 900 (99ms)
49+
50+
51+
5 passing (902ms)
52+
```
53+
54+
An example of passing multiple arguments
55+
56+
``` javascript
57+
var parallel = require('../index.js');
58+
var Promise = require('bluebird');
59+
var assert = require('assert');
60+
61+
describe('multiplications', function() {
62+
var args = [
63+
[1, 1, 1],
64+
[2, 2, 4],
65+
[3, 3, 9],
66+
[4, 4, 16]
67+
];
68+
69+
var names = args.map(function(val) {
70+
return val[0] + ' + ' + val[1] + ' = ' + val[2];
71+
});
72+
73+
parallel(names, args, function(x, y, res) {
74+
return Promise.delay(100).then(function() {
75+
assert.equal(x * y, res)
76+
});
77+
});
78+
});
79+
```
80+
81+
```
82+
multiplications
83+
✓ 1 + 1 = 1 (101ms)
84+
✓ 2 + 2 = 4
85+
✓ 3 + 3 = 9
86+
✓ 4 + 4 = 16
87+
88+
89+
4 passing (110ms)
90+
```

fixtures/delay.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var parallel = require('../index.js');
2+
var Promise = require('bluebird');
3+
4+
describe('delays', function() {
5+
var args = [500, 600, 700, 800, 900];
6+
parallel(args, args, function(arg) {
7+
return Promise.delay(arg);
8+
});
9+
});

fixtures/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
var path = require('path');
2+
3+
var absolutePaths = {};
4+
var fixtures = ['delay', 'multipleArgs'];
5+
6+
fixtures.forEach(function(fixture) {
7+
absolutePaths[fixture] = path.resolve(__dirname, fixture + '.js');
8+
});
9+
10+
module.exports = absolutePaths;

fixtures/multipleArgs.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
var parallel = require('../index.js');
2+
var Promise = require('bluebird');
3+
var assert = require('assert');
4+
5+
describe('multiplications', function() {
6+
var args = [
7+
[1, 1, 1],
8+
[2, 2, 4],
9+
[3, 3, 9],
10+
[4, 4, 16]
11+
];
12+
13+
var names = args.map(function(val) {
14+
return val[0] + ' + ' + val[1] + ' = ' + val[2];
15+
});
16+
17+
parallel(names, args, function(x, y, res) {
18+
return Promise.delay(100).then(function() {
19+
assert.equal(x * y, res)
20+
});
21+
});
22+
});

index.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Builds the test suite dynamically to allow for parallel execution of the
3+
* individual specs. While each spec is ran in parallel, specs resolve in
4+
* series, leading to deterministic output. Expects an array of names,
5+
* arguments, and a function that returns a Promise.
6+
*
7+
* @example
8+
* parallel(['test1', 'test2'], [[1, 2], [2, 4]], function(x, expected) {
9+
* return Promise.delay(100).then(function() {
10+
* assert.equal(x + x, res);
11+
* });
12+
* });
13+
*
14+
* @param {string[]} names Names to assign the specs
15+
* @param {*[]} args Arguments to pass to the function
16+
* @param {} A function returning a promise
17+
*/
18+
module.exports = function parallel(names, args, fn) {
19+
args.map(function(arg) {
20+
if (arg instanceof Array) {
21+
return fn.apply(fn, arg);
22+
} else {
23+
return fn(arg);
24+
}
25+
}).forEach(function(promise, i) {
26+
it(names[i], function() {
27+
return promise;
28+
});
29+
});
30+
};

package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "mocha.parallel",
3+
"version": "0.0.1",
4+
"description": "Run async mocha specs in parallel",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "mocha test.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/danielstjules/mocha.parallel.git"
12+
},
13+
"keywords": [
14+
"mocha",
15+
"parallel",
16+
"async",
17+
"test",
18+
"spec"
19+
],
20+
"author": "Daniel St. Jules <danielst.jules@gmail.com>",
21+
"license": "MIT",
22+
"bugs": {
23+
"url": "https://github.com/danielstjules/mocha.parallel/issues"
24+
},
25+
"homepage": "https://github.com/danielstjules/mocha.parallel",
26+
"devDependencies": {
27+
"bluebird": "^2.9.34",
28+
"mocha": "^2.2.5"
29+
}
30+
}

test.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
var exec = require('child_process').exec;
2+
var assert = require('assert');
3+
var fixtures = require('./fixtures');
4+
5+
describe('parallel', function() {
6+
this.timeout(2000);
7+
8+
it('runs specs in parallel', function(done) {
9+
var cmd = './node_modules/.bin/mocha ' + fixtures.delay;
10+
exec(cmd, function(err, stdout, stderr) {
11+
if (err) return done(err);
12+
13+
assert(!stderr.length);
14+
assert(stdout.indexOf('5 passing') !== -1);
15+
16+
['500', '600', '700', '800', '900'].forEach(function(delay) {
17+
var line = '✓ ' + delay;
18+
assert(stdout.indexOf(line) !== -1);
19+
});
20+
21+
// Specs should run in under 1s
22+
var timeStr = stdout.split('5 passing (')[1].split(')')[0];
23+
assert(parseInt(timeStr, 10) < 1000);
24+
25+
done();
26+
});
27+
});
28+
29+
it('can pass multiple arguments', function(done) {
30+
var cmd = './node_modules/.bin/mocha ' + fixtures.multipleArgs;
31+
exec(cmd, function(err, stdout, stderr) {
32+
if (err) return done(err);
33+
34+
assert(!stderr.length);
35+
assert(stdout.indexOf('4 passing') !== -1);
36+
37+
[
38+
'✓ 1 + 1 = 1',
39+
'✓ 2 + 2 = 4',
40+
'✓ 3 + 3 = 9',
41+
'✓ 4 + 4 = 16'
42+
].forEach(function(line) {
43+
assert(stdout.indexOf(line) !== -1);
44+
})
45+
46+
done();
47+
});
48+
});
49+
});

0 commit comments

Comments
 (0)