Skip to content

Commit 929189b

Browse files
authored
test(parser): change parser tests to check scope analysis (typescript-eslint#234)
1 parent 43b3c00 commit 929189b

15 files changed

+92234
-280886
lines changed

packages/parser/tests/lib/__snapshots__/basics.ts.snap

Lines changed: 1122 additions & 2979 deletions
Large diffs are not rendered by default.

packages/parser/tests/lib/__snapshots__/javascript.ts.snap

Lines changed: 53892 additions & 133173 deletions
Large diffs are not rendered by default.

packages/parser/tests/lib/__snapshots__/jsx.ts.snap

Lines changed: 1439 additions & 13026 deletions
Large diffs are not rendered by default.

packages/parser/tests/lib/__snapshots__/tsx.ts.snap

Lines changed: 235 additions & 1704 deletions
Large diffs are not rendered by default.

packages/parser/tests/lib/__snapshots__/typescript.ts.snap

Lines changed: 35283 additions & 129785 deletions
Large diffs are not rendered by default.

packages/parser/tests/lib/basics.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { Linter } from 'eslint';
22
import fs from 'fs';
33
import glob from 'glob';
44
import * as parser from '../../src/parser';
5-
import * as testUtils from '../../tools/test-utils';
5+
import {
6+
createScopeSnapshotTestBlock,
7+
formatSnapshotName
8+
} from '../tools/test-utils';
69

710
const FIXTURES_DIR = './tests/fixtures/basics';
811
const testFiles = glob.sync(`${FIXTURES_DIR}/**/*.src.js`);
@@ -15,8 +18,8 @@ describe('basics', () => {
1518
testFiles.forEach(filename => {
1619
const code = fs.readFileSync(filename, 'utf8');
1720
it(
18-
testUtils.formatSnapshotName(filename, FIXTURES_DIR),
19-
testUtils.createSnapshotTestBlock(code)
21+
formatSnapshotName(filename, FIXTURES_DIR),
22+
createScopeSnapshotTestBlock(code)
2023
);
2124
});
2225

packages/parser/tests/lib/comments.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import fs from 'fs';
22
import glob from 'glob';
3-
import * as testUtils from '../../tools/test-utils';
3+
import {
4+
createSnapshotTestBlock,
5+
formatSnapshotName
6+
} from '../tools/test-utils';
47
import { ParserOptions } from '../../src/parser-options';
58

69
const FIXTURES_DIR =
@@ -21,8 +24,8 @@ describe('Comments', () => {
2124
}
2225
};
2326
it(
24-
testUtils.formatSnapshotName(filename, FIXTURES_DIR),
25-
testUtils.createSnapshotTestBlock(code, config)
27+
formatSnapshotName(filename, FIXTURES_DIR),
28+
createSnapshotTestBlock(code, config)
2629
);
2730
});
2831
});

packages/parser/tests/lib/javascript.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import fs from 'fs';
22
import glob from 'glob';
3-
import * as testUtils from '../../tools/test-utils';
3+
import {
4+
createScopeSnapshotTestBlock,
5+
formatSnapshotName
6+
} from '../tools/test-utils';
47

58
const FIXTURES_DIR =
69
'../../node_modules/@typescript-eslint/shared-fixtures/fixtures/javascript';
@@ -14,8 +17,8 @@ describe('javascript', () => {
1417
testFiles.forEach(filename => {
1518
const code = fs.readFileSync(filename, 'utf8');
1619
it(
17-
testUtils.formatSnapshotName(filename, FIXTURES_DIR),
18-
testUtils.createSnapshotTestBlock(code)
20+
formatSnapshotName(filename, FIXTURES_DIR),
21+
createScopeSnapshotTestBlock(code)
1922
);
2023
});
2124
});

packages/parser/tests/lib/jsx.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import fs from 'fs';
22
import glob from 'glob';
33
import filesWithKnownIssues from '../../../shared-fixtures/jsx-known-issues';
4-
import * as testUtils from '../../tools/test-utils';
4+
import {
5+
createScopeSnapshotTestBlock,
6+
formatSnapshotName
7+
} from '../tools/test-utils';
58

