Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion api.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Api.prototype._reset = function () {
this.failCount = 0;
this.fileCount = 0;
this.testCount = 0;
this.hasExclusive = false;
this.errors = [];
this.stats = [];
this.tests = [];
Expand Down Expand Up @@ -103,6 +104,15 @@ Api.prototype._handleTeardown = function (data) {
};

Api.prototype._handleStats = function (stats) {
if (this.hasExclusive && !stats.hasExclusive) {
Copy link
Member

Choose a reason for hiding this comment

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

Could you add a comment as to why the function is returning here? It's because if we're running exclusive tests, but the test file does not include exclusive tests, then we don't want those tests to be counted, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct, although I'm not super keen on just dropping this info on the floor. I just went for consistency with how non-exclusive tests are dropped within test-collection. I'll add a comment to that effect.

That said, I would favor changing the reporting completely as suggested by #471.

return;
}

if (!this.hasExclusive && stats.hasExclusive) {
this.hasExclusive = true;
this.testCount = 0;
Copy link
Member

Choose a reason for hiding this comment

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

Similarly why is this being reset? Because we've already counted tests we're now not going to run, right? I appreciate test-collection has similar logic without comments but I reckon it'd be easier to understand for the next person if we'd explain it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, same logic. Again, not too keen on it but couldn't think of a more elegant solution. Suggestions welcome!

Copy link
Member

Choose a reason for hiding this comment

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

Nah it's good enough as is, just requires some extra thinking.

}

this.testCount += stats.testCount;
};

Expand Down Expand Up @@ -198,9 +208,12 @@ Api.prototype.run = function (files) {
self.emit('ready');

var method = self.options.serial ? 'mapSeries' : 'map';
var options = {
runOnlyExclusive: self.hasExclusive
};

resolve(Promise[method](files, function (file, index) {
return tests[index].run().catch(function (err) {
return tests[index].run(options).catch(function (err) {
// The test failed catastrophically. Flag it up as an
// exception, then return an empty result. Other tests may
// continue to run.
Expand Down
8 changes: 5 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function exit() {
}

globals.setImmediate(function () {
var hasExclusive = runner.tests.hasExclusive;
var numberOfTests = runner.tests.tests.concurrent.length + runner.tests.tests.serial.length;

if (numberOfTests === 0) {
Expand All @@ -78,13 +79,14 @@ globals.setImmediate(function () {
}

send('stats', {
testCount: numberOfTests
testCount: numberOfTests,
hasExclusive: hasExclusive
});

runner.on('test', test);

process.on('ava-run', function () {
runner.run().then(exit);
process.on('ava-run', function (options) {
runner.run(options).then(exit);
});
});

Expand Down
6 changes: 3 additions & 3 deletions lib/fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ module.exports = function (file, opts) {
isReady = true;
});

promise.run = function () {
promise.run = function (options) {
if (isReady) {
send(ps, 'run');
send(ps, 'run', options);
return promise;
}

ps.on('stats', function () {
send(ps, 'run');
send(ps, 'run', options);
});

return promise;
Expand Down
6 changes: 5 additions & 1 deletion lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,18 @@ Runner.prototype._addTestResult = function (result) {
this.emit('test', props);
};

Runner.prototype.run = function () {
Runner.prototype.run = function (options) {
var stats = this.stats = {
failCount: 0,
passCount: 0,
skipCount: 0,
testCount: 0
};

if (options.runOnlyExclusive && !this.tests.hasExclusive) {
return Promise.resolve();
}

this.tests.on('test', this._addTestResult);

return Promise.resolve(this.tests.build(this._bail).run()).then(function () {
Expand Down
20 changes: 20 additions & 0 deletions test/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,26 @@ test('test file with only skipped tests does not create a failure', function (t)
});
});

test('test file with exclusive tests causes non-exclusive tests in other files to be ignored', function (t) {
t.plan(4);

var files = [
path.join(__dirname, 'fixture/exclusive.js'),
path.join(__dirname, 'fixture/exclusive-nonexclusive.js'),
path.join(__dirname, 'fixture/one-pass-one-fail.js')
];

var api = new Api();

api.run(files)
.then(function () {
t.ok(api.hasExclusive);
t.is(api.testCount, 2);
t.is(api.passCount, 2);
t.is(api.failCount, 0);
});
});

test('resets state before running', function (t) {
t.plan(2);

Expand Down
9 changes: 9 additions & 0 deletions test/fixture/exclusive-nonexclusive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import test from '../../';

test.only(t => {
t.pass();
});

test(t => {
t.fail();
});
5 changes: 5 additions & 0 deletions test/fixture/exclusive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import test from '../../';

test.only(t => {
t.pass();
});
12 changes: 6 additions & 6 deletions test/fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ test('emits test event', function (t) {
t.plan(1);

fork(fixture('generators.js'))
.run()
.run({})
.on('test', function (tt) {
t.is(tt.title, 'generator function');
t.end();
Expand All @@ -34,7 +34,7 @@ test('resolves promise with tests info', function (t) {
var file = fixture('generators.js');

fork(file)
.run()
.run({})
.then(function (info) {
t.is(info.stats.passCount, 1);
t.is(info.tests.length, 1);
Expand All @@ -50,7 +50,7 @@ test('exit after tests are finished', function (t) {
var cleanupCompleted = false;

fork(fixture('long-running.js'))
.run()
.run({})
.on('exit', function () {
t.true(Date.now() - start < 10000, 'test waited for a pending setTimeout');
t.true(cleanupCompleted, 'cleanup did not complete');
Expand All @@ -62,7 +62,7 @@ test('exit after tests are finished', function (t) {

test('fake timers do not break duration', function (t) {
fork(fixture('fake-timers.js'))
.run()
.run({})
.then(function (info) {
var duration = info.tests[0].duration;
t.true(duration < 1000, duration + ' < 1000');
Expand All @@ -75,7 +75,7 @@ test('fake timers do not break duration', function (t) {
/*
test('destructuring of `t` is allowed', function (t) {
fork(fixture('destructuring-public-api.js'))
.run()
.run({})
.then(function (info) {
t.is(info.stats.failCount, 0);
t.is(info.stats.passCount, 3);
Expand All @@ -86,7 +86,7 @@ test('destructuring of `t` is allowed', function (t) {

test('babelrc is ignored', function (t) {
fork(fixture('babelrc/test.js'))
.run()
.run({})
.then(function (info) {
t.is(info.stats.passCount, 1);
t.end();
Expand Down
26 changes: 13 additions & 13 deletions test/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ test('before', function (t) {
arr.push('b');
});

runner.run().then(function () {
runner.run({}).then(function () {
t.same(arr, ['a', 'b']);
});
});
Expand All @@ -47,7 +47,7 @@ test('after', function (t) {
arr.push('a');
});

runner.run().then(function () {
runner.run({}).then(function () {
t.is(runner.stats.passCount, 1);
t.is(runner.stats.failCount, 0);
t.same(arr, ['a', 'b']);
Expand All @@ -74,7 +74,7 @@ test('stop if before hooks failed', function (t) {
a.end();
});

runner.run().then(function () {
runner.run({}).then(function () {
t.same(arr, ['a']);
t.end();
});
Expand Down Expand Up @@ -104,7 +104,7 @@ test('before each with concurrent tests', function (t) {
arr[1].push('d');
});

runner.run().then(function () {
runner.run({}).then(function () {
t.same(arr, [['a', 'b', 'c'], ['a', 'b', 'd']]);
t.end();
});
Expand Down Expand Up @@ -132,7 +132,7 @@ test('before each with serial tests', function (t) {
arr.push('d');
});

runner.run().then(function () {
runner.run({}).then(function () {
t.same(arr, ['a', 'b', 'c', 'a', 'b', 'd']);
t.end();
});
Expand All @@ -154,7 +154,7 @@ test('fail if beforeEach hook fails', function (t) {
a.pass();
});

runner.run().then(function () {
runner.run({}).then(function () {
t.is(runner.stats.failCount, 1);
t.same(arr, ['a']);
t.end();
Expand Down Expand Up @@ -185,7 +185,7 @@ test('after each with concurrent tests', function (t) {
arr[1].push('d');
});

runner.run().then(function () {
runner.run({}).then(function () {
t.same(arr, [['c', 'a', 'b'], ['d', 'a', 'b']]);
t.end();
});
Expand Down Expand Up @@ -213,7 +213,7 @@ test('after each with serial tests', function (t) {
arr.push('d');
});

runner.run().then(function () {
runner.run({}).then(function () {
t.same(arr, ['c', 'a', 'b', 'd', 'a', 'b']);
t.end();
});
Expand Down Expand Up @@ -245,7 +245,7 @@ test('ensure hooks run only around tests', function (t) {
arr.push('test');
});

runner.run().then(function () {
runner.run({}).then(function () {
t.same(arr, ['before', 'beforeEach', 'test', 'afterEach', 'after']);
t.end();
});
Expand Down Expand Up @@ -278,7 +278,7 @@ test('shared context', function (t) {
a.same(a.context.arr, ['a', 'b', 'c']);
});

runner.run().then(function () {
runner.run({}).then(function () {
t.is(runner.stats.failCount, 0);
t.end();
});
Expand All @@ -297,7 +297,7 @@ test('shared context of any type', function (t) {
a.is(a.context, 'foo');
});

runner.run().then(function () {
runner.run({}).then(function () {
t.is(runner.stats.failCount, 0);
t.end();
});
Expand All @@ -307,7 +307,7 @@ test('don\'t display hook title if it did not fail', function (t) {
t.plan(2);

fork(path.join(__dirname, 'fixture', 'hooks-passing.js'))
.run()
.run({})
.on('test', function (test) {
t.same(test.error, null);
t.is(test.title, 'pass');
Expand All @@ -321,7 +321,7 @@ test('display hook title if it failed', function (t) {
t.plan(2);

fork(path.join(__dirname, 'fixture', 'hooks-failing.js'))
.run()
.run({})
.on('test', function (test) {
t.is(test.error.name, 'AssertionError');
t.is(test.title, 'fail for pass');
Expand Down
Loading