]> git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/lib/rules/no-unreachable.js
import 8.3.0 source
[pve-eslint.git] / eslint / tests / lib / rules / no-unreachable.js
1 /**
2 * @fileoverview Tests for no-unreachable rule.
3 * @author Joel Feenstra
4 */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Requirements
10 //------------------------------------------------------------------------------
11
12 const rule = require("../../../lib/rules/no-unreachable"),
13 { RuleTester } = require("../../../lib/rule-tester");
14
15 //------------------------------------------------------------------------------
16 // Tests
17 //------------------------------------------------------------------------------
18
19 const ruleTester = new RuleTester();
20
21 ruleTester.run("no-unreachable", rule, {
22 valid: [
23 "function foo() { function bar() { return 1; } return bar(); }",
24 "function foo() { return bar(); function bar() { return 1; } }",
25 "function foo() { return x; var x; }",
26 "function foo() { var x = 1; var y = 2; }",
27 "function foo() { var x = 1; var y = 2; return; }",
28 "while (true) { switch (foo) { case 1: x = 1; x = 2;} }",
29 "while (true) { break; var x; }",
30 "while (true) { continue; var x, y; }",
31 "while (true) { throw 'message'; var x; }",
32 "while (true) { if (true) break; var x = 1; }",
33 "while (true) continue;",
34 "switch (foo) { case 1: break; var x; }",
35 "switch (foo) { case 1: break; var x; default: throw true; };",
36 {
37 code: "const arrow_direction = arrow => { switch (arrow) { default: throw new Error(); };}",
38 parserOptions: {
39 ecmaVersion: 6
40 }
41 },
42 "var x = 1; y = 2; throw 'uh oh'; var y;",
43 "function foo() { var x = 1; if (x) { return; } x = 2; }",
44 "function foo() { var x = 1; if (x) { } else { return; } x = 2; }",
45 "function foo() { var x = 1; switch (x) { case 0: break; default: return; } x = 2; }",
46 "function foo() { var x = 1; while (x) { return; } x = 2; }",
47 "function foo() { var x = 1; for (x in {}) { return; } x = 2; }",
48 "function foo() { var x = 1; try { return; } finally { x = 2; } }",
49 "function foo() { var x = 1; for (;;) { if (x) break; } x = 2; }",
50 "A: { break A; } foo()",
51 {
52 code: "function* foo() { try { yield 1; return; } catch (err) { return err; } }",
53 parserOptions: {
54 ecmaVersion: 6
55 }
56 },
57 {
58 code: "function foo() { try { bar(); return; } catch (err) { return err; } }",
59 parserOptions: {
60 ecmaVersion: 6
61 }
62 },
63 {
64 code: "function foo() { try { a.b.c = 1; return; } catch (err) { return err; } }",
65 parserOptions: {
66 ecmaVersion: 6
67 }
68 },
69 {
70 code: "class C { foo = reachable; }",
71 parserOptions: { ecmaVersion: 2022 }
72 },
73 {
74 code: "class C { foo = reachable; constructor() {} }",
75 parserOptions: { ecmaVersion: 2022 }
76 },
77 {
78 code: "class C extends B { foo = reachable; }",
79 parserOptions: { ecmaVersion: 2022 }
80 },
81 {
82 code: "class C extends B { foo = reachable; constructor() { super(); } }",
83 parserOptions: { ecmaVersion: 2022 }
84 },
85 {
86 code: "class C extends B { static foo = reachable; constructor() {} }",
87 parserOptions: { ecmaVersion: 2022 }
88 }
89 ],
90 invalid: [
91 { code: "function foo() { return x; var x = 1; }", errors: [{ messageId: "unreachableCode", type: "VariableDeclaration" }] },
92 { code: "function foo() { return x; var x, y = 1; }", errors: [{ messageId: "unreachableCode", type: "VariableDeclaration" }] },
93 { code: "while (true) { continue; var x = 1; }", errors: [{ messageId: "unreachableCode", type: "VariableDeclaration" }] },
94 { code: "function foo() { return; x = 1; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
95 { code: "function foo() { throw error; x = 1; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
96 { code: "while (true) { break; x = 1; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
97 { code: "while (true) { continue; x = 1; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
98 { code: "function foo() { switch (foo) { case 1: return; x = 1; } }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
99 { code: "function foo() { switch (foo) { case 1: throw e; x = 1; } }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
100 { code: "while (true) { switch (foo) { case 1: break; x = 1; } }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
101 { code: "while (true) { switch (foo) { case 1: continue; x = 1; } }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
102 { code: "var x = 1; throw 'uh oh'; var y = 2;", errors: [{ messageId: "unreachableCode", type: "VariableDeclaration" }] },
103 { code: "function foo() { var x = 1; if (x) { return; } else { throw e; } x = 2; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
104 { code: "function foo() { var x = 1; if (x) return; else throw -1; x = 2; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
105 { code: "function foo() { var x = 1; try { return; } finally {} x = 2; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
106 { code: "function foo() { var x = 1; try { } finally { return; } x = 2; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
107 { code: "function foo() { var x = 1; do { return; } while (x); x = 2; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
108 { code: "function foo() { var x = 1; while (x) { if (x) break; else continue; x = 2; } }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
109 { code: "function foo() { var x = 1; for (;;) { if (x) continue; } x = 2; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
110 { code: "function foo() { var x = 1; while (true) { } x = 2; }", errors: [{ messageId: "unreachableCode", type: "ExpressionStatement" }] },
111 {
112 code: "const arrow_direction = arrow => { switch (arrow) { default: throw new Error(); }; g() }",
113 parserOptions: { ecmaVersion: 6 },
114 errors: [
115 {
116 messageId: "unreachableCode",
117 type: "ExpressionStatement",
118 line: 1,
119 column: 86,
120 endLine: 1,
121 endColumn: 89
122 }
123 ]
124 },
125
126 // Merge the warnings of continuous unreachable nodes.
127 {
128 code: `
129 function foo() {
130 return;
131
132 a(); // ← ERROR: Unreachable code. (no-unreachable)
133
134 b() // ↑ ';' token is included in the unreachable code, so this statement will be merged.
135 // comment
136 c(); // ↑ ')' token is included in the unreachable code, so this statement will be merged.
137 }
138 `,
139 errors: [
140 {
141 messageId: "unreachableCode",
142 type: "ExpressionStatement",
143 line: 5,
144 column: 21,
145 endLine: 9,
146 endColumn: 25
147 }
148 ]
149 },
150 {
151 code: `
152 function foo() {
153 return;
154
155 a();
156
157 if (b()) {
158 c()
159 } else {
160 d()
161 }
162 }
163 `,
164 errors: [
165 {
166 messageId: "unreachableCode",
167 type: "ExpressionStatement",
168 line: 5,
169 column: 21,
170 endLine: 11,
171 endColumn: 22
172 }
173 ]
174 },
175 {
176 code: `
177 function foo() {
178 if (a) {
179 return
180 b();
181 c();
182 } else {
183 throw err
184 d();
185 }
186 }
187 `,
188 errors: [
189 {
190 messageId: "unreachableCode",
191 type: "ExpressionStatement",
192 line: 5,
193 column: 25,
194 endLine: 6,
195 endColumn: 29
196 },
197 {
198 messageId: "unreachableCode",
199 type: "ExpressionStatement",
200 line: 9,
201 column: 25,
202 endLine: 9,
203 endColumn: 29
204 }
205 ]
206 },
207 {
208 code: `
209 function foo() {
210 if (a) {
211 return
212 b();
213 c();
214 } else {
215 throw err
216 d();
217 }
218 e();
219 }
220 `,
221 errors: [
222 {
223 messageId: "unreachableCode",
224 type: "ExpressionStatement",
225 line: 5,
226 column: 25,
227 endLine: 6,
228 endColumn: 29
229 },
230 {
231 messageId: "unreachableCode",
232 type: "ExpressionStatement",
233 line: 9,
234 column: 25,
235 endLine: 9,
236 endColumn: 29
237 },
238 {
239 messageId: "unreachableCode",
240 type: "ExpressionStatement",
241 line: 11,
242 column: 21,
243 endLine: 11,
244 endColumn: 25
245 }
246 ]
247 },
248 {
249 code: `
250 function* foo() {
251 try {
252 return;
253 } catch (err) {
254 return err;
255 }
256 }`,
257 parserOptions: {
258 ecmaVersion: 6
259 },
260 errors: [
261 {
262 messageId: "unreachableCode",
263 type: "BlockStatement",
264 line: 5,
265 column: 35,
266 endLine: 7,
267 endColumn: 22
268 }
269 ]
270 },
271 {
272 code: `
273 function foo() {
274 try {
275 return;
276 } catch (err) {
277 return err;
278 }
279 }`,
280 parserOptions: {
281 ecmaVersion: 6
282 },
283 errors: [
284 {
285 messageId: "unreachableCode",
286 type: "BlockStatement",
287 line: 5,
288 column: 35,
289 endLine: 7,
290 endColumn: 22
291 }
292 ]
293 },
294 {
295 code: `
296 function foo() {
297 try {
298 return;
299 let a = 1;
300 } catch (err) {
301 return err;
302 }
303 }`,
304 parserOptions: {
305 ecmaVersion: 6
306 },
307 errors: [
308 {
309 messageId: "unreachableCode",
310 type: "VariableDeclaration",
311 line: 5,
312 column: 25,
313 endLine: 5,
314 endColumn: 35
315 },
316 {
317 messageId: "unreachableCode",
318 type: "BlockStatement",
319 line: 6,
320 column: 35,
321 endLine: 8,
322 endColumn: 22
323 }
324 ]
325 },
326
327 /*
328 * If `extends` exists, constructor exists, and the constructor doesn't
329 * contain `super()`, then the fields are unreachable because the
330 * evaluation of `super()` initializes fields in that case.
331 * In most cases, such an instantiation throws runtime errors, but
332 * doesn't throw if the constructor returns a value.
333 */
334 {
335 code: "class C extends B { foo; constructor() {} }",
336 parserOptions: { ecmaVersion: 2022 },
337 errors: [{ messageId: "unreachableCode", column: 21, endColumn: 25 }]
338 },
339 {
340 code: "class C extends B { foo = unreachable + code; constructor() {} }",
341 parserOptions: { ecmaVersion: 2022 },
342 errors: [{ messageId: "unreachableCode", column: 21, endColumn: 46 }]
343 },
344 {
345 code: "class C extends B { foo; bar; constructor() {} }",
346 parserOptions: { ecmaVersion: 2022 },
347 errors: [{ messageId: "unreachableCode", column: 21, endColumn: 30 }]
348 },
349 {
350 code: "class C extends B { foo; constructor() {} bar; }",
351 parserOptions: { ecmaVersion: 2022 },
352 errors: [
353 { messageId: "unreachableCode", column: 21, endColumn: 25 },
354 { messageId: "unreachableCode", column: 43, endColumn: 47 }
355 ]
356 },
357 {
358 code: "(class extends B { foo; constructor() {} bar; })",
359 parserOptions: { ecmaVersion: 2022 },
360 errors: [
361 { messageId: "unreachableCode", column: 20, endColumn: 24 },
362 { messageId: "unreachableCode", column: 42, endColumn: 46 }
363 ]
364 },
365 {
366 code: "class B extends A { x; constructor() { class C extends D { [super().x]; constructor() {} } } }",
367 parserOptions: { ecmaVersion: 2022 },
368 errors: [
369 { messageId: "unreachableCode", column: 60, endColumn: 72 }
370 ]
371 },
372 {
373 code: "class B extends A { x; constructor() { class C extends super().x { y; constructor() {} } } }",
374 parserOptions: { ecmaVersion: 2022 },
375 errors: [
376 { messageId: "unreachableCode", column: 68, endColumn: 70 }
377 ]
378 },
379 {
380 code: "class B extends A { x; static y; z; static q; constructor() {} }",
381 parserOptions: { ecmaVersion: 2022 },
382 errors: [
383 { messageId: "unreachableCode", column: 21, endColumn: 23 },
384 { messageId: "unreachableCode", column: 34, endColumn: 36 }
385 ]
386 }
387 ]
388 });