Repository: avajs/ava
Pull request #2792 (2021-07-23 17:55:04)

Add StackBlitz examples for TypeScript
I improved the TypeScript support on StackBlitz and added two TypeScript examples.

- [Basic example for AVA with TypeScript](https://stackblitz.com/github/SamVerschueren/ava/tree/stackblitz/examples/typescript/examples/typescript-basic?file=source%2Ftest.ts&terminal=test&view=editor)
- [TypeScript example for typing `t.context`](https://stackblitz.com/github/SamVerschueren/ava/tree/stackblitz/examples/typescript/examples/typescript-context?file=source%2Ftest.ts&terminal=test&view=editor)

SamVerschueren: @sindresorhus I use a `tsconfig.json` file which extends from `@sindresorhus/tsconfig` for the examples. But `@sindresorhus/tsconfig` does not exist after the CI runs `npm install`. So we end up with this error.

![image](https://user-images.githubusercontent.com/1913805/126824057-508501f6-d7c0-4b94-9792-32ad277ed43b.png)

Can I somehow disable the `tsconfig` inference and use the built-in `parserOptions.project`? I could disable linting of those files, but it's a bit of a bummer 🤔 .
SamVerschueren: Not sure why, but sometimes some tests are flaky. Is that normal on Windows?

Patch:
diff --git a/.xo-config.json b/.xo-config.json
index 5bd460e0..e0d14448 100644
--- a/.xo-config.json
+++ b/.xo-config.json
@@ -3,7 +3,8 @@
 		"media/**",
 		"test/config/fixtures/config-errors/test.js",
 		"test-tap/fixture/snapshots/test-sourcemaps/build/**",
-		"test-tap/fixture/report/edgecases/ast-syntax-error.cjs"
+		"test-tap/fixture/report/edgecases/ast-syntax-error.cjs",
+		"examples/typescript-*/**/*.ts"
 	],
 	"rules": {
 		"import/no-anonymous-default-export": "off",
diff --git a/docs/recipes/typescript.md b/docs/recipes/typescript.md
index 84cc1db5..497ff9a7 100644
--- a/docs/recipes/typescript.md
+++ b/docs/recipes/typescript.md
@@ -95,6 +95,8 @@ It's worth noting that with this configuration, tests will fail if there are Typ
 
 ## Writing tests
 
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/avajs/ava/tree/main/examples/typescript-basic?file=source%2Ftest.ts&terminal=test&view=editor)
+
 Create a `test.ts` file.
 
 ```ts
@@ -186,6 +188,8 @@ test('providedTitle', macro, '3 * 3', 9);
 
 ## Typing [`t.context`](../01-writing-tests.md#test-context)
 
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/avajs/ava/tree/main/examples/typescript-context?file=source%2Ftest.ts&terminal=test&view=editor)
+
 By default, the type of `t.context` will be the empty object (`{}`). AVA exposes an interface `TestInterface<Context>` (in AVA 4 this is `TestFn<Context>`) which you can use to apply your own type to `t.context`. This can help you catch errors at compile-time:
 
 ```ts
diff --git a/examples/timeouts/index.js b/examples/timeouts/index.js
new file mode 100644
index 00000000..12ecbc77
--- /dev/null
+++ b/examples/timeouts/index.js
@@ -0,0 +1,42 @@
+'use strict';
+
+const delay = ms => {
+	return new Promise(resolve => {
+		setTimeout(resolve, ms);
+	});
+};
+
+exports.fetchUsers = async () => {
+	await delay(50);
+
+	return [
+		{
+			id: 1,
+			firstName: 'Ava',
+			name: 'Rocks',
+			email: 'ava@rocks.com'
+		}
+	];
+};
+
+exports.fetchPosts = async userId => {
+	await delay(200);
+
+	return [
+		{
+			id: 1,
+			userId,
+			message: 'AVA Rocks 🚀'
+		}
+	];
+};
+
+exports.createPost = async message => {
+	await delay(3000);
+
+	return {
+		id: 2,
+		userId: 1,
+		message
+	};
+};
diff --git a/examples/timeouts/package.json b/examples/timeouts/package.json
new file mode 100644
index 00000000..ec288c77
--- /dev/null
+++ b/examples/timeouts/package.json
@@ -0,0 +1,10 @@
+{
+	"name": "ava-timeouts",
+	"description": "Example for test timeouts",
+	"scripts": {
+		"test": "ava --timeout=2s --verbose"
+	},
+	"devDependencies": {
+		"ava": "^3.15.0"
+	}
+}
diff --git a/examples/timeouts/readme.md b/examples/timeouts/readme.md
new file mode 100644
index 00000000..c04cb919
--- /dev/null
+++ b/examples/timeouts/readme.md
@@ -0,0 +1,5 @@
+# Test timeouts
+
+> Example for [test timeouts](https://github.com/avajs/ava/blob/main/docs/07-test-timeouts.md)
+
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/avajs/ava/tree/main/examples/timeouts?file=test.js&terminal=test&view=editor)
diff --git a/examples/typescript-basic/package.json b/examples/typescript-basic/package.json
new file mode 100644
index 00000000..ad85254f
--- /dev/null
+++ b/examples/typescript-basic/package.json
@@ -0,0 +1,21 @@
+{
+	"name": "ava-typescript-basic",
+	"description": "Basic example for AVA with TypeScript",
+	"scripts": {
+		"test": "ava"
+	},
+	"devDependencies": {
+		"@ava/typescript": "^2.0.0",
+		"@sindresorhus/tsconfig": "^1.0.2",
+		"ava": "^3.15.0",
+		"typescript": "^4.3.4"
+	},
+	"ava": {
+		"typescript": {
+			"compile": "tsc",
+			"rewritePaths": {
+				"source/": "build/"
+			}
+		}
+	}
+}
diff --git a/examples/typescript-basic/readme.md b/examples/typescript-basic/readme.md
new file mode 100644
index 00000000..7068cc19
--- /dev/null
+++ b/examples/typescript-basic/readme.md
@@ -0,0 +1,5 @@
+# TypeScript basic example
+
+> Basic example for [AVA with TypeScript](https://github.com/avajs/ava/blob/main/docs/recipes/typescript.md)
+
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/avajs/ava/tree/main/examples/typescript-basic?file=source%2Ftest.ts&terminal=test&view=editor)
diff --git a/examples/typescript-basic/source/index.ts b/examples/typescript-basic/source/index.ts
new file mode 100644
index 00000000..c8e7568d
--- /dev/null
+++ b/examples/typescript-basic/source/index.ts
@@ -0,0 +1,3 @@
+export const sum = (a: number, b: number) => a + b;
+
+export const subtract = (a: number, b: number) => a - b;
diff --git a/examples/typescript-basic/tsconfig.json b/examples/typescript-basic/tsconfig.json
new file mode 100644
index 00000000..60833d01
--- /dev/null
+++ b/examples/typescript-basic/tsconfig.json
@@ -0,0 +1,7 @@
+{
+	"extends": "@sindresorhus/tsconfig",
+	"compilerOptions": {
+		"module": "commonjs",
+		"outDir": "build",
+	}
+}
diff --git a/examples/typescript-context/package.json b/examples/typescript-context/package.json
new file mode 100644
index 00000000..f577a30e
--- /dev/null
+++ b/examples/typescript-context/package.json
@@ -0,0 +1,21 @@
+{
+	"name": "ava-typescript-context",
+	"description": "TypeScript example for typing t.context",
+	"scripts": {
+		"test": "ava"
+	},
+	"devDependencies": {
+		"@ava/typescript": "^2.0.0",
+		"@sindresorhus/tsconfig": "^1.0.2",
+		"ava": "^3.15.0",
+		"typescript": "^4.3.4"
+	},
+	"ava": {
+		"typescript": {
+			"compile": "tsc",
+			"rewritePaths": {
+				"source/": "build/"
+			}
+		}
+	}
+}
diff --git a/examples/typescript-context/readme.md b/examples/typescript-context/readme.md
new file mode 100644
index 00000000..fa94dccf
--- /dev/null
+++ b/examples/typescript-context/readme.md
@@ -0,0 +1,5 @@
+# TypeScript context example
+
+> TypeScript example for [typing `t.context`](https://github.com/avajs/ava/blob/main/docs/recipes/typescript.md#typing-tcontext)
+
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/avajs/ava/tree/main/examples/typescript-context?file=source%2Ftest.ts&terminal=test&view=editor)
diff --git a/examples/typescript-context/source/index.ts b/examples/typescript-context/source/index.ts
new file mode 100644
index 00000000..8ec3c670
--- /dev/null
+++ b/examples/typescript-context/source/index.ts
@@ -0,0 +1,1 @@
+export const concat = (input: string[]) => input.join(' ');
diff --git a/examples/typescript-context/tsconfig.json b/examples/typescript-context/tsconfig.json
new file mode 100644
index 00000000..60833d01
--- /dev/null
+++ b/examples/typescript-context/tsconfig.json
@@ -0,0 +1,7 @@
+{
+	"extends": "@sindresorhus/tsconfig",
+	"compilerOptions": {
+		"module": "commonjs",
+		"outDir": "build",
+	}
+}


Test patch:
diff --git a/docs/07-test-timeouts.md b/docs/07-test-timeouts.md
index 5850386e..4ca9b8f5 100644
--- a/docs/07-test-timeouts.md
+++ b/docs/07-test-timeouts.md
@@ -2,6 +2,8 @@
 
 Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/docs/07-test-timeouts.md)
 
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/avajs/ava/tree/main/examples/timeouts?file=test.js&terminal=test&view=editor)
+
 Timeouts in AVA behave differently than in other test frameworks. AVA resets a timer after each test, forcing tests to quit if no new test results were received within the specified timeout. This can be used to handle stalled tests.
 
 The default timeout is 10 seconds.
