`t.throws()` and `t.notThrows()` can be called with an observable or
promise. This commit forces users to wait for the assertion to complete
before finishing the test. Usually this means the test has to be written
like:
```js
test(async t => {
await t.throws(Promise.reject(new Error()))
})
```
Or for callback tests:
```js
test.cb(t => {
t.throws(Promise.reject(new Error())).then(t.end)
})
```
This simplifies internal logic and helps discourage code like in #1327.
Anecdotally users are surprised by the previous behavior where a
synchronous test worked with an asynchronous assertion
(https://github.com/avajs/ava/issues/1327#issuecomment-291122432).
Fixes#1327.
* Make the Runner manage the snapshot state. Thread an accessor to the
`t.snapshot()` assertion.
* Save snapshots when runner has finished. Fixes#1218.
* Use jest-snapshot directly, without serializing values. Use jest-diff
to generate the diff if the snapshot doesn't match. This does mean the
output is not colored and has other subtle differences with how other
assertions format values, but that's OK for now. Fixes#1220, #1254.
* Pin jest-snapshot and jest-diff versions. This isn't ideal but we're
using private APIs and making other assumptions, so I'm not comfortable
with using a loose SemVer range.
* Don't mix option chain with the prototype, simply expose it on the
instance. Actual code only exposed the `test` method to the user, and
that happens to be the default starting point anyway
* `run()` doesn't need to return stats
* Ensure `run()` always returns a promise, and does not throw
* Simplify `buildStats()`
* Derive chainable methods from the actual chain when generating the
TypeScript definition
* Don't bother prefixing methods / properties with underscores
Show instructions on how to use `t.throws()` with the test results,
without writing them to stderr. Detect the improper usage even if user
code swallows the error, meaning that tests will definitely fail.
Assume that errors thrown, or emitted from an observable, or if the
returned promise was rejected, that that error is due to the improper
usage of `t.throws()`.
Assume that if a test has a pending throws assertion, and an error leaks
as an uncaught exception or an unhandled rejection, the error was
thrown due to the pending throws assertion. Attribute it to the test.
The formatted labels sometimes assume the context of the error message.
And, since formatted values can be quite long, it's odd to see the
message only at the very end.
If a pending assertion fails before the test implementation returns a
rejected promise, the assertion failure should cause the test to fail,
not the promise rejection.
If the assertion fails, the AssertionError no longer has access to the
stack of when the assertion was called. Record it before entering the
promise chain.
Rather than keeping an infinite timer open, waiting for `t.end()` to be
called, fail the callback test if it is not ended when the event loop
empties.
Similarly, fail promise/observable returning tests if the promise hasn't
fulfilled or the observable hasn't completed when the event loop
empties.
Note that user code can keep the event loop busy, e.g. if it's listening
on a socket or starts long timers. Even after this change, async tests
may hang if the event loop is kept busy.
* Do away with underscore prefixes. They were used inconsistently, and
are generally not worth it
* Keep `_test` prefixed in ExecutionContext, since that is exposed to
calling code
* Reorder methods
* Assume all arguments are passed and are correct. They're already
validated in `test-collection.js`
*Pass metadata when instantiating Tests
* Rewrite test finish logic. There's still a fair bit of interleaving
due to the `test.cb()` API, but it's now a lot easier to understand.
Due to the last change, tests with `t.end()` and only synchronous
assertions end immediately. Previously they would end asynchronously
due to a promise being in the completion chain.
Similarly, returning a promise or observable for a `test.cb()` test
immediately fails.
Test results are emitted directly, so Test#run() only needs to return a
(promise for) a boolean, indicating whether the test passed.
Make the same change in Concurrent and Sequence, and return a boolean
if all runnables passed.
Refactor tests to stop relying on Test instances returning their result.
* Clarify responsibilities
* Consistently import dependencies
* Clarify significance of `exports.avaRequired`
* Stop mimicking process with process-adapter. Reference it using
`adapter` instead. Use the `process` global where applicable. Masking
the process global with a mimicked object is unnecessarily confusing.
* Remove superstitious delays in exiting workers
The worker now only exits when told by the main process. This means the
IPC channel must have drained before the main process can send the
instruction. There's no need to wait before sending the message that
teardown has completed.
The AppVeyor workaround was introduced to solve Node.js 0.10 issues.
We're no longer supporting that version. In theory, issues around
flushing I/O exist regardless of whether AVA is running in AppVeyor.
There is no clear way around this though, so let's assume it's not
actually an issue.
Only print the first level. For arrays/maps/objects/sets this means the
indexes/keys are printed. Presumably since we do print all statements
this provides enough context.
Format statements, generate diffs and otherwise format values when
AssertionErrors are created. Make labels contextual to the assertion.
Always print power-assert statements in mini and verbose reporters, but
after the values. Accept the duplication when the statement covers the
value passed to the assertion.
Detect whether `t.throws()` failed because no error was thrown, or because
the thrown error did not meet expectations.
Explicitly test `t.fail()` default message in assertion test.
Wrap callback errors, rejected promises or synchronously thrown values
in an `AssertionError`. Rely on the `actual` value being printed by the
reporters, which means it's still shown to the user.
Remove now obsolete `Error: ` prefix added to non-assertion errors in
`run-status.js`. Instead more helpful messages from `test.js` can be
shown.
Try to reuse the stack trace from any original error, so magic assert
can show context.
Fail `t.throws()` / `t.notThrows()` with an AssertionError if called
with an improper argument, rather than throwing a TypeError.
* Retain non-standard error properties in a cleaned `object` property
* Make AssertionError serialization more explicit
* Flag whether the serialized error came from AVA's AssertionError
* Use our own AssertionError class. Now we can track the assertion
rather than abusing the operator field. We can also stop depending on
`core-assert` once we implement `t.throws()` ourselves. Reserve the
`statements` property for power-assert output
* Directly create `AssertionError`s, making it easier to specify the
varying options
* Default the assertion message to an empty string, removing workarounds
in the mini and verbose reporters
* Improve `t.plan()` assertion errors. Specify 'plan' as the assertion,
and use `===` as the operator
* Refactor `t.throws()` and `t.notThrows()`, improving readability and
fixing #1227
* Move knowledge of when to show output into `serialize-error.js`. It
sat kind of awkwardly in `assert.js`
* Always try to format errors in mini and verbose reporters, check
if actual / expected values are available when formatting
* Wrap assertions in `assert.js` for use with the `ExecutionContext`
* Only enhance the power-assert assertions, don't use `empower-core`
to wrap the others
* Remove superfluous `empower-core` 'originalMessage' handling. Our
assertions create `AssertionError`s with the correct message
* Refactor overloaded `Test#_assert()` method and assertion tracking
internals. Note that only `t.throws()` and `notThrows()` are (possibly)
asynchronous
* Properly dump errors
* Only print actual and expected values if they're present, and strings.
This assumes they're serialized in the test workers
* Strip ANSI from actual and expected values
* Print additional name & message properties
* Determine 'at' value similar to serialize-error.js. Recompute since
here we want the full line
* Print unhandled errors using the same logic
* package-hash@^2
* Allow precompiler setup to be asynchronous
* Consistently refer to babel-config module as babelConfigHelper
* Manage Babel config using hullabaloo
Fixes#707
* Disable Babel cache when precompiling