]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Tests for no-use-before-define rule. | |
3 | * @author Ilya Volodin | |
4 | */ | |
5 | ||
6 | "use strict"; | |
7 | ||
8 | //------------------------------------------------------------------------------ | |
9 | // Requirements | |
10 | //------------------------------------------------------------------------------ | |
11 | ||
12 | const rule = require("../../../lib/rules/no-use-before-define"), | |
13 | { RuleTester } = require("../../../lib/rule-tester"); | |
14 | ||
15 | //------------------------------------------------------------------------------ | |
16 | // Tests | |
17 | //------------------------------------------------------------------------------ | |
18 | ||
19 | const ruleTester = new RuleTester(); | |
20 | ||
21 | ruleTester.run("no-use-before-define", rule, { | |
22 | valid: [ | |
23 | "var a=10; alert(a);", | |
24 | "function b(a) { alert(a); }", | |
25 | "Object.hasOwnProperty.call(a);", | |
26 | "function a() { alert(arguments);}", | |
27 | { code: "a(); function a() { alert(arguments); }", options: ["nofunc"] }, | |
28 | { code: "(() => { var a = 42; alert(a); })();", parserOptions: { ecmaVersion: 6 } }, | |
29 | "a(); try { throw new Error() } catch (a) {}", | |
30 | { code: "class A {} new A();", parserOptions: { ecmaVersion: 6 } }, | |
31 | "var a = 0, b = a;", | |
32 | { code: "var {a = 0, b = a} = {};", parserOptions: { ecmaVersion: 6 } }, | |
33 | { code: "var [a = 0, b = a] = {};", parserOptions: { ecmaVersion: 6 } }, | |
34 | "function foo() { foo(); }", | |
35 | "var foo = function() { foo(); };", | |
36 | "var a; for (a in a) {}", | |
37 | { code: "var a; for (a of a) {}", parserOptions: { ecmaVersion: 6 } }, | |
38 | ||
39 | // Block-level bindings | |
40 | { code: "\"use strict\"; a(); { function a() {} }", parserOptions: { ecmaVersion: 6 } }, | |
41 | { code: "\"use strict\"; { a(); function a() {} }", options: ["nofunc"], parserOptions: { ecmaVersion: 6 } }, | |
42 | { code: "switch (foo) { case 1: { a(); } default: { let a; }}", parserOptions: { ecmaVersion: 6 } }, | |
43 | { code: "a(); { let a = function () {}; }", parserOptions: { ecmaVersion: 6 } }, | |
44 | ||
45 | // object style options | |
46 | { code: "a(); function a() { alert(arguments); }", options: [{ functions: false }] }, | |
47 | { code: "\"use strict\"; { a(); function a() {} }", options: [{ functions: false }], parserOptions: { ecmaVersion: 6 } }, | |
48 | { code: "function foo() { new A(); } class A {};", options: [{ classes: false }], parserOptions: { ecmaVersion: 6 } }, | |
49 | ||
50 | // "variables" option | |
51 | { | |
52 | code: "function foo() { bar; } var bar;", | |
53 | options: [{ variables: false }] | |
54 | }, | |
55 | { | |
56 | code: "var foo = () => bar; var bar;", | |
57 | options: [{ variables: false }], | |
58 | parserOptions: { ecmaVersion: 6 } | |
59 | } | |
60 | ], | |
61 | invalid: [ | |
62 | { | |
63 | code: "a++; var a=19;", | |
64 | parserOptions: { ecmaVersion: 6, sourceType: "module" }, | |
65 | errors: [{ | |
66 | messageId: "usedBeforeDefined", | |
67 | data: { name: "a" }, | |
68 | type: "Identifier" | |
69 | }] | |
70 | }, | |
71 | { | |
72 | code: "a++; var a=19;", | |
73 | parserOptions: { parserOptions: { ecmaVersion: 6 } }, | |
74 | errors: [{ | |
75 | messageId: "usedBeforeDefined", | |
76 | data: { name: "a" }, | |
77 | type: "Identifier" | |
78 | }] | |
79 | }, | |
80 | { | |
81 | code: "a++; var a=19;", | |
82 | errors: [{ | |
83 | messageId: "usedBeforeDefined", | |
84 | data: { name: "a" }, | |
85 | type: "Identifier" | |
86 | }] | |
87 | }, | |
88 | { | |
89 | code: "a(); var a=function() {};", | |
90 | errors: [{ | |
91 | messageId: "usedBeforeDefined", | |
92 | data: { name: "a" }, | |
93 | type: "Identifier" | |
94 | }] | |
95 | }, | |
96 | { | |
97 | code: "alert(a[1]); var a=[1,3];", | |
98 | errors: [{ | |
99 | messageId: "usedBeforeDefined", | |
100 | data: { name: "a" }, | |
101 | type: "Identifier" | |
102 | }] | |
103 | }, | |
104 | { | |
105 | code: "a(); function a() { alert(b); var b=10; a(); }", | |
106 | errors: [ | |
107 | { | |
108 | messageId: "usedBeforeDefined", | |
109 | data: { name: "a" }, | |
110 | type: "Identifier" | |
111 | }, | |
112 | { | |
113 | messageId: "usedBeforeDefined", | |
114 | data: { name: "b" }, | |
115 | type: "Identifier" | |
116 | } | |
117 | ] | |
118 | }, | |
119 | { | |
120 | code: "a(); var a=function() {};", | |
121 | options: ["nofunc"], | |
122 | errors: [{ | |
123 | messageId: "usedBeforeDefined", | |
124 | data: { name: "a" }, | |
125 | type: "Identifier" | |
126 | }] | |
127 | }, | |
128 | { | |
129 | code: "(() => { alert(a); var a = 42; })();", | |
130 | parserOptions: { ecmaVersion: 6 }, | |
131 | errors: [{ | |
132 | messageId: "usedBeforeDefined", | |
133 | data: { name: "a" }, | |
134 | type: "Identifier" | |
135 | }] | |
136 | }, | |
137 | { | |
138 | code: "(() => a())(); function a() { }", | |
139 | parserOptions: { ecmaVersion: 6 }, | |
140 | errors: [{ | |
141 | messageId: "usedBeforeDefined", | |
142 | data: { name: "a" }, | |
143 | type: "Identifier" | |
144 | }] | |
145 | }, | |
146 | { | |
147 | code: "\"use strict\"; a(); { function a() {} }", | |
148 | errors: [{ | |
149 | messageId: "usedBeforeDefined", | |
150 | data: { name: "a" }, | |
151 | type: "Identifier" | |
152 | }] | |
153 | }, | |
154 | { | |
155 | code: "a(); try { throw new Error() } catch (foo) {var a;}", | |
156 | errors: [{ | |
157 | messageId: "usedBeforeDefined", | |
158 | data: { name: "a" }, | |
159 | type: "Identifier" | |
160 | }] | |
161 | }, | |
162 | { | |
163 | code: "var f = () => a; var a;", | |
164 | parserOptions: { ecmaVersion: 6 }, | |
165 | errors: [{ | |
166 | messageId: "usedBeforeDefined", | |
167 | data: { name: "a" }, | |
168 | type: "Identifier" | |
169 | }] | |
170 | }, | |
171 | { | |
172 | code: "new A(); class A {};", | |
173 | parserOptions: { ecmaVersion: 6 }, | |
174 | errors: [{ | |
175 | messageId: "usedBeforeDefined", | |
176 | data: { name: "A" }, | |
177 | type: "Identifier" | |
178 | }] | |
179 | }, | |
180 | { | |
181 | code: "function foo() { new A(); } class A {};", | |
182 | parserOptions: { ecmaVersion: 6 }, | |
183 | errors: [{ | |
184 | messageId: "usedBeforeDefined", | |
185 | data: { name: "A" }, | |
186 | type: "Identifier" | |
187 | }] | |
188 | }, | |
189 | { | |
190 | code: "new A(); var A = class {};", | |
191 | parserOptions: { ecmaVersion: 6 }, | |
192 | errors: [{ | |
193 | messageId: "usedBeforeDefined", | |
194 | data: { name: "A" }, | |
195 | type: "Identifier" | |
196 | }] | |
197 | }, | |
198 | { | |
199 | code: "function foo() { new A(); } var A = class {};", | |
200 | parserOptions: { ecmaVersion: 6 }, | |
201 | errors: [{ | |
202 | messageId: "usedBeforeDefined", | |
203 | data: { name: "A" }, | |
204 | type: "Identifier" | |
205 | }] | |
206 | }, | |
207 | ||
208 | // Block-level bindings | |
209 | { | |
210 | code: "a++; { var a; }", | |
211 | parserOptions: { ecmaVersion: 6 }, | |
212 | errors: [{ | |
213 | messageId: "usedBeforeDefined", | |
214 | data: { name: "a" }, | |
215 | type: "Identifier" | |
216 | }] | |
217 | }, | |
218 | { | |
219 | code: "\"use strict\"; { a(); function a() {} }", | |
220 | parserOptions: { ecmaVersion: 6 }, | |
221 | errors: [{ | |
222 | messageId: "usedBeforeDefined", | |
223 | data: { name: "a" }, | |
224 | type: "Identifier" | |
225 | }] | |
226 | }, | |
227 | { | |
228 | code: "{a; let a = 1}", | |
229 | parserOptions: { ecmaVersion: 6 }, | |
230 | errors: [{ | |
231 | messageId: "usedBeforeDefined", | |
232 | data: { name: "a" }, | |
233 | type: "Identifier" | |
234 | }] | |
235 | }, | |
236 | { | |
237 | code: "switch (foo) { case 1: a();\n default: \n let a;}", | |
238 | parserOptions: { ecmaVersion: 6 }, | |
239 | errors: [{ | |
240 | messageId: "usedBeforeDefined", | |
241 | data: { name: "a" }, | |
242 | type: "Identifier" | |
243 | }] | |
244 | }, | |
245 | { | |
246 | code: "if (true) { function foo() { a; } let a;}", | |
247 | parserOptions: { ecmaVersion: 6 }, | |
248 | errors: [{ | |
249 | messageId: "usedBeforeDefined", | |
250 | data: { name: "a" }, | |
251 | type: "Identifier" | |
252 | }] | |
253 | }, | |
254 | ||
255 | // object style options | |
256 | { | |
257 | code: "a(); var a=function() {};", | |
258 | options: [{ functions: false, classes: false }], | |
259 | errors: [{ | |
260 | messageId: "usedBeforeDefined", | |
261 | data: { name: "a" }, | |
262 | type: "Identifier" | |
263 | }] | |
264 | }, | |
265 | { | |
266 | code: "new A(); class A {};", | |
267 | options: [{ functions: false, classes: false }], | |
268 | parserOptions: { ecmaVersion: 6 }, | |
269 | errors: [{ | |
270 | messageId: "usedBeforeDefined", | |
271 | data: { name: "A" }, | |
272 | type: "Identifier" | |
273 | }] | |
274 | }, | |
275 | { | |
276 | code: "new A(); var A = class {};", | |
277 | options: [{ classes: false }], | |
278 | parserOptions: { ecmaVersion: 6 }, | |
279 | errors: [{ | |
280 | messageId: "usedBeforeDefined", | |
281 | data: { name: "A" }, | |
282 | type: "Identifier" | |
283 | }] | |
284 | }, | |
285 | { | |
286 | code: "function foo() { new A(); } var A = class {};", | |
287 | options: [{ classes: false }], | |
288 | parserOptions: { ecmaVersion: 6 }, | |
289 | errors: [{ | |
290 | messageId: "usedBeforeDefined", | |
291 | data: { name: "A" }, | |
292 | type: "Identifier" | |
293 | }] | |
294 | }, | |
295 | ||
296 | // invalid initializers | |
297 | { | |
298 | code: "var a = a;", | |
299 | errors: [{ | |
300 | messageId: "usedBeforeDefined", | |
301 | data: { name: "a" }, | |
302 | type: "Identifier" | |
303 | }] | |
304 | }, | |
305 | { | |
306 | code: "let a = a + b;", | |
307 | parserOptions: { ecmaVersion: 6 }, | |
308 | errors: [{ | |
309 | messageId: "usedBeforeDefined", | |
310 | data: { name: "a" }, | |
311 | type: "Identifier" | |
312 | }] | |
313 | }, | |
314 | { | |
315 | code: "const a = foo(a);", | |
316 | parserOptions: { ecmaVersion: 6 }, | |
317 | errors: [{ | |
318 | messageId: "usedBeforeDefined", | |
319 | data: { name: "a" }, | |
320 | type: "Identifier" | |
321 | }] | |
322 | }, | |
323 | { | |
324 | code: "function foo(a = a) {}", | |
325 | parserOptions: { ecmaVersion: 6 }, | |
326 | errors: [{ | |
327 | messageId: "usedBeforeDefined", | |
328 | data: { name: "a" }, | |
329 | type: "Identifier" | |
330 | }] | |
331 | }, | |
332 | { | |
333 | code: "var {a = a} = [];", | |
334 | parserOptions: { ecmaVersion: 6 }, | |
335 | errors: [{ | |
336 | messageId: "usedBeforeDefined", | |
337 | data: { name: "a" }, | |
338 | type: "Identifier" | |
339 | }] | |
340 | }, | |
341 | { | |
342 | code: "var [a = a] = [];", | |
343 | parserOptions: { ecmaVersion: 6 }, | |
344 | errors: [{ | |
345 | messageId: "usedBeforeDefined", | |
346 | data: { name: "a" }, | |
347 | type: "Identifier" | |
348 | }] | |
349 | }, | |
350 | { | |
351 | code: "var {b = a, a} = {};", | |
352 | parserOptions: { ecmaVersion: 6 }, | |
353 | errors: [{ | |
354 | messageId: "usedBeforeDefined", | |
355 | data: { name: "a" }, | |
356 | type: "Identifier" | |
357 | }] | |
358 | }, | |
359 | { | |
360 | code: "var [b = a, a] = {};", | |
361 | parserOptions: { ecmaVersion: 6 }, | |
362 | errors: [{ | |
363 | messageId: "usedBeforeDefined", | |
364 | data: { name: "a" }, | |
365 | type: "Identifier" | |
366 | }] | |
367 | }, | |
368 | { | |
369 | code: "var {a = 0} = a;", | |
370 | parserOptions: { ecmaVersion: 6 }, | |
371 | errors: [{ | |
372 | messageId: "usedBeforeDefined", | |
373 | data: { name: "a" }, | |
374 | type: "Identifier" | |
375 | }] | |
376 | }, | |
377 | { | |
378 | code: "var [a = 0] = a;", | |
379 | parserOptions: { ecmaVersion: 6 }, | |
380 | errors: [{ | |
381 | messageId: "usedBeforeDefined", | |
382 | data: { name: "a" }, | |
383 | type: "Identifier" | |
384 | }] | |
385 | }, | |
386 | { | |
387 | code: "for (var a in a) {}", | |
388 | errors: [{ | |
389 | messageId: "usedBeforeDefined", | |
390 | data: { name: "a" }, | |
391 | type: "Identifier" | |
392 | }] | |
393 | }, | |
394 | { | |
395 | code: "for (var a of a) {}", | |
396 | parserOptions: { ecmaVersion: 6 }, | |
397 | errors: [{ | |
398 | messageId: "usedBeforeDefined", | |
399 | data: { name: "a" }, | |
400 | type: "Identifier" | |
401 | }] | |
402 | }, | |
403 | ||
404 | // "variables" option | |
405 | { | |
406 | code: "function foo() { bar; var bar = 1; } var bar;", | |
407 | options: [{ variables: false }], | |
408 | errors: [{ | |
409 | messageId: "usedBeforeDefined", | |
410 | data: { name: "bar" }, | |
411 | type: "Identifier" | |
412 | }] | |
413 | }, | |
414 | { | |
415 | code: "foo; var foo;", | |
416 | options: [{ variables: false }], | |
417 | errors: [{ | |
418 | messageId: "usedBeforeDefined", | |
419 | data: { name: "foo" }, | |
420 | type: "Identifier" | |
421 | }] | |
422 | }, | |
423 | ||
424 | // https://github.com/eslint/eslint/issues/10227 | |
425 | { | |
426 | code: "for (let x = x;;); let x = 0", | |
427 | parserOptions: { ecmaVersion: 2015 }, | |
428 | errors: [{ | |
429 | messageId: "usedBeforeDefined", | |
430 | data: { name: "x" } | |
431 | }] | |
432 | }, | |
433 | { | |
434 | code: "for (let x in xs); let xs = []", | |
435 | parserOptions: { ecmaVersion: 2015 }, | |
436 | errors: [{ | |
437 | messageId: "usedBeforeDefined", | |
438 | data: { name: "xs" } | |
439 | }] | |
440 | }, | |
441 | { | |
442 | code: "for (let x of xs); let xs = []", | |
443 | parserOptions: { ecmaVersion: 2015 }, | |
444 | errors: [{ | |
445 | messageId: "usedBeforeDefined", | |
446 | data: { name: "xs" } | |
447 | }] | |
448 | }, | |
449 | { | |
450 | code: "try {} catch ({message = x}) {} let x = ''", | |
451 | parserOptions: { ecmaVersion: 2015 }, | |
452 | errors: [{ | |
453 | messageId: "usedBeforeDefined", | |
454 | data: { name: "x" } | |
455 | }] | |
456 | }, | |
457 | { | |
458 | code: "with (obj) x; let x = {}", | |
459 | parserOptions: { ecmaVersion: 2015 }, | |
460 | errors: [{ | |
461 | messageId: "usedBeforeDefined", | |
462 | data: { name: "x" } | |
463 | }] | |
464 | }, | |
465 | ||
466 | // WithStatements. | |
467 | { | |
468 | code: "with (x); let x = {}", | |
469 | parserOptions: { ecmaVersion: 2015 }, | |
470 | errors: [{ | |
471 | messageId: "usedBeforeDefined", | |
472 | data: { name: "x" } | |
473 | }] | |
474 | }, | |
475 | { | |
476 | code: "with (obj) { x } let x = {}", | |
477 | parserOptions: { ecmaVersion: 2015 }, | |
478 | errors: [{ | |
479 | messageId: "usedBeforeDefined", | |
480 | data: { name: "x" } | |
481 | }] | |
482 | }, | |
483 | { | |
484 | code: "with (obj) { if (a) { x } } let x = {}", | |
485 | parserOptions: { ecmaVersion: 2015 }, | |
486 | errors: [{ | |
487 | messageId: "usedBeforeDefined", | |
488 | data: { name: "x" } | |
489 | }] | |
490 | }, | |
491 | { | |
492 | code: "with (obj) { (() => { if (a) { x } })() } let x = {}", | |
493 | parserOptions: { ecmaVersion: 2015 }, | |
494 | errors: [{ | |
495 | messageId: "usedBeforeDefined", | |
496 | data: { name: "x" } | |
497 | }] | |
498 | } | |
499 | ] | |
500 | }); |