Skip to content

Commit bdded7e

Browse files
committed
test(ast/estree): add tests for JSX via raw transfer (#10241)
Add tests for JSX syntax parsing via raw transfer.
1 parent cc1267e commit bdded7e

File tree

1 file changed

+60
-15
lines changed

1 file changed

+60
-15
lines changed

napi/parser/test/parse-raw.test.ts

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@ import { describe, expect, it } from 'vitest';
44

55
import { parseSync } from '../index.js';
66

7-
const TARGET_DIR_PATH = pathJoin(import.meta.dirname, '../../../target');
8-
const TEST262_DIR_PATH = pathJoin(import.meta.dirname, '../../../tasks/coverage/test262/test');
9-
const ACORN_TEST262_DIR_PATH = pathJoin(import.meta.dirname, '../../../tasks/coverage/acorn-test262/test');
10-
const ESTREE_SNAPSHOT_PATH = pathJoin(import.meta.dirname, '../../../tasks/coverage/snapshots/estree_test262.snap');
7+
const ROOT_DIR = pathJoin(import.meta.dirname, '../../..');
8+
const TARGET_DIR_PATH = pathJoin(ROOT_DIR, 'target');
9+
const TEST262_SHORT_DIR_PATH = 'tasks/coverage/test262/test';
10+
const TEST262_DIR_PATH = pathJoin(ROOT_DIR, TEST262_SHORT_DIR_PATH);
11+
const ACORN_TEST262_DIR_PATH = pathJoin(ROOT_DIR, 'tasks/coverage/acorn-test262/test');
12+
const JSX_SHORT_DIR_PATH = 'tasks/coverage/acorn-test262/test-acorn-jsx/pass';
13+
const JSX_DIR_PATH = pathJoin(ROOT_DIR, JSX_SHORT_DIR_PATH);
14+
const TEST262_SNAPSHOT_PATH = pathJoin(ROOT_DIR, 'tasks/coverage/snapshots/estree_test262.snap');
15+
const JSX_SNAPSHOT_PATH = pathJoin(ROOT_DIR, 'tasks/coverage/snapshots/estree_acorn_jsx.snap');
1116

1217
const INFINITY_PLACEHOLDER = '__INFINITY__INFINITY__INFINITY__';
1318
const INFINITY_REGEXP = new RegExp(`"${INFINITY_PLACEHOLDER}"`, 'g');
@@ -46,26 +51,20 @@ const benchFixtures = await Promise.all(benchFixtureUrls.map(async (url) => {
4651
return [filename, sourceText];
4752
}));
4853

54+
// Test raw transfer output matches JSON snapshots for Test262 test cases.
55+
//
4956
// Only test Test262 fixtures which Acorn is able to parse.
50-
// Skip tests which we know we can't pass (listed as failing in `ESTree` snapshot file),
57+
// Skip tests which we know we can't pass (listed as failing in `estree_test262.snap` snapshot file),
5158
// and skip tests related to hashbangs (where output is correct, but Acorn doesn't parse hashbangs).
52-
const SNAPSHOT_FAIL_PREFIX = 'Mismatch: tasks/coverage/test262/test/';
53-
const snapshotFailPaths = new Set(
54-
(await readFile(ESTREE_SNAPSHOT_PATH, 'utf8'))
55-
.split('\n')
56-
.filter(line => line.startsWith(SNAPSHOT_FAIL_PREFIX))
57-
.map(line => line.slice(SNAPSHOT_FAIL_PREFIX.length)),
58-
);
59-
59+
const test262FailPaths = await getTestFailurePaths(TEST262_SNAPSHOT_PATH, TEST262_SHORT_DIR_PATH);
6060
const test262FixturePaths = [];
6161
for (let path of await readdir(ACORN_TEST262_DIR_PATH, { recursive: true })) {
6262
if (!path.endsWith('.json')) continue;
6363
path = path.slice(0, -2);
64-
if (snapshotFailPaths.has(path) || path.startsWith('language/comments/hashbang/')) continue;
64+
if (test262FailPaths.has(path) || path.startsWith('language/comments/hashbang/')) continue;
6565
test262FixturePaths.push(path);
6666
}
6767

68-
// Test raw transfer output matches standard (via JSON) output for Test262 test cases
6968
describe('test262', () => {
7069
it.each(test262FixturePaths)('%s', async (path) => {
7170
const filename = basename(path);
@@ -90,6 +89,39 @@ describe('test262', () => {
9089
});
9190
});
9291

92+
// Test raw transfer output matches JSON snapshots for Acorn-JSX test cases.
93+
//
94+
// Only test Acorn-JSX fixtures which Acorn is able to parse.
95+
// Skip tests which we know we can't pass (listed as failing in `estree_acron_jsx.snap` snapshot file).
96+
const jsxFailPaths = await getTestFailurePaths(JSX_SNAPSHOT_PATH, JSX_SHORT_DIR_PATH);
97+
const jsxFixturePaths = (await readdir(JSX_DIR_PATH, { recursive: true }))
98+
.filter(path => path.endsWith('.jsx') && !jsxFailPaths.has(path));
99+
100+
describe('JSX', () => {
101+
it.each(jsxFixturePaths)('%s', async (filename) => {
102+
const sourcePath = pathJoin(JSX_DIR_PATH, filename),
103+
jsonPath = sourcePath.slice(0, -1) + 'on'; // `.jsx` -> `.json`
104+
const [sourceText, acornJson] = await Promise.all([
105+
readFile(sourcePath, 'utf8'),
106+
readFile(jsonPath, 'utf8'),
107+
]);
108+
109+
// Acorn JSON files always end with:
110+
// ```
111+
// "sourceType": "script",
112+
// "hashbang": null
113+
// }
114+
// ```
115+
// For speed, extract `sourceType` with a slice, rather than parsing the JSON.
116+
const sourceType = acornJson.slice(-29, -23);
117+
118+
// @ts-ignore
119+
const { program } = parseSync(filename, sourceText, { sourceType, experimentalRawTransfer: true });
120+
const json = stringifyAcornTest262Style(program);
121+
expect(json).toEqual(acornJson);
122+
});
123+
});
124+
93125
// Test raw transfer output matches standard (via JSON) output for edge cases not covered by Test262
94126
describe('edge cases', () => {
95127
it.each([
@@ -142,6 +174,19 @@ function assertRawAndStandardMatch(filename, sourceText) {
142174
expect(jsonRaw).toEqual(jsonStandard);
143175
}
144176

177+
// Get `Set` containing test paths which failed from snapshot file
178+
async function getTestFailurePaths(snapshotPath, pathPrefix) {
179+
const mismatchPrefix = `Mismatch: ${pathPrefix}/`,
180+
mismatchPrefixLen = mismatchPrefix.length;
181+
182+
const snapshot = await readFile(snapshotPath, 'utf8');
183+
return new Set(
184+
snapshot.split('\n')
185+
.filter(line => line.startsWith(mismatchPrefix))
186+
.map(line => line.slice(mismatchPrefixLen)),
187+
);
188+
}
189+
145190
// Stringify to JSON, removing values which are invalid in JSON
146191
function stringify(obj) {
147192
return JSON.stringify(obj, (_key, value) => {

0 commit comments

Comments
 (0)