Rely on TypeScript 4.7 and update integration + tests
* Only test against TypeScript 4.7 * Move type definitions to entrypoints/ Only TS 4.7 will resolve them now, but it's cleaner. * Use @sindresorhus/tsconfig * Fix test TypeScript files, make compilable and lintable * Use tsc directly, instead of tsd * Add *.cts versions of type tests * Reorganize type tests * Use tsc directly, avoid npx, print actual version Somehow `npx tsc` was pointing at an older version. Possibly the binstubs are corrupted in CI… somehow.
This commit is contained in:
parent
d0af7297b8
commit
02f4e27b53
45 changed files with 532 additions and 93 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"all": true,
|
||||
"exclude": [
|
||||
"{coverage,examples,media,test,test-d,test-tap,types}/**",
|
||||
"{coverage,examples,media,test,test-types,test-tap,types}/**",
|
||||
"*.config.cjs",
|
||||
"*.d.*(c|m)ts"
|
||||
],
|
||||
|
|
|
|||
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
ts-version: [~4.4, ~4.5, ~4.6, ~4.7]
|
||||
ts-version: [~4.7]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
|
|
@ -55,9 +55,8 @@ jobs:
|
|||
- run: npm i typescript@${TS_VERSION}
|
||||
env:
|
||||
TS_VERSION: ${{ matrix.ts-version }}
|
||||
- run: npm ls typescript
|
||||
continue-on-error: true
|
||||
- run: npx tsd
|
||||
- run: ./node_modules/typescript/bin/tsc --version
|
||||
- run: ./node_modules/typescript/bin/tsc --noEmit
|
||||
|
||||
lockfile_churn:
|
||||
name: Test package-lock for unexpected modifications
|
||||
|
|
|
|||
|
|
@ -49,6 +49,15 @@ module.exports = {
|
|||
'unicorn/no-empty-file': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: 'test-types/**',
|
||||
rules: {
|
||||
'ava/assertion-arguments': 'off',
|
||||
'ava/no-ignored-test-files': 'off',
|
||||
'ava/no-skip-assert': 'off',
|
||||
'ava/use-t': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
// TODO: Update tests.
|
||||
files: 'test/**',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export default { // eslint-disable-line import/no-anonymous-default-export
|
||||
files: ['test/**', '!test/**/{fixtures,helpers}/**'],
|
||||
ignoredByWatcher: ['{coverage,docs,media,test-d,test-tap}/**'],
|
||||
ignoredByWatcher: ['{coverage,docs,media,test-types,test-tap}/**'],
|
||||
environmentVariables: {
|
||||
AVA_FAKE_SCM_ROOT: '.fake-root', // This is an internal test flag.
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Translations: [Español](https://github.com/avajs/ava-docs/blob/main/es_ES/docs/
|
|||
|
||||
AVA comes bundled with a TypeScript definition file. This allows developers to leverage TypeScript for writing tests.
|
||||
|
||||
This guide assumes you've already set up TypeScript for your project. Note that AVA's definition expects at least version 4.4.
|
||||
This guide assumes you've already set up TypeScript for your project. Note that AVA's definition expects at least version 4.7.
|
||||
|
||||
## Enabling AVA's support for TypeScript test files
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
export {default} from '../index.js';
|
||||
export * from '../index.js';
|
||||
2
entrypoints/main.d.cts
Normal file
2
entrypoints/main.d.cts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export {default} from './main.js';
|
||||
export * from './main.js';
|
||||
12
entrypoints/main.d.ts
vendored
Normal file
12
entrypoints/main.d.ts
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import type {TestFn} from '../types/test-fn.js';
|
||||
|
||||
export * from '../types/assertions.js';
|
||||
export * from '../types/try-fn.js';
|
||||
export * from '../types/test-fn.js';
|
||||
export * from '../types/subscribable.js';
|
||||
|
||||
/** Call to declare a test, or chain to declare hooks or test modifiers */
|
||||
declare const test: TestFn;
|
||||
|
||||
/** Call to declare a test, or chain to declare hooks or test modifiers */
|
||||
export default test;
|
||||
|
|
@ -1 +1 @@
|
|||
export * from '../plugin.js'
|
||||
export * from './plugin.js'
|
||||
|
|
|
|||
0
plugin.d.ts → entrypoints/plugin.d.ts
vendored
0
plugin.d.ts → entrypoints/plugin.d.ts
vendored
12
index.d.ts
vendored
12
index.d.ts
vendored
|
|
@ -1,12 +0,0 @@
|
|||
import type {TestFn} from './types/test-fn.js';
|
||||
|
||||
export * from './types/assertions.js';
|
||||
export * from './types/try-fn.js';
|
||||
export * from './types/test-fn.js';
|
||||
export * from './types/subscribable.js';
|
||||
|
||||
/** Call to declare a test, or chain to declare hooks or test modifiers */
|
||||
declare const test: TestFn;
|
||||
|
||||
/** Call to declare a test, or chain to declare hooks or test modifiers */
|
||||
export default test;
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
|
|
@ -61,6 +61,7 @@
|
|||
"devDependencies": {
|
||||
"@ava/test": "github:avajs/test",
|
||||
"@ava/typescript": "^3.0.1",
|
||||
"@sindresorhus/tsconfig": "^3.0.1",
|
||||
"@sinonjs/fake-timers": "^9.1.2",
|
||||
"ansi-escapes": "^5.0.0",
|
||||
"c8": "^7.11.3",
|
||||
|
|
@ -75,7 +76,7 @@
|
|||
"tempy": "^2.0.0",
|
||||
"touch": "^3.1.0",
|
||||
"tsd": "^0.20.0",
|
||||
"typescript": "^4.7.2",
|
||||
"typescript": "^4.7.3",
|
||||
"xo": "^0.49.0",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
|
|
@ -1149,6 +1150,15 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sindresorhus/tsconfig": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/tsconfig/-/tsconfig-3.0.1.tgz",
|
||||
"integrity": "sha512-0/gtPNTY3++0J2BZM5nHHULg0BIMw886gqdn8vWN+Av6bgF5ZU2qIcHubAn+Z9KNvJhO8WFE+9kDOU3n6OcKtA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@sinonjs/commons": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
|
||||
|
|
@ -9992,9 +10002,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.7.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz",
|
||||
"integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==",
|
||||
"version": "4.7.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz",
|
||||
"integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
|
|
|||
15
package.json
15
package.json
|
|
@ -11,18 +11,18 @@
|
|||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./index.d.ts",
|
||||
"types": "./entrypoints/main.d.ts",
|
||||
"default": "./entrypoints/main.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./entrypoints/index.d.cts",
|
||||
"types": "./entrypoints/main.d.cts",
|
||||
"default": "./entrypoints/main.cjs"
|
||||
}
|
||||
},
|
||||
"./eslint-plugin-helper": "./entrypoints/eslint-plugin-helper.cjs",
|
||||
"./plugin": {
|
||||
"import": {
|
||||
"types": "./plugin.d.ts",
|
||||
"types": "./entrypoints/plugin.d.ts",
|
||||
"default": "./entrypoints/plugin.mjs"
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -37,14 +37,12 @@
|
|||
},
|
||||
"scripts": {
|
||||
"cover": "c8 --report=none test-ava && c8 --report=none --no-clean tap && c8 report",
|
||||
"test": "xo && tsd && npm run -s cover"
|
||||
"test": "xo && tsc --noEmit && npm run -s cover"
|
||||
},
|
||||
"files": [
|
||||
"entrypoints",
|
||||
"lib",
|
||||
"types",
|
||||
"index.d.ts",
|
||||
"plugin.d.ts"
|
||||
"types"
|
||||
],
|
||||
"keywords": [
|
||||
"🦄",
|
||||
|
|
@ -131,6 +129,7 @@
|
|||
"devDependencies": {
|
||||
"@ava/test": "github:avajs/test",
|
||||
"@ava/typescript": "^3.0.1",
|
||||
"@sindresorhus/tsconfig": "^3.0.1",
|
||||
"@sinonjs/fake-timers": "^9.1.2",
|
||||
"ansi-escapes": "^5.0.0",
|
||||
"c8": "^7.11.3",
|
||||
|
|
@ -145,7 +144,7 @@
|
|||
"tempy": "^2.0.0",
|
||||
"touch": "^3.1.0",
|
||||
"tsd": "^0.20.0",
|
||||
"typescript": "^4.7.2",
|
||||
"typescript": "^4.7.3",
|
||||
"xo": "^0.49.0",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
import test from '../../../../../../../entrypoints/main.cjs';
|
||||
|
||||
test('feature test title', t => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
import test from '../../../../../entrypoints/main.cjs';
|
||||
|
||||
test('top level test title', t => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
import test from '../../../../../../entrypoints/main.cjs';
|
||||
|
||||
test('test title', t => {
|
||||
|
|
|
|||
0
test-d/.gitignore → test-types/.gitignore
vendored
0
test-d/.gitignore → test-types/.gitignore
vendored
40
test-types/import-in-cts/assertions-as-type-guards.cts
Normal file
40
test-types/import-in-cts/assertions-as-type-guards.cts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import test from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
type Expected = {foo: 'bar'};
|
||||
const expected: Expected = {foo: 'bar'};
|
||||
|
||||
test('deepEqual', t => {
|
||||
const actual: unknown = {};
|
||||
if (t.deepEqual(actual, expected)) {
|
||||
expectType<Expected>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('like', t => {
|
||||
const actual: unknown = {};
|
||||
if (t.like(actual, expected)) {
|
||||
expectType<Expected>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('is', t => {
|
||||
const actual: unknown = 2;
|
||||
if (t.is(actual, 3 as const)) {
|
||||
expectType<3>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('false', t => {
|
||||
const actual: unknown = true;
|
||||
if (t.false(actual)) {
|
||||
expectType<false>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('true', t => {
|
||||
const actual: unknown = false;
|
||||
if (t.true(actual)) {
|
||||
expectType<true>(actual);
|
||||
}
|
||||
});
|
||||
33
test-types/import-in-cts/context.cts
Normal file
33
test-types/import-in-cts/context.cts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import anyTest, {ExecutionContext, TestFn} from 'ava';
|
||||
import {expectError, expectType} from 'tsd';
|
||||
|
||||
interface Context {
|
||||
foo: string;
|
||||
}
|
||||
|
||||
const test = anyTest as TestFn<Context>;
|
||||
|
||||
const macro = test.macro((t, _expected: number) => {
|
||||
expectType<string>(t.context.foo);
|
||||
});
|
||||
|
||||
test.beforeEach(t => {
|
||||
expectType<Context>(t.context);
|
||||
});
|
||||
|
||||
// @ts-expect-error TS2769
|
||||
expectError(test('foo is bar', macro, 'bar')); // eslint-disable-line @typescript-eslint/no-confusing-void-expression
|
||||
|
||||
anyTest('default context is unknown', t => {
|
||||
expectType<unknown>(t.context);
|
||||
});
|
||||
|
||||
// See https://github.com/avajs/ava/issues/2253
|
||||
interface Covariant extends Context {
|
||||
bar: number;
|
||||
}
|
||||
|
||||
const test2 = anyTest as TestFn<Covariant>;
|
||||
const hook = (_t: ExecutionContext<Context>) => {};
|
||||
test2.beforeEach(hook);
|
||||
29
test-types/import-in-cts/deep-equal.cts
Normal file
29
test-types/import-in-cts/deep-equal.cts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import test from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
test('actual extends expected', t => {
|
||||
type Expected = {foo: [1, 2, 3]};
|
||||
const expected: Expected = {foo: [1, 2, 3]};
|
||||
const actual = {foo: [1, 2, 3]};
|
||||
if (t.deepEqual(actual, expected)) {
|
||||
expectType<Expected>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('expected extends actual', t => {
|
||||
type Expected = {foo: Array<number | string>};
|
||||
type Actual = {foo: number[]};
|
||||
const expected: Expected = {foo: [1, 2, 3]};
|
||||
const actual: Actual = {foo: [1, 2, 3]};
|
||||
if (t.deepEqual(actual, expected)) {
|
||||
expectType<Actual>(expected);
|
||||
}
|
||||
});
|
||||
|
||||
test('neither extends the each other', t => {
|
||||
type Expected = {readonly foo: readonly [1, 2, 3]};
|
||||
type Actual = {foo: number[]};
|
||||
const expected: Expected = {foo: [1, 2, 3]};
|
||||
const actual: Actual = {foo: [1, 2, 3]};
|
||||
t.deepEqual(actual, expected);
|
||||
});
|
||||
20
test-types/import-in-cts/implementation-result.cts
Normal file
20
test-types/import-in-cts/implementation-result.cts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import test from 'ava';
|
||||
|
||||
test.after('return anything else', _t => ({
|
||||
foo: 'bar',
|
||||
subscribe() {},
|
||||
then() {}, // eslint-disable-line unicorn/no-thenable
|
||||
}));
|
||||
|
||||
test('return a promise-like', _t => ({
|
||||
then(resolve) { // eslint-disable-line unicorn/no-thenable
|
||||
resolve?.(); // eslint-disable-line @typescript-eslint/no-floating-promises
|
||||
},
|
||||
}));
|
||||
|
||||
test('return a subscribable', _t => ({
|
||||
subscribe({complete}) {
|
||||
complete();
|
||||
},
|
||||
}));
|
||||
25
test-types/import-in-cts/like.cts
Normal file
25
test-types/import-in-cts/like.cts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import test from 'ava';
|
||||
|
||||
test('like', t => {
|
||||
t.like({
|
||||
map: new Map([['foo', 'bar']]),
|
||||
nested: {
|
||||
baz: 'thud',
|
||||
qux: 'quux',
|
||||
},
|
||||
}, {
|
||||
map: new Map([['foo', 'bar']]),
|
||||
nested: {
|
||||
baz: 'thud',
|
||||
},
|
||||
});
|
||||
|
||||
type Foo = {
|
||||
foo?: 'foo';
|
||||
bar?: 'bar';
|
||||
};
|
||||
|
||||
const foo: Foo = {bar: 'bar'};
|
||||
const {foo: _, ...expected} = foo;
|
||||
t.like(expected, {bar: 'bar'});
|
||||
});
|
||||
126
test-types/import-in-cts/macros.cts
Normal file
126
test-types/import-in-cts/macros.cts
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/* eslint-disable no-lone-blocks */
|
||||
import test, {ExecutionContext} from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
// Typed arguments through generics.
|
||||
{
|
||||
const hasLength = test.macro<[string, number]>((t, input, expected) => {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
});
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
}
|
||||
|
||||
{
|
||||
const hasLength = test.macro<[string, number]>({
|
||||
exec(t, input, expected) {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
},
|
||||
title(_providedTitle, input, expected) {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
return 'title';
|
||||
},
|
||||
});
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
}
|
||||
|
||||
// Typed arguments in execution function.
|
||||
{
|
||||
const hasLength = test.macro((t, input: string, expected: number) => {
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
});
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
}
|
||||
|
||||
{
|
||||
const hasLength = test.macro({
|
||||
exec(t, input: string, expected: number) {
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
},
|
||||
title(_providedTitle, input, expected) {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
return 'title';
|
||||
},
|
||||
});
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
}
|
||||
|
||||
// Untyped arguments
|
||||
{
|
||||
const hasLength = test.macro((t, input, expected) => {
|
||||
expectType<unknown>(input);
|
||||
expectType<unknown>(expected);
|
||||
t.is(input, expected);
|
||||
});
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
}
|
||||
|
||||
// Usable without title, even if the macro lacks a title function.
|
||||
{
|
||||
const hasLength = test.macro<[string, number]>((t, input, expected) => {
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
});
|
||||
|
||||
test(hasLength, 'bar', 3);
|
||||
}
|
||||
|
||||
// No arguments
|
||||
{
|
||||
const pass = test.macro<[]>({ // eslint-disable-line @typescript-eslint/ban-types
|
||||
exec(_t, ...args) {
|
||||
expectType<[]>(args); // eslint-disable-line @typescript-eslint/ban-types
|
||||
},
|
||||
title(providedTitle, ...args) {
|
||||
expectType<string | undefined>(providedTitle);
|
||||
expectType<[]>(args); // eslint-disable-line @typescript-eslint/ban-types
|
||||
return '';
|
||||
},
|
||||
});
|
||||
|
||||
test(pass);
|
||||
}
|
||||
|
||||
// Without test.macro()
|
||||
{
|
||||
const hasLength = (t: ExecutionContext, input: string, expected: number) => {
|
||||
t.is(input.length, expected);
|
||||
};
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
}
|
||||
|
||||
// Inline function with explicit argument types.
|
||||
test('has length 3', (t: ExecutionContext, input: string, expected: number) => {
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
}, 'bar', 3);
|
||||
|
||||
// Completely inferred arguments for inline functions.
|
||||
test('has length 3', (t, input, expected) => {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
}, 'foo', 3);
|
||||
|
||||
test.skip('skip', (t, input, expected) => {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
}, 'foo', 3);
|
||||
18
test-types/import-in-cts/plugin.cts
Normal file
18
test-types/import-in-cts/plugin.cts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import plugin from 'ava/plugin';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
expectType<plugin.SharedWorker.Plugin.Protocol>(plugin.registerSharedWorker({filename: '', supportedProtocols: ['ava-4']}));
|
||||
|
||||
const factory: plugin.SharedWorker.Factory = ({negotiateProtocol}) => {
|
||||
const protocol = negotiateProtocol(['ava-4']);
|
||||
expectType<plugin.SharedWorker.Protocol>(protocol);
|
||||
|
||||
(async () => {
|
||||
for await (const w of protocol.testWorkers()) {
|
||||
expectType<() => Promise<void>>(w.teardown(() => {})); // eslint-disable-line @typescript-eslint/no-empty-function
|
||||
expectType<() => Promise<void>>(w.teardown(async () => {})); // eslint-disable-line @typescript-eslint/no-empty-function
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
export default factory;
|
||||
16
test-types/import-in-cts/snapshot.cts
Normal file
16
test-types/import-in-cts/snapshot.cts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import test from 'ava';
|
||||
import {expectError} from 'tsd';
|
||||
|
||||
test('snapshot', t => {
|
||||
t.snapshot({foo: 'bar'});
|
||||
t.snapshot(null, 'a snapshot with a message');
|
||||
// @ts-expect-error TS2345
|
||||
expectError(t.snapshot('hello world', null)); // eslint-disable-line @typescript-eslint/no-confusing-void-expression
|
||||
});
|
||||
|
||||
test('snapshot.skip', t => {
|
||||
t.snapshot.skip({foo: 'bar'});
|
||||
t.snapshot.skip(null, 'a snapshot with a message');
|
||||
// @ts-expect-error TS2345
|
||||
expectError(t.snapshot.skip('hello world', null)); // eslint-disable-line @typescript-eslint/no-confusing-void-expression
|
||||
});
|
||||
6
test-types/import-in-cts/teardown.cts
Normal file
6
test-types/import-in-cts/teardown.cts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import test from 'ava';
|
||||
|
||||
test('test', t => {
|
||||
t.teardown(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
|
||||
t.teardown(async () => {}); // eslint-disable-line @typescript-eslint/no-empty-function
|
||||
});
|
||||
26
test-types/import-in-cts/throws.cts
Normal file
26
test-types/import-in-cts/throws.cts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import test from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
class CustomError extends Error {
|
||||
foo: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.foo = 'foo';
|
||||
}
|
||||
}
|
||||
|
||||
test('throws', t => {
|
||||
expectType<Error | undefined>(t.throws(() => {}));
|
||||
const error2: CustomError | undefined = t.throws(() => {});
|
||||
expectType<CustomError | undefined>(error2);
|
||||
expectType<CustomError | undefined>(t.throws<CustomError>(() => {}));
|
||||
});
|
||||
|
||||
test('throwsAsync', async t => {
|
||||
expectType<Error | undefined>(await t.throwsAsync(async () => {}));
|
||||
expectType<CustomError | undefined>(await t.throwsAsync<CustomError>(async () => {}));
|
||||
expectType<Error | undefined>(await t.throwsAsync(Promise.reject()));
|
||||
expectType<CustomError | undefined>(await t.throwsAsync<CustomError>(Promise.reject()));
|
||||
});
|
||||
67
test-types/import-in-cts/try-commit.cts
Normal file
67
test-types/import-in-cts/try-commit.cts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import test, {ExecutionContext} from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
test('attempt', async t => {
|
||||
const attempt = await t.try(
|
||||
(u, a, b) => {
|
||||
expectType<ExecutionContext>(u);
|
||||
expectType<string>(a);
|
||||
expectType<number>(b);
|
||||
},
|
||||
'string',
|
||||
6,
|
||||
);
|
||||
attempt.commit();
|
||||
});
|
||||
|
||||
test('attempt with title', async t => {
|
||||
const attempt = await t.try(
|
||||
'attempt title',
|
||||
(u, a, b) => {
|
||||
expectType<ExecutionContext>(u);
|
||||
expectType<string>(a);
|
||||
expectType<number>(b);
|
||||
},
|
||||
'string',
|
||||
6,
|
||||
);
|
||||
attempt.commit();
|
||||
});
|
||||
|
||||
const lengthCheck = (t: ExecutionContext, a: string, b: number): void => {
|
||||
t.is(a.length, b);
|
||||
};
|
||||
|
||||
test('attempt with helper', async t => {
|
||||
const attempt = await t.try(lengthCheck, 'string', 6);
|
||||
attempt.commit();
|
||||
});
|
||||
|
||||
test('attempt with title', async t => {
|
||||
const attempt = await t.try('title', lengthCheck, 'string', 6);
|
||||
attempt.commit();
|
||||
});
|
||||
|
||||
test('all possible variants to pass to t.try', async t => {
|
||||
// No params
|
||||
void t.try(tt => tt.pass());
|
||||
|
||||
void t.try('test', tt => tt.pass());
|
||||
|
||||
// Some params
|
||||
void t.try((tt, a, b) => tt.is(a.length, b), 'hello', 5);
|
||||
|
||||
void t.try('test', (tt, a, b) => tt.is(a.length, b), 'hello', 5);
|
||||
|
||||
// Macro with title
|
||||
const macro1 = test.macro<[string, number]>({
|
||||
exec: (tt, a, b) => tt.is(a.length, b),
|
||||
title: (title, a, b) => `${title ? `${String(title)} ` : ''}str: "${String(a)}" with len: "${String(b)}"`,
|
||||
});
|
||||
const macro2 = test.macro<[string, number]>((tt, a, b) => tt.is(a.slice(b), ''));
|
||||
|
||||
void t.try(macro1, 'hello', 5);
|
||||
void t.try(macro2, 'hello', 5);
|
||||
void t.try('title', macro1, 'hello', 5);
|
||||
void t.try('title', macro2, 'hello', 5);
|
||||
});
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import test from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
import test from '..';
|
||||
|
||||
type Expected = {foo: 'bar'};
|
||||
const expected: Expected = {foo: 'bar'};
|
||||
|
||||
|
|
@ -1,15 +1,14 @@
|
|||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import anyTest, {ExecutionContext, TestFn} from 'ava';
|
||||
import {expectError, expectType} from 'tsd';
|
||||
|
||||
import anyTest, {ExecutionContext, TestFn} from '..';
|
||||
|
||||
interface Context {
|
||||
foo: string;
|
||||
}
|
||||
|
||||
const test = anyTest as TestFn<Context>;
|
||||
|
||||
const macro = test.macro((t, expected: number) => {
|
||||
const macro = test.macro((t, _expected: number) => {
|
||||
expectType<string>(t.context.foo);
|
||||
});
|
||||
|
||||
|
|
@ -17,6 +16,7 @@ test.beforeEach(t => {
|
|||
expectType<Context>(t.context);
|
||||
});
|
||||
|
||||
// @ts-expect-error TS2769
|
||||
expectError(test('foo is bar', macro, 'bar')); // eslint-disable-line @typescript-eslint/no-confusing-void-expression
|
||||
|
||||
anyTest('default context is unknown', t => {
|
||||
|
|
@ -29,5 +29,5 @@ interface Covariant extends Context {
|
|||
}
|
||||
|
||||
const test2 = anyTest as TestFn<Covariant>;
|
||||
const hook = (t: ExecutionContext<Context>) => {};
|
||||
const hook = (_t: ExecutionContext<Context>) => {};
|
||||
test2.beforeEach(hook);
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import test from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
import test from '..';
|
||||
|
||||
test('actual extends expected', t => {
|
||||
type Expected = {foo: [1, 2, 3]};
|
||||
const expected: Expected = {foo: [1, 2, 3]};
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import test from '..';
|
||||
import test from 'ava';
|
||||
|
||||
test('return a promise-like', t => ({
|
||||
test.after('return anything else', _t => ({
|
||||
foo: 'bar',
|
||||
subscribe() {},
|
||||
then() {}, // eslint-disable-line unicorn/no-thenable
|
||||
}));
|
||||
|
||||
test('return a promise-like', _t => ({
|
||||
then(resolve) { // eslint-disable-line unicorn/no-thenable
|
||||
resolve?.(); // eslint-disable-line @typescript-eslint/no-floating-promises
|
||||
},
|
||||
}));
|
||||
|
||||
test('return a subscribable', t => ({
|
||||
test('return a subscribable', _t => ({
|
||||
subscribe({complete}) {
|
||||
complete();
|
||||
},
|
||||
}));
|
||||
|
||||
test.after('return anything else', t => ({
|
||||
foo: 'bar',
|
||||
subscribe() {},
|
||||
then() {}, // eslint-disable-line unicorn/no-thenable
|
||||
}));
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '..';
|
||||
import test from 'ava';
|
||||
|
||||
test('like', t => {
|
||||
t.like({
|
||||
|
|
@ -21,5 +21,5 @@ test('like', t => {
|
|||
|
||||
const foo: Foo = {bar: 'bar'};
|
||||
const {foo: _, ...expected} = foo;
|
||||
t.like({bar: 'bar'}, expected);
|
||||
t.like(expected, {bar: 'bar'});
|
||||
});
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
/* eslint-disable no-lone-blocks, @typescript-eslint/no-empty-function */
|
||||
/* eslint-disable no-lone-blocks */
|
||||
import test, {ExecutionContext} from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
import test, {ExecutionContext} from '..';
|
||||
|
||||
// Typed arguments through generics.
|
||||
{
|
||||
const hasLength = test.macro<[string, number]>((t, input, expected) => {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
});
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
|
|
@ -18,8 +19,10 @@ import test, {ExecutionContext} from '..';
|
|||
exec(t, input, expected) {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
},
|
||||
title(providedTitle, input, expected) {
|
||||
title(_providedTitle, input, expected) {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
return 'title';
|
||||
|
|
@ -31,15 +34,21 @@ import test, {ExecutionContext} from '..';
|
|||
|
||||
// Typed arguments in execution function.
|
||||
{
|
||||
const hasLength = test.macro((t, input: string, expected: number) => {});
|
||||
const hasLength = test.macro((t, input: string, expected: number) => {
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
});
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
}
|
||||
|
||||
{
|
||||
const hasLength = test.macro({
|
||||
exec(t, input: string, expected: number) {},
|
||||
title(providedTitle, input, expected) {
|
||||
exec(t, input: string, expected: number) {
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
},
|
||||
title(_providedTitle, input, expected) {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
return 'title';
|
||||
|
|
@ -54,6 +63,7 @@ import test, {ExecutionContext} from '..';
|
|||
const hasLength = test.macro((t, input, expected) => {
|
||||
expectType<unknown>(input);
|
||||
expectType<unknown>(expected);
|
||||
t.is(input, expected);
|
||||
});
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
|
|
@ -61,7 +71,10 @@ import test, {ExecutionContext} from '..';
|
|||
|
||||
// Usable without title, even if the macro lacks a title function.
|
||||
{
|
||||
const hasLength = test.macro<[string, number]>((t, input, expected) => {});
|
||||
const hasLength = test.macro<[string, number]>((t, input, expected) => {
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
});
|
||||
|
||||
test(hasLength, 'bar', 3);
|
||||
}
|
||||
|
|
@ -69,7 +82,7 @@ import test, {ExecutionContext} from '..';
|
|||
// No arguments
|
||||
{
|
||||
const pass = test.macro<[]>({ // eslint-disable-line @typescript-eslint/ban-types
|
||||
exec(t, ...args) {
|
||||
exec(_t, ...args) {
|
||||
expectType<[]>(args); // eslint-disable-line @typescript-eslint/ban-types
|
||||
},
|
||||
title(providedTitle, ...args) {
|
||||
|
|
@ -92,15 +105,22 @@ import test, {ExecutionContext} from '..';
|
|||
}
|
||||
|
||||
// Inline function with explicit argument types.
|
||||
test('has length 3', (t: ExecutionContext, input: string, expected: number) => {}, 'bar', 3);
|
||||
test('has length 3', (t: ExecutionContext, input: string, expected: number) => {
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
}, 'bar', 3);
|
||||
|
||||
// Completely inferred arguments for inline functions.
|
||||
test('has length 3', (t, input, expected) => {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
}, 'foo', 3);
|
||||
|
||||
test.skip('skip', (t, input, expected) => {
|
||||
expectType<string>(input);
|
||||
expectType<number>(expected);
|
||||
// @ts-expect-error TS2345
|
||||
t.is(input, expected);
|
||||
}, 'foo', 3);
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import * as plugin from 'ava/plugin';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
import * as plugin from '../plugin'; // eslint-disable-line import/extensions
|
||||
|
||||
expectType<plugin.SharedWorker.Plugin.Protocol>(plugin.registerSharedWorker({filename: '', supportedProtocols: ['ava-4']}));
|
||||
|
||||
const factory: plugin.SharedWorker.Factory = ({negotiateProtocol}) => {
|
||||
|
|
@ -15,3 +14,5 @@ const factory: plugin.SharedWorker.Factory = ({negotiateProtocol}) => {
|
|||
}
|
||||
})();
|
||||
};
|
||||
|
||||
export default factory;
|
||||
|
|
@ -1,15 +1,16 @@
|
|||
import test from 'ava';
|
||||
import {expectError} from 'tsd';
|
||||
|
||||
import test from '..';
|
||||
|
||||
test('snapshot', t => {
|
||||
t.snapshot({foo: 'bar'});
|
||||
t.snapshot(null, 'a snapshot with a message');
|
||||
// @ts-expect-error TS2345
|
||||
expectError(t.snapshot('hello world', null)); // eslint-disable-line @typescript-eslint/no-confusing-void-expression
|
||||
});
|
||||
|
||||
test('snapshot.skip', t => {
|
||||
t.snapshot.skip({foo: 'bar'});
|
||||
t.snapshot.skip(null, 'a snapshot with a message');
|
||||
// @ts-expect-error TS2345
|
||||
expectError(t.snapshot.skip('hello world', null)); // eslint-disable-line @typescript-eslint/no-confusing-void-expression
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '..';
|
||||
import test from 'ava';
|
||||
|
||||
test('test', t => {
|
||||
t.teardown(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import test from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
import test from '..';
|
||||
|
||||
class CustomError extends Error {
|
||||
foo: string;
|
||||
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import test, {ExecutionContext} from 'ava';
|
||||
import {expectType} from 'tsd';
|
||||
|
||||
import test, {ExecutionContext} from '..';
|
||||
|
||||
test('attempt', async t => {
|
||||
const attempt = await t.try(
|
||||
(u, a, b) => {
|
||||
|
|
@ -2,16 +2,16 @@ import test from '@ava/test';
|
|||
|
||||
import {fixture} from '../helpers/exec.js';
|
||||
|
||||
test('load ts as commonjs (using an extensions array)', async t => {
|
||||
const result = await fixture(['*.ts', '--config', 'array-custom.config.js']);
|
||||
test('load cts as commonjs (using an extensions array)', async t => {
|
||||
const result = await fixture(['*.cts', '--config', 'array-custom.config.js']);
|
||||
const files = new Set(result.stats.passed.map(({file}) => file));
|
||||
t.is(files.size, 1);
|
||||
t.true(files.has('test.ts'));
|
||||
t.true(files.has('test.cts'));
|
||||
});
|
||||
|
||||
test('load ts as commonjs (using an extensions object)', async t => {
|
||||
const result = await fixture(['*.ts', '--config', 'object-custom.config.js']);
|
||||
test('load cts as commonjs (using an extensions object)', async t => {
|
||||
const result = await fixture(['*.cts', '--config', 'object-custom.config.js']);
|
||||
const files = new Set(result.stats.passed.map(({file}) => file));
|
||||
t.is(files.size, 1);
|
||||
t.true(files.has('test.ts'));
|
||||
t.true(files.has('test.cts'));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
export default {
|
||||
extensions: ['js', 'ts'],
|
||||
extensions: ['js', 'cts'],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export default {
|
||||
extensions: {
|
||||
js: true,
|
||||
ts: 'commonjs',
|
||||
cts: 'commonjs',
|
||||
},
|
||||
};
|
||||
|
|
|
|||
8
test/configurable-module-format/fixtures/test.cts
Normal file
8
test/configurable-module-format/fixtures/test.cts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
const test = require('ava'); // eslint-disable-line ava/no-ignored-test-files
|
||||
|
||||
// @ts-expect-error TS2345
|
||||
test('always passing test', t => {
|
||||
const numberWithTypes = 0;
|
||||
|
||||
t.is(numberWithTypes, 0);
|
||||
});
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
|
||||
const test = require('ava'); // eslint-disable-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires, ava/no-ignored-test-files, unicorn/prefer-module
|
||||
|
||||
test('always passing test', t => {
|
||||
const numberWithTypes = 0;
|
||||
|
||||
t.is(numberWithTypes, 0);
|
||||
});
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"extends": "@sindresorhus/tsconfig",
|
||||
"include": [
|
||||
"test",
|
||||
"test-d",
|
||||
"test-tap"
|
||||
"test-tap",
|
||||
"test-types"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue