Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d6555ec

Browse files
committed
test: snapshot testing
1 parent 0219f68 commit d6555ec

File tree

156 files changed

+7528
-92
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+7528
-92
lines changed

.cspell.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"**/*.{json,snap}",
1313
".cspell.json",
1414
"yarn.lock",
15-
".github/workflows/**"
15+
".github/workflows/**",
16+
".vscode/*.json"
1617
],
1718
"dictionaries": [
1819
"typescript",

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
**/tests/fixtures/**/*
2+
!packages/scope-manager/tests/fixtures/**/*
23
**/tests/fixture-project/**/*
34
**/dist
45
**/coverage

.vscode/extensions.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"recommendations": [
3-
"esbenp.prettier-vscode",
3+
"davidanson.vscode-markdownlint",
44
"dbaeumer.vscode-eslint",
55
"editorconfig.editorconfig",
6+
"esbenp.prettier-vscode",
67
"streetsidesoftware.code-spell-checker",
7-
"davidanson.vscode-markdownlint"
8+
"tlent.jest-snapshot-language-support"
89
],
910
"unwantedRecommendations": ["hookyqr.beautify", "dbaeumer.jshint"]
1011
}

.vscode/settings.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,21 @@
1818
"javascript.preferences.quoteStyle": "single",
1919
"typescript.preferences.quoteStyle": "single",
2020
"editor.defaultFormatter": "esbenp.prettier-vscode",
21+
22+
// make the .shot files from jest-specific-snapshot act like normal snapshots
23+
"files.associations": {
24+
"*.shot": "jest-snapshot"
25+
},
26+
"vsicons.associations.files": [
27+
{
28+
"icon": "jest_snapshot",
29+
"extensions": [
30+
".ts.shot",
31+
".tsx.shot",
32+
".js.shot",
33+
".jsx.shot",
34+
],
35+
"extends": "jest_snapshot"
36+
},
37+
],
2138
}

packages/scope-manager/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ module.exports = {
2020
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
2121
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
2222
coverageReporters: ['text-summary', 'lcov'],
23-
setupFilesAfterEnv: ['./tests/serializers/index.ts'],
23+
setupFilesAfterEnv: ['./tests/util/serializers/index.ts'],
2424
};