diff --git a/examples/timeouts/test.js b/examples/timeouts/test.js
new file mode 100644
index 00000000..ea215ded
--- /dev/null
+++ b/examples/timeouts/test.js
@@ -0,0 +1,43 @@
+'use strict';
+const test = require('ava');
+
+const {fetchUsers, fetchPosts, createPost} = require('.');
+
+test('retrieve users', async t => {
+	t.timeout(100);
+
+	const users = await fetchUsers();
+
+	t.deepEqual(users, [
+		{
+			id: 1,
+			firstName: 'Ava',
+			name: 'Rocks',
+			email: 'ava@rocks.com'
+		}
+	]);
+});
+
+test('retrieve posts', async t => {
+	t.timeout(100, 'retrieving posts is too slow');
+
+	const posts = await fetchPosts(1);
+
+	t.deepEqual(posts, [
+		{
+			id: 1,
+			userId: 1,
+			message: 'AVA Rocks 🚀'
+		}
+	]);
+});
+
+test('create post', async t => {
+	const post = await createPost('I love 🦄 and 🌈');
+
+	t.deepEqual(post, {
+		id: 2,
+		userId: 1,
+		message: 'I love 🦄 and 🌈'
+	});
+});
diff --git a/examples/typescript-basic/source/test.ts b/examples/typescript-basic/source/test.ts
new file mode 100644
index 00000000..339a2321
--- /dev/null
+++ b/examples/typescript-basic/source/test.ts
@@ -0,0 +1,13 @@
+import test from 'ava';
+
+import {sum, subtract} from '.';
+
+test('sum', t => {
+	t.is(sum(0, 0), 0);
+	t.is(sum(2, 2), 4);
+});
+
+test('subtract', t => {
+	t.is(subtract(0, 0), 0);
+	t.is(subtract(4, 2), 2);
+});
diff --git a/examples/typescript-context/source/test.ts b/examples/typescript-context/source/test.ts
new file mode 100644
index 00000000..feccdaac
--- /dev/null
+++ b/examples/typescript-context/source/test.ts
@@ -0,0 +1,15 @@
+import anyTest, {TestInterface} from 'ava';
+
+import {concat} from '.';
+
+const test = anyTest as TestInterface<{sort: (a: string, b: string) => number}>;
+
+test.beforeEach(t => {
+	t.context = {
+		sort: (a: string, b: string) => a.localeCompare(b)
+	};
+});
+
+test('concat', t => {
+	t.is(concat(['b', 'c', 'a'].sort(t.context.sort)), 'a b c');
+});