Skip to content

Commit

Permalink
Close #565 PR: Add todo test modifier. Fixes #563
Browse files Browse the repository at this point in the history
  • Loading branch information
BarryThePenguin authored and sindresorhus committed Mar 4, 2016
1 parent d967956 commit e697629
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 13 deletions.
4 changes: 3 additions & 1 deletion api.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Api.prototype._reset = function () {
this.exceptionCount = 0;
this.passCount = 0;
this.skipCount = 0;
this.todoCount = 0;
this.failCount = 0;
this.fileCount = 0;
this.testCount = 0;
Expand Down Expand Up @@ -217,7 +218,7 @@ Api.prototype.run = function (files) {
});

return {
stats: {passCount: 0, skipCount: 0, failCount: 0},
stats: {passCount: 0, skipCount: 0, todoCount: 0, failCount: 0},
tests: []
};
});
Expand All @@ -244,6 +245,7 @@ Api.prototype.run = function (files) {

self.passCount = sum(self.stats, 'passCount');
self.skipCount = sum(self.stats, 'skipCount');
self.todoCount = sum(self.stats, 'todoCount');
self.failCount = sum(self.stats, 'failCount');
});
};
Expand Down
1 change: 1 addition & 0 deletions lib/colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var chalk = require('chalk');
module.exports = {
error: chalk.red,
skip: chalk.yellow,
todo: chalk.blue,
pass: chalk.green,
duration: chalk.gray.dim,
stack: chalk.red
Expand Down
10 changes: 9 additions & 1 deletion lib/reporters/mini.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ MiniReporter.prototype.reset = function () {
this.passCount = 0;
this.failCount = 0;
this.skipCount = 0;
this.todoCount = 0;
this.rejectionCount = 0;
this.exceptionCount = 0;
this.currentStatus = '';
Expand All @@ -36,7 +37,10 @@ MiniReporter.prototype.test = function (test) {
var status = '';
var title;

if (test.skip) {
if (test.todo) {
title = colors.todo('- ' + test.title);
this.todoCount++;
} else if (test.skip) {
title = colors.skip('- ' + test.title);
this.skipCount++;
} else if (test.error) {
Expand Down Expand Up @@ -80,6 +84,10 @@ MiniReporter.prototype.finish = function () {
status += ' ' + colors.skip(this.skipCount, 'skipped');
}

if (this.todoCount > 0) {
status += ' ' + colors.todo(this.todoCount, 'todo');
}

if (this.failCount > 0) {
status += ' ' + colors.error(this.failCount, 'failed');
}
Expand Down
11 changes: 10 additions & 1 deletion lib/reporters/tap.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ TapReporter.prototype.start = function () {
TapReporter.prototype.test = function (test) {
var output;

var directive = '';
var passed = test.todo ? 'not ok' : 'ok';

if (test.todo) {
directive = '# TODO';
} else if (test.skip) {
directive = '# SKIP';
}

if (test.error) {
output = [
'# ' + test.title,
Expand All @@ -41,7 +50,7 @@ TapReporter.prototype.test = function (test) {
} else {
output = [
'# ' + test.title,
format('ok %d - %s', ++this.i, test.title)
format('%s %d - %s %s', passed, ++this.i, test.title, directive).trim()
];
}

Expand Down
8 changes: 7 additions & 1 deletion lib/reporters/verbose.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ VerboseReporter.prototype.test = function (test) {
return ' ' + colors.error(figures.cross) + ' ' + test.title + ' ' + colors.error(test.error.message);
}

if (test.skip) {
if (test.todo) {
return ' ' + colors.todo('- ' + test.title);
} else if (test.skip) {
return ' ' + colors.skip('- ' + test.title);
}

Expand Down Expand Up @@ -72,6 +74,10 @@ VerboseReporter.prototype.finish = function () {
output += ' ' + colors.skip(this.api.skipCount, plur('test', this.api.skipCount), 'skipped') + '\n';
}

if (this.api.todoCount > 0) {
output += ' ' + colors.todo(this.api.todoCount, plur('test', this.api.todoCount), 'todo') + '\n';
}

if (this.api.rejectionCount > 0) {
output += ' ' + colors.error(this.api.rejectionCount, 'unhandled', plur('rejection', this.api.rejectionCount)) + '\n';
}
Expand Down
30 changes: 24 additions & 6 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ var Promise = require('bluebird');
var optionChain = require('option-chain');
var TestCollection = require('./test-collection');

function noop() {}

var chainableMethods = {
spread: true,
defaults: {
type: 'test',
serial: false,
exclusive: false,
skipped: false,
todo: false,
callback: false
},
chainableMethods: {
Expand All @@ -20,6 +23,7 @@ var chainableMethods = {
before: {type: 'before'},
after: {type: 'after'},
skip: {skipped: true},
todo: {todo: true},
only: {exclusive: true},
beforeEach: {type: 'beforeEach'},
afterEach: {type: 'afterEach'},
Expand Down Expand Up @@ -51,6 +55,16 @@ optionChain(chainableMethods, function (opts, title, fn) {
title = null;
}

if (opts.todo) {
fn = noop;

if (typeof title !== 'string') {
throw new TypeError('`todo` tests require a title');
}
} else if (opts.skipped && typeof fn !== 'function') {
throw new TypeError('Expected a function. Use `test.todo()` for tests without a function.');
}

if (this._serial) {
opts.serial = true;
}
Expand All @@ -63,10 +77,14 @@ optionChain(chainableMethods, function (opts, title, fn) {
}, Runner.prototype);

Runner.prototype._addTestResult = function (result) {
if (result.result.metadata.type === 'test') {
var test = result.result;

if (test.metadata.type === 'test') {
this.stats.testCount++;

if (result.result.metadata.skipped) {
if (test.metadata.todo) {
this.stats.todoCount++;
} else if (test.metadata.skipped) {
this.stats.skipCount++;
}
}
Expand All @@ -75,14 +93,13 @@ Runner.prototype._addTestResult = function (result) {
this.stats.failCount++;
}

var test = result.result;

var props = {
duration: test.duration,
title: test.title,
error: result.reason,
type: test.metadata.type,
skip: test.metadata.skipped
skip: test.metadata.skipped,
todo: test.metadata.todo
};

this.emit('test', props);
Expand All @@ -93,6 +110,7 @@ Runner.prototype.run = function (options) {
failCount: 0,
passCount: 0,
skipCount: 0,
todoCount: 0,
testCount: 0
};

Expand All @@ -103,6 +121,6 @@ Runner.prototype.run = function (options) {
this.tests.on('test', this._addTestResult);

return Promise.resolve(this.tests.build(this._bail).run()).then(function () {
stats.passCount = stats.testCount - stats.failCount - stats.skipCount;
stats.passCount = stats.testCount - stats.failCount - stats.skipCount - stats.todoCount;
});
};
2 changes: 1 addition & 1 deletion lib/test-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ TestCollection.prototype._buildHooks = function (hooks, testTitle, context) {
return hooks.map(function (hook) {
var test = this._buildHook(hook, testTitle, context);

if (hook.metadata.skipped) {
if (hook.metadata.skipped || hook.metadata.todo) {
return this._skippedTest(test);
}

Expand Down
11 changes: 10 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,22 @@ test.only('will be run', t => {

### Skip-tests

Skip-tests are shown in the output as skipped but never run.
Skip-tests are shown in the output as skipped but never run. Skip-tests require a function.

```js
test.skip('will not be run', t => {
t.fail();
});
```

### Todo-tests

Todo-tests, like skip-tests, are shown in the output but are never run. They can be useful for planning future tests. Todo-tests require only a test title.

```js
test.todo('will think about writing this later');
```

### Before & after hooks

When setup and/or teardown is required, you can use `test.before()` and `test.after()`,
Expand Down Expand Up @@ -478,6 +486,7 @@ AVA automatically removes unrelated lines in stack traces, allowing you to find
### test.cb([title], body)
### test.only([title], body)
### test.skip([title], body)
### test.todo(title)
### test.before([title], body)
### test.after([title], body)
### test.beforeEach([title], body)
Expand Down
19 changes: 19 additions & 0 deletions test/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -664,3 +664,22 @@ test('emits dependencies for test files', function (t) {
api.on('error', function () {});
result.catch(function () {});
});

test('verify test count', function (t) {
t.plan(8);

var api = new Api();

t.is(api.passCount, 0);
t.is(api.failCount, 0);
t.is(api.skipCount, 0);
t.is(api.todoCount, 0);

api.run([path.join(__dirname, 'fixture/test-count.js')])
.then(function () {
t.is(api.passCount, 1);
t.is(api.failCount, 1);
t.is(api.skipCount, 1);
t.is(api.todoCount, 1);
});
});
15 changes: 15 additions & 0 deletions test/fixture/test-count.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import test from '../../';

test('passCount', t => {
t.pass();
});

test('failCount', t => {
t.fail();
});

test.skip('skipCount', t => {
t.pass();
});

test.todo('todoCount');
35 changes: 35 additions & 0 deletions test/reporters/mini.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,25 @@ test('skipped test', function (t) {
t.end();
});

test('todo test', function (t) {
var reporter = miniReporter();

var actualOutput = reporter.test({
title: 'todo',
skip: true,
todo: true
});

var expectedOutput = [
' ' + chalk.blue('- todo'),
'',
''
].join('\n');

t.is(actualOutput, expectedOutput);
t.end();
});

test('results with passing tests', function (t) {
var reporter = miniReporter();
reporter.passCount = 1;
Expand Down Expand Up @@ -100,6 +119,22 @@ test('results with skipped tests', function (t) {
t.end();
});

test('results with todo tests', function (t) {
var reporter = miniReporter();
reporter.passCount = 0;
reporter.todoCount = 1;
reporter.failCount = 0;

var actualOutput = reporter.finish();
var expectedOutput = [
'\n ' + chalk.blue('1 todo'),
''
].join('\n');

t.is(actualOutput, expectedOutput);
t.end();
});

test('results with passing skipped tests', function (t) {
var reporter = miniReporter();
reporter.passCount = 1;
Expand Down
37 changes: 37 additions & 0 deletions test/reporters/tap.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,40 @@ test('results does not show skipped tests if there are none', function (t) {
t.is(actualOutput, expectedOutput);
t.end();
});

test('todo test', function (t) {
var reporter = tapReporter();

var actualOutput = reporter.test({
title: 'should think about doing this',
passed: false,
skip: true,
todo: true
});

var expectedOutput = [
'# should think about doing this',
'not ok 1 - should think about doing this # TODO'
].join('\n');

t.is(actualOutput, expectedOutput);
t.end();
});

test('skip test', function (t) {
var reporter = tapReporter();

var actualOutput = reporter.test({
title: 'skipped',
passed: true,
skip: true
});

var expectedOutput = [
'# skipped',
'ok 1 - skipped # SKIP'
].join('\n');

t.is(actualOutput, expectedOutput);
t.end();
});
Loading

0 comments on commit e697629

Please sign in to comment.