]> git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/lib/rules/no-unsafe-optional-chaining.js
import 8.3.0 source
[pve-eslint.git] / eslint / tests / lib / rules / no-unsafe-optional-chaining.js
1 /**
2 * @fileoverview Tests for no-unsafe-optional-chaining rule.
3 * @author Yeon JuAn
4 */
5
6 "use strict";
7
8 const rule = require("../../../lib/rules/no-unsafe-optional-chaining");
9 const { RuleTester } = require("../../../lib/rule-tester");
10
11 //------------------------------------------------------------------------------
12 // Tests
13 //------------------------------------------------------------------------------
14
15 const parserOptions = {
16 ecmaVersion: 2021,
17 sourceType: "module"
18 };
19
20 const ruleTester = new RuleTester({ parserOptions });
21
22 ruleTester.run("no-unsafe-optional-chaining", rule, {
23 valid: [
24 "var foo;",
25 "class Foo {}",
26 "!!obj?.foo",
27 "obj?.foo();",
28 "obj?.foo?.();",
29 "(obj?.foo ?? bar)();",
30 "(obj?.foo)?.()",
31 "(obj?.foo ?? bar?.baz)?.()",
32 "(obj.foo)?.();",
33 "obj?.foo.bar;",
34 "obj?.foo?.bar;",
35 "(obj?.foo)?.bar;",
36 "(obj?.foo)?.bar.baz;",
37 "(obj?.foo)?.().bar",
38 "(obj?.foo ?? bar).baz;",
39 "(obj?.foo ?? val)`template`",
40 "new (obj?.foo ?? val)()",
41 "new bar();",
42 "obj?.foo?.()();",
43 "const {foo} = obj?.baz || {};",
44 "const foo = obj?.bar",
45 "foo = obj?.bar",
46 "foo.bar = obj?.bar",
47 "bar(...obj?.foo ?? []);",
48 "var bar = {...foo?.bar};",
49 "foo?.bar in {};",
50 "foo?.bar < foo?.baz;",
51 "foo?.bar <= foo?.baz;",
52 "foo?.bar > foo?.baz;",
53 "foo?.bar >= foo?.baz;",
54 "[foo = obj?.bar] = [];",
55 "[foo.bar = obj?.bar] = [];",
56 "({foo = obj?.bar} = obj);",
57 "({foo: obj.bar = obj?.baz} = obj);",
58 "(foo?.bar, bar)();",
59 "(foo?.bar ? baz : qux)();",
60 `
61 async function func() {
62 await obj?.foo();
63 await obj?.foo?.();
64 (await obj?.foo)?.();
65 (await obj?.foo)?.bar;
66 await bar?.baz;
67 await (foo ?? obj?.foo.baz);
68 (await bar?.baz ?? bar).baz;
69 (await bar?.baz ?? await bar).baz;
70 await (foo?.bar ? baz : qux);
71 }
72 `,
73
74 // logical operations
75 "(obj?.foo ?? bar?.baz ?? qux)();",
76 "((obj?.foo ?? bar?.baz) || qux)();",
77 "((obj?.foo || bar?.baz) || qux)();",
78 "((obj?.foo && bar?.baz) || qux)();",
79
80 // The default value option disallowArithmeticOperators is false
81 "obj?.foo - bar;",
82 "obj?.foo + bar;",
83 "obj?.foo * bar;",
84 "obj?.foo / bar;",
85 "obj?.foo % bar;",
86 "obj?.foo ** bar;",
87 "+obj?.foo;",
88 "-obj?.foo;",
89 "bar += obj?.foo;",
90 "bar -= obj?.foo;",
91 "bar %= obj?.foo;",
92 "bar **= obj?.foo;",
93 "bar *= obj?.boo",
94 "bar /= obj?.boo",
95 `async function func() {
96 await obj?.foo + await obj?.bar;
97 await obj?.foo - await obj?.bar;
98 await obj?.foo * await obj?.bar;
99 +await obj?.foo;
100 -await obj?.foo;
101 bar += await obj?.foo;
102 bar -= await obj?.foo;
103 bar %= await obj?.foo;
104 bar **= await obj?.foo;
105 bar *= await obj?.boo;
106 bar /= await obj?.boo;
107 }
108 `,
109 ...[
110 "obj?.foo | bar",
111 "obj?.foo & bar",
112 "obj?.foo >> obj?.bar;",
113 "obj?.foo << obj?.bar;",
114 "obj?.foo >>> obj?.bar;",
115 "(obj?.foo || baz) + bar;",
116 "(obj?.foo ?? baz) + bar;",
117 "(obj?.foo ?? baz) - bar;",
118 "(obj?.foo ?? baz) * bar;",
119 "(obj?.foo ?? baz) / bar;",
120 "(obj?.foo ?? baz) % bar;",
121 "(obj?.foo ?? baz) ** bar;",
122 "void obj?.foo;",
123 "typeof obj?.foo;",
124 "!obj?.foo",
125 "~obj?.foo",
126 "+(obj?.foo ?? bar)",
127 "-(obj?.foo ?? bar)",
128 "bar |= obj?.foo;",
129 "bar &= obj?.foo;",
130 "bar ^= obj?.foo;",
131 "bar <<= obj?.foo;",
132 "bar >>= obj?.foo;",
133 "bar >>>= obj?.foo;",
134 "bar ||= obj?.foo",
135 "bar &&= obj?.foo",
136 "bar += (obj?.foo ?? baz);",
137 "bar -= (obj?.foo ?? baz)",
138 "bar *= (obj?.foo ?? baz)",
139 "bar /= (obj?.foo ?? baz)",
140 "bar %= (obj?.foo ?? baz);",
141 "bar **= (obj?.foo ?? baz)",
142
143 `async function foo() {
144 (await obj?.foo || baz) + bar;
145 (await obj?.foo ?? baz) + bar;
146 (await obj?.foo ?? baz) - bar;
147 (await obj?.foo ?? baz) * bar;
148 (await obj?.foo ?? baz) / bar;
149 (await obj?.foo ?? baz) % bar;
150 "(await obj?.foo ?? baz) ** bar;",
151 "void await obj?.foo;",
152 "typeof await obj?.foo;",
153 "!await obj?.foo",
154 "~await obj?.foo",
155 "+(await obj?.foo ?? bar)",
156 "-(await obj?.foo ?? bar)",
157 bar |= await obj?.foo;
158 bar &= await obj?.foo;
159 bar ^= await obj?.foo;
160 bar <<= await obj?.foo;
161 bar >>= await obj?.foo;
162 bar >>>= await obj?.foo
163 bar += ((await obj?.foo) ?? baz);
164 bar -= ((await obj?.foo) ?? baz);
165 bar /= ((await obj?.foo) ?? baz);
166 bar %= ((await obj?.foo) ?? baz);
167 bar **= ((await obj?.foo) ?? baz);
168 }`
169 ].map(code => ({
170 code,
171 options: [{
172 disallowArithmeticOperators: true
173 }]
174 })),
175 {
176 code: "obj?.foo - bar;",
177 options: [{}]
178 },
179 {
180 code: "obj?.foo - bar;",
181 options: [{
182 disallowArithmeticOperators: false
183 }]
184 }
185 ],
186
187 invalid: [
188 ...[
189 "(obj?.foo)();",
190 "(obj.foo ?? bar?.baz)();",
191 "(obj.foo || bar?.baz)();",
192 "(obj?.foo && bar)();",
193 "(bar && obj?.foo)();",
194 "(obj?.foo?.())();",
195 "(obj?.foo).bar",
196 "(obj?.foo)[1];",
197 "(obj?.foo)`template`",
198 "new (obj?.foo)();",
199 "new (obj?.foo?.())()",
200 "new (obj?.foo?.() || obj?.bar)()",
201
202 `async function foo() {
203 (await obj?.foo)();
204 }`,
205 `async function foo() {
206 (await obj?.foo).bar;
207 }`,
208 `async function foo() {
209 (bar?.baz ?? await obj?.foo)();
210 }`,
211 `async function foo() {
212 (bar && await obj?.foo)();
213 }`,
214 `async function foo() {
215 (await (bar && obj?.foo))();
216 }`,
217
218 // spread
219 "[...obj?.foo];",
220 "bar(...obj?.foo);",
221 "new Bar(...obj?.foo);",
222
223 // destructuring
224 "const {foo} = obj?.bar;",
225 "const {foo} = obj?.bar();",
226 "const {foo: bar} = obj?.bar();",
227 "const [foo] = obj?.bar;",
228 "const [foo] = obj?.bar || obj?.foo;",
229 "([foo] = obj?.bar);",
230 "const [foo] = obj?.bar?.();",
231 "[{ foo } = obj?.bar] = [];",
232 "({bar: [ foo ] = obj?.prop} = {});",
233 "[[ foo ] = obj?.bar] = [];",
234 "async function foo() { const {foo} = await obj?.bar; }",
235 "async function foo() { const {foo} = await obj?.bar(); }",
236 "async function foo() { const [foo] = await obj?.bar || await obj?.foo; }",
237 "async function foo() { ([foo] = await obj?.bar); }",
238
239 // class declaration
240 "class A extends obj?.foo {}",
241 "async function foo() { class A extends (await obj?.foo) {}}",
242
243 // class expression
244 "var a = class A extends obj?.foo {}",
245 "async function foo() { var a = class A extends (await obj?.foo) {}}",
246
247 // relational operations
248 "foo instanceof obj?.prop",
249 "async function foo() { foo instanceof await obj?.prop }",
250 "1 in foo?.bar;",
251 "async function foo() { 1 in await foo?.bar; }",
252
253 // for...of
254 "for (foo of obj?.bar);",
255 "async function foo() { for (foo of await obj?.bar);}",
256
257 // sequence expression
258 "(foo, obj?.foo)();",
259 "(foo, obj?.foo)[1];",
260 "async function foo() { (await (foo, obj?.foo))(); }",
261 "async function foo() { ((foo, await obj?.foo))(); }",
262 "async function foo() { (foo, await obj?.foo)[1]; }",
263 "async function foo() { (await (foo, obj?.foo)) [1]; }",
264
265 // conditional expression
266 "(a ? obj?.foo : b)();",
267 "(a ? b : obj?.foo)();",
268 "(a ? obj?.foo : b)[1];",
269 "(a ? b : obj?.foo).bar;",
270 "async function foo() { (await (a ? obj?.foo : b))(); }",
271 "async function foo() { (a ? await obj?.foo : b)(); }",
272 "async function foo() { (await (a ? b : obj?.foo))(); }",
273 "async function foo() { (await (a ? obj?.foo : b))[1]; }",
274 "async function foo() { (await (a ? b : obj?.foo)).bar; }",
275 "async function foo() { (a ? b : await obj?.foo).bar; }"
276 ].map(code => ({
277 code,
278 errors: [{ messageId: "unsafeOptionalChain", type: "ChainExpression" }]
279 })),
280 {
281 code: "(obj?.foo && obj?.baz).bar",
282 errors: [
283 {
284 messageId: "unsafeOptionalChain",
285 type: "ChainExpression",
286 line: 1,
287 column: 2
288 },
289 {
290 messageId: "unsafeOptionalChain",
291 type: "ChainExpression",
292 line: 1,
293 column: 14
294 }
295 ]
296 },
297 {
298 code: "with (obj?.foo) {};",
299 parserOptions: {
300 sourceType: "script"
301 },
302 errors: [
303 {
304 messageId: "unsafeOptionalChain",
305 type: "ChainExpression",
306 line: 1,
307 column: 7
308 }
309 ]
310 },
311 {
312 code: "async function foo() { with ( await obj?.foo) {}; }",
313 parserOptions: {
314 sourceType: "script"
315 },
316 errors: [
317 {
318 messageId: "unsafeOptionalChain",
319 type: "ChainExpression",
320 line: 1,
321 column: 37
322 }
323 ]
324 },
325 {
326 code: "(foo ? obj?.foo : obj?.bar).bar",
327 errors: [
328 {
329 messageId: "unsafeOptionalChain",
330 type: "ChainExpression",
331 line: 1,
332 column: 8
333 },
334 {
335 messageId: "unsafeOptionalChain",
336 type: "ChainExpression",
337 line: 1,
338 column: 19
339 }
340 ]
341 },
342 ...[
343 "obj?.foo + bar;",
344 "(foo || obj?.foo) + bar;",
345 "bar + (foo || obj?.foo);",
346 "(a ? obj?.foo : b) + bar",
347 "(a ? b : obj?.foo) + bar",
348 "(foo, bar, baz?.qux) + bar",
349 "obj?.foo - bar;",
350 "obj?.foo * bar;",
351 "obj?.foo / bar;",
352 "obj?.foo % bar;",
353 "obj?.foo ** bar;",
354 "+obj?.foo;",
355 "-obj?.foo;",
356 "+(foo ?? obj?.foo);",
357 "+(foo || obj?.bar);",
358 "+(obj?.bar && foo);",
359 "+(foo ? obj?.foo : bar);",
360 "+(foo ? bar : obj?.foo);",
361 "bar += obj?.foo;",
362 "bar -= obj?.foo;",
363 "bar %= obj?.foo;",
364 "bar **= obj?.foo;",
365 "bar *= obj?.boo",
366 "bar /= obj?.boo",
367 "bar += (foo ?? obj?.foo);",
368 "bar += (foo || obj?.foo);",
369 "bar += (foo && obj?.foo);",
370 "bar += (foo ? obj?.foo : bar);",
371 "bar += (foo ? bar : obj?.foo);",
372 "async function foo() { await obj?.foo + bar; }",
373 "async function foo() { (foo || await obj?.foo) + bar;}",
374 "async function foo() { bar + (foo || await obj?.foo); }"
375 ].map(code => ({
376 code,
377 options: [{ disallowArithmeticOperators: true }],
378 errors: [{ messageId: "unsafeArithmetic", type: "ChainExpression" }]
379 }))
380 ]
381 });