]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/lib/rules/prefer-exponentiation-operator.js
42bf8ec047deee058c1245b54e78ec375efb176c
2 * @fileoverview Tests for the prefer-exponentiation-operator rule
3 * @author Milos Djermanovic
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const rule
= require("../../../lib/rules/prefer-exponentiation-operator");
13 const { RuleTester
} = require("../../../lib/rule-tester");
15 //------------------------------------------------------------------------------
17 //------------------------------------------------------------------------------
20 * Create an object for the invalid array
21 * @param {string} code source code
22 * @param {string} output fixed source code
23 * @returns {Object} result object
26 function invalid(code
, output
) {
32 messageId
: "useExponentiation",
33 type
: "CallExpression"
39 //------------------------------------------------------------------------------
41 //------------------------------------------------------------------------------
43 const ruleTester
= new RuleTester({ parserOptions
: { ecmaVersion
: 2018 } });
45 ruleTester
.run("prefer-exponentiation-operator", rule
, {
61 { code
: "globalThis.Object.pow(a, b)", env
: { es2020
: true } },
62 { code
: "globalThis.Math.max(a, b)", env
: { es2020
: true } },
64 // not the global Math
65 "/* globals Math:off*/ Math.pow(a, b)",
66 "let Math; Math.pow(a, b);",
67 "if (foo) { const Math = 1; Math.pow(a, b); }",
68 "var x = function Math() { Math.pow(a, b); }",
69 "function foo(Math) { Math.pow(a, b); }",
70 "function foo() { Math.pow(a, b); var Math; }",
72 "globalThis.Math.pow(a, b)",
73 { code
: "globalThis.Math.pow(a, b)", env
: { es6
: true } },
74 { code
: "globalThis.Math.pow(a, b)", env
: { es2017
: true } },
78 globalThis.Math.pow(a, b)
86 invalid("Math.pow(a, b)", "a**b"),
87 invalid("(Math).pow(a, b)", "a**b"),
88 invalid("Math['pow'](a, b)", "a**b"),
89 invalid("(Math)['pow'](a, b)", "a**b"),
90 invalid("var x=Math\n. pow( a, \n b )", "var x=a**b"),
92 code
: "globalThis.Math.pow(a, b)",
94 env
: { es2020
: true },
97 messageId
: "useExponentiation",
98 type
: "CallExpression",
107 code
: "globalThis.Math['pow'](a, b)",
109 env
: { es2020
: true },
112 messageId
: "useExponentiation",
113 type
: "CallExpression",
122 // able to catch some workarounds
123 invalid("Math[`pow`](a, b)", "a**b"),
124 invalid("Math[`${'pow'}`](a, b)", "a**b"),
125 invalid("Math['p' + 'o' + 'w'](a, b)", "a**b"),
127 // non-expression parents that don't require parens
128 invalid("var x = Math.pow(a, b);", "var x = a**b;"),
129 invalid("if(Math.pow(a, b)){}", "if(a**b){}"),
130 invalid("for(;Math.pow(a, b);){}", "for(;a**b;){}"),
131 invalid("switch(foo){ case Math.pow(a, b): break; }", "switch(foo){ case a**b: break; }"),
132 invalid("{ foo: Math.pow(a, b) }", "{ foo: a**b }"),
133 invalid("function foo(bar, baz = Math.pow(a, b), quux){}", "function foo(bar, baz = a**b, quux){}"),
134 invalid("`${Math.pow(a, b)}`", "`${a**b}`"),
136 // non-expression parents that do require parens
137 invalid("class C extends Math.pow(a, b) {}", "class C extends (a**b) {}"),
139 // parents with a higher precedence
140 invalid("+ Math.pow(a, b)", "+ (a**b)"),
141 invalid("- Math.pow(a, b)", "- (a**b)"),
142 invalid("! Math.pow(a, b)", "! (a**b)"),
143 invalid("typeof Math.pow(a, b)", "typeof (a**b)"),
144 invalid("void Math.pow(a, b)", "void (a**b)"),
145 invalid("Math.pow(a, b) .toString()", "(a**b) .toString()"),
146 invalid("Math.pow(a, b) ()", "(a**b) ()"),
147 invalid("Math.pow(a, b) ``", "(a**b) ``"),
148 invalid("(class extends Math.pow(a, b) {})", "(class extends (a**b) {})"),
150 // already parenthesised, shouldn't insert extra parens
151 invalid("+(Math.pow(a, b))", "+(a**b)"),
152 invalid("(Math.pow(a, b)).toString()", "(a**b).toString()"),
153 invalid("(class extends (Math.pow(a, b)) {})", "(class extends (a**b) {})"),
154 invalid("class C extends (Math.pow(a, b)) {}", "class C extends (a**b) {}"),
156 // parents with a higher precedence, but the expression's role doesn't require parens
157 invalid("f(Math.pow(a, b))", "f(a**b)"),
158 invalid("f(foo, Math.pow(a, b))", "f(foo, a**b)"),
159 invalid("f(Math.pow(a, b), foo)", "f(a**b, foo)"),
160 invalid("f(foo, Math.pow(a, b), bar)", "f(foo, a**b, bar)"),
161 invalid("new F(Math.pow(a, b))", "new F(a**b)"),
162 invalid("new F(foo, Math.pow(a, b))", "new F(foo, a**b)"),
163 invalid("new F(Math.pow(a, b), foo)", "new F(a**b, foo)"),
164 invalid("new F(foo, Math.pow(a, b), bar)", "new F(foo, a**b, bar)"),
165 invalid("obj[Math.pow(a, b)]", "obj[a**b]"),
166 invalid("[foo, Math.pow(a, b), bar]", "[foo, a**b, bar]"),
168 // parents with a lower precedence
169 invalid("a * Math.pow(b, c)", "a * b**c"),
170 invalid("Math.pow(a, b) * c", "a**b * c"),
171 invalid("a + Math.pow(b, c)", "a + b**c"),
172 invalid("Math.pow(a, b)/c", "a**b/c"),
173 invalid("a < Math.pow(b, c)", "a < b**c"),
174 invalid("Math.pow(a, b) > c", "a**b > c"),
175 invalid("a === Math.pow(b, c)", "a === b**c"),
176 invalid("a ? Math.pow(b, c) : d", "a ? b**c : d"),
177 invalid("a = Math.pow(b, c)", "a = b**c"),
178 invalid("a += Math.pow(b, c)", "a += b**c"),
179 invalid("function *f() { yield Math.pow(a, b) }", "function *f() { yield a**b }"),
180 invalid("a, Math.pow(b, c), d", "a, b**c, d"),
182 // '**' is right-associative, that applies to both parent and child nodes
183 invalid("a ** Math.pow(b, c)", "a ** b**c"),
184 invalid("Math.pow(a, b) ** c", "(a**b) ** c"),
185 invalid("Math.pow(a, b ** c)", "a**b ** c"),
186 invalid("Math.pow(a ** b, c)", "(a ** b)**c"),
187 invalid("a ** Math.pow(b ** c, d ** e) ** f", "a ** ((b ** c)**d ** e) ** f"),
189 // doesn't remove already existing unnecessary parens around the whole expression
190 invalid("(Math.pow(a, b))", "(a**b)"),
191 invalid("foo + (Math.pow(a, b))", "foo + (a**b)"),
192 invalid("(Math.pow(a, b)) + foo", "(a**b) + foo"),
193 invalid("`${(Math.pow(a, b))}`", "`${(a**b)}`"),
195 // base and exponent with a higher precedence
196 invalid("Math.pow(2, 3)", "2**3"),
197 invalid("Math.pow(a.foo, b)", "a.foo**b"),
198 invalid("Math.pow(a, b.foo)", "a**b.foo"),
199 invalid("Math.pow(a(), b)", "a()**b"),
200 invalid("Math.pow(a, b())", "a**b()"),
201 invalid("Math.pow(++a, ++b)", "++a**++b"),
202 invalid("Math.pow(a++, ++b)", "a++**++b"),
203 invalid("Math.pow(a--, b--)", "a--**b--"),
204 invalid("Math.pow(--a, b--)", "--a**b--"),
206 // doesn't preserve unnecessary parens around base and exponent
207 invalid("Math.pow((a), (b))", "a**b"),
208 invalid("Math.pow(((a)), ((b)))", "a**b"),
209 invalid("Math.pow((a.foo), b)", "a.foo**b"),
210 invalid("Math.pow(a, (b.foo))", "a**b.foo"),
211 invalid("Math.pow((a()), b)", "a()**b"),
212 invalid("Math.pow(a, (b()))", "a**b()"),
214 // unary expressions are exception by the language - parens are required for the base to disambiguate operator precedence
215 invalid("Math.pow(+a, b)", "(+a)**b"),
216 invalid("Math.pow(a, +b)", "a**+b"),
217 invalid("Math.pow(-a, b)", "(-a)**b"),
218 invalid("Math.pow(a, -b)", "a**-b"),
219 invalid("Math.pow(-2, 3)", "(-2)**3"),
220 invalid("Math.pow(2, -3)", "2**-3"),
222 // base and exponent with a lower precedence
223 invalid("Math.pow(a * b, c)", "(a * b)**c"),
224 invalid("Math.pow(a, b * c)", "a**(b * c)"),
225 invalid("Math.pow(a / b, c)", "(a / b)**c"),
226 invalid("Math.pow(a, b / c)", "a**(b / c)"),
227 invalid("Math.pow(a + b, 3)", "(a + b)**3"),
228 invalid("Math.pow(2, a - b)", "2**(a - b)"),
229 invalid("Math.pow(a + b, c + d)", "(a + b)**(c + d)"),
230 invalid("Math.pow(a = b, c = d)", "(a = b)**(c = d)"),
231 invalid("Math.pow(a += b, c -= d)", "(a += b)**(c -= d)"),
232 invalid("Math.pow((a, b), (c, d))", "(a, b)**(c, d)"),
233 invalid("function *f() { Math.pow(yield, yield) }", "function *f() { (yield)**(yield) }"),
235 // doesn't put extra parens
236 invalid("Math.pow((a + b), (c + d))", "(a + b)**(c + d)"),
238 // tokens that can be adjacent
239 invalid("a+Math.pow(b, c)+d", "a+b**c+d"),
241 // tokens that cannot be adjacent
242 invalid("a+Math.pow(++b, c)", "a+ ++b**c"),
243 invalid("(a)+(Math).pow((++b), c)", "(a)+ ++b**c"),
244 invalid("Math.pow(a, b)in c", "a**b in c"),
245 invalid("Math.pow(a, (b))in (c)", "a**b in (c)"),
246 invalid("a+Math.pow(++b, c)in d", "a+ ++b**c in d"),
247 invalid("a+Math.pow( ++b, c )in d", "a+ ++b**c in d"),
249 // tokens that cannot be adjacent, but there is already space or something else between
250 invalid("a+ Math.pow(++b, c) in d", "a+ ++b**c in d"),
251 invalid("a+/**/Math.pow(++b, c)/**/in d", "a+/**/++b**c/**/in d"),
252 invalid("a+(Math.pow(++b, c))in d", "a+(++b**c)in d"),
254 // tokens that cannot be adjacent, but the autofix inserts parens required for precedence, so there is no need for an extra space
255 invalid("+Math.pow(++a, b)", "+(++a**b)"),
256 invalid("Math.pow(a, b + c)in d", "a**(b + c)in d"),
259 code
: "Math.pow(a, b) + Math.pow(c,\n d)",
260 output
: "a**b + c**d",
263 messageId
: "useExponentiation",
264 type
: "CallExpression",
271 messageId
: "useExponentiation",
272 type
: "CallExpression",
281 code
: "Math.pow(Math.pow(a, b), Math.pow(c, d))",
282 output
: "Math.pow(a, b)**Math.pow(c, d)", // tests perform only one autofix iteration, below is the following one
285 messageId
: "useExponentiation",
286 type
: "CallExpression",
291 messageId
: "useExponentiation",
292 type
: "CallExpression",
297 messageId
: "useExponentiation",
298 type
: "CallExpression",
305 code
: "Math.pow(a, b)**Math.pow(c, d)",
306 output
: "(a**b)**c**d",
309 messageId
: "useExponentiation",
310 type
: "CallExpression",
315 messageId
: "useExponentiation",
316 type
: "CallExpression",
323 // shouldn't autofix if the call doesn't have exactly two arguments
324 invalid("Math.pow()", null),
325 invalid("Math.pow(a)", null),
326 invalid("Math.pow(a, b, c)", null),
327 invalid("Math.pow(a, b, c, d)", null),
329 // shouldn't autofix if any of the arguments is spread
330 invalid("Math.pow(...a)", null),
331 invalid("Math.pow(...a, b)", null),
332 invalid("Math.pow(a, ...b)", null),
333 invalid("Math.pow(a, b, ...c)", null),
335 // shouldn't autofix if that would remove comments
336 invalid("/* comment */Math.pow(a, b)", "/* comment */a**b"),
337 invalid("Math/**/.pow(a, b)", null),
338 invalid("Math//\n.pow(a, b)", null),
339 invalid("Math[//\n'pow'](a, b)", null),
340 invalid("Math['pow'/**/](a, b)", null),
341 invalid("Math./**/pow(a, b)", null),
342 invalid("Math.pow/**/(a, b)", null),
343 invalid("Math.pow//\n(a, b)", null),
344 invalid("Math.pow(/**/a, b)", null),
345 invalid("Math.pow(a,//\n b)", null),
346 invalid("Math.pow(a, b/**/)", null),
347 invalid("Math.pow(a, b//\n)", null),
348 invalid("Math.pow(a, b)/* comment */;", "a**b/* comment */;"),
349 invalid("Math.pow(a, b)// comment\n;", "a**b// comment\n;")