]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/lib/rules/prefer-const.js
2 * @fileoverview Tests for prefer-const rule.
3 * @author Toru Nagashima
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const rule
= require("../../../lib/rules/prefer-const"),
13 fixtureParser
= require("../../fixtures/fixture-parser"),
14 { RuleTester
} = require("../../../lib/rule-tester");
16 //------------------------------------------------------------------------------
18 //------------------------------------------------------------------------------
20 const ruleTester
= new RuleTester({ parserOptions
: { ecmaVersion
: 6 } });
22 ruleTester
.defineRule("use-x", context
=> ({
23 VariableDeclaration() {
24 context
.markVariableAsUsed("x");
28 ruleTester
.run("prefer-const", rule
, {
32 "let x; { x = 0; } foo(x);",
35 "for (let i = 0, end = 10; i < end; ++i) {}",
36 "for (let i in [1,2,3]) { i = 0; }",
37 "for (let x of [1,2,3]) { x = 0; }",
38 "(function() { var x = 0; })();",
39 "(function() { let x; })();",
40 "(function() { let x; { x = 0; } foo(x); })();",
41 "(function() { let x = 0; x = 1; })();",
42 "(function() { const x = 0; })();",
43 "(function() { for (let i = 0, end = 10; i < end; ++i) {} })();",
44 "(function() { for (let i in [1,2,3]) { i = 0; } })();",
45 "(function() { for (let x of [1,2,3]) { x = 0; } })();",
46 "(function(x = 0) { })();",
47 "let a; while (a = foo());",
48 "let a; do {} while (a = foo());",
49 "let a; for (; a = foo(); );",
50 "let a; for (;; ++a);",
51 "let a; for (const {b = ++a} in foo());",
52 "let a; for (const {b = ++a} of foo());",
53 "let a; for (const x of [1,2,3]) { if (a) {} a = foo(); }",
54 "let a; for (const x of [1,2,3]) { a = a || foo(); bar(a); }",
55 "let a; for (const x of [1,2,3]) { foo(++a); }",
56 "let a; function foo() { if (a) {} a = bar(); }",
57 "let a; function foo() { a = a || bar(); baz(a); }",
58 "let a; function foo() { bar(++a); }",
62 " if (typeof id !== 'undefined') {",
65 " id = setInterval(() => {}, 250);",
69 "/*exported a*/ let a; function init() { a = foo(); }",
70 "/*exported a*/ let a = 1",
71 "let a; if (true) a = 0; foo(a);",
84 "var a; { var b; ({ a, b } = obj); }",
85 "let a; { let b; ({ a, b } = obj); }",
86 "var a; { var b; ([ a, b ] = obj); }",
87 "let a; { let b; ([ a, b ] = obj); }",
90 * The assignment is located in a different scope.
91 * Those are warned by prefer-smaller-scope.
93 "let x; { x = 0; foo(x); }",
94 "(function() { let x; { x = 0; foo(x); } })();",
95 "let x; for (const a of [1,2,3]) { x = foo(); bar(x); }",
96 "(function() { let x; for (const a of [1,2,3]) { x = foo(); bar(x); } })();",
97 "let x; for (x of array) { x; }",
100 code
: "let {a, b} = obj; b = 0;",
101 options
: [{ destructuring
: "all" }]
104 code
: "let a, b; ({a, b} = obj); b++;",
105 options
: [{ destructuring
: "all" }]
108 // https://github.com/eslint/eslint/issues/8187
110 code
: "let { name, ...otherStuff } = obj; otherStuff = {};",
111 options
: [{ destructuring
: "all" }],
112 parserOptions
: { ecmaVersion
: 2018 }
115 code
: "let { name, ...otherStuff } = obj; otherStuff = {};",
116 options
: [{ destructuring
: "all" }],
117 parser
: fixtureParser("babel-eslint5/destructuring-object-spread")
120 // https://github.com/eslint/eslint/issues/8308
122 code
: "let predicate; [typeNode.returnType, predicate] = foo();",
123 parserOptions
: { ecmaVersion
: 2018 }
126 code
: "let predicate; [typeNode.returnType, ...predicate] = foo();",
127 parserOptions
: { ecmaVersion
: 2018 }
131 // intentionally testing empty slot in destructuring assignment
132 code
: "let predicate; [typeNode.returnType,, predicate] = foo();",
133 parserOptions
: { ecmaVersion
: 2018 }
136 code
: "let predicate; [typeNode.returnType=5, predicate] = foo();",
137 parserOptions
: { ecmaVersion
: 2018 }
140 code
: "let predicate; [[typeNode.returnType=5], predicate] = foo();",
141 parserOptions
: { ecmaVersion
: 2018 }
144 code
: "let predicate; [[typeNode.returnType, predicate]] = foo();",
145 parserOptions
: { ecmaVersion
: 2018 }
148 code
: "let predicate; [typeNode.returnType, [predicate]] = foo();",
149 parserOptions
: { ecmaVersion
: 2018 }
152 code
: "let predicate; [, [typeNode.returnType, predicate]] = foo();",
153 parserOptions
: { ecmaVersion
: 2018 }
156 code
: "let predicate; [, {foo:typeNode.returnType, predicate}] = foo();",
157 parserOptions
: { ecmaVersion
: 2018 }
160 code
: "let predicate; [, {foo:typeNode.returnType, ...predicate}] = foo();",
161 parserOptions
: { ecmaVersion
: 2018 }
164 code
: "let a; const b = {}; ({ a, c: b.c } = func());",
165 parserOptions
: { ecmaVersion
: 2018 }
168 // ignoreReadBeforeAssign
170 code
: "let x; function foo() { bar(x); } x = 0;",
171 options
: [{ ignoreReadBeforeAssign
: true }]
174 // https://github.com/eslint/eslint/issues/10520
175 "const x = [1,2]; let y; [,y] = x; y = 0;",
176 "const x = [1,2,3]; let y, z; [y,,z] = x; y = 0; z = 0;",
179 code
: "class C { static { let a = 1; a = 2; } }",
180 parserOptions
: { ecmaVersion
: 2022 }
183 code
: "class C { static { let a; a = 1; a = 2; } }",
184 parserOptions
: { ecmaVersion
: 2022 }
187 code
: "let a; class C { static { a = 1; } }",
188 parserOptions
: { ecmaVersion
: 2022 }
191 code
: "class C { static { let a; if (foo) { a = 1; } } }",
192 parserOptions
: { ecmaVersion
: 2022 }
195 code
: "class C { static { let a; if (foo) a = 1; } }",
196 parserOptions
: { ecmaVersion
: 2022 }
199 code
: "class C { static { let a, b; if (foo) { ({ a, b } = foo); } } }",
201 parserOptions
: { ecmaVersion
: 2022 },
203 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
204 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" }
208 code
: "class C { static { let a, b; if (foo) ({ a, b } = foo); } }",
210 parserOptions
: { ecmaVersion
: 2022 },
212 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
213 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" }
217 code
: "class C { static { a; } } let a = 1; ",
218 options
: [{ ignoreReadBeforeAssign
: true }],
219 parserOptions
: { ecmaVersion
: 2022 }
222 code
: "class C { static { () => a; let a = 1; } };",
223 options
: [{ ignoreReadBeforeAssign
: true }],
224 parserOptions
: { ecmaVersion
: 2022 }
229 code
: "let x = 1; foo(x);",
230 output
: "const x = 1; foo(x);",
231 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
234 code
: "for (let i in [1,2,3]) { foo(i); }",
235 output
: "for (const i in [1,2,3]) { foo(i); }",
236 errors
: [{ messageId
: "useConst", data
: { name
: "i" }, type
: "Identifier" }]
239 code
: "for (let x of [1,2,3]) { foo(x); }",
240 output
: "for (const x of [1,2,3]) { foo(x); }",
241 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
244 code
: "let [x = -1, y] = [1,2]; y = 0;",
246 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
249 code
: "let {a: x = -1, b: y} = {a:1,b:2}; y = 0;",
251 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
254 code
: "(function() { let x = 1; foo(x); })();",
255 output
: "(function() { const x = 1; foo(x); })();",
256 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
259 code
: "(function() { for (let i in [1,2,3]) { foo(i); } })();",
260 output
: "(function() { for (const i in [1,2,3]) { foo(i); } })();",
261 errors
: [{ messageId
: "useConst", data
: { name
: "i" }, type
: "Identifier" }]
264 code
: "(function() { for (let x of [1,2,3]) { foo(x); } })();",
265 output
: "(function() { for (const x of [1,2,3]) { foo(x); } })();",
266 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
269 code
: "(function() { let [x = -1, y] = [1,2]; y = 0; })();",
271 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
274 code
: "let f = (function() { let g = x; })(); f = 1;",
275 output
: "let f = (function() { const g = x; })(); f = 1;",
276 errors
: [{ messageId
: "useConst", data
: { name
: "g" }, type
: "Identifier" }]
279 code
: "(function() { let {a: x = -1, b: y} = {a:1,b:2}; y = 0; })();",
281 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
284 code
: "let x = 0; { let x = 1; foo(x); } x = 0;",
285 output
: "let x = 0; { const x = 1; foo(x); } x = 0;",
286 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
289 code
: "for (let i = 0; i < 10; ++i) { let x = 1; foo(x); }",
290 output
: "for (let i = 0; i < 10; ++i) { const x = 1; foo(x); }",
291 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
294 code
: "for (let i in [1,2,3]) { let x = 1; foo(x); }",
295 output
: "for (const i in [1,2,3]) { const x = 1; foo(x); }",
297 { messageId
: "useConst", data
: { name
: "i" }, type
: "Identifier" },
298 { messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }
303 "var foo = function() {",
304 " for (const b of c) {",
312 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }
317 "var foo = function() {",
318 " for (const b of c) {",
326 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }
331 code
: "let x; x = 0;",
333 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier", column
: 8 }]
336 code
: "switch (a) { case 0: let x; x = 0; }",
338 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier", column
: 29 }]
341 code
: "(function() { let x; x = 1; })();",
343 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier", column
: 22 }]
347 code
: "let {a = 0, b} = obj; b = 0; foo(a, b);",
349 options
: [{ destructuring
: "any" }],
350 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }]
353 code
: "let {a: {b, c}} = {a: {b: 1, c: 2}}; b = 3;",
355 options
: [{ destructuring
: "any" }],
356 errors
: [{ messageId
: "useConst", data
: { name
: "c" }, type
: "Identifier" }]
359 code
: "let {a: {b, c}} = {a: {b: 1, c: 2}}",
360 output
: "const {a: {b, c}} = {a: {b: 1, c: 2}}",
361 options
: [{ destructuring
: "all" }],
363 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" },
364 { messageId
: "useConst", data
: { name
: "c" }, type
: "Identifier" }
368 code
: "let a, b; ({a = 0, b} = obj); b = 0; foo(a, b);",
370 options
: [{ destructuring
: "any" }],
371 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }]
374 code
: "let {a = 0, b} = obj; foo(a, b);",
375 output
: "const {a = 0, b} = obj; foo(a, b);",
376 options
: [{ destructuring
: "all" }],
378 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
379 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" }
383 code
: "let [a] = [1]",
384 output
: "const [a] = [1]",
387 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }
391 code
: "let {a} = obj",
392 output
: "const {a} = obj",
395 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }
399 code
: "let a, b; ({a = 0, b} = obj); foo(a, b);",
401 options
: [{ destructuring
: "all" }],
403 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
404 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" }
408 code
: "let {a = 0, b} = obj, c = a; b = a;",
410 options
: [{ destructuring
: "any" }],
412 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
413 { messageId
: "useConst", data
: { name
: "c" }, type
: "Identifier" }
417 code
: "let {a = 0, b} = obj, c = a; b = a;",
419 options
: [{ destructuring
: "all" }],
420 errors
: [{ messageId
: "useConst", data
: { name
: "c" }, type
: "Identifier" }]
423 // https://github.com/eslint/eslint/issues/8187
425 code
: "let { name, ...otherStuff } = obj; otherStuff = {};",
427 options
: [{ destructuring
: "any" }],
428 parserOptions
: { ecmaVersion
: 2018 },
429 errors
: [{ messageId
: "useConst", data
: { name
: "name" }, type
: "Identifier", column
: 7 }]
432 code
: "let { name, ...otherStuff } = obj; otherStuff = {};",
434 options
: [{ destructuring
: "any" }],
435 parser
: fixtureParser("babel-eslint5/destructuring-object-spread"),
436 errors
: [{ messageId
: "useConst", data
: { name
: "name" }, type
: "Identifier", column
: 7 }]
439 // Warnings are located at declaration if there are reading references before assignments.
441 code
: "let x; function foo() { bar(x); } x = 0;",
443 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier", column
: 5 }]
446 // https://github.com/eslint/eslint/issues/5837
448 code
: "/*eslint use-x:error*/ let x = 1",
449 output
: "/*eslint use-x:error*/ const x = 1",
450 parserOptions
: { ecmaFeatures
: { globalReturn
: true } },
451 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
454 code
: "/*eslint use-x:error*/ { let x = 1 }",
455 output
: "/*eslint use-x:error*/ { const x = 1 }",
456 errors
: [{ messageId
: "useConst", data
: { name
: "x" }, type
: "Identifier" }]
459 code
: "let { foo, bar } = baz;",
460 output
: "const { foo, bar } = baz;",
462 { messageId
: "useConst", data
: { name
: "foo" }, type
: "Identifier" },
463 { messageId
: "useConst", data
: { name
: "bar" }, type
: "Identifier" }
467 // https://github.com/eslint/eslint/issues/10520
469 code
: "const x = [1,2]; let [,y] = x;",
470 output
: "const x = [1,2]; const [,y] = x;",
471 errors
: [{ messageId
: "useConst", data
: { name
: "y" }, type
: "Identifier" }]
474 code
: "const x = [1,2,3]; let [y,,z] = x;",
475 output
: "const x = [1,2,3]; const [y,,z] = x;",
477 { messageId
: "useConst", data
: { name
: "y" }, type
: "Identifier" },
478 { messageId
: "useConst", data
: { name
: "z" }, type
: "Identifier" }
482 // https://github.com/eslint/eslint/issues/8308
484 code
: "let predicate; [, {foo:returnType, predicate}] = foo();",
486 parserOptions
: { ecmaVersion
: 2018 },
488 { message
: "'predicate' is never reassigned. Use 'const' instead.", type
: "Identifier" }
492 code
: "let predicate; [, {foo:returnType, predicate}, ...bar ] = foo();",
494 parserOptions
: { ecmaVersion
: 2018 },
496 { message
: "'predicate' is never reassigned. Use 'const' instead.", type
: "Identifier" }
500 code
: "let predicate; [, {foo:returnType, ...predicate} ] = foo();",
502 parserOptions
: { ecmaVersion
: 2018 },
504 { message
: "'predicate' is never reassigned. Use 'const' instead.", type
: "Identifier" }
508 code
: "let x = 'x', y = 'y';",
509 output
: "const x = 'x', y = 'y';",
511 { message
: "'x' is never reassigned. Use 'const' instead.", type
: "Identifier" },
512 { message
: "'y' is never reassigned. Use 'const' instead.", type
: "Identifier" }
516 code
: "let x = 'x', y = 'y'; x = 1",
519 { message
: "'y' is never reassigned. Use 'const' instead.", type
: "Identifier" }
523 code
: "let x = 1, y = 'y'; let z = 1;",
524 output
: "const x = 1, y = 'y'; const z = 1;",
526 { message
: "'x' is never reassigned. Use 'const' instead.", type
: "Identifier" },
527 { message
: "'y' is never reassigned. Use 'const' instead.", type
: "Identifier" },
528 { message
: "'z' is never reassigned. Use 'const' instead.", type
: "Identifier" }
532 code
: "let { a, b, c} = obj; let { x, y, z} = anotherObj; x = 2;",
533 output
: "const { a, b, c} = obj; let { x, y, z} = anotherObj; x = 2;",
535 { message
: "'a' is never reassigned. Use 'const' instead.", type
: "Identifier" },
536 { message
: "'b' is never reassigned. Use 'const' instead.", type
: "Identifier" },
537 { message
: "'c' is never reassigned. Use 'const' instead.", type
: "Identifier" },
538 { message
: "'y' is never reassigned. Use 'const' instead.", type
: "Identifier" },
539 { message
: "'z' is never reassigned. Use 'const' instead.", type
: "Identifier" }
543 code
: "let x = 'x', y = 'y'; function someFunc() { let a = 1, b = 2; foo(a, b) }",
544 output
: "const x = 'x', y = 'y'; function someFunc() { const a = 1, b = 2; foo(a, b) }",
546 { message
: "'x' is never reassigned. Use 'const' instead.", type
: "Identifier" },
547 { message
: "'y' is never reassigned. Use 'const' instead.", type
: "Identifier" },
548 { message
: "'a' is never reassigned. Use 'const' instead.", type
: "Identifier" },
549 { message
: "'b' is never reassigned. Use 'const' instead.", type
: "Identifier" }
553 // The inner `let` will be auto-fixed in the second pass
555 code
: "let someFunc = () => { let a = 1, b = 2; foo(a, b) }",
556 output
: "const someFunc = () => { let a = 1, b = 2; foo(a, b) }",
558 { message
: "'someFunc' is never reassigned. Use 'const' instead.", type
: "Identifier" },
559 { message
: "'a' is never reassigned. Use 'const' instead.", type
: "Identifier" },
560 { message
: "'b' is never reassigned. Use 'const' instead.", type
: "Identifier" }
564 // https://github.com/eslint/eslint/issues/11699
566 code
: "let {a, b} = c, d;",
569 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
570 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" }
574 code
: "let {a, b, c} = {}, e, f;",
577 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
578 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" },
579 { messageId
: "useConst", data
: { name
: "c" }, type
: "Identifier" }
597 { message
: "'bar' is never reassigned. Use 'const' instead.", type
: "Identifier" },
598 { message
: "'bar' is never reassigned. Use 'const' instead.", type
: "Identifier" }
602 // https://github.com/eslint/eslint/issues/13899
604 code
: "/*eslint no-undef-init:error*/ let foo = undefined;",
605 output
: "/*eslint no-undef-init:error*/ const foo = undefined;",
610 code
: "let a = 1; class C { static { a; } }",
611 output
: "const a = 1; class C { static { a; } }",
612 parserOptions
: { ecmaVersion
: 2022 },
613 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }]
617 // this is a TDZ error with either `let` or `const`, but that isn't a concern of this rule
618 code
: "class C { static { a; } } let a = 1;",
619 output
: "class C { static { a; } } const a = 1;",
620 parserOptions
: { ecmaVersion
: 2022 },
621 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }]
624 code
: "class C { static { let a = 1; } }",
625 output
: "class C { static { const a = 1; } }",
626 parserOptions
: { ecmaVersion
: 2022 },
627 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }]
630 code
: "class C { static { if (foo) { let a = 1; } } }",
631 output
: "class C { static { if (foo) { const a = 1; } } }",
632 parserOptions
: { ecmaVersion
: 2022 },
633 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }]
636 code
: "class C { static { let a = 1; if (foo) { a; } } }",
637 output
: "class C { static { const a = 1; if (foo) { a; } } }",
638 parserOptions
: { ecmaVersion
: 2022 },
639 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }]
642 code
: "class C { static { if (foo) { let a; a = 1; } } }",
644 parserOptions
: { ecmaVersion
: 2022 },
645 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }]
648 code
: "class C { static { let a; a = 1; } }",
650 parserOptions
: { ecmaVersion
: 2022 },
651 errors
: [{ messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier", column
: 27 }]
654 code
: "class C { static { let { a, b } = foo; } }",
655 output
: "class C { static { const { a, b } = foo; } }",
656 parserOptions
: { ecmaVersion
: 2022 },
658 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
659 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" }
663 code
: "class C { static { let a, b; ({ a, b } = foo); } }",
665 parserOptions
: { ecmaVersion
: 2022 },
667 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
668 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" }
672 code
: "class C { static { let a; let b; ({ a, b } = foo); } }",
674 parserOptions
: { ecmaVersion
: 2022 },
676 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" },
677 { messageId
: "useConst", data
: { name
: "b" }, type
: "Identifier" }
681 code
: "class C { static { let a; a = 0; console.log(a); } }",
683 parserOptions
: { ecmaVersion
: 2022 },
685 { messageId
: "useConst", data
: { name
: "a" }, type
: "Identifier" }