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

Add todo test modifier #565

Closed
wants to merge 3 commits into from
Closed

Add todo test modifier #565

wants to merge 3 commits into from

Conversation

BarryThePenguin
Copy link
Contributor

Seems too simple...

Fixes #563

@mention-bot
Copy link

By analyzing the blame information on this pull request, we identified @Carnubak and @sohamkamani to be potential reviewers

@@ -46,6 +46,8 @@ util.inherits(Runner, EventEmitter);
module.exports = Runner;

optionChain(chainableMethods, function (opts, title, fn) {
fn = fn || function () {};
Copy link
Contributor

Choose a reason for hiding this comment

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

I think having function noop() {} at the top of the file and using it here instead of anonymous function inline would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool, can do. Was also wondering if || is enough, or should I explicitly be checking for typeof fn === 'undefined'?

Copy link
Contributor

Choose a reason for hiding this comment

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

Nah, || is enough here.

@vadimdemedes
Copy link
Contributor

Thanks for this PR, @BarryThePenguin!

@sindresorhus
Copy link
Member

@sindresorhus
Copy link
Member

This allows omitting test function for all tests, not just .skip, @vdemedes are we ok with that?

@vadimdemedes
Copy link
Contributor

@sindresorhus Very good point. I guess we came back to the problems discussed in #9, test.todo() makes more sense in that case. But for now, maybe we should restrict function-less tests only to .skip.

@BarryThePenguin
Copy link
Contributor Author

Mmm... in this context skip and todo are synonymous with each other. Maybe it's worth exploring?

@BarryThePenguin
Copy link
Contributor Author

Also, noting the api change, this allows for test.skip(). Not sure how helpful that is to people

@kentcdodds
Copy link
Contributor

Also, noting the api change, this allows for test.skip(). Not sure how helpful that is to people

That makes sense. I wonder though if we should think about explicitly disallowing that to avoid people abusing it and confusing others.

@BarryThePenguin
Copy link
Contributor Author

I'd be happy to investigate the possibility of having both a .skip() and .todo() modifier.

Thoughts so far:

  • skip has optional title, requires a test function
  • todo requires a test title, won't accept a test function

Would also require adding todo to the tap reporter output

@kentcdodds
Copy link
Contributor

You know, I would actually prefer to leave skip as it is and introduce a todo that only accepts a message. I would still like to have the todo in the output so it's a constant reminder. I think that's the value of coding the todo rather than just using a comment.

@BarryThePenguin
Copy link
Contributor Author

I've had a go at the todo modifier. I also had a go at implementing the tap output for both todo and skip directives

@@ -27,6 +27,10 @@ TapReporter.prototype.start = function () {
TapReporter.prototype.test = function (test) {
var output;

var passed = test.todo ? 'not ok' : 'ok';
var todoDirective = test.todo ? '# TODO' : '';
var skipDirective = test.skipped ? '# SKIP' : '';
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps do:

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

Which simplifies the todoDirective || skipDirective || '' statement below and removes the unnecessary || '' fall-through.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ha, great. Will do 💩

@kentcdodds
Copy link
Contributor

I'm not certain I follow the results of all the changes. But I'll just say that I would recommend that skip require a function and the only way to avoid having to specify a function is if you use todo. Fewer ways to do the same thing is 👍 :D

@novemberborn
Copy link
Member

But I'll just say that I would recommend that skip require a function and the only way to avoid having to specify a function is if you use todo. Fewer ways to do the same thing is 👍

Yes agreed. Would be good to make test.skip('my test') fail with a helpful error, pointing at test.todo().

@BarryThePenguin changes are looking good generally, nice work. Would be good to clear up some of the logic and state management so it's easier to follow how these special test cases (pun very much intended) are handled.

@sindresorhus sindresorhus changed the title Omit function for skipped test Add todo test modifier Feb 26, 2016
@BarryThePenguin
Copy link
Contributor Author

Just went through the review.

Added Mini and Verbose reporter handling for todo + tests

@vadimdemedes
Copy link
Contributor

I like it, LGTM from me!

@sindresorhus @novemberborn @jamestalmage ?

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

Choose a reason for hiding this comment

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

throw new TypeError('Expected a function. Use `test.todo()` for tests without a function.');

@sindresorhus
Copy link
Member

Looks pretty good. The docs needs to be updated and some inline feedback resolved.

fn = noop;

if (typeof title !== 'string') {
throw new TypeError('Expected a string');
Copy link
Member

Choose a reason for hiding this comment

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

throw new TypeError('`todo` tests require a title');

@BarryThePenguin
Copy link
Contributor Author

Updated. Happy to squash/rebase to make the commit history a little more sane 👍

@sindresorhus
Copy link
Member

LGTM

@sindresorhus
Copy link
Member

Happy to squash/rebase to make the commit history a little more sane

👍


if (test.todo) {
directive = '# TODO';
} else if (test.skipped) {
Copy link
Member

Choose a reason for hiding this comment

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

this.stats.testCount++;

if (result.result.metadata.skipped) {
if (test.metadata.skipped && !test.metadata.todo) {
Copy link
Member

Choose a reason for hiding this comment

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

You still need to increase the todoCount, as well as initialize it to 0 in the run() method. Then in https://github.com/sindresorhus/ava/blob/0e1886582833986b896c31859aa61d8da404e996/api.js#L233 you need to compute the total todoCount. These counts are mocked in the reporter tests.

Copy link
Member

Choose a reason for hiding this comment

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

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

if (test.todo) {
directive = '# TODO';
Copy link
Contributor

Choose a reason for hiding this comment

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

If I'm not mistaken, there's no such directive as # TODO in TAP spec. For TAP, we could treat todo tests just like skip and output them the same way.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

In that case, great! :)

@kentcdodds
Copy link
Contributor

This is awesome! Thanks everyone for your work on this. Looking forward to seeing this merged :-)

@sindresorhus
Copy link
Member

Still some things to iron out I think.

import test from 'ava';
test.todo('foo');
test.todo('bar');

Gives no output with the default reporter:

~/dev
❯ ava          




And with --verbose:

~/dev
❯ ava --verbose

  - foo
  - bar

  2 tests failed



I don't think todo tests should be failing.

import test from 'ava';
test('foo', t => t.pass());
test.todo('bar');

Outputs it's passing, but no mention of the 1 todo and the test run still exit with exit code 1 even though the output indicates differently:

~/dev
❯ ava

  1 passed


this.stats.testCount++;

if (result.result.metadata.skipped) {
if (test.metadata.todo) {
this.stats.todoCount++;
Copy link
Member

Choose a reason for hiding this comment

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

You need to initialize todoCount to 0 in the Runner#run() method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@novemberborn
Copy link
Member

@BarryThePenguin would you mind adding a test in test/api.js that verifies the passCount, skipCount, todoCount and failCount values? There is no explicit test for at the moment. The reporter tests use mocked values so everything seems fine until it's verified by hand.

@BarryThePenguin
Copy link
Contributor Author

@sindresorhus sure, I'll see if I can work these out

I'm starting to question my reasoning for initially marking todo tests as failed. I've been following the TAP spec and I'm not sure it's quite clear.

These tests represent a feature to be implemented or a bug to be fixed and act as something of an executable “things to do” list. They are not expected to succeed. Should a todo test point begin succeeding, the harness should report it as a bonus. This indicates that whatever you were supposed to do has been done and you should promote this to a normal test point.

This implies that todo tests fail until they are implemented. This PR currently expects todo tests to have no implementation. Does this mean we mark them as failed? Again, I'm not sure how tightly we want AVA coupled with the TAP spec.

@BarryThePenguin
Copy link
Contributor Author

Also, thanks everyone for providing feedback and spending the time to help out. It's been a really enjoyable experience 🐹

@sindresorhus
Copy link
Member

The TAP description doesn't explicitly say they should fail either, though, just that they shouldn't succeed like a normal test. I think we should rather enable users to fail todo tests in the linting step, not in AVA. Todo tests should be like TODO comments, informative, but not affecting.

@novemberborn
Copy link
Member

I think we should rather enable users to fail todo tests in the linting step, not in AVA. Todo tests should be like TODO comments, informative, but not affecting.

👍

@BarryThePenguin
Copy link
Contributor Author

Updated.

@vdemedes @novemberborn todo is no longer skipped as well. Instead, in test-collection we check for the skipped and todo modifier.

@novemberborn I've added the test/api.js test

@sindresorhus I'm not quite sure about the exit code being 1, when should the exit code be 1? These are the outputs for the examples you provided above

mini reporter


  2 todo

verbose reporter


  - foo
  - bar

  0 tests passed
  2 tests todo

test + todo example


  1 passed  1 todo

@sindresorhus
Copy link
Member

@BarryThePenguin Perfect. Exactly what I was thinking :)

LGTM

@vadimdemedes
Copy link
Contributor

Looks fine to me as well, thanks @BarryThePenguin!

@BarryThePenguin BarryThePenguin deleted the skip-noop branch March 4, 2016 08:14
@sindresorhus
Copy link
Member

Landed. Thank you for tirelessly working on this one @BarryThePenguin. It turned out really good.

unicorn18

@jfmengels
Copy link
Contributor

Thanks @BarryThePenguin!

@kentcdodds
Copy link
Contributor

This is terrific. I love the level of thought for quality coming from this project. Thanks everyone (especially @BarryThePenguin)!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants