Skip to content

Conversation

jamestalmage
Copy link
Contributor

See #244

@jamestalmage
Copy link
Contributor Author

Overall, I like it.

There are a few places where it creates some weirdness. All revolve around our async assertions (t.throws(rejectedPromise), t.throws(rejectedObservable)).

test('this does not work', t => {
  var promise = Promise.reject(new Error('foo'));

  // this assertion actually happens asynchronously
  t.throws(promise);
  // we do not return a promise, so AVA assumes this is a synchronous function
});

There are a number of easy ways around this this. The issue will be preventing user confusion.

(Ordered from best to worst workaround IMHO)

test('use async/await', async t => {
  var promise = Promise.reject(new Error('foo'));

  await t.throws(promise); 
});
test('return the assertion promise', t => {
  var promise = Promise.reject(new Error('foo'));

  // t.throws returns a promise, so return it from our test function.
  return t.throws(promise);
});
test.async('legacy async with a plan', t => {
  t.plan(1);
  var promise = Promise.reject(new Error('foo'));

  // test is auto-ended once this resolves and we reach our plan count.
  t.throws(promise);
});

I like this last one the least. As previously stated, I think allowing t.plan() to auto-end tests is a bad choice that causes confusing false positives. Since we are biting the bullet with a major breaking change here, I would love to see us correct that as well.

@jamestalmage jamestalmage force-pushed the disallow-end-callback-on-non-async branch 2 times, most recently from d6024be to 28b1641 Compare November 23, 2015 23:35
@sindresorhus sindresorhus added this to the 0.7.0 milestone Nov 24, 2015
@sindresorhus
Copy link
Member

(Ordered from best to worst workaround IMHO)

#1 is how I already use it and how it was intended. We should just document it better.

@sindresorhus
Copy link
Member

I think we have a resolution in #244, unless there's anything else that's still undecided? Could you rebase this PR?

@jamestalmage jamestalmage force-pushed the disallow-end-callback-on-non-async branch 2 times, most recently from 0fd3ff8 to 458c36c Compare November 24, 2015 21:22
@jamestalmage jamestalmage changed the title Exploratory: Implementation of #244 Breaking: t.end requires test.async/ t.plan will not auto end tests. Fixes #244. Nov 24, 2015
@jamestalmage jamestalmage changed the title Breaking: t.end requires test.async/ t.plan will not auto end tests. Fixes #244. Breaking: t.end requires test.async, and t.plan will not auto end tests. Fixes #244. Nov 24, 2015
@jamestalmage jamestalmage force-pushed the disallow-end-callback-on-non-async branch from f75fe47 to e684a24 Compare November 25, 2015 03:39
@jamestalmage
Copy link
Contributor Author

This is ready for review.

// @sindresorhus @vdemedes

I have updated the docs to reflect the new behavior, with a few language tweaks along the way.

readme.md Outdated
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The previous Observable example was so trivial that I don't feel it adequately explained the advantage AVA offered.
I think this:

  1. Is a simple enough usage of observable that you don't necessarily need to be familiar with them to understand what is happening.
  2. Shows a novel use of t.plan() in coordination with the Observable filter. It's a little closer to a test someone might actually right.

@BarryThePenguin
What I know about Observables I learned in the last 20 minutes, so feel free to tell me where I missed the mark.

Copy link
Contributor

Choose a reason for hiding this comment

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

You could change map with .do(() => t.pass());. Otherwise, looks good.

RxJS has some docs on marble testing. But I'm not sure how they would fit with AvA

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call! Thanks!

Accessing `t.end` now throws an error unless the test is first
declared async via `test.async([title], fn)`

Reference:
  avajs#244

(cherry picked from commit 28b1641)
  Initial implementation of avajs#244 - require explicit test.async
@jamestalmage jamestalmage force-pushed the disallow-end-callback-on-non-async branch 2 times, most recently from 4400d0e to 77ebd84 Compare November 25, 2015 08:27
Copy link
Member

Choose a reason for hiding this comment

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

Why not just this here instead?

if (!this.metadata.async) {
    throw new Error('t.end is not supported in this context. To use t.end as a callback, you must explicitly declare the test asynchronous via `test.async(testName, fn)` ');
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean just have t.end throw when executed?

Because we want to fail fast, and if passed as a callback:

   fs.readFile(path, t.end);

We are waiting for the function to actually be called instead of throwing ASAP.

Copy link
Member

Choose a reason for hiding this comment

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

Does it matter? It shouldn't be used with test() anyways. So I don't see how it makes a difference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If they don't return a promise - we assume sync. We might mark the test done before the callback returns.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, never mind. Got it now. Sorry about the noise.

@sindresorhus
Copy link
Member

Looks good to me, except for a few inline comments :)

@vdemedes ?

@vadimdemedes
Copy link
Contributor

✅from me.

@jamestalmage
Copy link
Contributor Author

Today is a major holiday in the US, so I won't be wrapping this up untill tomorrow.

@sindresorhus
Copy link
Member

@jamestalmage No worries at all. Enjoy Thanksgiving :D

AVA will no longer automatically end tests when you reach the plan limit.
Users must explicitly call t.end().

It is now an error to return an async object (promise/observable) from
a legacy `test.async` test.

Reference:
  avajs#244 (comment)
@jamestalmage jamestalmage force-pushed the disallow-end-callback-on-non-async branch from 77ebd84 to 982a451 Compare November 27, 2015 05:14
@jamestalmage
Copy link
Contributor Author

Ahhh, Windows!

@sindresorhus - I'll start looking into it here, but can you just retrigger the build? I was watching that one, and it was running REALLY slow. I think something was wrong on that VM.

@sindresorhus
Copy link
Member

Done

@jamestalmage
Copy link
Contributor Author

OK, CI passed.

Are we good here? I think all concerns are addressed.

sindresorhus added a commit that referenced this pull request Nov 27, 2015
…n-async

Breaking: `t.end` requires `test.async`, and `t.plan` will not auto end tests. Fixes #244.
@sindresorhus sindresorhus merged commit 2a7a639 into avajs:master Nov 27, 2015
@jamestalmage jamestalmage deleted the disallow-end-callback-on-non-async branch November 27, 2015 06:19
@sindresorhus
Copy link
Member

👍 Excellent. I'm super excited about this!

tumblr_mkwooez15j1qdlh1io1_400

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.

4 participants