From 149230ce7e296c029a0b6c085216fc0360ed4c65 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Fri, 6 Aug 2021 22:34:08 +0200 Subject: [PATCH 01/17] Chore: Specify Node 14.x for Verify Files CI job (#14896) --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc3d1e701f3..170bf15b018 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,8 @@ jobs: steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 + with: + node-version: '14.x' - name: Install Packages run: npm install - name: Lint Files From d66e9414be60e05badb96bc3e1a55ca34636d7f8 Mon Sep 17 00:00:00 2001 From: Bryan Mishkin <698306+bmish@users.noreply.github.com> Date: Fri, 6 Aug 2021 17:44:31 -0700 Subject: [PATCH 02/17] Upgrade: @humanwhocodes/config-array to 0.6 (#14891) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d4f699bbaff..98b79a48fc6 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "bugs": "https://github.com/eslint/eslint/issues/", "dependencies": { "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", + "@humanwhocodes/config-array": "^0.6.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", From e53d8cf9d73bd105cf6ba4f6b5477ccc4b980939 Mon Sep 17 00:00:00 2001 From: Bryan Mishkin <698306+bmish@users.noreply.github.com> Date: Sat, 7 Aug 2021 11:35:57 -0700 Subject: [PATCH 03/17] Upgrade: `markdownlint` dev dependencies (#14883) --- .markdownlintignore | 1 + Makefile.js | 3 ++- package.json | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 .markdownlintignore diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 00000000000..1b763b1bae0 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1 @@ +CHANGELOG.md diff --git a/Makefile.js b/Makefile.js index e84d21abf2c..b93697857c6 100644 --- a/Makefile.js +++ b/Makefile.js @@ -66,7 +66,8 @@ const NODE = "node ", // intentional extra space // Files RULE_FILES = glob.sync("lib/rules/*.js").filter(filePath => path.basename(filePath) !== "index.js"), JSON_FILES = find("conf/").filter(fileType("json")), - MARKDOWN_FILES_ARRAY = find("docs/").concat(ls(".")).filter(fileType("md")), + MARKDOWNLINT_IGNORED_FILES = fs.readFileSync(path.join(__dirname, ".markdownlintignore"), "utf-8").split("\n"), + MARKDOWN_FILES_ARRAY = find("docs/").concat(ls(".")).filter(fileType("md")).filter(file => !MARKDOWNLINT_IGNORED_FILES.includes(file)), TEST_FILES = "\"tests/{bin,lib,tools}/**/*.js\"", PERF_ESLINTRC = path.join(PERF_TMP_DIR, "eslintrc.yml"), PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"), diff --git a/package.json b/package.json index 98b79a48fc6..e8ff2663f78 100644 --- a/package.json +++ b/package.json @@ -116,8 +116,8 @@ "karma-webpack": "^5.0.0", "lint-staged": "^11.0.0", "load-perf": "^0.2.0", - "markdownlint": "^0.19.0", - "markdownlint-cli": "^0.22.0", + "markdownlint": "^0.23.1", + "markdownlint-cli": "^0.28.1", "memfs": "^3.0.1", "mocha": "^8.3.2", "mocha-junit-reporter": "^2.0.0", From ae6072b1de5c8b30ce6c58290852082439c40b30 Mon Sep 17 00:00:00 2001 From: Bryan Mishkin <698306+bmish@users.noreply.github.com> Date: Sat, 7 Aug 2021 12:19:49 -0700 Subject: [PATCH 04/17] Upgrade: `eslint-visitor-keys` to v3 (#14902) https://github.com/eslint/eslint-visitor-keys/releases/tag/v3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8ff2663f78..f0cd1bf67b0 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^6.0.0", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^2.1.0", + "eslint-visitor-keys": "^3.0.0", "espree": "^8.0.0", "esquery": "^1.4.0", "esutils": "^2.0.2", From d234d890b383837f8e4bda0f6ce1e2a348f9835e Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Mon, 9 Aug 2021 19:49:53 +0200 Subject: [PATCH 05/17] Docs: add class fields in func-names documentation (refs #14857) (#14908) --- docs/rules/func-names.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/rules/func-names.md b/docs/rules/func-names.md index 27b9cc20fcf..ea1ba617e54 100644 --- a/docs/rules/func-names.md +++ b/docs/rules/func-names.md @@ -17,14 +17,14 @@ This rule can enforce or disallow the use of named function expressions. This rule has a string option: * `"always"` (default) requires function expressions to have a name -* `"as-needed"` requires function expressions to have a name, if the name cannot be assigned automatically in an ES6 environment +* `"as-needed"` requires function expressions to have a name, if the name isn't assigned automatically per the ECMAScript specification. * `"never"` disallows named function expressions, except in recursive functions, where a name is needed This rule has an object option: * `"generators": "always" | "as-needed" | "never"` * `"always"` require named generators - * `"as-needed"` require named generators if the name cannot be assigned automatically in an ES6 environment. + * `"as-needed"` require named generators if the name isn't assigned automatically per the ECMAScript specification. * `"never"` disallow named generators where possible. When a value for `generators` is not provided the behavior for generator functions falls back to the base option. @@ -98,6 +98,13 @@ const cat = { meow: function() {} } +class C { + #bar = function() {}; + baz = function() {}; +} + +quux ??= function() {}; + (function bar() { // ... }()) From 5c3a47072aeb5cfda40a1eb20b43a10c5ca7aab3 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Mon, 9 Aug 2021 19:50:36 +0200 Subject: [PATCH 06/17] Docs: add class fields in no-multi-assign documentation (refs #14857) (#14907) --- docs/rules/no-multi-assign.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/rules/no-multi-assign.md b/docs/rules/no-multi-assign.md index 7ef70567593..14721dab0d8 100644 --- a/docs/rules/no-multi-assign.md +++ b/docs/rules/no-multi-assign.md @@ -26,12 +26,19 @@ const foo = bar = "baz"; let a = b = c; + +class Foo { + a = b = 10; +} + +a = b = "quux"; ``` Examples of **correct** code for this rule: ```js /*eslint no-multi-assign: "error"*/ + var a = 5; var b = 5; var c = 5; @@ -41,13 +48,21 @@ const bar = "baz"; let a = c; let b = c; + +class Foo { + a = 10; + b = 10; +} + +a = "quux"; +b = "quux"; ``` ## Options This rule has an object option: -* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration. Default is `false`. +* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration or initializing a class field. Default is `false`. ### ignoreNonDeclaration @@ -73,6 +88,10 @@ Examples of **incorrect** code for the `{ "ignoreNonDeclaration": true }` option let a = b = "baz"; const foo = bar = 1; + +class Foo { + a = b = 10; +} ``` ## Related Rules From 9052eee07a459dc059cd92f657a3ae73acc95bb5 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Mon, 9 Aug 2021 19:51:43 +0200 Subject: [PATCH 07/17] Update: check class fields in no-extra-parens (refs #14857) (#14906) --- docs/rules/no-extra-parens.md | 16 ++++++++++++ lib/rules/no-extra-parens.js | 23 ++++++++++++----- tests/lib/rules/no-extra-parens.js | 41 +++++++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/docs/rules/no-extra-parens.md b/docs/rules/no-extra-parens.md index 68b986eff6c..b521dcbe268 100644 --- a/docs/rules/no-extra-parens.md +++ b/docs/rules/no-extra-parens.md @@ -48,6 +48,14 @@ for (a of (b)); typeof (a); (function(){} ? a() : b()); + +class A { + [(x)] = 1; +} + +class B { + x = (y + z); +} ``` Examples of **correct** code for this rule with the default `"all"` option: @@ -72,6 +80,14 @@ for (a of b); for (a in b, c); for (a in b); + +class A { + [x] = 1; +} + +class B { + x = y + z; +} ``` ### conditionalAssign diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js index 307e340c958..d063350461d 100644 --- a/lib/rules/no-extra-parens.js +++ b/lib/rules/no-extra-parens.js @@ -808,13 +808,6 @@ module.exports = { CallExpression: checkCallNew, - ClassBody(node) { - node.body - .filter(member => member.type === "MethodDefinition" && member.computed && member.key) - .filter(member => hasExcessParensWithPrecedence(member.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) - .forEach(member => report(member.key)); - }, - ConditionalExpression(node) { if (isReturnAssignException(node)) { return; @@ -1063,6 +1056,12 @@ module.exports = { } }, + "MethodDefinition[computed=true]"(node) { + if (hasExcessParensWithPrecedence(node.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.key); + } + }, + NewExpression: checkCallNew, ObjectExpression(node) { @@ -1090,6 +1089,16 @@ module.exports = { } }, + PropertyDefinition(node) { + if (node.computed && hasExcessParensWithPrecedence(node.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.key); + } + + if (node.value && hasExcessParensWithPrecedence(node.value, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.value); + } + }, + RestElement(node) { const argument = node.argument; diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js index a14ececc099..5a4dba6482e 100644 --- a/tests/lib/rules/no-extra-parens.js +++ b/tests/lib/rules/no-extra-parens.js @@ -44,7 +44,7 @@ function invalid(code, output, type, line, config) { const ruleTester = new RuleTester({ parserOptions: { - ecmaVersion: 2021, + ecmaVersion: 2022, ecmaFeatures: { jsx: true } @@ -182,6 +182,25 @@ ruleTester.run("no-extra-parens", rule, { "class foo { a(){} [b](){} c(){} [(d,e)](){} }", "class foo { [(a,b)](){} c(){} [d](){} e(){} }", "const foo = class { constructor(){} a(){} get b(){} set b(bar){} get c(){} set d(baz){} static e(){} }", + "class foo { x; }", + "class foo { static x; }", + "class foo { x = 1; }", + "class foo { static x = 1; }", + "class foo { #x; }", + "class foo { static #x; }", + "class foo { static #x = 1; }", + "class foo { #x(){} get #y() {} set #y(value) {} static #z(){} static get #q() {} static set #q(value) {} }", + "const foo = class { #x(){} get #y() {} set #y(value) {} static #z(){} static get #q() {} static set #q(value) {} }", + "class foo { [(x, y)]; }", + "class foo { static [(x, y)]; }", + "class foo { [(x, y)] = 1; }", + "class foo { static [(x, y)] = 1; }", + "class foo { x = (y, z); }", + "class foo { static x = (y, z); }", + "class foo { #x = (y, z); }", + "class foo { static #x = (y, z); }", + "class foo { [(1, 2)] = (3, 4) }", + "const foo = class { [(1, 2)] = (3, 4) }", // ExpressionStatement restricted productions "({});", @@ -771,6 +790,26 @@ ruleTester.run("no-extra-parens", rule, { invalid("class foo { [(a,b)](){} [(c+d)](){} }", "class foo { [(a,b)](){} [c+d](){} }", "BinaryExpression"), invalid("class foo { [a+(b*c)](){} }", "class foo { [a+b*c](){} }", "BinaryExpression"), invalid("const foo = class { [(a)](){} }", "const foo = class { [a](){} }", "Identifier"), + invalid("class foo { [(x)]; }", "class foo { [x]; }", "Identifier"), + invalid("class foo { static [(x)]; }", "class foo { static [x]; }", "Identifier"), + invalid("class foo { [(x)] = 1; }", "class foo { [x] = 1; }", "Identifier"), + invalid("class foo { static [(x)] = 1; }", "class foo { static [x] = 1; }", "Identifier"), + invalid("const foo = class { [(x)]; }", "const foo = class { [x]; }", "Identifier"), + invalid("class foo { [(x = y)]; }", "class foo { [x = y]; }", "AssignmentExpression"), + invalid("class foo { [(x + y)]; }", "class foo { [x + y]; }", "BinaryExpression"), + invalid("class foo { [(x ? y : z)]; }", "class foo { [x ? y : z]; }", "ConditionalExpression"), + invalid("class foo { [((x, y))]; }", "class foo { [(x, y)]; }", "SequenceExpression"), + invalid("class foo { x = (y); }", "class foo { x = y; }", "Identifier"), + invalid("class foo { static x = (y); }", "class foo { static x = y; }", "Identifier"), + invalid("class foo { #x = (y); }", "class foo { #x = y; }", "Identifier"), + invalid("class foo { static #x = (y); }", "class foo { static #x = y; }", "Identifier"), + invalid("const foo = class { x = (y); }", "const foo = class { x = y; }", "Identifier"), + invalid("class foo { x = (() => {}); }", "class foo { x = () => {}; }", "ArrowFunctionExpression"), + invalid("class foo { x = (y + z); }", "class foo { x = y + z; }", "BinaryExpression"), + invalid("class foo { x = (y ? z : q); }", "class foo { x = y ? z : q; }", "ConditionalExpression"), + invalid("class foo { x = ((y, z)); }", "class foo { x = (y, z); }", "SequenceExpression"), + + // invalid( "var foo = (function*() { if ((yield foo())) { return; } }())", "var foo = (function*() { if (yield foo()) { return; } }())", From c4e58023f22381508babfc52087853b5e3965b9c Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Mon, 9 Aug 2021 23:22:48 +0530 Subject: [PATCH 08/17] Docs: improve rule details for `no-console` (fixes #14793) (#14901) --- docs/rules/no-console.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/rules/no-console.md b/docs/rules/no-console.md index f2fb79ec421..b1e4e601c0f 100644 --- a/docs/rules/no-console.md +++ b/docs/rules/no-console.md @@ -9,7 +9,7 @@ console.error("That shouldn't have happened."); ## Rule Details -This rule disallows calls to methods of the `console` object. +This rule disallows calls or assignments to methods of the `console` object. Examples of **incorrect** code for this rule: @@ -19,6 +19,7 @@ Examples of **incorrect** code for this rule: console.log("Log a debug level message."); console.warn("Log a warn level message."); console.error("Log an error level message."); +console.log = foo(); ``` Examples of **correct** code for this rule: From a3dd8257252f392de5cf793c36ecab2acd955659 Mon Sep 17 00:00:00 2001 From: ESLint Jenkins Date: Mon, 9 Aug 2021 15:11:31 -0400 Subject: [PATCH 09/17] Sponsors: Sync README with website --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a429bdf848b..3db86c1b376 100644 --- a/README.md +++ b/README.md @@ -298,7 +298,7 @@ The following companies, organizations, and individuals support ESLint's ongoing

Automattic

Gold Sponsors

Nx (by Nrwl) Chrome's Web Framework & Tools Performance Fund Salesforce Airbnb Coinbase Substack

Silver Sponsors

Retool Liftoff

Bronze Sponsors

-

Mobilen Anagram Solver Bugsnag Stability Monitoring Mixpanel VPS Server Icons8: free icons, photos, illustrations, and music Discord ThemeIsle Fire Stick Tricks Practice Ignition

+

Troy Mobilen Anagram Solver Bugsnag Stability Monitoring Mixpanel VPS Server Icons8: free icons, photos, illustrations, and music Discord ThemeIsle Fire Stick Tricks Practice Ignition

## Technology Sponsors From 8c350660e61284c41a5cc1a5955c858db53c516b Mon Sep 17 00:00:00 2001 From: ESLint Jenkins Date: Mon, 9 Aug 2021 17:11:22 -0400 Subject: [PATCH 10/17] Sponsors: Sync README with website --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3db86c1b376..3082aeffb75 100644 --- a/README.md +++ b/README.md @@ -298,7 +298,7 @@ The following companies, organizations, and individuals support ESLint's ongoing

Automattic

Gold Sponsors

Nx (by Nrwl) Chrome's Web Framework & Tools Performance Fund Salesforce Airbnb Coinbase Substack

Silver Sponsors

Retool Liftoff

Bronze Sponsors

-

Troy Mobilen Anagram Solver Bugsnag Stability Monitoring Mixpanel VPS Server Icons8: free icons, photos, illustrations, and music Discord ThemeIsle Fire Stick Tricks Practice Ignition

+

TROYPOINT Mobilen Anagram Solver Bugsnag Stability Monitoring Mixpanel VPS Server Icons8: free icons, photos, illustrations, and music Discord ThemeIsle Fire Stick Tricks Practice Ignition

## Technology Sponsors From ccb9a9138acd63457e004630475495954c1be6f4 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Tue, 10 Aug 2021 02:46:23 +0200 Subject: [PATCH 11/17] Fix: dot-notation false positive with private identifier (refs #14857) (#14898) * Fix: dot-notation false positive with private identifier (refs #14857) * Add example in docs --- docs/rules/dot-notation.md | 13 +++++++++++++ lib/rules/dot-notation.js | 1 + tests/lib/rules/dot-notation.js | 7 ++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/rules/dot-notation.md b/docs/rules/dot-notation.md index a13049a3f3f..26c77756c4b 100644 --- a/docs/rules/dot-notation.md +++ b/docs/rules/dot-notation.md @@ -46,6 +46,19 @@ var foo = { "class": "CS 101" } var x = foo["class"]; // Property name is a reserved word, square-bracket notation required ``` +Examples of additional **correct** code for the `{ "allowKeywords": false }` option: + +```js +/*eslint dot-notation: ["error", { "allowKeywords": false }]*/ + +class C { + #in; + foo() { + this.#in; // Dot notation is required for private identifiers + } +} +``` + ### allowPattern For example, when preparing data to be sent to an external API, it is often required to use property names that include underscores. If the `camelcase` rule is in effect, these [snake case](https://en.wikipedia.org/wiki/Snake_case) properties would not be allowed. By providing an `allowPattern` to the `dot-notation` rule, these snake case properties can be accessed with bracket notation. diff --git a/lib/rules/dot-notation.js b/lib/rules/dot-notation.js index 3aa9f3110f5..20434f3594c 100644 --- a/lib/rules/dot-notation.js +++ b/lib/rules/dot-notation.js @@ -141,6 +141,7 @@ module.exports = { if ( !allowKeywords && !node.computed && + node.property.type === "Identifier" && keywords.indexOf(String(node.property.name)) !== -1 ) { context.report({ diff --git a/tests/lib/rules/dot-notation.js b/tests/lib/rules/dot-notation.js index fed94c128cf..249faf80e8f 100644 --- a/tests/lib/rules/dot-notation.js +++ b/tests/lib/rules/dot-notation.js @@ -59,7 +59,12 @@ ruleTester.run("dot-notation", rule, { "a[void 0];", "a[b()];", { code: "a[/(?0)/];", parserOptions: { ecmaVersion: 2018 } }, - { code: "class C { foo() { this['#a'] } }", parserOptions: { ecmaVersion: 2022 } } + { code: "class C { foo() { this['#a'] } }", parserOptions: { ecmaVersion: 2022 } }, + { + code: "class C { #in; foo() { this.#in; } }", + options: [{ allowKeywords: false }], + parserOptions: { ecmaVersion: 2022 } + } ], invalid: [ { From cbc43daad2ea229fb15a9198efd2bc2721dfb75f Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Tue, 10 Aug 2021 02:49:24 +0200 Subject: [PATCH 12/17] Fix: prefer-destructuring PrivateIdentifier false positive (refs #14857) (#14897) --- docs/rules/prefer-destructuring.md | 11 ++++++++ lib/rules/prefer-destructuring.js | 6 +++- tests/lib/rules/prefer-destructuring.js | 37 +++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/docs/rules/prefer-destructuring.md b/docs/rules/prefer-destructuring.md index 7f18559ed50..64e914fcee4 100644 --- a/docs/rules/prefer-destructuring.md +++ b/docs/rules/prefer-destructuring.md @@ -62,6 +62,17 @@ Examples of **correct** code when `enforceForRenamedProperties` is enabled: var { bar: foo } = object; ``` +Examples of additional **correct** code when `enforceForRenamedProperties` is enabled: + +```javascript +class C { + #x; + foo() { + const bar = this.#x; // private identifiers are not allowed in destructuring + } +} +``` + An example configuration, with the defaults `array` and `object` filled in, looks like this: ```json diff --git a/lib/rules/prefer-destructuring.js b/lib/rules/prefer-destructuring.js index f82bb75c122..f76087e5250 100644 --- a/lib/rules/prefer-destructuring.js +++ b/lib/rules/prefer-destructuring.js @@ -221,7 +221,11 @@ module.exports = { * @returns {void} */ function performCheck(leftNode, rightNode, reportNode) { - if (rightNode.type !== "MemberExpression" || rightNode.object.type === "Super") { + if ( + rightNode.type !== "MemberExpression" || + rightNode.object.type === "Super" || + rightNode.property.type === "PrivateIdentifier" + ) { return; } diff --git a/tests/lib/rules/prefer-destructuring.js b/tests/lib/rules/prefer-destructuring.js index 8f111a1d8c2..7f808a64218 100644 --- a/tests/lib/rules/prefer-destructuring.js +++ b/tests/lib/rules/prefer-destructuring.js @@ -16,7 +16,7 @@ const rule = require("../../../lib/rules/prefer-destructuring"), // Tests //------------------------------------------------------------------------------ -const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2020 } }); +const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2022 } }); ruleTester.run("prefer-destructuring", rule, { valid: [ @@ -157,7 +157,40 @@ ruleTester.run("prefer-destructuring", rule, { // Optional chaining "var foo = array?.[0];", // because the fixed code can throw TypeError. - "var foo = object?.foo;" + "var foo = object?.foo;", + + // Private identifiers + "class C { #x; foo() { const x = this.#x; } }", + "class C { #x; foo() { x = this.#x; } }", + "class C { #x; foo(a) { x = a.#x; } }", + { + code: "class C { #x; foo() { const x = this.#x; } }", + options: [{ array: true, object: true }, { enforceForRenamedProperties: true }] + }, + { + code: "class C { #x; foo() { const y = this.#x; } }", + options: [{ array: true, object: true }, { enforceForRenamedProperties: true }] + }, + { + code: "class C { #x; foo() { x = this.#x; } }", + options: [{ array: true, object: true }, { enforceForRenamedProperties: true }] + }, + { + code: "class C { #x; foo() { y = this.#x; } }", + options: [{ array: true, object: true }, { enforceForRenamedProperties: true }] + }, + { + code: "class C { #x; foo(a) { x = a.#x; } }", + options: [{ array: true, object: true }, { enforceForRenamedProperties: true }] + }, + { + code: "class C { #x; foo(a) { y = a.#x; } }", + options: [{ array: true, object: true }, { enforceForRenamedProperties: true }] + }, + { + code: "class C { #x; foo() { x = this.a.#x; } }", + options: [{ array: true, object: true }, { enforceForRenamedProperties: true }] + } ], invalid: [ From 88db3f54988dddfbda35764ecf1ea16354c4213a Mon Sep 17 00:00:00 2001 From: Bryan Mishkin <698306+bmish@users.noreply.github.com> Date: Mon, 9 Aug 2021 20:03:24 -0500 Subject: [PATCH 13/17] Upgrade: `js-yaml` to v4 (#14890) * Upgrade: js-yaml to v4 https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md#400---2021-01-03 * allow Python licenses --- Makefile.js | 6 +++--- lib/cli-engine/formatters/tap.js | 2 +- lib/init/config-file.js | 2 +- package.json | 2 +- tests/lib/init/config-file.js | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.js b/Makefile.js index b93697857c6..3ee1b4c1b4c 100644 --- a/Makefile.js +++ b/Makefile.js @@ -43,7 +43,7 @@ const { cat, cd, cp, echo, exec, exit, find, ls, mkdir, pwd, rm, test } = requir const PERF_MULTIPLIER = 13e6; const OPEN_SOURCE_LICENSES = [ - /MIT/u, /BSD/u, /Apache/u, /ISC/u, /WTF/u, /Public Domain/u, /LGPL/u + /MIT/u, /BSD/u, /Apache/u, /ISC/u, /WTF/u, /Public Domain/u, /LGPL/u, /Python/u ]; //------------------------------------------------------------------------------ @@ -214,7 +214,7 @@ function generateRuleIndexPage() { // `.rules` will be `undefined` if all rules in category are deprecated. categoriesData.categories = categoriesData.categories.filter(category => !!category.rules); - const output = yaml.safeDump(categoriesData, { sortKeys: true }); + const output = yaml.dump(categoriesData, { sortKeys: true }); output.to(outputFile); } @@ -390,7 +390,7 @@ function getFirstVersionOfDeletion(filePath) { * @private */ function lintMarkdown(files) { - const config = yaml.safeLoad(fs.readFileSync(path.join(__dirname, "./.markdownlint.yml"), "utf8")), + const config = yaml.load(fs.readFileSync(path.join(__dirname, "./.markdownlint.yml"), "utf8")), result = markdownlint.sync({ files, config, diff --git a/lib/cli-engine/formatters/tap.js b/lib/cli-engine/formatters/tap.js index 354872a0c92..e4148a3b392 100644 --- a/lib/cli-engine/formatters/tap.js +++ b/lib/cli-engine/formatters/tap.js @@ -31,7 +31,7 @@ function outputDiagnostics(diagnostic) { const prefix = " "; let output = `${prefix}---\n`; - output += prefix + yaml.safeDump(diagnostic).split("\n").join(`\n${prefix}`); + output += prefix + yaml.dump(diagnostic).split("\n").join(`\n${prefix}`); output += "...\n"; return output; } diff --git a/lib/init/config-file.js b/lib/init/config-file.js index 4c648ac0551..a51f92e1c48 100644 --- a/lib/init/config-file.js +++ b/lib/init/config-file.js @@ -63,7 +63,7 @@ function writeYAMLConfigFile(config, filePath) { // lazy load YAML to improve performance when not used const yaml = require("js-yaml"); - const content = yaml.safeDump(config, { sortKeys: true }); + const content = yaml.dump(config, { sortKeys: true }); fs.writeFileSync(filePath, content, "utf8"); } diff --git a/package.json b/package.json index f0cd1bf67b0..746d6cc7003 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", diff --git a/tests/lib/init/config-file.js b/tests/lib/init/config-file.js index e9fe62e2c30..50a9af1d507 100644 --- a/tests/lib/init/config-file.js +++ b/tests/lib/init/config-file.js @@ -60,8 +60,8 @@ describe("ConfigFile", () => { [ ["JavaScript", "foo.js", espree.parse], ["JSON", "bar.json", JSON.parse], - ["YAML", "foo.yaml", yaml.safeLoad], - ["YML", "foo.yml", yaml.safeLoad] + ["YAML", "foo.yaml", yaml.load], + ["YML", "foo.yml", yaml.load] ].forEach(([fileType, filename, validate]) => { it(`should write a file through fs when a ${fileType} path is passed`, () => { From a773b99873965652a86bec489193dc42a8923f5f Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Tue, 10 Aug 2021 03:06:35 +0200 Subject: [PATCH 14/17] Fix: no-useless-computed-key edge cases with class fields (refs #14857) (#14903) --- docs/rules/no-useless-computed-key.md | 59 ++++++++++++++- lib/rules/no-useless-computed-key.js | 87 ++++++++++++++++++---- tests/lib/rules/no-useless-computed-key.js | 64 ++++++++++++++++ 3 files changed, 191 insertions(+), 19 deletions(-) diff --git a/docs/rules/no-useless-computed-key.md b/docs/rules/no-useless-computed-key.md index 9b3c592849b..2d3ddb3d50b 100644 --- a/docs/rules/no-useless-computed-key.md +++ b/docs/rules/no-useless-computed-key.md @@ -20,7 +20,6 @@ Examples of **incorrect** code for this rule: ```js /*eslint no-useless-computed-key: "error"*/ -/*eslint-env es6*/ var a = { ['0']: 0 }; var a = { ['0+1,234']: 0 }; @@ -41,6 +40,18 @@ var c = { a: 0 }; var c = { '0+1,234': 0 }; ``` +Examples of additional **correct** code for this rule: + +```js +/*eslint no-useless-computed-key: "error"*/ + +var c = { + "__proto__": foo, // defines object's prototype + + ["__proto__"]: bar // defines a property named "__proto__" +}; +``` + ## Options This rule has an object option: @@ -52,24 +63,64 @@ This rule has an object option: By default, this rule does not check class declarations and class expressions, as the default value for `enforceForClassMembers` is `false`. -When `enforceForClassMembers` is set to `true`, the rule will also disallow unnecessary computed -keys inside of class methods, getters and setters. +When `enforceForClassMembers` is set to `true`, the rule will also disallow unnecessary computed keys inside of class fields, class methods, class getters, and class setters. -Examples of **incorrect** code for `{ "enforceForClassMembers": true }`: +Examples of **incorrect** code for this rule with the `{ "enforceForClassMembers": true }` option: ```js /*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/ class Foo { + ["foo"] = "bar"; + [0]() {} ['a']() {} get ['b']() {} set ['c'](value) {} + static ["foo"] = "bar"; + static ['a']() {} } ``` +Examples of **correct** code for this rule with the `{ "enforceForClassMembers": true }` option: + +```js +/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/ + +class Foo { + "foo" = "bar"; + + 0() {} + 'a'() {} + get 'b'() {} + set 'c'(value) {} + + static "foo" = "bar"; + + static 'a'() {} +} +``` + +Examples of additional **correct** code for this rule with the `{ "enforceForClassMembers": true }` option: + +```js +/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/ + +class Foo { + ["constructor"]; // instance field named "constructor" + + "constructor"() {} // the constructor of this class + + ["constructor"]() {} // method named "constructor" + + static ["constructor"]; // static field named "constructor" + + static ["prototype"]; // runtime error, it would be a parsing error without `[]` +} +``` + ## When Not To Use It If you don't want to be notified about unnecessary computed property keys, you can safely disable this rule. diff --git a/lib/rules/no-useless-computed-key.js b/lib/rules/no-useless-computed-key.js index 08df712657c..a6643061928 100644 --- a/lib/rules/no-useless-computed-key.js +++ b/lib/rules/no-useless-computed-key.js @@ -10,6 +10,76 @@ const astUtils = require("./utils/ast-utils"); +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines whether the computed key syntax is unnecessarily used for the given node. + * In particular, it determines whether removing the square brackets and using the content between them + * directly as the key (e.g. ['foo'] -> 'foo') would produce valid syntax and preserve the same behavior. + * Valid non-computed keys are only: identifiers, number literals and string literals. + * Only literals can preserve the same behavior, with a few exceptions for specific node types: + * Property + * - { ["__proto__"]: foo } defines a property named "__proto__" + * { "__proto__": foo } defines object's prototype + * PropertyDefinition + * - class C { ["constructor"]; } defines an instance field named "constructor" + * class C { "constructor"; } produces a parsing error + * - class C { static ["constructor"]; } defines a static field named "constructor" + * class C { static "constructor"; } produces a parsing error + * - class C { static ["prototype"]; } produces a runtime error (doesn't break the whole script) + * class C { static "prototype"; } produces a parsing error (breaks the whole script) + * MethodDefinition + * - class C { ["constructor"]() {} } defines a prototype method named "constructor" + * class C { "constructor"() {} } defines the constructor + * - class C { static ["prototype"]() {} } produces a runtime error (doesn't break the whole script) + * class C { static "prototype"() {} } produces a parsing error (breaks the whole script) + * @param {ASTNode} node The node to check. It can be `Property`, `PropertyDefinition` or `MethodDefinition`. + * @returns {void} `true` if the node has useless computed key. + */ +function hasUselessComputedKey(node) { + if (!node.computed) { + return false; + } + + const { key } = node; + + if (key.type !== "Literal") { + return false; + } + + const { value } = key; + + if (typeof value !== "number" && typeof value !== "string") { + return false; + } + + switch (node.type) { + case "Property": + return value !== "__proto__"; + + case "PropertyDefinition": + if (node.static) { + return value !== "constructor" && value !== "prototype"; + } + + return value !== "constructor"; + + case "MethodDefinition": + if (node.static) { + return value !== "prototype"; + } + + return value !== "constructor"; + + /* istanbul ignore next */ + default: + throw new Error(`Unexpected node type: ${node.type}`); + } + +} + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -51,22 +121,9 @@ module.exports = { * @returns {void} */ function check(node) { - if (!node.computed) { - return; - } - - const key = node.key, - nodeType = typeof key.value; - - let allowedKey; - - if (node.type === "MethodDefinition") { - allowedKey = node.static ? "prototype" : "constructor"; - } else { - allowedKey = "__proto__"; - } + if (hasUselessComputedKey(node)) { + const { key } = node; - if (key.type === "Literal" && (nodeType === "string" || nodeType === "number") && key.value !== allowedKey) { context.report({ node, messageId: "unnecessarilyComputedProperty", diff --git a/tests/lib/rules/no-useless-computed-key.js b/tests/lib/rules/no-useless-computed-key.js index a7bf323cf38..37f31118878 100644 --- a/tests/lib/rules/no-useless-computed-key.js +++ b/tests/lib/rules/no-useless-computed-key.js @@ -42,6 +42,9 @@ ruleTester.run("no-useless-computed-key", rule, { { code: "class Foo { static ['constructor']() {} }", options: [{ enforceForClassMembers: false }] }, { code: "class Foo { ['prototype']() {} }", options: [{ enforceForClassMembers: false }] }, { code: "class Foo { a }", options: [{ enforceForClassMembers: true }] }, + { code: "class Foo { ['constructor'] }", options: [{ enforceForClassMembers: true }] }, + { code: "class Foo { static ['constructor'] }", options: [{ enforceForClassMembers: true }] }, + { code: "class Foo { static ['prototype'] }", options: [{ enforceForClassMembers: true }] }, /* * Well-known browsers throw syntax error bigint literals on property names, @@ -241,6 +244,22 @@ ruleTester.run("no-useless-computed-key", rule, { data: { property: "2" }, type: "Property" }] + }, { + code: "({ ['constructor']: 1 })", + output: "({ 'constructor': 1 })", + errors: [{ + messageId: "unnecessarilyComputedProperty", + data: { property: "'constructor'" }, + type: "Property" + }] + }, { + code: "({ ['prototype']: 1 })", + output: "({ 'prototype': 1 })", + errors: [{ + messageId: "unnecessarilyComputedProperty", + data: { property: "'prototype'" }, + type: "Property" + }] }, { code: "class Foo { ['0']() {} }", output: "class Foo { '0'() {} }", @@ -461,6 +480,24 @@ ruleTester.run("no-useless-computed-key", rule, { data: { property: "'x'" }, type: "MethodDefinition" }] + }, { + code: "(class { ['__proto__']() {} })", + output: "(class { '__proto__'() {} })", + options: [{ enforceForClassMembers: true }], + errors: [{ + messageId: "unnecessarilyComputedProperty", + data: { property: "'__proto__'" }, + type: "MethodDefinition" + }] + }, { + code: "(class { static ['__proto__']() {} })", + output: "(class { static '__proto__'() {} })", + options: [{ enforceForClassMembers: true }], + errors: [{ + messageId: "unnecessarilyComputedProperty", + data: { property: "'__proto__'" }, + type: "MethodDefinition" + }] }, { code: "(class { static ['constructor']() {} })", output: "(class { static 'constructor'() {} })", @@ -515,6 +552,33 @@ ruleTester.run("no-useless-computed-key", rule, { data: { property: "'#foo'" }, type: "PropertyDefinition" }] + }, { + code: "(class { ['__proto__'] })", + output: "(class { '__proto__' })", + options: [{ enforceForClassMembers: true }], + errors: [{ + messageId: "unnecessarilyComputedProperty", + data: { property: "'__proto__'" }, + type: "PropertyDefinition" + }] + }, { + code: "(class { static ['__proto__'] })", + output: "(class { static '__proto__' })", + options: [{ enforceForClassMembers: true }], + errors: [{ + messageId: "unnecessarilyComputedProperty", + data: { property: "'__proto__'" }, + type: "PropertyDefinition" + }] + }, { + code: "(class { ['prototype'] })", + output: "(class { 'prototype' })", + options: [{ enforceForClassMembers: true }], + errors: [{ + messageId: "unnecessarilyComputedProperty", + data: { property: "'prototype'" }, + type: "PropertyDefinition" + }] } ] }); From f98451584a82e41f82ceacd484ea0fe90aa9ce63 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Tue, 10 Aug 2021 06:37:55 +0530 Subject: [PATCH 15/17] Chore: add assertions on reporting location in `semi` (#14899) --- tests/lib/rules/semi.js | 605 ++++++++++++++++++++++++++++++++++------ 1 file changed, 516 insertions(+), 89 deletions(-) diff --git a/tests/lib/rules/semi.js b/tests/lib/rules/semi.js index 740251bffe9..092dae15336 100644 --- a/tests/lib/rules/semi.js +++ b/tests/lib/rules/semi.js @@ -316,6 +316,7 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "ImportDeclaration", + line: 1, column: 33, endLine: void 0, endColumn: void 0 @@ -327,7 +328,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ImportDeclaration" + type: "ImportDeclaration", + line: 1, + column: 35, + endLine: void 0, + endColumn: void 0 }] }, { @@ -336,7 +341,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ImportDeclaration" + type: "ImportDeclaration", + line: 1, + column: 37, + endLine: void 0, + endColumn: void 0 }] }, { @@ -345,7 +354,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ImportDeclaration" + type: "ImportDeclaration", + line: 1, + column: 19, + endLine: void 0, + endColumn: void 0 }] }, { @@ -354,7 +367,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ImportDeclaration" + type: "ImportDeclaration", + line: 1, + column: 55, + endLine: void 0, + endColumn: void 0 }] }, { @@ -362,7 +379,11 @@ ruleTester.run("semi", rule, { output: "function foo() { return []; }", errors: [{ messageId: "missingSemi", - type: "ReturnStatement" + type: "ReturnStatement", + line: 1, + column: 27, + endLine: 1, + endColumn: 28 }] }, { @@ -370,7 +391,11 @@ ruleTester.run("semi", rule, { output: "while(true) { break; }", errors: [{ messageId: "missingSemi", - type: "BreakStatement" + type: "BreakStatement", + line: 1, + column: 20, + endLine: 1, + endColumn: 21 }] }, { @@ -378,7 +403,11 @@ ruleTester.run("semi", rule, { output: "while(true) { continue; }", errors: [{ messageId: "missingSemi", - type: "ContinueStatement" + type: "ContinueStatement", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 }] }, { @@ -387,7 +416,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 10, + endLine: void 0, + endColumn: void 0 }] }, { @@ -395,7 +428,11 @@ ruleTester.run("semi", rule, { output: "var x = 5;", errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 10, + endLine: void 0, + endColumn: void 0 }] }, { @@ -403,7 +440,11 @@ ruleTester.run("semi", rule, { output: "var x = 5, y;", errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 13, + endLine: void 0, + endColumn: void 0 }] }, { @@ -411,7 +452,11 @@ ruleTester.run("semi", rule, { output: "debugger;", errors: [{ messageId: "missingSemi", - type: "DebuggerStatement" + type: "DebuggerStatement", + line: 1, + column: 9, + endLine: void 0, + endColumn: void 0 }] }, { @@ -420,7 +465,9 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "ExpressionStatement", + line: 1, column: 6, + endLine: void 0, endColumn: void 0 }] }, @@ -430,6 +477,7 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "ExpressionStatement", + line: 1, column: 6, endLine: 2, endColumn: 1 @@ -441,6 +489,7 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "ExpressionStatement", + line: 1, column: 6, endLine: 2, endColumn: 1 @@ -452,6 +501,7 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "ExpressionStatement", + line: 1, column: 6, endLine: 2, endColumn: 1 @@ -463,6 +513,7 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "ExpressionStatement", + line: 1, column: 6, endLine: 2, endColumn: 1 @@ -473,7 +524,11 @@ ruleTester.run("semi", rule, { output: "for (var a in b) var i; ", errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 }] }, { @@ -481,7 +536,11 @@ ruleTester.run("semi", rule, { output: "for (;;){var i;}", errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 15, + endLine: 1, + endColumn: 16 }] }, { @@ -489,7 +548,11 @@ ruleTester.run("semi", rule, { output: "for (;;) var i; ", errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 15, + endLine: 1, + endColumn: 16 }] }, { @@ -497,7 +560,11 @@ ruleTester.run("semi", rule, { output: "for (var j;;) {var i;}", errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 21, + endLine: 1, + endColumn: 22 }] }, { @@ -506,7 +573,10 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "VariableDeclaration", - line: 3 + line: 3, + column: 2, + endLine: void 0, + endColumn: void 0 }] }, { @@ -515,7 +585,10 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "VariableDeclaration", - line: 1 + line: 1, + column: 8, + endLine: 2, + endColumn: 1 }] }, { @@ -524,7 +597,10 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "ThrowStatement", - line: 1 + line: 1, + column: 23, + endLine: void 0, + endColumn: void 0 }] }, { @@ -533,7 +609,10 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "missingSemi", type: "DoWhileStatement", - line: 1 + line: 1, + column: 16, + endLine: void 0, + endColumn: void 0 }] }, { @@ -541,7 +620,9 @@ ruleTester.run("semi", rule, { output: "if (foo) {bar();}", errors: [{ messageId: "missingSemi", + line: 1, column: 16, + endLine: 1, endColumn: 17 }] }, @@ -550,7 +631,9 @@ ruleTester.run("semi", rule, { output: "if (foo) {bar();} ", errors: [{ messageId: "missingSemi", + line: 1, column: 16, + endLine: 1, endColumn: 17 }] }, @@ -559,6 +642,7 @@ ruleTester.run("semi", rule, { output: "if (foo) {bar();\n}", errors: [{ messageId: "missingSemi", + line: 1, column: 16, endLine: 2, endColumn: 1 @@ -572,7 +656,10 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "extraSemi", type: "ThrowStatement", - column: 23 + line: 1, + column: 23, + endLine: 1, + endColumn: 24 }] }, { @@ -581,7 +668,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "ReturnStatement" + type: "ReturnStatement", + line: 1, + column: 27, + endLine: 1, + endColumn: 28 }] }, { @@ -590,7 +681,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "BreakStatement" + type: "BreakStatement", + line: 1, + column: 20, + endLine: 1, + endColumn: 21 }] }, { @@ -599,7 +694,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "ContinueStatement" + type: "ContinueStatement", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 }] }, { @@ -609,7 +708,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 10, + endLine: 1, + endColumn: 11 }] }, { @@ -618,7 +721,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 10, + endLine: 1, + endColumn: 11 }] }, { @@ -627,7 +734,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 13, + endLine: 1, + endColumn: 14 }] }, { @@ -636,7 +747,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "DebuggerStatement" + type: "DebuggerStatement", + line: 1, + column: 9, + endLine: 1, + endColumn: 10 }] }, { @@ -645,7 +760,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "ExpressionStatement" + type: "ExpressionStatement", + line: 1, + column: 6, + endLine: 1, + endColumn: 7 }] }, { @@ -654,7 +773,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 }] }, { @@ -663,7 +786,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 15, + endLine: 1, + endColumn: 16 }] }, { @@ -672,7 +799,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 15, + endLine: 1, + endColumn: 16 }] }, { @@ -681,7 +812,11 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 21, + endLine: 1, + endColumn: 22 }] }, { @@ -691,7 +826,10 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "extraSemi", type: "VariableDeclaration", - line: 3 + line: 3, + column: 2, + endLine: 3, + endColumn: 3 }] }, { @@ -701,7 +839,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "ImportDeclaration" + type: "ImportDeclaration", + line: 1, + column: 55, + endLine: 1, + endColumn: 56 }] }, { @@ -711,7 +853,10 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "extraSemi", type: "DoWhileStatement", - line: 1 + line: 1, + column: 16, + endLine: 1, + endColumn: 17 }] }, @@ -720,7 +865,11 @@ ruleTester.run("semi", rule, { output: "if (foo) { bar();\n }", options: ["always", { omitLastInOneLineBlock: true }], errors: [{ - messageId: "missingSemi" + messageId: "missingSemi", + line: 1, + column: 17, + endLine: 2, + endColumn: 1 }] }, { @@ -728,7 +877,11 @@ ruleTester.run("semi", rule, { output: "if (foo) {\n bar(); }", options: ["always", { omitLastInOneLineBlock: true }], errors: [{ - messageId: "missingSemi" + messageId: "missingSemi", + line: 2, + column: 7, + endLine: 2, + endColumn: 8 }] }, { @@ -736,7 +889,11 @@ ruleTester.run("semi", rule, { output: "if (foo) {\n bar(); baz(); }", options: ["always", { omitLastInOneLineBlock: true }], errors: [{ - messageId: "missingSemi" + messageId: "missingSemi", + line: 2, + column: 14, + endLine: 2, + endColumn: 15 }] }, { @@ -744,7 +901,11 @@ ruleTester.run("semi", rule, { output: "if (foo) { bar() }", options: ["always", { omitLastInOneLineBlock: true }], errors: [{ - messageId: "extraSemi" + messageId: "extraSemi", + line: 1, + column: 17, + endLine: 1, + endColumn: 18 }] }, @@ -756,7 +917,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ExportAllDeclaration" + type: "ExportAllDeclaration", + line: 1, + column: 20, + endLine: void 0, + endColumn: void 0 }] }, { @@ -765,7 +930,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ExportNamedDeclaration" + type: "ExportNamedDeclaration", + line: 1, + column: 26, + endLine: void 0, + endColumn: void 0 }] }, { @@ -774,7 +943,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ExportNamedDeclaration" + type: "ExportNamedDeclaration", + line: 1, + column: 27, + endLine: void 0, + endColumn: void 0 }] }, { @@ -783,7 +956,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 15, + endLine: void 0, + endColumn: void 0 }] }, { @@ -792,7 +969,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 15, + endLine: void 0, + endColumn: void 0 }] }, { @@ -801,7 +982,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 22, + endLine: void 0, + endColumn: void 0 }] }, { @@ -810,7 +995,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ExportDefaultDeclaration" + type: "ExportDefaultDeclaration", + line: 1, + column: 26, + endLine: void 0, + endColumn: void 0 }] }, { @@ -819,7 +1008,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ExportDefaultDeclaration" + type: "ExportDefaultDeclaration", + line: 1, + column: 34, + endLine: void 0, + endColumn: void 0 }] }, { @@ -828,7 +1021,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ExportDefaultDeclaration" + type: "ExportDefaultDeclaration", + line: 1, + column: 24, + endLine: void 0, + endColumn: void 0 }] }, { @@ -837,7 +1034,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "missingSemi", - type: "ExportDefaultDeclaration" + type: "ExportDefaultDeclaration", + line: 1, + column: 25, + endLine: void 0, + endColumn: void 0 }] }, @@ -850,7 +1051,9 @@ ruleTester.run("semi", rule, { errors: [{ messageId: "extraSemi", type: "ExportAllDeclaration", + line: 1, column: 20, + endLine: 1, endColumn: 21 }] }, @@ -861,7 +1064,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "ExportNamedDeclaration" + type: "ExportNamedDeclaration", + line: 1, + column: 26, + endLine: 1, + endColumn: 27 }] }, { @@ -871,7 +1078,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "ExportNamedDeclaration" + type: "ExportNamedDeclaration", + line: 1, + column: 27, + endLine: 1, + endColumn: 28 }] }, { @@ -881,7 +1092,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 15, + endLine: 1, + endColumn: 16 }] }, { @@ -891,7 +1106,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 15, + endLine: 1, + endColumn: 16 }] }, { @@ -901,7 +1120,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "VariableDeclaration" + type: "VariableDeclaration", + line: 1, + column: 22, + endLine: 1, + endColumn: 23 }] }, { @@ -911,7 +1134,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "ExportDefaultDeclaration" + type: "ExportDefaultDeclaration", + line: 1, + column: 26, + endLine: 1, + endColumn: 27 }] }, { @@ -921,7 +1148,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "ExportDefaultDeclaration" + type: "ExportDefaultDeclaration", + line: 1, + column: 34, + endLine: 1, + endColumn: 35 }] }, { @@ -931,7 +1162,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "ExportDefaultDeclaration" + type: "ExportDefaultDeclaration", + line: 1, + column: 24, + endLine: 1, + endColumn: 25 }] }, { @@ -941,7 +1176,11 @@ ruleTester.run("semi", rule, { parserOptions: { ecmaVersion: 6, sourceType: "module" }, errors: [{ messageId: "extraSemi", - type: "ExportDefaultDeclaration" + type: "ExportDefaultDeclaration", + line: 1, + column: 25, + endLine: 1, + endColumn: 26 }] }, { @@ -950,7 +1189,9 @@ ruleTester.run("semi", rule, { options: ["never"], errors: [{ messageId: "extraSemi", + line: 1, column: 2, + endLine: 1, endColumn: 3 }] }, @@ -969,8 +1210,20 @@ ruleTester.run("semi", rule, { ].join("\n"), options: ["never"], errors: [ - "Extra semicolon.", - "Unnecessary semicolon." + { + messageId: "extraSemi", + line: 2, + column: 6, + endLine: 2, + endColumn: 7 + }, + { + message: "Unnecessary semicolon.", + line: 3, + column: 1, + endLine: 3, + endColumn: 2 + } ] }, @@ -986,7 +1239,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "always" }], parserOptions: { ecmaVersion: 6, sourceType: "module" }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 2, + column: 34, + endLine: 3, + endColumn: 1 + }] }, { code: ` @@ -999,7 +1258,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "always" }], parserOptions: { ecmaVersion: 6, sourceType: "module" }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 2, + column: 38, + endLine: 3, + endColumn: 1 + }] }, { code: ` @@ -1016,7 +1281,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "always" }], parserOptions: { ecmaVersion: 2015 }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 3, + column: 27, + endLine: 4, + endColumn: 1 + }] }, { code: ` @@ -1032,7 +1303,13 @@ ruleTester.run("semi", rule, { } `, options: ["never", { beforeStatementContinuationChars: "always" }], - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 3, + column: 26, + endLine: 4, + endColumn: 1 + }] }, { code: ` @@ -1048,7 +1325,13 @@ ruleTester.run("semi", rule, { } `, options: ["never", { beforeStatementContinuationChars: "always" }], - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 3, + column: 29, + endLine: 4, + endColumn: 1 + }] }, { code: ` @@ -1060,7 +1343,13 @@ ruleTester.run("semi", rule, { [1,2,3].forEach(doSomething) `, options: ["never", { beforeStatementContinuationChars: "always" }], - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 2, + column: 29, + endLine: 3, + endColumn: 1 + }] }, { code: ` @@ -1073,7 +1362,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "always" }], parserOptions: { ecmaVersion: 2015 }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 2, + column: 35, + endLine: 3, + endColumn: 1 + }] }, { code: ` @@ -1086,7 +1381,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 6, sourceType: "module" }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 2, + column: 34, + endLine: 2, + endColumn: 35 + }] }, { code: ` @@ -1099,7 +1400,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 6, sourceType: "module" }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 2, + column: 38, + endLine: 2, + endColumn: 39 + }] }, { code: ` @@ -1116,7 +1423,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 2015 }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 3, + column: 27, + endLine: 3, + endColumn: 28 + }] }, { code: ` @@ -1132,7 +1445,13 @@ ruleTester.run("semi", rule, { } `, options: ["never", { beforeStatementContinuationChars: "never" }], - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 3, + column: 26, + endLine: 3, + endColumn: 27 + }] }, { code: ` @@ -1148,7 +1467,13 @@ ruleTester.run("semi", rule, { } `, options: ["never", { beforeStatementContinuationChars: "never" }], - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 3, + column: 29, + endLine: 3, + endColumn: 30 + }] }, { code: ` @@ -1160,7 +1485,13 @@ ruleTester.run("semi", rule, { [1,2,3].forEach(doSomething) `, options: ["never", { beforeStatementContinuationChars: "never" }], - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 2, + column: 29, + endLine: 2, + endColumn: 30 + }] }, { code: ` @@ -1173,7 +1504,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 2015 }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 2, + column: 35, + endLine: 2, + endColumn: 36 + }] }, { code: ` @@ -1186,7 +1523,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 6, sourceType: "module" }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 3, + column: 17, + endLine: 3, + endColumn: 18 + }] }, { code: ` @@ -1199,7 +1542,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 6, sourceType: "module" }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 3, + column: 17, + endLine: 3, + endColumn: 18 + }] }, { code: ` @@ -1215,7 +1564,13 @@ ruleTester.run("semi", rule, { } `, options: ["never", { beforeStatementContinuationChars: "never" }], - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 4, + column: 21, + endLine: 4, + endColumn: 22 + }] }, { code: ` @@ -1231,7 +1586,13 @@ ruleTester.run("semi", rule, { } `, options: ["never", { beforeStatementContinuationChars: "never" }], - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 4, + column: 21, + endLine: 4, + endColumn: 22 + }] }, { code: ` @@ -1247,7 +1608,13 @@ ruleTester.run("semi", rule, { } `, options: ["never", { beforeStatementContinuationChars: "never" }], - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 4, + column: 21, + endLine: 4, + endColumn: 22 + }] }, { code: ` @@ -1259,7 +1626,13 @@ ruleTester.run("semi", rule, { [1,2,3].forEach(doSomething) `, options: ["never", { beforeStatementContinuationChars: "never" }], - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 3, + column: 17, + endLine: 3, + endColumn: 18 + }] }, { code: ` @@ -1272,7 +1645,13 @@ ruleTester.run("semi", rule, { `, options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 2015 }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 3, + column: 17, + endLine: 3, + endColumn: 18 + }] }, // Class fields @@ -1280,56 +1659,104 @@ ruleTester.run("semi", rule, { code: "class C { foo }", output: "class C { foo; }", parserOptions: { ecmaVersion: 2022 }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 1, + column: 14, + endLine: 1, + endColumn: 15 + }] }, { code: "class C { foo }", output: "class C { foo; }", options: ["always"], parserOptions: { ecmaVersion: 2022 }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 1, + column: 14, + endLine: 1, + endColumn: 15 + }] }, { code: "class C { foo; }", output: "class C { foo }", options: ["never"], parserOptions: { ecmaVersion: 2022 }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 1, + column: 14, + endLine: 1, + endColumn: 15 + }] }, { code: "class C { foo\n[bar]; }", output: "class C { foo;\n[bar]; }", options: ["always"], parserOptions: { ecmaVersion: 2022 }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 1, + column: 14, + endLine: 2, + endColumn: 1 + }] }, { code: "class C { foo\n[bar] }", output: "class C { foo;\n[bar] }", options: ["never", { beforeStatementContinuationChars: "always" }], parserOptions: { ecmaVersion: 2022 }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 1, + column: 14, + endLine: 2, + endColumn: 1 + }] }, { code: "class C { foo\n;[bar] }", output: "class C { foo\n[bar] }", options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 2022 }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 2, + column: 1, + endLine: 2, + endColumn: 2 + }] }, { code: "class C { foo = () => {}\n[bar] }", output: "class C { foo = () => {};\n[bar] }", options: ["never", { beforeStatementContinuationChars: "always" }], parserOptions: { ecmaVersion: 2022 }, - errors: ["Missing semicolon."] + errors: [{ + messageId: "missingSemi", + line: 1, + column: 25, + endLine: 2, + endColumn: 1 + }] }, { code: "class C { foo = () => {}\n;[bar] }", output: "class C { foo = () => {}\n[bar] }", options: ["never", { beforeStatementContinuationChars: "never" }], parserOptions: { ecmaVersion: 2022 }, - errors: ["Extra semicolon."] + errors: [{ + messageId: "extraSemi", + line: 2, + column: 1, + endLine: 2, + endColumn: 2 + }] } ] }); From 62c6fe7d10ff4eeebd196e143f96cfd88818393d Mon Sep 17 00:00:00 2001 From: sandesh bafna Date: Tue, 10 Aug 2021 06:39:23 +0530 Subject: [PATCH 16/17] Upgrade: Debug 4.0.1 > 4.3.2 (#14892) * Updated debug library version to avoid vulnerabilities scan error * update --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 746d6cc7003..275554884bd 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", From 3b6cd8934b3640ffb6fa49b471babf07f0ad769a Mon Sep 17 00:00:00 2001 From: Bryan Mishkin <698306+bmish@users.noreply.github.com> Date: Tue, 10 Aug 2021 19:11:52 -0500 Subject: [PATCH 17/17] Chore: Add rel/abs path tests in `no-restricted-{imports/modules}` rules (#14910) --- tests/lib/rules/no-restricted-imports.js | 79 +++++++++++++++++++++++ tests/lib/rules/no-restricted-modules.js | 81 +++++++++++++++++++++++- 2 files changed, 159 insertions(+), 1 deletion(-) diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js index f54d4df0354..c86e67ecf65 100644 --- a/tests/lib/rules/no-restricted-imports.js +++ b/tests/lib/rules/no-restricted-imports.js @@ -29,6 +29,19 @@ ruleTester.run("no-restricted-imports", rule, { { code: "import \"foo/bar\";", options: ["foo"] }, { code: "import withPaths from \"foo/bar\";", options: [{ paths: ["foo", "bar"] }] }, { code: "import withPatterns from \"foo/bar\";", options: [{ patterns: ["foo/c*"] }] }, + { code: "import foo from 'foo';", options: ["../foo"] }, + { code: "import foo from 'foo';", options: [{ paths: ["../foo"] }] }, + { code: "import foo from 'foo';", options: [{ patterns: ["../foo"] }] }, + { code: "import foo from 'foo';", options: ["/foo"] }, + { code: "import foo from 'foo';", options: [{ paths: ["/foo"] }] }, + "import relative from '../foo';", + { code: "import relative from '../foo';", options: ["../notFoo"] }, + { code: "import relativeWithPaths from '../foo';", options: [{ paths: ["../notFoo"] }] }, + { code: "import relativeWithPatterns from '../foo';", options: [{ patterns: ["notFoo"] }] }, + "import absolute from '/foo';", + { code: "import absolute from '/foo';", options: ["/notFoo"] }, + { code: "import absoluteWithPaths from '/foo';", options: [{ paths: ["/notFoo"] }] }, + { code: "import absoluteWithPatterns from '/foo';", options: [{ patterns: ["notFoo"] }] }, { code: "import withPatternsAndPaths from \"foo/bar\";", options: [{ paths: ["foo"], patterns: ["foo/c*"] }] @@ -815,6 +828,72 @@ ruleTester.run("no-restricted-imports", rule, { column: 15, endColumn: 29 }] + }, + { + code: "import relative from '../foo';", + options: ["../foo"], + errors: [{ + message: "'../foo' import is restricted from being used.", + type: "ImportDeclaration", + line: 1, + column: 1, + endColumn: 31 + }] + }, + { + code: "import relativeWithPaths from '../foo';", + options: [{ paths: ["../foo"] }], + errors: [{ + message: "'../foo' import is restricted from being used.", + type: "ImportDeclaration", + line: 1, + column: 1, + endColumn: 40 + }] + }, + { + code: "import relativeWithPatterns from '../foo';", + options: [{ patterns: ["../foo"] }], + errors: [{ + message: "'../foo' import is restricted from being used by a pattern.", + type: "ImportDeclaration", + line: 1, + column: 1, + endColumn: 43 + }] + }, + { + code: "import absolute from '/foo';", + options: ["/foo"], + errors: [{ + message: "'/foo' import is restricted from being used.", + type: "ImportDeclaration", + line: 1, + column: 1, + endColumn: 29 + }] + }, + { + code: "import absoluteWithPaths from '/foo';", + options: [{ paths: ["/foo"] }], + errors: [{ + message: "'/foo' import is restricted from being used.", + type: "ImportDeclaration", + line: 1, + column: 1, + endColumn: 38 + }] + }, + { + code: "import absoluteWithPatterns from '/foo';", + options: [{ patterns: ["foo"] }], + errors: [{ + message: "'/foo' import is restricted from being used by a pattern.", + type: "ImportDeclaration", + line: 1, + column: 1, + endColumn: 41 + }] } ] }); diff --git a/tests/lib/rules/no-restricted-modules.js b/tests/lib/rules/no-restricted-modules.js index 08cc7c092f5..5e89a6a7329 100644 --- a/tests/lib/rules/no-restricted-modules.js +++ b/tests/lib/rules/no-restricted-modules.js @@ -32,7 +32,20 @@ ruleTester.run("no-restricted-modules", rule, { { code: "var withPatternsAndPaths = require(\"foo/bar\");", options: [{ paths: ["foo"], patterns: ["foo/c*"] }] }, { code: "var withGitignores = require(\"foo/bar\");", options: [{ paths: ["foo"], patterns: ["foo/*", "!foo/bar"] }] }, { code: "require(`fs`)", options: ["crypto"], parserOptions: { ecmaVersion: 6 } }, - { code: "require(`foo${bar}`)", options: ["foo"], parserOptions: { ecmaVersion: 6 } } + { code: "require(`foo${bar}`)", options: ["foo"], parserOptions: { ecmaVersion: 6 } }, + { code: "var foo = require('foo');", options: ["../foo"] }, + { code: "var foo = require('foo');", options: [{ paths: ["../foo"] }] }, + { code: "var foo = require('foo');", options: [{ patterns: ["../foo"] }] }, + { code: "var foo = require('foo');", options: ["/foo"] }, + { code: "var foo = require('foo');", options: [{ paths: ["/foo"] }] }, + "var relative = require('../foo');", + { code: "var relative = require('../foo');", options: ["../notFoo"] }, + { code: "var relativeWithPaths = require('../foo');", options: [{ paths: ["../notFoo"] }] }, + { code: "var relativeWithPatterns = require('../foo');", options: [{ patterns: ["notFoo"] }] }, + "var absolute = require('/foo');", + { code: "var absolute = require('/foo');", options: ["/notFoo"] }, + { code: "var absoluteWithPaths = require('/foo');", options: [{ paths: ["/notFoo"] }] }, + { code: "var absoluteWithPatterns = require('/foo');", options: [{ patterns: ["notFoo"] }] } ], invalid: [{ code: "require(\"fs\")", @@ -111,5 +124,71 @@ ruleTester.run("no-restricted-modules", rule, { options: ["crypto"], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "defaultMessage", data: { name: "crypto" }, type: "CallExpression" }] + }, + { + code: "var relative = require('../foo');", + options: ["../foo"], + errors: [{ + message: "'../foo' module is restricted from being used.", + type: "CallExpression", + line: 1, + column: 16, + endColumn: 33 + }] + }, + { + code: "var relativeWithPaths = require('../foo');", + options: [{ paths: ["../foo"] }], + errors: [{ + message: "'../foo' module is restricted from being used.", + type: "CallExpression", + line: 1, + column: 25, + endColumn: 42 + }] + }, + { + code: "var relativeWithPatterns = require('../foo');", + options: [{ patterns: ["../foo"] }], + errors: [{ + message: "'../foo' module is restricted from being used by a pattern.", + type: "CallExpression", + line: 1, + column: 28, + endColumn: 45 + }] + }, + { + code: "var absolute = require('/foo');", + options: ["/foo"], + errors: [{ + message: "'/foo' module is restricted from being used.", + type: "CallExpression", + line: 1, + column: 16, + endColumn: 31 + }] + }, + { + code: "var absoluteWithPaths = require('/foo');", + options: [{ paths: ["/foo"] }], + errors: [{ + message: "'/foo' module is restricted from being used.", + type: "CallExpression", + line: 1, + column: 25, + endColumn: 40 + }] + }, + { + code: "var absoluteWithPatterns = require('/foo');", + options: [{ patterns: ["foo"] }], + errors: [{ + message: "'/foo' module is restricted from being used by a pattern.", + type: "CallExpression", + line: 1, + column: 28, + endColumn: 43 + }] }] });