Skip to content

Support additional extensions and other modernizations #45

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

Merged
merged 6 commits into from
Mar 12, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Support .cts and .mts
  • Loading branch information
novemberborn committed Mar 12, 2023
commit c3075c9ff9e76fd05f262520ac277e4c7e16b95d
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ You can enable compilation via the `compile` property. If `false`, AVA will assu

Output files are expected to have the `.js` extension.

AVA searches your entire project for `*.js`, `*.cjs`, `*.mjs` and `*.ts` files (or other extensions you've configured). It will ignore such files found in the `rewritePaths` targets (e.g. `build/`). If you use more specific paths, for instance `build/main/`, you may need to change AVA's `files` configuration to ignore other directories.
AVA searches your entire project for `*.js`, `*.cjs`, `*.mjs`, `*.ts`, `*.cts` and `*.mts` files (or other extensions you've configured). It will ignore such files found in the `rewritePaths` targets (e.g. `build/`). If you use more specific paths, for instance `build/main/`, you may need to change AVA's `files` configuration to ignore other directories.

## ES Modules

Expand Down
36 changes: 28 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default function typescriptProvider({negotiateProtocol}) {
validate(config, configProperties);

const {
extensions = ['ts'],
extensions = ['ts', 'cts', 'mts'],
rewritePaths: relativeRewritePaths,
compile,
} = config;
Expand Down Expand Up @@ -118,7 +118,7 @@ export default function typescriptProvider({negotiateProtocol}) {
return rewritePaths.some(([from]) => filePath.startsWith(from));
},

resolveTestFile(testfile) {
resolveTestFile(testfile) { // Used under AVA 3.2 protocol by legacy watcher implementation.
if (!testFileExtension.test(testfile)) {
return testfile;
}
Expand All @@ -129,8 +129,14 @@ export default function typescriptProvider({negotiateProtocol}) {
}

const [from, to] = rewrite;
// TODO: Support JSX preserve mode — https://www.typescriptlang.org/docs/handbook/jsx.html
return `${to}${testfile.slice(from.length)}`.replace(testFileExtension, '.js');
let newExtension = '.js';
if (testfile.endsWith('.cts')) {
newExtension = '.cjs';
} else if (testfile.endsWith('.mts')) {
newExtension = '.mjs';
}

return `${to}${testfile.slice(from.length)}`.replace(testFileExtension, newExtension);
},

updateGlobs({filePatterns, ignoredByWatcherPatterns}) {
Expand All @@ -142,15 +148,19 @@ export default function typescriptProvider({negotiateProtocol}) {
],
ignoredByWatcherPatterns: [
...ignoredByWatcherPatterns,
...Object.values(relativeRewritePaths).map(to => `${to}**/*.js.map`),
...Object.values(relativeRewritePaths).flatMap(to => [
`${to}**/*.js.map`,
`${to}**/*.cjs.map`,
`${to}**/*.mjs.map`,
]),
],
};
},
};
},

worker({extensionsToLoadAsModules, state: {extensions, rewritePaths}}) {
const useImport = extensionsToLoadAsModules.includes('js');
const importJs = extensionsToLoadAsModules.includes('js');
const testFileExtension = new RegExp(`\\.(${extensions.map(ext => escapeStringRegexp(ext)).join('|')})$`);

return {
Expand All @@ -160,8 +170,18 @@ export default function typescriptProvider({negotiateProtocol}) {

async load(ref, {requireFn}) {
const [from, to] = rewritePaths.find(([from]) => ref.startsWith(from));
// TODO: Support JSX preserve mode — https://www.typescriptlang.org/docs/handbook/jsx.html
const rewritten = `${to}${ref.slice(from.length)}`.replace(testFileExtension, '.js');
let rewritten = `${to}${ref.slice(from.length)}`;
let useImport = true;
if (ref.endsWith('.cts')) {
rewritten = rewritten.replace(/\.cts$/, '.cjs');
useImport = false;
} else if (ref.endsWith('.mts')) {
rewritten = rewritten.replace(/\.mts$/, '.mjs');
} else {
rewritten = rewritten.replace(testFileExtension, '.js');
useImport = importJs;
}

return useImport ? import(pathToFileURL(rewritten)) : requireFn(rewritten); // eslint-disable-line node/no-unsupported-features/es-syntax
},
};
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
},
"xo": {
"ignores": [
"test/broken-fixtures"
"test/broken-fixtures",
"test/fixtures/**/compiled/**"
]
}
}
33 changes: 0 additions & 33 deletions test/esm.js

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/esm/index.js

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/esm/index.ts

This file was deleted.

3 changes: 3 additions & 0 deletions test/fixtures/load/compiled/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
console.log('logged in fixtures/load/index.cts');
2 changes: 2 additions & 0 deletions test/fixtures/load/compiled/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
console.log('logged in fixtures/load/index.ts');
export {};
2 changes: 2 additions & 0 deletions test/fixtures/load/compiled/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
console.log('logged in fixtures/load/index.mts');
export {};
1 change: 1 addition & 0 deletions test/fixtures/load/index.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('logged in fixtures/load/index.cts');
1 change: 1 addition & 0 deletions test/fixtures/load/index.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('logged in fixtures/load/index.mts');
1 change: 1 addition & 0 deletions test/fixtures/load/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('logged in fixtures/load/index.ts');
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"module": "Node16",
"outDir": "compiled"
},
"include": [
Expand Down
61 changes: 61 additions & 0 deletions test/load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import path from 'node:path';
import {fileURLToPath} from 'node:url';
import test from 'ava';
import execa from 'execa';
import createProviderMacro from './_with-provider.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const withProvider = createProviderMacro('ava-3.2', '3.2.0', path.join(__dirname, 'fixtures'));

const setup = async provider => ({
state: await provider.main({
config: {
rewritePaths: {
'load/': 'load/compiled/',
},
compile: false,
},
}).compile(),
});

test('worker(): load .cts', withProvider, async (t, provider) => {
const {state} = await setup(provider);
const {stdout, stderr} = await execa.node(
path.join(__dirname, 'fixtures/install-and-load'),
[JSON.stringify({state}), path.join(__dirname, 'fixtures/load', 'index.cts')],
{cwd: path.join(__dirname, 'fixtures')},
);
if (stderr.length > 0) {
t.log(stderr);
}

t.snapshot(stdout);
});

test('worker(): load .mts', withProvider, async (t, provider) => {
const {state} = await setup(provider);
const {stdout, stderr} = await execa.node(
path.join(__dirname, 'fixtures/install-and-load'),
[JSON.stringify({state}), path.join(__dirname, 'fixtures/load', 'index.mts')],
{cwd: path.join(__dirname, 'fixtures')},
);
if (stderr.length > 0) {
t.log(stderr);
}

t.snapshot(stdout);
});

test('worker(): load .ts', withProvider, async (t, provider) => {
const {state} = await setup(provider);
const {stdout, stderr} = await execa.node(
path.join(__dirname, 'fixtures/install-and-load'),
[JSON.stringify({extensionsToLoadAsModules: ['js'], state}), path.join(__dirname, 'fixtures/load', 'index.ts')],
{cwd: path.join(__dirname, 'fixtures')},
);
if (stderr.length > 0) {
t.log(stderr);
}

t.snapshot(stdout);
});
6 changes: 4 additions & 2 deletions test/protocol-ava-3.2.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ test('main() config validation: rewrite paths must end in a /', withProvider, (t
validateConfig(t, provider, {rewritePaths: {'src/': 'build', compile: false}});
});

test('main() extensions: defaults to [\'ts\']', withProvider, (t, provider) => {
t.deepEqual(provider.main({config: {rewritePaths: {'src/': 'build/'}, compile: false}}).extensions, ['ts']);
test('main() extensions: defaults to [\'ts\', \'cts\', \'mts\']', withProvider, (t, provider) => {
t.deepEqual(provider.main({config: {rewritePaths: {'src/': 'build/'}, compile: false}}).extensions, ['ts', 'cts', 'mts']);
});

test('main() extensions: returns configured extensions', withProvider, (t, provider) => {
Expand All @@ -76,6 +76,8 @@ test('main() ignoreChange()', withProvider, (t, provider) => {
test('main() resolveTestfile()', withProvider, (t, provider) => {
const main = provider.main({config: {rewritePaths: {'src/': 'build/'}, compile: false}});
t.is(main.resolveTestFile(path.join(__dirname, 'src/foo.ts')), path.join(__dirname, 'build/foo.js'));
t.is(main.resolveTestFile(path.join(__dirname, 'src/foo.cts')), path.join(__dirname, 'build/foo.cjs'));
t.is(main.resolveTestFile(path.join(__dirname, 'src/foo.mts')), path.join(__dirname, 'build/foo.mjs'));
t.is(main.resolveTestFile(path.join(__dirname, 'build/foo.js')), path.join(__dirname, 'build/foo.js'));
t.is(main.resolveTestFile(path.join(__dirname, 'foo/bar.ts')), path.join(__dirname, 'foo/bar.ts'));
});
Expand Down
11 changes: 0 additions & 11 deletions test/snapshots/esm.js.md

This file was deleted.

Binary file removed test/snapshots/esm.js.snap
Binary file not shown.
23 changes: 23 additions & 0 deletions test/snapshots/load.js.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Snapshot report for `test/load.js`

The actual snapshot is saved in `load.js.snap`.

Generated by [AVA](https://avajs.dev).

## worker(): load .cts

> Snapshot 1

'logged in fixtures/load/index.cts'

## worker(): load .mts

> Snapshot 1

'logged in fixtures/load/index.mts'

## worker(): load .ts

> Snapshot 1

'logged in fixtures/load/index.ts'
Binary file added test/snapshots/load.js.snap
Binary file not shown.
2 changes: 2 additions & 0 deletions test/snapshots/protocol-ava-3.2.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,7 @@ Generated by [AVA](https://avajs.dev).
ignoredByWatcherPatterns: [
'assets/**',
'build/**/*.js.map',
'build/**/*.cjs.map',
'build/**/*.mjs.map',
],
}
Binary file modified test/snapshots/protocol-ava-3.2.js.snap
Binary file not shown.