69
const JSX_FIXTURES_DIR =
710
'../../node_modules/@typescript-eslint/shared-fixtures/fixtures/jsx';
@@ -33,8 +36,8 @@ describe('JSX', () => {
3336
}
3437
};
3538
it(
36-
testUtils.formatSnapshotName(filename, fixturesDir),
37-
testUtils.createSnapshotTestBlock(code, config)
39+
formatSnapshotName(filename, fixturesDir),
40+
createScopeSnapshotTestBlock(code, config)
3841
);
3942
};
4043
}
Lines changed: 17 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -1,220 +1,47 @@
11
import fs from 'fs';
22
import path from 'path';
3-
import * as parser from '../../src/parser';
4-
5-
/** Reference resolver. */
6-
class ReferenceResolver {
7-
map: Map<any, any>;
8-
9-
constructor() {
10-
this.map = new Map();
11-
}
12-
13-
resolve(obj: any, properties: any) {
14-
const resolved = Object.assign({ $id: this.map.size }, properties);
15-
this.map.set(obj, resolved);
16-
return resolved;
17-
}
18-
19-
ref(obj: any) {
20-
if (typeof obj !== 'object' || obj === null) {
21-
return obj;
22-
}
23-
24-
const { map } = this;
25-
return {
26-
get $ref() {
27-
return map.get(obj).$id;
28-
}
29-
};
30-
}
31-
}
32-
33-
/**
34-
* Convert a given node object to JSON object.
35-
* This saves only type and range to know what the node is.
36-
* @param {ASTNode} node The AST node object.
37-
* @returns {Object} The object that can be used for JSON.stringify.
38-
*/
39-
function nodeToJSON(node: any) {
40-
if (!node) {
41-
return node;
42-
}
43-
44-
const { type, name, range } = node;
45-
if (node.type === 'Identifier') {
46-
return { type, name, range };
47-
}
48-
return { type, range };
49-
}
50-
51-
/**
52-
* Convert a given variable object to JSON object.
53-
* @param {Variable} variable The eslint-scope's variable object.
54-
* @param {ReferenceResolver} resolver The reference resolver.
55-
* @returns {Object} The object that can be used for JSON.stringify.
56-
*/
57-
function variableToJSON(variable: any, resolver: any) {
58-
const { name, eslintUsed } = variable;
59-
const defs = variable.defs.map((d: any) => ({
60-
type: d.type,
61-
name: nodeToJSON(d.name),
62-
node: nodeToJSON(d.node),
63-
parent: nodeToJSON(d.parent)
64-
}));
65-
const identifiers = variable.identifiers.map(nodeToJSON);
66-
const references = variable.references.map(resolver.ref, resolver);
67-
const scope = resolver.ref(variable.scope);
68-
69-
return resolver.resolve(variable, {
70-
name,
71-
defs,
72-
identifiers,
73-
references,
74-
scope,
75-
eslintUsed
76-
});
77-
}
78-
79-
/**
80-
* Convert a given reference object to JSON object.
81-
* @param {Reference} reference The eslint-scope's reference object.
82-
* @param {ReferenceResolver} resolver The reference resolver.
83-
* @returns {Object} The object that can be used for JSON.stringify.
84-
*/
85-
function referenceToJSON(reference: any, resolver: any) {
86-
const kind = `${reference.isRead() ? 'r' : ''}${
87-
reference.isWrite() ? 'w' : ''
88-
}`;
89-
const from = resolver.ref(reference.from);
90-
const identifier = nodeToJSON(reference.identifier);
91-
const writeExpr = nodeToJSON(reference.writeExpr);
92-
const resolved = resolver.ref(reference.resolved);
93-
94-
return resolver.resolve(reference, {
95-
kind,
96-
from,
97-
identifier,
98-
writeExpr,
99-
resolved
100-
});
101-
}
102-
103-
/**
104-
* Convert a given scope object to JSON object.
105-
* @param {Scope} scope The eslint-scope's scope object.
106-
* @param {ReferenceResolver} resolver The reference resolver.
107-
* @returns {Object} The object that can be used for JSON.stringify.
108-
*/
109-
function scopeToJSON(scope: any, resolver = new ReferenceResolver()) {
110-
const { type, functionExpressionScope, isStrict } = scope;
111-
const block = nodeToJSON(scope.block);
112-
const variables = scope.variables.map((v: any) =>
113-
variableToJSON(v, resolver)
114-
);
115-
const references = scope.references.map((r: any) =>
116-
referenceToJSON(r, resolver)
117-
);
118-
const variableMap = Array.from(scope.set.entries()).reduce(
119-
(map: any, [name, variable]: any) => {
120-
map[name] = resolver.ref(variable);
121-
return map;
122-
},
123-
{}
124-
);
125-
const throughReferences = scope.through.map(resolver.ref, resolver);
126-
const variableScope = resolver.ref(scope.variableScope);
127-
const upperScope = resolver.ref(scope.upper);
128-
const childScopes = scope.childScopes.map((c: any) =>
129-
scopeToJSON(c, resolver)
130-
);
131-
132-
return resolver.resolve(scope, {
133-
type,
134-
functionExpressionScope,
135-
isStrict,
136-
block,
137-
variables,
138-
references,
139-
variableMap,
140-
throughReferences,
141-
variableScope,
142-
upperScope,
143-
childScopes
144-
});
145-
}
3+
import { createScopeSnapshotTestBlock } from '../tools/test-utils';
1464

