From 4e2cd771dcf011b040eeccf7a748f40aba001201 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Mon, 2 Jul 2018 20:47:20 +0900 Subject: [PATCH] Breaking: drop supporting ESLint 3.x, 4.x - upgrade eslint-scope to 4.0.0 - upgrade espree to 4.0.0 And upgrade ESLint setting of this repo. --- .eslintrc.json | 35 -- .eslintrc.yml | 14 + README.md | 2 +- package.json | 52 +-- rollup.config.js | 14 +- .../tools => scripts}/update-fixtures-ast.js | 25 +- src/ast/errors.ts | 142 +++--- src/ast/nodes.ts | 211 ++++++--- src/ast/traverse.ts | 10 +- src/common/location-calculator.ts | 25 +- src/html/intermediate-tokenizer.ts | 81 ++-- src/html/parser.ts | 170 +++++-- src/html/tokenizer.ts | 430 +++++++++++------- src/index.ts | 63 ++- src/parser-services.ts | 46 +- src/script/index.ts | 156 +++++-- src/script/scope-analyzer.ts | 40 +- src/template/index.ts | 215 +++++++-- test/.eslintrc.json | 3 - test/ast.js | 41 +- test/core-rules.js | 8 +- .../ast.json | 42 +- test/fixtures/eslint | 2 +- test/index.js | 111 +++-- test/tokens.js | 200 +++++--- test/tools/.eslintrc.json | 6 - test/variables-references.js | 155 +++++-- 27 files changed, 1544 insertions(+), 755 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 .eslintrc.yml rename {test/tools => scripts}/update-fixtures-ast.js (84%) delete mode 100644 test/.eslintrc.json delete mode 100644 test/tools/.eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 2dedb446..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "extends": [ - "mysticatea", - "mysticatea/node", - "mysticatea/modules" - ], - "parser": "typescript-eslint-parser", - "rules": { - "complexity": "off", - "indent": "off", - "indent-legacy": ["error", 4, {"SwitchCase": 1}], - "init-declarations": "off", - "no-constant-condition": "off", - "no-param-reassign": "off", - "no-restricted-globals": ["error", "require"], - "no-undef": "off", - "no-unused-vars": "off", - "no-use-before-define": "off", - "valid-jsdoc": "off", - "node/no-unsupported-features": ["error", {"ignores": ["modules"]}] - }, - "settings": { - "node": { - "tryExtensions": [".ts", ".d.ts", ".js", ".json"] - } - }, - "overrides": [ - { - "files": "typings/**", - "rules": { - "node/no-missing-import": ["error", {"allowModules": ["estree"]}] - } - } - ] -} diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 00000000..d1ee2dff --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,14 @@ +extends: + - plugin:@mysticatea/es2015 + - plugin:@mysticatea/+node + - plugin:@mysticatea/+modules +overrides: + - files: "*.ts" + rules: + "@mysticatea/ts/no-use-before-define": "off" + - files: "typings/**" + rules: + node/no-missing-import: + - error + - allowModules: + - estree diff --git a/README.md b/README.md index 0fc98136..d151bb18 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ $ npm install --save-dev eslint vue-eslint-parser ``` - Requires Node.js 6.5.0 or later. -- Requires ESLint 3.9.0 or later. +- Requires ESLint 5.0.0 or later. ## 📖 Usage diff --git a/package.json b/package.json index 63f679aa..c191d53b 100644 --- a/package.json +++ b/package.json @@ -12,42 +12,42 @@ "index.js.map" ], "peerDependencies": { - "eslint": ">=3.9.0" + "eslint": "^5.0.0" }, "dependencies": { "debug": "^3.1.0", - "eslint-scope": "^3.7.1", + "eslint-scope": "^4.0.0", "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.2", - "esquery": "^1.0.0", - "lodash": "^4.17.4" + "espree": "^4.0.0", + "esquery": "^1.0.1", + "lodash": "^4.17.10" }, "devDependencies": { + "@mysticatea/eslint-plugin": "^5.0.1", "@types/debug": "0.0.30", "@types/estree": "0.0.38", - "@types/lodash": "^4.14.91", - "@types/mocha": "^2.2.44", - "@types/node": "^6.0.85", - "babel-eslint": "^8.1.1", - "chokidar": "^1.7.0", - "codecov": "^3.0.0", - "cross-spawn": "^5.1.0", + "@types/lodash": "^4.14.110", + "@types/mocha": "^5.2.4", + "@types/node": "^6.0.113", + "babel-eslint": "^8.2.5", + "chokidar": "^2.0.4", + "codecov": "^3.0.2", + "cross-spawn": "^6.0.5", "dts-bundle": "^0.7.3", - "eslint": "^4.14.0", - "eslint-config-mysticatea": "^12.0.0", - "fs-extra": "^5.0.0", - "mocha": "^4.0.1", - "npm-run-all": "^4.1.2", - "nyc": "^11.4.1", + "eslint": "^5.0.1", + "fs-extra": "^6.0.1", + "mocha": "^5.2.0", + "npm-run-all": "^4.1.3", + "nyc": "^12.0.2", "opener": "^1.4.3", "rimraf": "^2.6.2", - "rollup": "^0.53.0", - "rollup-plugin-node-resolve": "^3.0.0", + "rollup": "^0.60.7", + "rollup-plugin-node-resolve": "^3.3.0", "rollup-plugin-sourcemaps": "^0.4.2", "rollup-watch": "^4.3.1", - "typescript": "~2.6.2", - "typescript-eslint-parser": "^11.0.0", - "wait-on": "^2.0.2", + "typescript": "^2.9.2", + "typescript-eslint-parser": "^16.0.1", + "wait-on": "^2.1.0", "warun": "^1.0.0" }, "scripts": { @@ -57,12 +57,12 @@ "clean": "rimraf .nyc_output .temp coverage index.*", "codecov": "nyc report --reporter lcovonly && codecov", "coverage": "nyc report --reporter lcov && opener ./coverage/lcov-report/index.html", - "lint": "eslint src test --ext .ts", + "lint": "eslint src test --ext .js,.ts", "setup": "git submodule update --init && cd test/fixtures/eslint && npm install", "pretest": "run-s build lint", "test": "nyc npm run _mocha", "preupdate-fixtures": "npm run -s build", - "update-fixtures": "node test/tools/update-fixtures-ast.js", + "update-fixtures": "node scripts/update-fixtures-ast.js", "preversion": "npm test", "version": "npm run -s build", "postversion": "git push && git push --tags", @@ -71,7 +71,7 @@ "watch:tsc": "tsc --watch", "watch:rollup": "wait-on .temp/index.js && rollup -c -o index.js --watch", "watch:test": "wait-on index.js && warun index.js \"test/*.js\" \"test/fixtures/ast/*/*.json\" \"test/fixtures/*\" --debounce 1000 --no-initial -- nyc -r lcov npm run -s _mocha", - "watch:update-ast": "wait-on index.js && warun index.js \"test/fixtures/ast/*/*.vue\" -- node test/tools/update-fixtures-ast.js", + "watch:update-ast": "wait-on index.js && warun index.js \"test/fixtures/ast/*/*.vue\" -- node scripts/update-fixtures-ast.js", "watch:coverage-report": "wait-on coverage/lcov-report/index.html && opener coverage/lcov-report/index.html" }, "repository": { diff --git a/rollup.config.js b/rollup.config.js index ab17cc9c..6f1942cb 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -8,11 +8,7 @@ import sourcemaps from "rollup-plugin-sourcemaps" const pkg = require("./package.json") const deps = new Set( - [ - "assert", - "events", - "path", - ].concat(Object.keys(pkg.dependencies)) + ["assert", "events", "path"].concat(Object.keys(pkg.dependencies)) ) export default { @@ -22,13 +18,9 @@ export default { format: "cjs", sourcemap: true, sourcemapFile: "index.js.map", - strict: true, }, - plugins: [ - sourcemaps(), - resolve(), - ], - external: (id) => deps.has(id) || id.startsWith("lodash"), + plugins: [sourcemaps(), resolve()], + external: id => deps.has(id) || id.startsWith("lodash"), banner: `/** * @author Toru Nagashima * @copyright 2017 Toru Nagashima. All rights reserved. diff --git a/test/tools/update-fixtures-ast.js b/scripts/update-fixtures-ast.js similarity index 84% rename from test/tools/update-fixtures-ast.js rename to scripts/update-fixtures-ast.js index ebba6610..c4673795 100644 --- a/test/tools/update-fixtures-ast.js +++ b/scripts/update-fixtures-ast.js @@ -11,13 +11,13 @@ const fs = require("fs") const path = require("path") -const parser = require("../..") +const parser = require("../") //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -const ROOT = path.join(__dirname, "../fixtures/ast") +const ROOT = path.join(__dirname, "../test/fixtures/ast") const TARGETS = fs.readdirSync(ROOT) const PARSER_OPTIONS = { comment: true, @@ -79,11 +79,13 @@ function getTree(source, ast) { parser.AST.traverseNodes(ast.templateBody, { enterNode(node) { stack.push(current) - current.children.push(current = { - type: node.type, - text: source.slice(node.range[0], node.range[1]), - children: [], - }) + current.children.push( + (current = { + type: node.type, + text: source.slice(node.range[0], node.range[1]), + children: [], + }) + ) }, leaveNode() { current = stack.pop() @@ -103,8 +105,13 @@ for (const name of TARGETS) { const tokenRangesPath = path.join(ROOT, `${name}/token-ranges.json`) const treePath = path.join(ROOT, `${name}/tree.json`) const source = fs.readFileSync(sourcePath, "utf8") - const actual = parser.parse(source, Object.assign({ filePath: sourcePath }, PARSER_OPTIONS)) - const tokenRanges = getAllTokens(actual).map(t => source.slice(t.range[0], t.range[1])) + const actual = parser.parse( + source, + Object.assign({ filePath: sourcePath }, PARSER_OPTIONS) + ) + const tokenRanges = getAllTokens(actual).map(t => + source.slice(t.range[0], t.range[1]) + ) const tree = getTree(source, actual) console.log("Update:", name) diff --git a/src/ast/errors.ts b/src/ast/errors.ts index 25b424e5..48d59055 100644 --- a/src/ast/errors.ts +++ b/src/ast/errors.ts @@ -10,7 +10,9 @@ import { Location } from "./locations" * @param x The value to check. * @returns `true` if the value has acorn style location information. */ -function isAcornStyleParseError(x: any): x is {message: string, pos: number, loc: Location} { +function isAcornStyleParseError( + x: any, +): x is { message: string; pos: number; loc: Location } { return ( typeof x.message === "string" && typeof x.pos === "number" && @@ -37,7 +39,12 @@ export class ParseError extends SyntaxError { * @param line The line number of this error. * @param column The column number of this error. */ - static fromCode(code: ErrorCode, offset: number, line: number, column: number): ParseError { + public static fromCode( + code: ErrorCode, + offset: number, + line: number, + column: number, + ): ParseError { return new ParseError(code, code, offset, line, column) } @@ -45,7 +52,7 @@ export class ParseError extends SyntaxError { * Normalize the error object. * @param x The error object to normalize. */ - static normalize(x: any): ParseError | null { + public static normalize(x: any): ParseError | null { if (ParseError.isParseError(x)) { return x } @@ -55,7 +62,7 @@ export class ParseError extends SyntaxError { undefined, x.pos, x.loc.line, - x.loc.column + x.loc.column, ) } return null @@ -69,7 +76,13 @@ export class ParseError extends SyntaxError { * @param line The line number of this error. * @param column The column number of this error. */ - constructor(message: string, code: ErrorCode | undefined, offset: number, line: number, column: number) { + public constructor( + message: string, + code: ErrorCode | undefined, + offset: number, + line: number, + column: number, + ) { super(message) this.code = code this.index = offset @@ -82,12 +95,13 @@ export class ParseError extends SyntaxError { * @param x The value to check. * @returns `true` if the value has `message`, `pos`, `loc` properties. */ - static isParseError(x: any): x is ParseError { - return x instanceof ParseError || ( - typeof x.message === "string" && - typeof x.index === "number" && - typeof x.lineNumber === "number" && - typeof x.column === "number" + public static isParseError(x: any): x is ParseError { + return ( + x instanceof ParseError || + (typeof x.message === "string" && + typeof x.index === "number" && + typeof x.lineNumber === "number" && + typeof x.column === "number") ) } } @@ -97,56 +111,56 @@ export class ParseError extends SyntaxError { * https://html.spec.whatwg.org/multipage/parsing.html#parse-errors */ export type ErrorCode = - "abrupt-closing-of-empty-comment" | - "absence-of-digits-in-numeric-character-reference" | - "cdata-in-html-content" | - "character-reference-outside-unicode-range" | - "control-character-in-input-stream" | - "control-character-reference" | - "eof-before-tag-name" | - "eof-in-cdata" | - "eof-in-comment" | - "eof-in-tag" | - "incorrectly-closed-comment" | - "incorrectly-opened-comment" | - "invalid-first-character-of-tag-name" | - "missing-attribute-value" | - "missing-end-tag-name" | - "missing-semicolon-after-character-reference" | - "missing-whitespace-between-attributes" | - "nested-comment" | - "noncharacter-character-reference" | - "noncharacter-in-input-stream" | - "null-character-reference" | - "surrogate-character-reference" | - "surrogate-in-input-stream" | - "unexpected-character-in-attribute-name" | - "unexpected-character-in-unquoted-attribute-value" | - "unexpected-equals-sign-before-attribute-name" | - "unexpected-null-character" | - "unexpected-question-mark-instead-of-tag-name" | - "unexpected-solidus-in-tag" | - "unknown-named-character-reference" | - "end-tag-with-attributes" | - "duplicate-attribute" | - "end-tag-with-trailing-solidus" | - "non-void-html-element-start-tag-with-trailing-solidus" | - "x-invalid-end-tag" | - "x-invalid-namespace" - // ---- Use RAWTEXT state for ` } return `` @@ -76,7 +76,8 @@ function modifyPattern(pattern) { parser: PARSER_PATH, } } - if (pattern.parser != null || + if ( + pattern.parser != null || pattern.filename != null || pattern.code.startsWith("#!") ) { @@ -145,8 +146,7 @@ try { require(path.join(RULE_TESTS_ROOT, fileName)) } }) -} -finally { +} finally { RuleTester.prototype.run = originalRun processed.clear() } diff --git a/test/fixtures/ast/v-for-directives-with-destructuring/ast.json b/test/fixtures/ast/v-for-directives-with-destructuring/ast.json index 67651818..62ff5f7f 100644 --- a/test/fixtures/ast/v-for-directives-with-destructuring/ast.json +++ b/test/fixtures/ast/v-for-directives-with-destructuring/ast.json @@ -1462,69 +1462,69 @@ { "id": { "type": "Identifier", - "start": 172, - "end": 176, + "start": 154, + "end": 155, "loc": { "start": { "line": 5, - "column": 36 + "column": 18 }, "end": { "line": 5, - "column": 40 + "column": 19 } }, "range": [ - 172, - 176 + 154, + 155 ], - "name": "list" + "name": "z" }, "mode": "r" }, { "id": { "type": "Identifier", - "start": 154, - "end": 155, + "start": 161, + "end": 162, "loc": { "start": { "line": 5, - "column": 18 + "column": 25 }, "end": { "line": 5, - "column": 19 + "column": 26 } }, "range": [ - 154, - 155 + 161, + 162 ], - "name": "z" + "name": "x" }, "mode": "r" }, { "id": { "type": "Identifier", - "start": 161, - "end": 162, + "start": 172, + "end": 176, "loc": { "start": { "line": 5, - "column": 25 + "column": 36 }, "end": { "line": 5, - "column": 26 + "column": 40 } }, "range": [ - 161, - 162 + 172, + 176 ], - "name": "x" + "name": "list" }, "mode": "r" } diff --git a/test/fixtures/eslint b/test/fixtures/eslint index 8d166b41..caeb223c 160000 --- a/test/fixtures/eslint +++ b/test/fixtures/eslint @@ -1 +1 @@ -Subproject commit 8d166b4190dbbd1c3796f68a1a5bf3bf71e6837a +Subproject commit caeb223c4f7b0b6fe35e5348ae0df4c6446b5bed diff --git a/test/index.js b/test/index.js index bce0fd7f..9d2ceb59 100644 --- a/test/index.js +++ b/test/index.js @@ -62,11 +62,9 @@ describe("Basic tests", () => { assert(messages[0].ruleId === "semi") assert(messages[0].line === 8) assert(messages[0].column === 35) - assert(messages[0].source === " return {greeting: \"Hello\"}") assert(messages[1].ruleId === "semi") assert(messages[1].line === 10) assert(messages[1].column === 2) - assert(messages[1].source === "}") }) it("should fix 2 'semi' errors with --fix option", () => { @@ -80,8 +78,14 @@ describe("Basic tests", () => { }) CLIEngine.outputFixes(cli.executeOnFiles(["hello.vue"])) - const actual = fs.readFileSync(path.join(FIXTURE_DIR, "hello.vue"), "utf8") - const expected = fs.readFileSync(path.join(FIXTURE_DIR, "hello.vue.fixed"), "utf8") + const actual = fs.readFileSync( + path.join(FIXTURE_DIR, "hello.vue"), + "utf8" + ) + const expected = fs.readFileSync( + path.join(FIXTURE_DIR, "hello.vue.fixed"), + "utf8" + ) assert(actual === expected) }) @@ -167,7 +171,6 @@ describe("Basic tests", () => { assert(messages[0].ruleId === "semi") assert(messages[0].line === 1) assert(messages[0].column === 21) - assert(messages[0].source === "console.log(\"hello\")") }) it("should fix a 'semi' error with --fix option", () => { @@ -181,8 +184,14 @@ describe("Basic tests", () => { }) CLIEngine.outputFixes(cli.executeOnFiles(["notvue.js"])) - const actual = fs.readFileSync(path.join(FIXTURE_DIR, "notvue.js"), "utf8") - const expected = fs.readFileSync(path.join(FIXTURE_DIR, "notvue.js.fixed"), "utf8") + const actual = fs.readFileSync( + path.join(FIXTURE_DIR, "notvue.js"), + "utf8" + ) + const expected = fs.readFileSync( + path.join(FIXTURE_DIR, "notvue.js.fixed"), + "utf8" + ) assert(actual === expected) }) @@ -228,7 +237,8 @@ describe("Basic tests", () => { cwd: FIXTURE_DIR, envs: ["es6", "node"], parser: PARSER_PATH, - parserOptions: { // + parserOptions: { + // parser: "typescript-eslint-parser", }, rules: { semi: ["error", "never"] }, @@ -265,7 +275,8 @@ describe("Basic tests", () => { cwd: FIXTURE_DIR, envs: ["es6", "node"], parser: PARSER_PATH, - parserOptions: { // + parserOptions: { + // parser: "typescript-eslint-parser", }, rules: { semi: ["error", "never"] }, @@ -292,8 +303,14 @@ describe("Basic tests", () => { }) CLIEngine.outputFixes(cli.executeOnFiles(["typed.vue"])) - const actual = fs.readFileSync(path.join(FIXTURE_DIR, "typed.vue"), "utf8") - const expected = fs.readFileSync(path.join(FIXTURE_DIR, "typed.vue.fixed"), "utf8") + const actual = fs.readFileSync( + path.join(FIXTURE_DIR, "typed.vue"), + "utf8" + ) + const expected = fs.readFileSync( + path.join(FIXTURE_DIR, "typed.vue.fixed"), + "utf8" + ) assert(actual === expected) }) @@ -304,7 +321,8 @@ describe("Basic tests", () => { envs: ["es6", "node"], fix: true, parser: PARSER_PATH, - parserOptions: { // + parserOptions: { + // parser: "typescript-eslint-parser", }, rules: { semi: ["error", "always"] }, @@ -312,8 +330,14 @@ describe("Basic tests", () => { }) CLIEngine.outputFixes(cli.executeOnFiles(["typed.vue"])) - const actual = fs.readFileSync(path.join(FIXTURE_DIR, "typed.vue"), "utf8") - const expected = fs.readFileSync(path.join(FIXTURE_DIR, "typed.vue.fixed"), "utf8") + const actual = fs.readFileSync( + path.join(FIXTURE_DIR, "typed.vue"), + "utf8" + ) + const expected = fs.readFileSync( + path.join(FIXTURE_DIR, "typed.vue.fixed"), + "utf8" + ) assert(actual === expected) }) @@ -363,7 +387,9 @@ describe("Basic tests", () => { }, useEslintrc: false, }) - const report = cli.executeOnFiles(["location-issue-with-babel-eslint.vue"]) + const report = cli.executeOnFiles([ + "location-issue-with-babel-eslint.vue", + ]) const messages = report.results[0].messages assert(messages.length === 0) @@ -382,7 +408,9 @@ describe("Basic tests", () => { }) it("should replace NULL by U+FFFD REPLACEMENT CHARACTER in RCDATA state.", () => { - const ast = parse("") + const ast = parse( + "" + ) const text = ast.templateBody.children[0].children[0] const errors = ast.templateBody.errors @@ -413,7 +441,8 @@ describe("Basic tests", () => { it("should replace NULL by U+FFFD REPLACEMENT CHARACTER in ATTRIBUTE_NAME state.", () => { const ast = parse("") - const attribute = ast.templateBody.children[0].startTag.attributes[0] + const attribute = + ast.templateBody.children[0].startTag.attributes[0] const errors = ast.templateBody.errors assert.equal(attribute.key.name, "a\uFFFD") @@ -422,8 +451,9 @@ describe("Basic tests", () => { }) it("should replace NULL by U+FFFD REPLACEMENT CHARACTER in ATTRIBUTE_VALUE_DOUBLE_QUOTED state.", () => { - const ast = parse("") - const attribute = ast.templateBody.children[0].startTag.attributes[0] + const ast = parse('') + const attribute = + ast.templateBody.children[0].startTag.attributes[0] const errors = ast.templateBody.errors assert.equal(attribute.value.value, "\uFFFD") @@ -433,7 +463,8 @@ describe("Basic tests", () => { it("should replace NULL by U+FFFD REPLACEMENT CHARACTER in ATTRIBUTE_VALUE_SINGLE_QUOTED state.", () => { const ast = parse("") - const attribute = ast.templateBody.children[0].startTag.attributes[0] + const attribute = + ast.templateBody.children[0].startTag.attributes[0] const errors = ast.templateBody.errors assert.equal(attribute.value.value, "\uFFFD") @@ -443,7 +474,8 @@ describe("Basic tests", () => { it("should replace NULL by U+FFFD REPLACEMENT CHARACTER in ATTRIBUTE_VALUE_UNQUOTED state.", () => { const ast = parse("") - const attribute = ast.templateBody.children[0].startTag.attributes[0] + const attribute = + ast.templateBody.children[0].startTag.attributes[0] const errors = ast.templateBody.errors assert.equal(attribute.value.value, "\uFFFD") @@ -468,7 +500,10 @@ describe("Basic tests", () => { assert.equal(comment.value, "? \uFFFD ?") assert.equal(errors.length, 1) - assert.equal(errors[0].code, "unexpected-question-mark-instead-of-tag-name") + assert.equal( + errors[0].code, + "unexpected-question-mark-instead-of-tag-name" + ) }) it("should not error in CDATA section state.", () => { @@ -483,17 +518,26 @@ describe("Basic tests", () => { describe("About parserServices", () => { it("should exist if the source code is a Vue SFC file.", () => { - assert.notEqual(parseForESLint("test", { filePath: "test.vue" }).services, undefined) + assert.notEqual( + parseForESLint("test", { filePath: "test.vue" }).services, + undefined + ) }) it("should exist even if the source code is not Vue SFC file.", () => { - assert.notEqual(parseForESLint("test", { filePath: "test.js" }).services, undefined) + assert.notEqual( + parseForESLint("test", { filePath: "test.js" }).services, + undefined + ) }) }) describe("https://github.com/mysticatea/vue-eslint-parser/issues/21", () => { it("should make the correct location of decorators", () => { - const code = fs.readFileSync(path.join(FIXTURE_DIR, "issue21.vue"), "utf8") + const code = fs.readFileSync( + path.join(FIXTURE_DIR, "issue21.vue"), + "utf8" + ) const indexOfDecorator = code.indexOf("@Component") const ast = parse(code, { parser: "babel-eslint", @@ -505,10 +549,7 @@ describe("Basic tests", () => { eslintVisitorKeys: true, }) - assert.equal( - ast.body[2].declaration.range[0], - indexOfDecorator - ) + assert.equal(ast.body[2].declaration.range[0], indexOfDecorator) assert.equal( ast.body[2].declaration.decorators[0].range[0], indexOfDecorator @@ -528,11 +569,13 @@ describe("Basic tests", () => { const linter = new Linter() //eslint-disable-next-line no-shadow - linter.defineRule("test-rule", (context) => context.parserServices.defineTemplateBodyVisitor({ - "VElement[name='div']"(node) { - context.report({ node, message: "OK" }) - }, - })) + linter.defineRule("test-rule", context => + context.parserServices.defineTemplateBodyVisitor({ + "VElement[name='div']"(node) { + context.report({ node, message: "OK" }) + }, + }) + ) const messages1 = linter.verify(code, config) const messages2 = linter.verify(linter.getSourceCode(), config) diff --git a/test/tokens.js b/test/tokens.js index f9cecd5a..e7f23555 100644 --- a/test/tokens.js +++ b/test/tokens.js @@ -52,7 +52,10 @@ describe("services.getTemplateBodyTokenStore", () => { let tokens = null before(() => { - const result = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)) + const result = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ) ast = result.ast tokens = result.services.getTemplateBodyTokenStore() }) @@ -61,19 +64,77 @@ describe("services.getTemplateBodyTokenStore", () => { it("should return all tokens (except comments) in the template.", () => { const actual = tokens.getTokens(ast.templateBody).map(toValue) - assert.deepStrictEqual( - actual, - ["template", ">", "\n ", "\n ", "div", "a", "=", "b", "v-show", "=", "\"", "c", "<", "3", "&&", "ok", "==", "\"ok\"", "\"", ">", "{{", "message", "}}", "div", ">", "\n", "template", ">"] - ) + assert.deepStrictEqual(actual, [ + "template", + ">", + "\n ", + "\n ", + "div", + "a", + "=", + "b", + "v-show", + "=", + '"', + "c", + "<", + "3", + "&&", + "ok", + "==", + '"ok"', + '"', + ">", + "{{", + "message", + "}}", + "div", + ">", + "\n", + "template", + ">", + ]) }) it("should return all tokens (include comments) in the template if you give {includeComments: true} option.", () => { - const actual = tokens.getTokens(ast.templateBody, { includeComments: true }).map(toValue) - - assert.deepStrictEqual( - actual, - ["template", ">", "\n ", "comment1", "\n ", "div", "a", "=", "b", "v-show", "=", "\"", "c", "<", "3", "&&", "ok", "==", "\"ok\"", "\"", ">", "comment2", "{{", "message", "comment3", "}}", "comment4", "div", ">", "\n", "template", ">"] - ) + const actual = tokens + .getTokens(ast.templateBody, { includeComments: true }) + .map(toValue) + + assert.deepStrictEqual(actual, [ + "template", + ">", + "\n ", + "comment1", + "\n ", + "div", + "a", + "=", + "b", + "v-show", + "=", + '"', + "c", + "<", + "3", + "&&", + "ok", + "==", + '"ok"', + '"', + ">", + "comment2", + "{{", + "message", + "comment3", + "}}", + "comment4", + "div", + ">", + "\n", + "template", + ">", + ]) }) }) @@ -82,10 +143,7 @@ describe("services.getTemplateBodyTokenStore", () => { const node = ast.templateBody.children[0] const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["\n "] - ) + assert.deepStrictEqual(actual, ["\n "]) }) }) @@ -94,10 +152,29 @@ describe("services.getTemplateBodyTokenStore", () => { const node = ast.templateBody.children[2] const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["div", "a", "=", "b", "v-show", "=", "\"", "c", "<", "3", "&&", "ok", "==", "\"ok\"", "\"", ">", "{{", "message", "}}", "div", ">"] - ) + assert.deepStrictEqual(actual, [ + "div", + "a", + "=", + "b", + "v-show", + "=", + '"', + "c", + "<", + "3", + "&&", + "ok", + "==", + '"ok"', + '"', + ">", + "{{", + "message", + "}}", + "div", + ">", + ]) }) }) @@ -106,10 +183,24 @@ describe("services.getTemplateBodyTokenStore", () => { const node = ast.templateBody.children[2].startTag const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["div", "a", "=", "b", "v-show", "=", "\"", "c", "<", "3", "&&", "ok", "==", "\"ok\"", "\"", ">"] - ) + assert.deepStrictEqual(actual, [ + "div", + "a", + "=", + "b", + "v-show", + "=", + '"', + "c", + "<", + "3", + "&&", + "ok", + "==", + '"ok"', + '"', + ">", + ]) }) }) @@ -118,10 +209,7 @@ describe("services.getTemplateBodyTokenStore", () => { const node = ast.templateBody.children[2].startTag.attributes[0] const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["a", "=", "b"] - ) + assert.deepStrictEqual(actual, ["a", "=", "b"]) }) }) @@ -130,22 +218,17 @@ describe("services.getTemplateBodyTokenStore", () => { const node = ast.templateBody.children[2].startTag.attributes[0].key const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["a"] - ) + assert.deepStrictEqual(actual, ["a"]) }) }) describe("ast.templateBody.children[2].startTag.attributes[0].value (VAttributeValue)", () => { it("should return the value token.", () => { - const node = ast.templateBody.children[2].startTag.attributes[0].value + const node = + ast.templateBody.children[2].startTag.attributes[0].value const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["b"] - ) + assert.deepStrictEqual(actual, ["b"]) }) }) @@ -154,34 +237,46 @@ describe("services.getTemplateBodyTokenStore", () => { const node = ast.templateBody.children[2].startTag.attributes[1].key const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["v-show"] - ) + assert.deepStrictEqual(actual, ["v-show"]) }) }) describe("ast.templateBody.children[2].startTag.attributes[1].value (VExpressionContainer)", () => { it("should return all tokens in the value.", () => { - const node = ast.templateBody.children[2].startTag.attributes[1].value + const node = + ast.templateBody.children[2].startTag.attributes[1].value const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["\"", "c", "<", "3", "&&", "ok", "==", "\"ok\"", "\""] - ) + assert.deepStrictEqual(actual, [ + '"', + "c", + "<", + "3", + "&&", + "ok", + "==", + '"ok"', + '"', + ]) }) }) describe("ast.templateBody.children[2].startTag.attributes[1].value.expression (BinaryExpression)", () => { it("should return all tokens in the expression.", () => { - const node = ast.templateBody.children[2].startTag.attributes[1].value.expression + const node = + ast.templateBody.children[2].startTag.attributes[1].value + .expression const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["c", "<", "3", "&&", "ok", "==", "\"ok\""] - ) + assert.deepStrictEqual(actual, [ + "c", + "<", + "3", + "&&", + "ok", + "==", + '"ok"', + ]) }) }) @@ -190,10 +285,7 @@ describe("services.getTemplateBodyTokenStore", () => { const node = ast.templateBody.children[2].endTag const actual = tokens.getTokens(node).map(toValue) - assert.deepStrictEqual( - actual, - ["div", ">"] - ) + assert.deepStrictEqual(actual, ["div", ">"]) }) }) }) diff --git a/test/tools/.eslintrc.json b/test/tools/.eslintrc.json deleted file mode 100644 index 07b54ecf..00000000 --- a/test/tools/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": ["mysticatea", "mysticatea/node"], - "rules": { - "no-console": "off" - } -} diff --git a/test/variables-references.js b/test/variables-references.js index c56a48d6..4ac4c67f 100644 --- a/test/variables-references.js +++ b/test/variables-references.js @@ -30,20 +30,30 @@ const PARSER_OPTIONS = { describe("[references] expression containers", () => { describe("in directives", () => { - const code = "" + const code = '' let ast = null before(() => { - ast = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)).ast + ast = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ).ast }) it("should have references", () => { - const directive = ast.templateBody.children[0].startTag.attributes[0] + const directive = + ast.templateBody.children[0].startTag.attributes[0] assert(directive.key.type === "VDirectiveKey") assert(directive.value.references != null) - assert(directive.value.references[0].id === directive.value.expression.left) - assert(directive.value.references[1].id === directive.value.expression.right) + assert( + directive.value.references[0].id === + directive.value.expression.left + ) + assert( + directive.value.references[1].id === + directive.value.expression.right + ) }) }) @@ -52,7 +62,10 @@ describe("[references] expression containers", () => { let ast = null before(() => { - ast = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)).ast + ast = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ).ast }) it("should have references", () => { @@ -66,31 +79,41 @@ describe("[references] expression containers", () => { }) describe("in v-on directive", () => { - const code = "" + const code = '' let ast = null before(() => { - ast = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)).ast + ast = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ).ast }) it("should not include $event references.", () => { - const directive = ast.templateBody.children[0].startTag.attributes[0] + const directive = + ast.templateBody.children[0].startTag.attributes[0] assert(directive.key.type === "VDirectiveKey") assert(directive.key.name === "on") assert(directive.value.references.length === 1) - assert(directive.value.references[0].id === directive.value.expression.body[0].expression.callee) + assert( + directive.value.references[0].id === + directive.value.expression.body[0].expression.callee + ) }) }) }) describe("[variables] elements", () => { describe("which have v-for directive", () => { - const code = "" + const code = '' let ast = null before(() => { - ast = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)).ast + ast = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ).ast }) it("should have references", () => { @@ -99,18 +122,26 @@ describe("[variables] elements", () => { assert(element.type === "VElement") assert(element.variables.length === 1) - assert(element.variables[0].id === directive.value.expression.left[0]) + assert( + element.variables[0].id === directive.value.expression.left[0] + ) assert(directive.value.references.length === 1) - assert(directive.value.references[0].id === directive.value.expression.right) + assert( + directive.value.references[0].id === + directive.value.expression.right + ) }) }) describe("which have v-for directive (with index)", () => { - const code = "" + const code = '' let ast = null before(() => { - ast = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)).ast + ast = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ).ast }) it("should have references", () => { @@ -119,19 +150,29 @@ describe("[variables] elements", () => { assert(element.type === "VElement") assert(element.variables.length === 2) - assert(element.variables[0].id === directive.value.expression.left[0]) - assert(element.variables[1].id === directive.value.expression.left[1]) + assert( + element.variables[0].id === directive.value.expression.left[0] + ) + assert( + element.variables[1].id === directive.value.expression.left[1] + ) assert(directive.value.references.length === 1) - assert(directive.value.references[0].id === directive.value.expression.right) + assert( + directive.value.references[0].id === + directive.value.expression.right + ) }) }) describe("which have scope attribute", () => { - const code = "" + const code = '' let ast = null before(() => { - ast = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)).ast + ast = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ).ast }) it("should have variables", () => { @@ -150,7 +191,8 @@ describe("[variables] elements", () => { }) describe("Variables of v-for and references", () => { - const code = "" + const code = + '' let variables = null let vForReferences = null let vBindKeyReferences = null @@ -159,12 +201,19 @@ describe("Variables of v-for and references", () => { let mustacheReferences3 = null before(() => { - const ast = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)).ast + const ast = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ).ast variables = ast.templateBody.children[0].variables - vForReferences = ast.templateBody.children[0].startTag.attributes[0].value.references - vBindKeyReferences = ast.templateBody.children[0].startTag.attributes[1].value.references - mustacheReferences1 = ast.templateBody.children[0].children[0].references - mustacheReferences2 = ast.templateBody.children[0].children[1].children[0].references + vForReferences = + ast.templateBody.children[0].startTag.attributes[0].value.references + vBindKeyReferences = + ast.templateBody.children[0].startTag.attributes[1].value.references + mustacheReferences1 = + ast.templateBody.children[0].children[0].references + mustacheReferences2 = + ast.templateBody.children[0].children[1].children[0].references mustacheReferences3 = ast.templateBody.children[1].references }) @@ -189,19 +238,32 @@ describe("Variables of v-for and references", () => { it("`Variable#references` should be non-enumerable", () => { for (const variable of variables) { - assert(Object.getOwnPropertyDescriptor(variable, "references").enumerable === false) + assert( + Object.getOwnPropertyDescriptor(variable, "references") + .enumerable === false + ) } }) it("`Reference#variable` should be non-enumerable", () => { - for (const reference of [].concat(vForReferences, vBindKeyReferences, mustacheReferences1, mustacheReferences2, mustacheReferences3)) { - assert(Object.getOwnPropertyDescriptor(reference, "variable").enumerable === false) + for (const reference of [].concat( + vForReferences, + vBindKeyReferences, + mustacheReferences1, + mustacheReferences2, + mustacheReferences3 + )) { + assert( + Object.getOwnPropertyDescriptor(reference, "variable") + .enumerable === false + ) } }) }) describe("Variables of template-scope and references", () => { - const code = "" + const code = + '' let variables = null let vBindKeyReferences = null let mustacheReferences1 = null @@ -209,11 +271,17 @@ describe("Variables of template-scope and references", () => { let mustacheReferences3 = null before(() => { - const ast = parse(code, Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS)).ast + const ast = parse( + code, + Object.assign({ filePath: "test.vue" }, PARSER_OPTIONS) + ).ast variables = ast.templateBody.children[0].variables - vBindKeyReferences = ast.templateBody.children[0].startTag.attributes[1].value.references - mustacheReferences1 = ast.templateBody.children[0].children[0].references - mustacheReferences2 = ast.templateBody.children[0].children[1].children[0].references + vBindKeyReferences = + ast.templateBody.children[0].startTag.attributes[1].value.references + mustacheReferences1 = + ast.templateBody.children[0].children[0].references + mustacheReferences2 = + ast.templateBody.children[0].children[1].children[0].references mustacheReferences3 = ast.templateBody.children[1].references }) @@ -236,13 +304,24 @@ describe("Variables of template-scope and references", () => { it("`Variable#references` should be non-enumerable", () => { for (const variable of variables) { - assert(Object.getOwnPropertyDescriptor(variable, "references").enumerable === false) + assert( + Object.getOwnPropertyDescriptor(variable, "references") + .enumerable === false + ) } }) it("`Reference#variable` should be non-enumerable", () => { - for (const reference of [].concat(vBindKeyReferences, mustacheReferences1, mustacheReferences2, mustacheReferences3)) { - assert(Object.getOwnPropertyDescriptor(reference, "variable").enumerable === false) + for (const reference of [].concat( + vBindKeyReferences, + mustacheReferences1, + mustacheReferences2, + mustacheReferences3 + )) { + assert( + Object.getOwnPropertyDescriptor(reference, "variable") + .enumerable === false + ) } }) })