Skip to content

Commit b31b242

Browse files
committed
Implement AVA 8 protocol
- Always import() when loading - Don't include .cts in default extensions
1 parent b4ae7ad commit b31b242

11 files changed

Lines changed: 465 additions & 100 deletions

index.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,17 @@ const changeInterpretations = Object.freeze(Object.assign(Object.create(null), {
7474
waitForOutOfBandCompilation: 2,
7575
}));
7676

77+
const defaultExtensions = ['ts', 'mts'];
78+
const defaultAva6Extensions = ['ts', 'cts', 'mts'];
79+
7780
export default function typescriptProvider({negotiateProtocol}) {
7881
const protocol = negotiateProtocol(['ava-6', 'ava-8'], {version: pkg.version});
7982
if (protocol === null) {
8083
return;
8184
}
8285

86+
const isAva8 = protocol.identifier === 'ava-8';
87+
8388
return {
8489
main({config}) {
8590
if (!isPlainObject(config)) {
@@ -89,7 +94,7 @@ export default function typescriptProvider({negotiateProtocol}) {
8994
validate(config, configProperties);
9095

9196
const {
92-
extensions = ['ts', 'cts', 'mts'],
97+
extensions = isAva8 ? defaultExtensions : defaultAva6Extensions,
9398
rewritePaths: relativeRewritePaths,
9499
compile,
95100
} = config;
@@ -244,21 +249,21 @@ export default function typescriptProvider({negotiateProtocol}) {
244249
},
245250

246251
worker({extensionsToLoadAsModules, state: {extensions, rewritePaths}}) {
247-
const importJs = extensionsToLoadAsModules.includes('js');
252+
const importJs = isAva8 || extensionsToLoadAsModules.includes('js');
248253
const testFileExtension = new RegExp(String.raw`\.(${extensions.map(extension => escapeStringRegexp(extension)).join('|')})$`, 'v');
249254

250255
return {
251256
canLoad(reference) {
252257
return testFileExtension.test(reference) && rewritePaths.some(([from]) => reference.startsWith(from));
253258
},
254259

255-
async load(reference, {requireFn}) {
260+
async load(reference, {requireFn} = {}) {
256261
const [from, to] = rewritePaths.find(([from]) => reference.startsWith(from));
257262
let rewritten = `${to}${reference.slice(from.length)}`;
258263
let useImport = true;
259264
if (reference.endsWith('.cts')) {
260265
rewritten = rewritten.replace(/\.cts$/v, '.cjs');
261-
useImport = false;
266+
useImport = isAva8;
262267
} else if (reference.endsWith('.mts')) {
263268
rewritten = rewritten.replace(/\.mts$/v, '.mjs');
264269
} else {

test/compilation.js

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,7 @@ import {deleteAsync} from 'del';
44
import {execaNode} from 'execa';
55
import createProviderMacro from './_with-provider.js';
66

7-
const withProvider = createProviderMacro(
8-
'ava-6',
9-
'6.0.0',
10-
path.join(import.meta.dirname, 'fixtures'),
11-
);
12-
const withAltProvider = createProviderMacro(
13-
'ava-6',
14-
'6.0.0',
15-
path.join(import.meta.dirname, 'broken-fixtures'),
16-
);
17-
18-
test.before('deleting compiled files', async t => {
7+
test.beforeEach('deleting compiled files', async t => {
198
t.log(await deleteAsync('test/fixtures/typescript/compiled'));
209
t.log(await deleteAsync('test/broken-fixtures/typescript/compiled'));
2110
});
@@ -34,16 +23,64 @@ const compile = async provider => ({
3423
.compile(),
3524
});
3625

37-
test(
38-
'worker(): load rewritten paths files',
39-
withProvider,
40-
async (t, provider) => {
26+
for (const [identifier, withProvider, withAltProvider] of [
27+
[
28+
'ava-6',
29+
createProviderMacro(
30+
'ava-6',
31+
'6.0.0',
32+
path.join(import.meta.dirname, 'fixtures'),
33+
),
34+
createProviderMacro(
35+
'ava-6',
36+
'6.0.0',
37+
path.join(import.meta.dirname, 'broken-fixtures'),
38+
),
39+
],
40+
[
41+
'ava-8',
42+
createProviderMacro(
43+
'ava-8',
44+
'8.0.0',
45+
path.join(import.meta.dirname, 'fixtures'),
46+
),
47+
createProviderMacro(
48+
'ava-8',
49+
'8.0.0',
50+
path.join(import.meta.dirname, 'broken-fixtures'),
51+
),
52+
],
53+
]) {
54+
test(
55+
'worker(): load rewritten paths files',
56+
withProvider,
57+
async (t, provider) => {
58+
const {state} = await compile(provider);
59+
const {stdout, stderr} = await execaNode(
60+
path.join(import.meta.dirname, 'fixtures/install-and-load'),
61+
[
62+
identifier,
63+
JSON.stringify({state}),
64+
path.join(import.meta.dirname, 'fixtures/ts', 'file.ts'),
65+
],
66+
{cwd: path.join(import.meta.dirname, 'fixtures')},
67+
);
68+
if (stderr.length > 0) {
69+
t.log(stderr);
70+
}
71+
72+
t.snapshot(stdout);
73+
},
74+
);
75+
76+
test('worker(): runs compiled files', withProvider, async (t, provider) => {
4177
const {state} = await compile(provider);
4278
const {stdout, stderr} = await execaNode(
4379
path.join(import.meta.dirname, 'fixtures/install-and-load'),
4480
[
81+
identifier,
4582
JSON.stringify({state}),
46-
path.join(import.meta.dirname, 'fixtures/ts', 'file.ts'),
83+
path.join(import.meta.dirname, 'fixtures/compiled', 'index.ts'),
4784
],
4885
{cwd: path.join(import.meta.dirname, 'fixtures')},
4986
);
@@ -52,28 +89,11 @@ test(
5289
}
5390

5491
t.snapshot(stdout);
55-
},
56-
);
92+
});
5793

58-
test('worker(): runs compiled files', withProvider, async (t, provider) => {
59-
const {state} = await compile(provider);
60-
const {stdout, stderr} = await execaNode(
61-
path.join(import.meta.dirname, 'fixtures/install-and-load'),
62-
[
63-
JSON.stringify({state}),
64-
path.join(import.meta.dirname, 'fixtures/compiled', 'index.ts'),
65-
],
66-
{cwd: path.join(import.meta.dirname, 'fixtures')},
67-
);
68-
if (stderr.length > 0) {
69-
t.log(stderr);
70-
}
94+
test('compile() error', withAltProvider, async (t, provider) => {
95+
const {message} = await t.throwsAsync(compile(provider));
7196

72-
t.snapshot(stdout);
73-
});
74-
75-
test('compile() error', withAltProvider, async (t, provider) => {
76-
const {message} = await t.throwsAsync(compile(provider));
77-
78-
t.snapshot(message);
79-
});
97+
t.snapshot(message);
98+
});
99+
}

test/fixtures/install-and-load.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,26 @@ import path from 'node:path';
33
import process from 'node:process';
44
import makeProvider from '@ava/typescript';
55

6+
const isAva8 = process.argv[2] === 'ava-8';
7+
68
const provider = makeProvider({
79
negotiateProtocol() {
8-
return {identifier: 'ava-6', ava: {version: '6.0.0'}, projectDir: import.meta.dirname};
10+
return {identifier: isAva8 ? 'ava-8' : 'ava-6', ava: {version: isAva8 ? '8.0.0' : '6.0.0'}, projectDir: import.meta.dirname};
911
},
1012
});
1113

1214
const worker = provider.worker({
13-
extensionsToLoadAsModules: [],
15+
...(!isAva8 && {extensionsToLoadAsModules: []}),
1416
state: {},
15-
...JSON.parse(process.argv[2]),
17+
...JSON.parse(process.argv[3]),
1618
});
1719

18-
const reference = path.resolve(process.argv[3]);
20+
const reference = path.resolve(process.argv[4]);
1921

2022
if (worker.canLoad(reference)) {
21-
worker.load(reference, {requireFn: createRequire(import.meta.url)});
23+
if (isAva8) {
24+
worker.load(reference);
25+
} else {
26+
worker.load(reference, {requireFn: createRequire(import.meta.url)});
27+
}
2228
}

test/load.js

Lines changed: 76 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,88 @@ import test from 'ava';
33
import {execaNode} from 'execa';
44
import createProviderMacro from './_with-provider.js';
55

6-
const withProvider = createProviderMacro('ava-6', '6.0.0', path.join(import.meta.dirname, 'fixtures'));
7-
86
const setup = async provider => ({
9-
state: await provider.main({
10-
config: {
11-
rewritePaths: {
12-
'load/': 'load/compiled/',
7+
state: await provider
8+
.main({
9+
config: {
10+
rewritePaths: {
11+
'load/': 'load/compiled/',
12+
},
13+
compile: false,
1314
},
14-
compile: false,
15-
},
16-
}).compile(),
15+
})
16+
.compile(),
1717
});
1818

19-
test('worker(): load .cts', withProvider, async (t, provider) => {
20-
const {state} = await setup(provider);
21-
const {stdout, stderr} = await execaNode(
22-
path.join(import.meta.dirname, 'fixtures/install-and-load'),
23-
[JSON.stringify({state}), path.join(import.meta.dirname, 'fixtures/load', 'index.cts')],
24-
{cwd: path.join(import.meta.dirname, 'fixtures')},
25-
);
26-
if (stderr.length > 0) {
27-
t.log(stderr);
28-
}
19+
for (const [identifier, withProvider] of [
20+
[
21+
'ava-6',
22+
createProviderMacro(
23+
'ava-6',
24+
'6.0.0',
25+
path.join(import.meta.dirname, 'fixtures'),
26+
),
27+
],
28+
[
29+
'ava-8',
30+
createProviderMacro(
31+
'ava-8',
32+
'8.0.0',
33+
path.join(import.meta.dirname, 'fixtures'),
34+
),
35+
],
36+
]) {
37+
test('worker(): load .cts', withProvider, async (t, provider) => {
38+
const {state} = await setup(provider);
39+
const {stdout, stderr} = await execaNode(
40+
path.join(import.meta.dirname, 'fixtures/install-and-load'),
41+
[
42+
identifier,
43+
JSON.stringify({state}),
44+
path.join(import.meta.dirname, 'fixtures/load', 'index.cts'),
45+
],
46+
{cwd: path.join(import.meta.dirname, 'fixtures')},
47+
);
48+
if (stderr.length > 0) {
49+
t.log(stderr);
50+
}
2951

30-
t.snapshot(stdout);
31-
});
52+
t.snapshot(stdout);
53+
});
3254

33-
test('worker(): load .mts', withProvider, async (t, provider) => {
34-
const {state} = await setup(provider);
35-
const {stdout, stderr} = await execaNode(
36-
path.join(import.meta.dirname, 'fixtures/install-and-load'),
37-
[JSON.stringify({state}), path.join(import.meta.dirname, 'fixtures/load', 'index.mts')],
38-
{cwd: path.join(import.meta.dirname, 'fixtures')},
39-
);
40-
if (stderr.length > 0) {
41-
t.log(stderr);
42-
}
55+
test('worker(): load .mts', withProvider, async (t, provider) => {
56+
const {state} = await setup(provider);
57+
const {stdout, stderr} = await execaNode(
58+
path.join(import.meta.dirname, 'fixtures/install-and-load'),
59+
[
60+
identifier,
61+
JSON.stringify({state}),
62+
path.join(import.meta.dirname, 'fixtures/load', 'index.mts'),
63+
],
64+
{cwd: path.join(import.meta.dirname, 'fixtures')},
65+
);
66+
if (stderr.length > 0) {
67+
t.log(stderr);
68+
}
4369

44-
t.snapshot(stdout);
45-
});
70+
t.snapshot(stdout);
71+
});
4672

47-
test('worker(): load .ts', withProvider, async (t, provider) => {
48-
const {state} = await setup(provider);
49-
const {stdout, stderr} = await execaNode(
50-
path.join(import.meta.dirname, 'fixtures/install-and-load'),
51-
[JSON.stringify({extensionsToLoadAsModules: ['js'], state}), path.join(import.meta.dirname, 'fixtures/load', 'index.ts')],
52-
{cwd: path.join(import.meta.dirname, 'fixtures')},
53-
);
54-
if (stderr.length > 0) {
55-
t.log(stderr);
56-
}
73+
test('worker(): load .ts', withProvider, async (t, provider) => {
74+
const {state} = await setup(provider);
75+
const {stdout, stderr} = await execaNode(
76+
path.join(import.meta.dirname, 'fixtures/install-and-load'),
77+
[
78+
identifier,
79+
JSON.stringify({extensionsToLoadAsModules: ['js'], state}),
80+
path.join(import.meta.dirname, 'fixtures/load', 'index.ts'),
81+
],
82+
{cwd: path.join(import.meta.dirname, 'fixtures')},
83+
);
84+
if (stderr.length > 0) {
85+
t.log(stderr);
86+
}
5787

58-
t.snapshot(stdout);
59-
});
88+
t.snapshot(stdout);
89+
});
90+
}

0 commit comments

Comments
 (0)