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

fix(testing): change assertThrows and assertThrowsAsync return type to void and Promise<void> #1052

Merged
merged 4 commits into from
Jul 28, 2021
Merged

fix(testing): change assertThrows and assertThrowsAsync return type to void and Promise<void> #1052

merged 4 commits into from
Jul 28, 2021

Conversation

lowlighter
Copy link
Contributor

This add a side note in documentation about assertThrowsAsync to mention that it is actually required to await them.

Examples are correct, but I feel like this should be highlighted as this is pretty hard to debug.

Since it's the only assertion that is async it's not really intuitive.
Failing to do so can result in the whole runner to be interrupted... (see below where test 3 is not even executed)

import { assert, assertThrowsAsync } from "https://deno.land/std@0.102.0/testing/asserts.ts";
Deno.test("1", () => { throw new Error() });
Deno.test("2", () => void assertThrowsAsync(async () => {}, Error));
Deno.test("3", () => {});
running 3 tests from file:///deno_std/test.ts
test 1 ... FAILED (25ms)
test 2 ...
test result: FAILED. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (129ms)

error: Uncaught (in promise) AssertionError: Expected function to throw.
    throw new AssertionError(msg);
          ^
    at assertThrowsAsync (https://deno.land/std@0.102.0/testing/asserts.ts:664:11)

What is confusing is that the assertion does have the expected result and looks fine looking at logs, and throwing inside Deno.test is fairly common but in this specific case it makes the test runner fails

I don't have another easy reproduction snippet, but sometimes it seems it could also result in having a mismatch between dispatched and fulfilled promises which will make the test case fails too.

@@ -108,6 +108,10 @@ Deno.test("fails", function (): void {

Using `assertThrowsAsync()`:

> ⚠️ Note that it is _required_ to `await` for `assertThrowsAsync` to ensure
Copy link
Contributor

Choose a reason for hiding this comment

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

This technically isn't true. The promise returned from assertThrowsAsync can just be returned as well.

It would be more accurate to state that assertThrowsAsync returns a promise that will be resolved if the assertion passes, or rejected if it fails. This promise should be be awaited or be the return value from the test function.

Also, it would be far better to put it in the inline documentation for the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This technically isn't true. The promise returned from assertThrowsAsync can just be returned as well.
This promise should be be awaited or be the return value from the test function.

This is actually not possible unless you void it. Trying to return the promise directly will make TypeScript complain because the test function expects void | Promise<void>:

error: TS2322 [ERROR]: Type 'Promise<Error>' is not assignable to type 'void | Promise<void>'.
  Type 'Promise<Error>' is not assignable to type 'Promise<void>'.
    Type 'Error' is not assignable to type 'void'.
Deno.test("2", () => assertThrowsAsync(async () => {}, Error));
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    at file:///deno_std/test.ts:6:22

    The expected type comes from the return type of this signature.
      export function test(name: string, fn: () => void | Promise<void>): void;
                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~
        at asset:///lib.deno.ns.d.ts:188:42

It would be more accurate to state that assertThrowsAsync returns a promise that will be resolved if the assertion passes, or rejected if it fails. This promise should be be awaited or be the return value from the test function.

I'll change the wording to reflect the first part of your suggestion and update the inline documentation at the top.
The last part about being the return value from the test function is not valid though (at least currently)

Copy link
Contributor

Choose a reason for hiding this comment

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

assertThrowsAsync shouldn't resolve with an error. I didn't realise that. Assertions shouldn't have return values.

Copy link
Contributor Author

@lowlighter lowlighter Jul 22, 2021

Choose a reason for hiding this comment

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

Seems that both assertThrows and assertThrowsAsync actually had Error and Promise<Error> instead of void and Promise<void> as return type so I patched them.

Assertions shouldn't have return values.

I agree with that statement, but it does feel awkward to retrieve error class from within the test function now.
At least it makes them consistent with other assertions return type and make it possible to avoid brackets use from inline arrow functions

@lowlighter lowlighter changed the title docs: add note about assertThrowsAsync which needs to be await fix(testing): change assertThrowsAsync return type to Promise<void> Jul 22, 2021
@lowlighter lowlighter changed the title fix(testing): change assertThrowsAsync return type to Promise<void> fix(testing): change assertThrows and assertThrowsAsync return type to void and Promise<void> Jul 22, 2021
@lowlighter lowlighter requested a review from kitsonk July 25, 2021 17:44
Copy link
Member

@kt3k kt3k left a comment

Choose a reason for hiding this comment

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

LGTM

@kt3k
Copy link
Member

kt3k commented Jul 28, 2021

@lowlighter Thank you for the contribution! nice work!

@kt3k kt3k merged commit 5606a10 into denoland:main Jul 28, 2021
nayeemrmn added a commit to nayeemrmn/deno_std that referenced this pull request Sep 9, 2021
nayeemrmn added a commit to nayeemrmn/deno_std that referenced this pull request Sep 9, 2021
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.

3 participants