8000 test: add scope test (#219) · vuejs/vue-eslint-parser@18e8e17 · GitHub
[go: up one dir, main page]

Skip to content
Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 18e8e17

Browse files
authored
test: add scope test (#219)
1 parent 7b1f6a1 commit 18e8e17

File tree

3 files changed

+165
-172
lines changed

3 files changed

+165
-172
lines changed

scripts/update-fixtures-ast.js

Lines changed: 6 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@
1212
const fs = require("fs")
1313
const path = require("path")
1414
const parser = require("../src")
15-
const escope = require("eslint-scope")
1615
const semver = require("semver")
16+
const {
17+
scopeToJSON,
18+
analyze,
19+
replacer,
20+
getAllTokens,
21+
} = require("../test/test-utils")
1722

1823
//------------------------------------------------------------------------------
1924
// Helpers
@@ -30,40 +35,6 @@ const PARSER_OPTIONS = {
3035
eslintScopeManager: true,
3136
}
3237

33-
/**
34-
* Remove `parent` proeprties from the given AST.
35-
* @param {string} key The key.
36-
* @param {any} value The value of the key.
37-
* @returns {any} The value of the key to output.
38-
*/
39-
function replacer(key, value) {
40-
if (key === "parent") {
41-
return undefined
42-
}
43-
if (key === "errors" && Array.isArray(value)) {
44-
return value.map((e) => ({
45-
message: e.message,
46-
index: e.index,
47-
lineNumber: e.lineNumber,
48-
column: e.column,
49-
}))
50-
}
51-
return value
52-
}
53-
54-
/**
55-
* Get all tokens of the given AST.
56-
* @param {ASTNode} ast The root node of AST.
57-
* @returns {Token[]} Tokens.
58-
*/
59-
function getAllTokens(ast) {
60-
const tokenArrays = [ast.tokens, ast.comments]
61-
if (ast.templateBody != null) {
62-
tokenArrays.push(ast.templateBody.tokens, ast.templateBody.comments)
63-
}
64-
return Array.prototype.concat.apply([], tokenArrays)
65-
}
66-
6738
/**
6839
* Create simple tree.
6940
* @param {string} source The source code.
@@ -98,109 +69,6 @@ function getTree(source, ast) {
9869
return root.children
9970
}
10071

101-
function scopeToJSON(scopeManager) {
102-
return JSON.stringify(normalizeScope(scopeManager.globalScope), replacer, 4)
103-
104-
function normalizeScope(scope) {
105-
return {
106-
type: scope.type,
107-
variables: scope.variables.map(normalizeVar),
108-
references: scope.references.map(normalizeReference),
109-
childScopes: scope.childScopes.map(normalizeScope),
110-
through: scope.through.map(normalizeReference),
111-
}
112-
}
113-
114-
function normalizeVar(v) {
115-
return {
116-
name: v.name,
117-
identifiers: v.identifiers.map(normalizeId),
118-
defs: v.defs.map(normalizeDef),
119-
references: v.references.map(normalizeReference),
120-
}
121-
}
122-
123-
function normalizeReference(reference) {
124-
return {
125-
identifier: normalizeId(reference.identifier),
126-
from: reference.from.type,
127-
resolved: normalizeId(
128-
reference.resolved &&
129-
reference.resolved.defs &&
130-
reference.resolved.defs[0] &&
131-
reference.resolved.defs[0].name,
132-
),
133-
init: reference.init || null,
134-
vueUsedInTemplate: reference.vueUsedInTemplate
135-
? reference.vueUsedInTemplate
136-
: undefined,
137-
}
138-
}
139-
140-
function normalizeDef(def) {
141-
return {
142-
type: def.type,
143-
node: normalizeDefNode(def.node),
144-
name: def.name.name,
145-
}
146-
}
147-
148-
function normalizeId(identifier) {
149-
return (
150-
identifier && {
151-
type: identifier.type,
152-
name: identifier.name,
153-
loc: identifier.loc,
154-
}
155-
)
156-
}
157-
158-
function normalizeDefNode(node) {
159-
return {
160-
type: node.type,
161-
loc: node.loc,
162-
}
163-
}
164-
}
165-
166-
/**
167-
* Analyze scope
168-
*/
169-
function analyze(ast, parserOptions) {
170-
const ecmaVersion = parserOptions.ecmaVersion || 2017
171-
const ecmaFeatures = parserOptions.ecmaFeatures || {}
172-
const sourceType = parserOptions.sourceType || "script"
173-
const result = escope.analyze(ast, {
174-
ignoreEval: true,
175-
nodejsScope: false,
176-
impliedStrict: ecmaFeatures.impliedStrict,
177-
ecmaVersion,
178-
sourceType,
179-
fallback: getFallbackKeys,
180-
})
181-
182-
return result
183-
184-
function getFallbackKeys(node) {
185-
return Object.keys(node).filter(fallbackKeysFilter, node)
186-
}
187-
188-
function fallbackKeysFilter(key) {
189-
const value = null
190-
return (
191-
key !== "comments" &&
192-
key !== "leadingComments" &&
193-
key !== "loc" &&
194-
key !== "parent" &&
195-
key !== "range" &&
196-
key !== "tokens" &&
197-
key !== "trailingComments" &&
198-
typeof value === "object" &&
199-
(typeof value.type === "string" || Array.isArray(value))
200-
)
201-
}
202-
}
203-
20472
//------------------------------------------------------------------------------
20573
// Main
20674
//------------------------------------------------------------------------------

test/ast.js

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const lodash = require("lodash")
1616
const parser = require("../src")
1717
const Linter = require("./fixtures/eslint").Linter
1818
const semver = require("semver")
19+
const { scopeToJSON, analyze, replacer, getAllTokens } = require("./test-utils")
1920

2021
//------------------------------------------------------------------------------
2122
// Helpers
@@ -30,40 +31,7 @@ const PARSER_OPTIONS = {
3031
loc: true,
3132
range: true,
3233
tokens: true,
33-
}
34-
35-
/**
36-
* Remove `parent` proeprties from the given AST.
37-
* @param {string} key The key.
38-
* @param {any} value The value of the key.
39-
* @returns {any} The value of the key to output.
40-
*/
41-
function replacer(key, value) {
42-
if (key === "parent") {
43-
return undefined
44-
}
45-
if (key === "errors" && Array.isArray(value)) {
46-
return value.map((e) => ({
47-
message: e.message,
48-
index: e.index,
49-
lineNumber: e.lineNumber,
50-
column: e.column,
51-
}))
52-
}
53-
return value
54-
}
55-
56-
/**
57-
* Get all tokens of the given AST.
58-
* @param {ASTNode} ast The root node of AST.
59-
* @returns {Token[]} Tokens.
60-
*/
61-
function getAllTokens(ast) {
62-
const tokenArrays = [ast.tokens, ast.comments]
63-
if (ast.templateBody != null) {
64-
tokenArrays.push(ast.templateBody.tokens, ast.templateBody.comments)
65-
}
66-
return Array.prototype.concat.apply([], tokenArrays)
34+
eslintScopeManager: true,
6735
}
6836

6937
/**
@@ -305,6 +273,23 @@ describe("Template AST", () => {
305273
assert.strictEqual(actualText, expectedText)
306274
})
307275

276+
it("should scope in the correct.", () => {
277+
const version = require(`eslint/package.json`).version
278+
if (!semver.satisfies(version, ">=8")) {
279+
return
280+
}
281+
const resultPath = path.join(ROOT, `${name}/scope.json`)
282+
if (!fs.existsSync(resultPath)) {
283+
return
284+
}
285+
const expectedText = fs.readFileSync(resultPath, "utf8")
286+
const actualText = scopeToJSON(
287+
actual.scopeManager || analyze(actual.ast, options),
288+
)
289+
290+
assert.strictEqual(actualText, expectedText)
291+
})
292+
308293
it("should have correct parent properties.", () => {
309294
validateParent(source, parserOptions)
310295
})

test/test-utils.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
const escope = require("eslint-scope")
2+
3+
module.exports = { replacer, getAllTokens, scopeToJSON, analyze }
4+
5+
/**
6+
* Remove `parent` properties from the given AST.
7+
* @param {string} key The key.
8+
* @param {any} value The value of the key.
9+
* @returns {any} The value of the key to output.
10+
*/
11+
function replacer(key, value) {
12+
if (key === "parent") {
13+
return undefined
14+
}
15+
if (key === "errors" && Array.isArray(value)) {
16+
return value.map((e) => ({
17+
message: e.message,
18+
index: e.index,
19+
lineNumber: e.lineNumber,
20+
column: e.column,
21+
}))
22+
}
23+
return value
24+
}
25+
26+
/**
27+
* Get all tokens of the given AST.
28+
* @param {ASTNode} ast The root node of AST.
29+
* @returns {Token[]} Tokens.
30+
*/
31+
function getAllTokens(ast) {
32+
const tokenArrays = [ast.tokens, ast.comments]
33+
if (ast.templateBody != null) {
34+
tokenArrays.push(ast.templateBody.tokens, ast.templateBody.comments)
35+
}
36+
return Array.prototype.concat.apply([], tokenArrays)
37+
}
38+
39+
function scopeToJSON(scopeManager) {
40+
return JSON.stringify(normalizeScope(scopeManager.globalScope), replacer, 4)
41+
42+
function normalizeScope(scope) {
43+
return {
44+
type: scope.type,
45+
variables: scope.variables.map(normalizeVar),
46+
references: scope.references.map(normalizeReference),
47+
childScopes: scope.childScopes.map(normalizeScope),
48+
through: scope.through.map(normalizeReference),
49+
}
50+
}
51+
52+
function normalizeVar(v) {
53+
return {
54+
name: v.name,
55+
identifiers: v.identifiers.map(normalizeId),
56+
defs: v.defs.map(normalizeDef),
57+
references: v.references.map(normalizeReference),
58+
}
59+
}
60+
61+
function normalizeReference(reference) {
62+
return {
63+
identifier: normalizeId(reference.identifier),
64+
from: reference.from.type,
65+
resolved: normalizeId(
66+
reference.resolved &&
67+
reference.resolved.defs &&
68+
reference.resolved.defs[0] &&
69+
reference.resolved.defs[0].name,
70+
),
71+
init: reference.init || null,
72+
vueUsedInTemplate: reference.vueUsedInTemplate
73+
? reference.vueUsedInTemplate
74+
: undefined,
75+
}
76+
}
77+
78+
function normalizeDef(def) {
79+
return {
80+
type: def.type,
81+
node: normalizeDefNode(def.node),
82+
name: def.name.name,
83+
}
84+
}
85+
86+
function normalizeId(identifier) {
87+
return (
88+
identifier && {
89+
type: identifier.type,
90+
name: identifier.name,
91+
loc: identifier.loc,
92+
}
93+
)
94+
}
95+
96+
function normalizeDefNode(node) {
97+
return {
98+
type: node.type,
99+
loc: node.loc,
100+
}
101+
}
102+
}
103+
104+
/**
105+
* Analyze scope
106+
*/
107+
function analyze(ast, parserOptions) {
108+
const ecmaVersion = parserOptions.ecmaVersion || 2017
109+
const ecmaFeatures = parserOptions.ecmaFeatures || {}
110+
const sourceType = parserOptions.sourceType || "script"
111+
const result = escope.analyze(ast, {
112+
ignoreEval: true,
113+
nodejsScope: false,
114+
impliedStrict: ecmaFeatures.impliedStrict,
115+
ecmaVersion,
116+
sourceType,
117+
fallback: getFallbackKeys,
118+
})
119+
120+
return result
121+
122+
function getFallbackKeys(node) {
123+
return Object.keys(node).filter(fallbackKeysFilter, node)
124+
}
125+
126+
function fallbackKeysFilter(key) {
127+
const value = null
128+
return (
129+
key !== "comments" &&
130+
key !== "leadingComments" &&
131+
key !== "loc" &&
132+
key !== "parent" &&
133+
key !== "range" &&
134+
key !== "tokens" &&
135+
key !== "trailingComments" &&
136+
typeof value === "object" &&
137+
(typeof value.type === "string" || Array.isArray(value))
138+
)
139+
}
140+
}

0 commit comments

Comments
 (0)
0