1475
describe('TypeScript scope analysis', () => {
148-
const root = 'tests/fixtures/scope-analysis';
6+
const fixturesDir = 'tests/fixtures/scope-analysis';
1497
const files = fs
150-
.readdirSync(root)
151-
.map(filename => path.join(root, filename).replace(/\\/g, '/'));
8+
.readdirSync(fixturesDir)
9+
.map(filename => path.join(fixturesDir, filename).replace(/\\/g, '/'));
15210

15311
describe('sourceType: module', () => {
15412
for (const filePath of files) {
155-
it(filePath, () => {
156-
const code = fs.readFileSync(filePath, 'utf8');
157-
const { scopeManager } = parser.parseForESLint(code, {
13+
const code = fs.readFileSync(filePath, 'utf8');
14+
it(
15+
filePath,
16+
createScopeSnapshotTestBlock(code, {
15817
loc: true,
15918
range: true,
16019
tokens: true,
16120
sourceType: 'module',
16221
ecmaFeatures: {
16322
jsx: path.extname(filePath) === '.tsx'
16423
}
165-
});
166-
const { globalScope } = scopeManager;
167-
168-
// Do the postprocess to test.
169-
// https://github.com/eslint/eslint/blob/4fe328787dd02d7a1f6fc21167f6175c860825e3/lib/linter.js#L222
170-
globalScope.through = globalScope.through.filter((reference: any) => {
171-
const name = reference.identifier.name;
172-
const variable = globalScope.set.get(name);
173-
if (variable) {
174-
reference.resolved = variable;
175-
variable.references.push(reference);
176-
return false;
177-
}
178-
return true;
179-
});
180-
181-
const scopeTree = scopeToJSON(globalScope);
182-
expect(scopeTree).toMatchSnapshot();
183-
});
24+
})
25+
);
18426
}
18527
});
18628

18729
describe('sourceType: script', () => {
18830
for (const filePath of files) {
189-
it(filePath, () => {
190-
const code = fs.readFileSync(filePath, 'utf8');
191-
const { scopeManager } = parser.parseForESLint(code, {
31+
const code = fs.readFileSync(filePath, 'utf8');
32+
33+
it(
34+
filePath,
35+
createScopeSnapshotTestBlock(code, {
19236
loc: true,
19337
range: true,
19438
tokens: true,
19539
sourceType: 'script',
19640
ecmaFeatures: {
19741
jsx: path.extname(filePath) === '.tsx'
19842
}
199-
});
200-
const { globalScope } = scopeManager;
201-
202-
// Do the postprocess to test.
203-
// https://github.com/eslint/eslint/blob/4fe328787dd02d7a1f6fc21167f6175c860825e3/lib/linter.js#L222
204-
globalScope.through = globalScope.through.filter((reference: any) => {
205-
const name = reference.identifier.name;
206-
const variable = globalScope.set.get(name);
207-
if (variable) {
208-
reference.resolved = variable;
209-
variable.references.push(reference);
210-
return false;
211-
}
212-
return true;
213-
});
214-
215-
const scopeTree = scopeToJSON(globalScope);
216-
expect(scopeTree).toMatchSnapshot();
217-
});
43+
})
44+
);
21845
}
21946
});
22047
});

packages/parser/tests/lib/services.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import path from 'path';
22
import fs from 'fs';
33
import glob from 'glob';
4-
import * as testUtils from '../../tools/test-utils';
4+
import {
5+
createSnapshotTestBlock,
6+
formatSnapshotName,
7+
testServices
8+
} from '../tools/test-utils';
59

610
//------------------------------------------------------------------------------
711
// Setup
@@ -28,15 +32,11 @@ describe('services', () => {
2832
const code = fs.readFileSync(filename, 'utf8');
2933
const config = createConfig(filename);
3034
it(
31-
testUtils.formatSnapshotName(filename, FIXTURES_DIR, '.ts'),
32-
testUtils.createSnapshotTestBlock(code, config)
35+
formatSnapshotName(filename, FIXTURES_DIR, '.ts'),
36+
createSnapshotTestBlock(code, config)
3337
);
34-
it(`${testUtils.formatSnapshotName(
35-
filename,
36-
FIXTURES_DIR,
37-
'.ts'
38-
)} services`, () => {
39-
testUtils.testServices(code, config);
38+
it(`${formatSnapshotName(filename, FIXTURES_DIR, '.ts')} services`, () => {
39+
testServices(code, config);
4040
});
4141
});
4242
});

packages/parser/tests/lib/tsx.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { Linter } from 'eslint';
22
import fs from 'fs';
33
import glob from 'glob';
44
import * as parser from '../../src/parser';
5-
import * as testUtils from '../../tools/test-utils';
5+
import {
6+
createScopeSnapshotTestBlock,
7+
formatSnapshotName
8+
} from '../tools/test-utils';
69

710
const FIXTURES_DIR =
811
'../../node_modules/@typescript-eslint/shared-fixtures/fixtures/tsx';
@@ -22,8 +25,8 @@ describe('TSX', () => {
2225
}
2326
};
2427
it(
25-
testUtils.formatSnapshotName(filename, FIXTURES_DIR, '.tsx'),
26-
testUtils.createSnapshotTestBlock(code, config)
28+
formatSnapshotName(filename, FIXTURES_DIR, '.tsx'),
29+
createScopeSnapshotTestBlock(code, config)
2730
);
2831
});
2932

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy