-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
ast-fixtures.test.ts
118 lines (107 loc) · 3.33 KB
/
ast-fixtures.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import fs from 'fs';
import glob from 'glob';
import { addSerializer } from 'jest-specific-snapshot';
import makeDir from 'make-dir';
import path from 'path';
import { parseAndGenerateServices } from '../src/parser';
import { isJSXFileType } from '../tools/test-utils';
import { serializer } from '../tools/tserror-serializer';
addSerializer(serializer);
// Assign a segment set to this variable to limit the test to only this segment
// This is super helpful if you need to debug why a specific fixture isn't producing the correct output
// eg. ['type-declaration', 'signatures', 'method-generic.src'] will only test /type-declaration/signatures/method-generic.src.ts
// prettier-ignore
const ONLY = [].join(path.sep);
const fixturesDir = path.resolve(
__dirname,
'..',
'..',
'..',
'node_modules',
'@typescript-eslint',
'shared-fixtures',
'fixtures',
);
const snapshotsDir = path.resolve(__dirname, 'snapshots');
const fixtures = glob
.sync(`**/*.src.{js,ts,jsx,tsx}`, { cwd: fixturesDir, absolute: true })
.map(absolute => {
const relative = path.relative(fixturesDir, absolute);
const { name, dir, ext } = path.parse(relative);
const segments = dir.split(path.sep);
const snapshotPath = path.join(snapshotsDir, dir);
return {
absolute,
isJsx: isJSXFileType(ext),
name,
segments,
snapshotPath,
snapshotFile: path.join(snapshotPath, `${name}${ext}.shot`),
};
});
function nestDescribe(
fixture: typeof fixtures[number],
segments = fixture.segments,
): void {
if (segments.length > 0) {
describe(segments[0], () => {
nestDescribe(fixture, segments.slice(1));
});
} else {
const test = (): void => {
const contents = fs.readFileSync(fixture.absolute, 'utf8');
try {
makeDir.sync(fixture.snapshotPath);
} catch (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
e: any
) {
if ('code' in e && e.code === 'EEXIST') {
// already exists - ignored
} else {
throw e;
}
}
try {
const { ast } = parseAndGenerateServices(contents, {
comment: true,
errorOnUnknownASTType: true,
jsx: fixture.isJsx,
loc: true,
range: true,
tokens: true,
});
expect(ast).toMatchSpecificSnapshot(fixture.snapshotFile);
} catch (e) {
expect(e).toMatchSpecificSnapshot(fixture.snapshotFile);
}
};
if ([...fixture.segments, fixture.name].join(path.sep) === ONLY) {
// eslint-disable-next-line jest/no-focused-tests
it.only(fixture.name, test);
} else {
it(fixture.name, test);
}
}
}
fixtures.forEach(f => nestDescribe(f));
if (ONLY === '') {
// ensure that the snapshots are cleaned up, because jest-specific-snapshot won't do this check
const snapshots = glob
.sync(`**/*.shot`, { cwd: snapshotsDir, absolute: true })
.map(absolute => {
const relative = path.relative(snapshotsDir, absolute);
const { name, dir } = path.parse(relative);
return {
relative,
fixturePath: path.join(fixturesDir, dir, name),
};
});
describe('ast snapshots should have an associated test', () => {
for (const snap of snapshots) {
it(snap.relative, () => {
fs.existsSync(snap.fixturePath);
});
}
});
}