packages/scope-manager/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@
4040
"esrecurse": "^4.2.1"
4141
},
4242
"devDependencies": {
43+
"@types/jest-specific-snapshot": "^0.5.4",
44+
"@types/mkdirp": "^1.0.0",
4345
"@typescript-eslint/parser": "2.30.0",
46+
"glob": "^7.1.6",
47+
"jest-specific-snapshot": "^3.0.0",
48+
"make-dir": "^3.1.0",
4449
"pretty-format": "^25.5.0"
4550
},
4651
"funding": {

packages/scope-manager/src/ScopeManager.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,29 @@ interface ScopeManagerOptions {
2626

2727
class ScopeManager {
2828
public currentScope: Scope | null;
29-
public declaredVariables: WeakMap<TSESTree.Node, Variable[]>;
29+
public readonly declaredVariables: WeakMap<TSESTree.Node, Variable[]>;
3030
/**
3131
* The root scope
3232
* @public
3333
*/
3434
public globalScope: GlobalScope | null;
35-
public nodeToScope: WeakMap<TSESTree.Node, Scope[]>;
36-
private options: ScopeManagerOptions;
35+
public readonly nodeToScope: WeakMap<TSESTree.Node, Scope[]>;
36+
private readonly options: ScopeManagerOptions;
3737
/**
3838
* All scopes
3939
* @public
4040
*/
41-
public scopes: Scope[];
41+
public readonly scopes: Scope[];
42+
43+
public get variables(): Variable[] {
44+
const variables = new Set<Variable>();
45+
function recurse(scope: Scope): void {
46+
scope.variables.forEach(v => variables.add(v));
47+
scope.childScopes.forEach(recurse);
48+
}
49+
this.scopes.forEach(recurse);
50+
return Array.from(variables).sort((a, b) => a.$id - b.$id);
51+
}
4252

4353
constructor(options: ScopeManagerOptions) {
4454
this.scopes = [];

packages/scope-manager/src/referencer/Referencer.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,13 @@ class Referencer extends Visitor {
276276
TypeVisitor.visit(this, node);
277277
}
278278

279+
protected visitTypeAssertion(
280+
node: TSESTree.TSAsExpression | TSESTree.TSTypeAssertion,
281+
): void {
282+
this.visit(node.expression);
283+
this.visitType(node.typeAnnotation);
284+
}
285+
279286
/////////////////////
280287
// Visit selectors //
281288
/////////////////////
@@ -551,7 +558,7 @@ class Referencer extends Visitor {
551558
}
552559

553560
protected TSAsExpression(node: TSESTree.TSAsExpression): void {
554-
this.visitType(node);
561+
this.visitTypeAssertion(node);
555562
}
556563

557564
protected TSDeclareFunction(node: TSESTree.TSDeclareFunction): void {
@@ -591,6 +598,10 @@ class Referencer extends Visitor {
591598
this.visitType(node);
592599
}
593600

601+
protected TSTypeAssertion(node: TSESTree.TSTypeAssertion): void {
602+
this.visitTypeAssertion(node);
603+
}
604+
594605
protected UpdateExpression(node: TSESTree.UpdateExpression): void {
595606
if (PatternVisitor.isPattern(node.argument)) {
596607
this.visitPattern(node.argument, pattern => {

packages/scope-manager/src/referencer/TypeVisitor.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ class TypeVisitor extends Visitor {
1414
this.referencer = referencer;
1515
}
1616

17+
static visit(referencer: Referencer, node: TSESTree.Node): void {
18+
const typeReferencer = new TypeVisitor(referencer);
19+
typeReferencer.visit(node);
20+
}
21+
1722
protected visitTypeDeclaration(
1823
name: TSESTree.Identifier,
1924
node: TSESTree.TSInterfaceDeclaration | TSESTree.TSTypeAliasDeclaration,
@@ -22,19 +27,12 @@ class TypeVisitor extends Visitor {
2227
.currentScope()
2328
.defineIdentifier(name, new TypeDefinition(name, node));
2429

25-
if (node.typeParameters) {
26-
// type parameters cannot be referenced from outside their current scope
27-
this.referencer.scopeManager.nestTypeScope(node);
28-
}
30+
// type parameters cannot be referenced from outside their current scope
31+
this.referencer.scopeManager.nestTypeScope(node);
2932

3033
this.visit(node.typeParameters);
3134
}
3235

33-
static visit(referencer: Referencer, node: TSESTree.Node): void {
34-
const typeReferencer = new TypeVisitor(referencer);
35-
typeReferencer.visit(node);
36-
}
37-
3836
protected TSTypeParameter(node: TSESTree.TSTypeParameter): void {
3937
this.referencer
4038
.currentScope()

packages/scope-manager/tests/eslint-scope/references.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { parseAndAnalyze } from '../util';
2-
import { analyze } from '../../src/analyze';
32

43
describe('References:', () => {
54
describe('When there is a `let` declaration on global,', () => {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import fs from 'fs';
2+
import glob from 'glob';
3+
import makeDir from 'make-dir';
4+
import path from 'path';
5+
import { parseAndAnalyze, AnalyzeOptions } from './util';
6+
7+
const FIXTURES_DIR = path.resolve(__dirname, 'fixtures');
8+
9+
const fixtures = glob
10+
.sync(`${FIXTURES_DIR}/**/*.{js,ts,jsx,tsx}`, {
11+
ignore: ['fixtures.test.ts'],
12+
})
13+
.map(absolute => {
14+
const relative = path.relative(FIXTURES_DIR, absolute);
15+
const { name, dir, ext } = path.parse(relative);
16+
const segments = dir.split(path.sep);
17+
const snapshotPath = path.join(FIXTURES_DIR, dir);
18+
return {
19+
absolute,
20+
name,
21+
segments,
22+
snapshotPath,
23+
snapshotFile: path.join(snapshotPath, `${name}${ext}.shot`),
24+
};
25+
});
26+
27+
const FOUR_SLASH = /^\/\/\/\/[ ]+@(\w+) = (.+)$/;
28+
const ALLOWED_OPTIONS: Set<string> = new Set<keyof AnalyzeOptions>([
29+
'ecmaVersion',
30+
'globalReturn',
31+
'impliedStrict',
32+
'sourceType',
33+
]);
34+
35+
function nestDescribe(
36+
fixture: typeof fixtures[number],
37+
segments = fixture.segments,
38+
): void {
39+
if (segments.length > 0) {
40+
describe(segments[0], () => {
41+
nestDescribe(fixture, segments.slice(1));
42+
});
43+
} else {
44+
it(fixture.name, () => {
45+
const contents = fs.readFileSync(fixture.absolute, 'utf8');
46+
47+
const lines = contents.split('\n');
48+
const options: Record<string, unknown> = {};
49+
for (const line of lines) {
50+
if (!line.startsWith('////')) {
51+
continue;
52+
}
53+
54+
const match = FOUR_SLASH.exec(line);
55+
if (!match) {
56+
continue;
57+
}
58+
const [, key, value] = match;
59+
if (!ALLOWED_OPTIONS.has(key)) {
60+
throw new Error(`Unknown option ${key}`);
61+
}
62+
63+
if (value === 'true') {
64+
options[key] = true;
65+
} else if (value === 'false') {
66+
options[key] = false;
67+
} else {
68+
options[key] = value;
69+
}
70+
}
71+
72+
try {
73+
makeDir.sync(fixture.snapshotPath);
74+
} catch (e) {
75+
if ('code' in e && e.code === 'EEXIST') {
76+
// already exists - ignored
77+
} else {
78+
throw e;
79+
}
80+
}
81+
82+
try {
83+
const { scopeManager } = parseAndAnalyze(contents, options);
84+
expect(scopeManager).toMatchSpecificSnapshot(fixture.snapshotFile);
85+
} catch (e) {
86+
expect(e).toMatchSpecificSnapshot(fixture.snapshotFile);
87+
}
88+
});
89+
}
90+
}
91+
92+
fixtures.forEach(f => nestDescribe(f));
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const a = 1;
2+
3+
{
4+
a;
5+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`block inherited-scope 1`] = `
4+
ScopeManager {
5+
variables: Array [
6+
Variable$1 {
7+
defs: Array [
8+
VariableDefinition$1 {
9+
name: Identifier<"a">,
10+
node: VariableDeclarator$1,
11+
},
12+
],
13+
identifiers: Array [
14+
Identifier<"a">,
15+
],
16+
name: "a",
17+
references: Array [
18+
Reference$1 {
19+
identifier: Identifier<"a">,
20+
init: true,
21+
isTypeReference: false,
22+
resolved: Variable$1,
23+
writeExpr: Literal$2,
24+
},
25+
Reference$2 {
26+
identifier: Identifier<"a">,
27+
isTypeReference: false,
28+
resolved: Variable$1,
29+
},
30+
],
31+
},
32+
],
33+
scopes: Array [
34+
GlobalScope$1 {
35+
block: Program$3,
36+
isStrict: false,
37+
references: Array [
38+
Reference$1,
39+
],
40+
set: Map {
41+
"a" => Variable$1,
42+
},
43+
type: "global",
44+
upper: null,
45+
variables: Array [
46+
Variable$1,
47+
],
48+
},
49+
BlockScope$2 {
50+
block: BlockStatement$4,
51+
isStrict: false,
52+
references: Array [
53+
Reference$2,
54+
],
55+
set: Map {},
56+
type: "block",
57+
upper: GlobalScope$1,
58+
variables: Array [],
59+
},
60+
],
61+
}
62+
`;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
let i = 20;
3+
let j = 1;
4+
i;
5+
}
6+
7+
j;

0 commit comments

Comments
 (0)