2 * @fileoverview Tests for no-unsafe-optional-chaining rule.
8 const rule
= require("../../../lib/rules/no-unsafe-optional-chaining");
9 const { RuleTester
} = require("../../../lib/rule-tester");
11 //------------------------------------------------------------------------------
13 //------------------------------------------------------------------------------
15 const parserOptions
= {
20 const ruleTester
= new RuleTester({ parserOptions
});
22 ruleTester
.run("no-unsafe-optional-chaining", rule
, {
29 "(obj?.foo ?? bar)();",
31 "(obj?.foo ?? bar?.baz)?.()",
36 "(obj?.foo)?.bar.baz;",
38 "(obj?.foo ?? bar).baz;",
39 "(obj?.foo ?? val)`template`",
40 "new (obj?.foo ?? val)()",
43 "const {foo} = obj?.baz || {};",
44 "const foo = obj?.bar",
47 "bar(...obj?.foo ?? []);",
48 "var bar = {...foo?.bar};",
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);",
59 "(foo?.bar ? baz : qux)();",
61 async function func() {
65 (await obj?.foo)?.bar;
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);
75 "(obj?.foo ?? bar?.baz ?? qux)();",
76 "((obj?.foo ?? bar?.baz) || qux)();",
77 "((obj?.foo || bar?.baz) || qux)();",
78 "((obj?.foo && bar?.baz) || qux)();",
80 // The default value option disallowArithmeticOperators is false
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;
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;
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;",
126 "+(obj?.foo ?? bar)",
127 "-(obj?.foo ?? bar)",
133 "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)",
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;",
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);
172 disallowArithmeticOperators
: true
176 code
: "obj?.foo - bar;",
180 code
: "obj?.foo - bar;",
182 disallowArithmeticOperators
: false
190 "(obj.foo ?? bar?.baz)();",
191 "(obj.foo || bar?.baz)();",
192 "(obj?.foo && bar)();",
193 "(bar && obj?.foo)();",
197 "(obj?.foo)`template`",
199 "new (obj?.foo?.())()",
200 "new (obj?.foo?.() || obj?.bar)()",
202 `async function foo() {
205 `async function foo() {
206 (await obj?.foo).bar;
208 `async function foo() {
209 (bar?.baz ?? await obj?.foo)();
211 `async function foo() {
212 (bar && await obj?.foo)();
214 `async function foo() {
215 (await (bar && obj?.foo))();
221 "new Bar(...obj?.foo);",
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); }",
240 "class A extends obj?.foo {}",
241 "async function foo() { class A extends (await obj?.foo) {}}",
244 "var a = class A extends obj?.foo {}",
245 "async function foo() { var a = class A extends (await obj?.foo) {}}",
247 // relational operations
248 "foo instanceof obj?.prop",
249 "async function foo() { foo instanceof await obj?.prop }",
251 "async function foo() { 1 in await foo?.bar; }",
254 "for (foo of obj?.bar);",
255 "async function foo() { for (foo of await obj?.bar);}",
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]; }",
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; }"
278 errors
: [{ messageId
: "unsafeOptionalChain", type
: "ChainExpression" }]
281 code
: "(obj?.foo && obj?.baz).bar",
284 messageId
: "unsafeOptionalChain",
285 type
: "ChainExpression",
290 messageId
: "unsafeOptionalChain",
291 type
: "ChainExpression",
298 code
: "with (obj?.foo) {};",
304 messageId
: "unsafeOptionalChain",
305 type
: "ChainExpression",
312 code
: "async function foo() { with ( await obj?.foo) {}; }",
318 messageId
: "unsafeOptionalChain",
319 type
: "ChainExpression",
326 code
: "(foo ? obj?.foo : obj?.bar).bar",
329 messageId
: "unsafeOptionalChain",
330 type
: "ChainExpression",
335 messageId
: "unsafeOptionalChain",
336 type
: "ChainExpression",
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",
356 "+(foo ?? obj?.foo);",
357 "+(foo || obj?.bar);",
358 "+(obj?.bar && foo);",
359 "+(foo ? obj?.foo : bar);",
360 "+(foo ? bar : obj?.foo);",
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); }"
377 options
: [{ disallowArithmeticOperators
: true }],
378 errors
: [{ messageId
: "unsafeArithmetic", type
: "ChainExpression" }]