From 841526144eb5529d057cb8b390a0b3bad0dda5eb Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Sun, 29 Jan 2023 20:35:53 +0100 Subject: [PATCH 1/3] State that documentation assumes ES modules (And update the sample version number because why not.) --- readme.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index a16e308be..81ab59c85 100644 --- a/readme.md +++ b/readme.md @@ -45,11 +45,12 @@ Your `package.json` will then look like this (exact version notwithstanding): ```json { "name": "awesome-package", + "type": "module", "scripts": { "test": "ava" }, "devDependencies": { - "ava": "^1.0.0" + "ava": "^5.0.0" } } ``` @@ -72,7 +73,9 @@ Don't forget to configure the `test` script in your `package.json` as per above. ### Create your test file -Create a file named `test.js` in the project root directory: +Create a file named `test.js` in the project root directory. + +_Note that AVA's documentation assumes you're using ES modules._ ```js import test from 'ava'; From 75596139a98d4b4fb4e8a6bba03963fa0904ac23 Mon Sep 17 00:00:00 2001 From: Tao Cumplido Date: Mon, 6 Feb 2023 21:20:42 +0100 Subject: [PATCH 2/3] Infer thrown error from expectations --- test-types/import-in-cts/throws.cts | 21 ++++++++++++++++++--- test-types/module/throws.ts | 21 ++++++++++++++++++--- types/assertions.d.cts | 19 ++++++++++++------- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/test-types/import-in-cts/throws.cts b/test-types/import-in-cts/throws.cts index 126dd174b..088cce716 100644 --- a/test-types/import-in-cts/throws.cts +++ b/test-types/import-in-cts/throws.cts @@ -12,15 +12,30 @@ class CustomError extends Error { } test('throws', t => { - expectType(t.throws(() => {})); + const error1 = t.throws(() => {}); + expectType(error1); const error2: CustomError | undefined = t.throws(() => {}); expectType(error2); expectType(t.throws(() => {})); + const error3 = t.throws(() => {}, {instanceOf: CustomError}); + expectType(error3); + const error4 = t.throws(() => {}, {is: new CustomError()}); + expectType(error4); + const error5 = t.throws(() => {}, {instanceOf: CustomError, is: new CustomError()}); + expectType(error5); }); test('throwsAsync', async t => { - expectType(await t.throwsAsync(async () => {})); + const error1 = await t.throwsAsync(async () => {}); + expectType(error1); expectType(await t.throwsAsync(async () => {})); - expectType(await t.throwsAsync(Promise.reject())); + const error2 = await t.throwsAsync(Promise.reject()); + expectType(error2); expectType(await t.throwsAsync(Promise.reject())); + const error3 = await t.throwsAsync(async () => {}, {instanceOf: CustomError}); + expectType(error3); + const error4 = await t.throwsAsync(async () => {}, {is: new CustomError()}); + expectType(error4); + const error5 = await t.throwsAsync(async () => {}, {instanceOf: CustomError, is: new CustomError()}); + expectType(error5); }); diff --git a/test-types/module/throws.ts b/test-types/module/throws.ts index 126dd174b..088cce716 100644 --- a/test-types/module/throws.ts +++ b/test-types/module/throws.ts @@ -12,15 +12,30 @@ class CustomError extends Error { } test('throws', t => { - expectType(t.throws(() => {})); + const error1 = t.throws(() => {}); + expectType(error1); const error2: CustomError | undefined = t.throws(() => {}); expectType(error2); expectType(t.throws(() => {})); + const error3 = t.throws(() => {}, {instanceOf: CustomError}); + expectType(error3); + const error4 = t.throws(() => {}, {is: new CustomError()}); + expectType(error4); + const error5 = t.throws(() => {}, {instanceOf: CustomError, is: new CustomError()}); + expectType(error5); }); test('throwsAsync', async t => { - expectType(await t.throwsAsync(async () => {})); + const error1 = await t.throwsAsync(async () => {}); + expectType(error1); expectType(await t.throwsAsync(async () => {})); - expectType(await t.throwsAsync(Promise.reject())); + const error2 = await t.throwsAsync(Promise.reject()); + expectType(error2); expectType(await t.throwsAsync(Promise.reject())); + const error3 = await t.throwsAsync(async () => {}, {instanceOf: CustomError}); + expectType(error3); + const error4 = await t.throwsAsync(async () => {}, {is: new CustomError()}); + expectType(error4); + const error5 = await t.throwsAsync(async () => {}, {instanceOf: CustomError, is: new CustomError()}); + expectType(error5); }); diff --git a/types/assertions.d.cts b/types/assertions.d.cts index 08c3e05f1..3fbd37556 100644 --- a/types/assertions.d.cts +++ b/types/assertions.d.cts @@ -1,15 +1,20 @@ -export type ErrorConstructor = new (...args: any[]) => Error; +export type ErrorConstructor = { + new (...args: any[]): ErrorType; + readonly prototype: ErrorType; +} + +export type ThrownError = ErrorType extends ErrorConstructor ? ErrorType['prototype'] : ErrorType; /** Specify one or more expectations the thrown error must satisfy. */ -export type ThrowsExpectation = { +export type ThrowsExpectation = { /** The thrown error must have a code that equals the given string or number. */ code?: string | number; /** The thrown error must be an instance of this constructor. */ - instanceOf?: ErrorConstructor; + instanceOf?: ErrorType extends ErrorConstructor ? ErrorType : ErrorType extends Error ? ErrorConstructor : never; /** The thrown error must be strictly equal to this value. */ - is?: Error; + is?: ErrorType extends ErrorConstructor ? ErrorType['prototype'] : ErrorType; /** The thrown error must have a message that equals the given string, or matches the regular expression. */ message?: string | RegExp | ((message: string) => boolean); @@ -293,7 +298,7 @@ export type ThrowsAssertion = { * Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value. * The error must satisfy all expectations. Returns undefined when the assertion fails. */ - (fn: () => any, expectations?: ThrowsExpectation, message?: string): ThrownError | undefined; + (fn: () => any, expectations?: ThrowsExpectation, message?: string): ThrownError | undefined; /** Skip this assertion. */ skip(fn: () => any, expectations?: any, message?: string): void; @@ -304,14 +309,14 @@ export type ThrowsAsyncAssertion = { * Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error * value. Returns undefined when the assertion fails. You must await the result. The error must satisfy all expectations. */ - (fn: () => PromiseLike, expectations?: ThrowsExpectation, message?: string): Promise; + (fn: () => PromiseLike, expectations?: ThrowsExpectation, message?: string): Promise | undefined>; /** * Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the * rejection reason. Returns undefined when the assertion fails. You must await the result. The error must satisfy all * expectations. */ - (promise: PromiseLike, expectations?: ThrowsExpectation, message?: string): Promise; + (promise: PromiseLike, expectations?: ThrowsExpectation, message?: string): Promise | undefined>; /** Skip this assertion. */ skip(thrower: any, expectations?: any, message?: string): void; From 1353b08ae5c3be0af96d2197e593be12f9eaab6b Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Mon, 6 Feb 2023 21:41:06 +0100 Subject: [PATCH 3/3] 5.2.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e768b4b0..2ef9080b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ava", - "version": "5.1.1", + "version": "5.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ava", - "version": "5.1.1", + "version": "5.2.0", "license": "MIT", "dependencies": { "acorn": "^8.8.1", diff --git a/package.json b/package.json index b977b5817..3e5caa15c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ava", - "version": "5.1.1", + "version": "5.2.0", "description": "Node.js test runner that lets you develop with confidence.", "license": "MIT", "repository": "avajs/ava",