]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/lib/rules/complexity.js
2 * @fileoverview Tests for complexity rule.
3 * @author Patrick Brosset
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const rule
= require("../../../lib/rules/complexity"),
13 { RuleTester
} = require("../../../lib/rule-tester");
15 //------------------------------------------------------------------------------
17 //------------------------------------------------------------------------------
20 * Generates a code string with the amount of complexity specified in the parameter
21 * @param {int} complexity The level of complexity
22 * @returns {string} Code with the amount of complexity specified in the parameter
25 function createComplexity(complexity
) {
26 let funcString
= "function test (a) { if (a === 1) {";
28 for (let i
= 2; i
< complexity
; i
++) {
29 funcString
+= `} else if (a === ${i}) {`;
38 * Create an expected error object
39 * @param {string} name The name of the symbol being tested
40 * @param {number} complexity The cyclomatic complexity value of the symbol
41 * @param {number} max The maximum cyclomatic complexity value of the symbol
42 * @returns {Object} The error object
44 function makeError(name
, complexity
, max
) {
47 data
: { name
, complexity
, max
}
51 //------------------------------------------------------------------------------
53 //------------------------------------------------------------------------------
55 const ruleTester
= new RuleTester({ parserOptions
: { ecmaVersion
: 2021 } });
57 ruleTester
.run("complexity", rule
, {
60 { code
: "function b(x) {}", options
: [1] },
61 { code
: "function a(x) {if (true) {return x;}}", options
: [2] },
62 { code
: "function a(x) {if (true) {return x;} else {return x+1;}}", options
: [2] },
63 { code
: "function a(x) {if (true) {return x;} else if (false) {return x+1;} else {return 4;}}", options
: [3] },
64 { code
: "function a(x) {for(var i = 0; i < 5; i ++) {x ++;} return x;}", options
: [2] },
65 { code
: "function a(obj) {for(var i in obj) {obj[i] = 3;}}", options
: [2] },
66 { code
: "function a(x) {for(var i = 0; i < 5; i ++) {if(i % 2 === 0) {x ++;}} return x;}", options
: [3] },
67 { code
: "function a(obj) {if(obj){ for(var x in obj) {try {x.getThis();} catch (e) {x.getThat();}}} else {return false;}}", options
: [4] },
68 { code
: "function a(x) {try {x.getThis();} catch (e) {x.getThat();}}", options
: [2] },
69 { code
: "function a(x) {return x === 4 ? 3 : 5;}", options
: [2] },
70 { code
: "function a(x) {return x === 4 ? 3 : (x === 3 ? 2 : 1);}", options
: [3] },
71 { code
: "function a(x) {return x || 4;}", options
: [2] },
72 { code
: "function a(x) {x && 4;}", options
: [2] },
73 { code
: "function a(x) {x ?? 4;}", options
: [2] },
74 { code
: "function a(x) {x ||= 4;}", options
: [2] },
75 { code
: "function a(x) {x &&= 4;}", options
: [2] },
76 { code
: "function a(x) {x ??= 4;}", options
: [2] },
77 { code
: "function a(x) {x = 4;}", options
: [1] },
78 { code
: "function a(x) {x |= 4;}", options
: [1] },
79 { code
: "function a(x) {x &= 4;}", options
: [1] },
80 { code
: "function a(x) {x += 4;}", options
: [1] },
81 { code
: "function a(x) {x >>= 4;}", options
: [1] },
82 { code
: "function a(x) {x >>>= 4;}", options
: [1] },
83 { code
: "function a(x) {x == 4;}", options
: [1] },
84 { code
: "function a(x) {x === 4;}", options
: [1] },
85 { code
: "function a(x) {switch(x){case 1: 1; break; case 2: 2; break; default: 3;}}", options
: [3] },
86 { code
: "function a(x) {switch(x){case 1: 1; break; case 2: 2; break; default: if(x == 'foo') {5;};}}", options
: [4] },
87 { code
: "function a(x) {while(true) {'foo';}}", options
: [2] },
88 { code
: "function a(x) {do {'foo';} while (true)}", options
: [2] },
89 { code
: "if (foo) { bar(); }", options
: [3] },
90 { code
: "var a = (x) => {do {'foo';} while (true)}", options
: [2], parserOptions
: { ecmaVersion
: 6 } },
93 { code
: "function foo() { class C { x = a || b; y = c || d; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
94 { code
: "function foo() { class C { static x = a || b; static y = c || d; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
95 { code
: "function foo() { class C { x = a || b; y = c || d; } e || f; }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
96 { code
: "function foo() { a || b; class C { x = c || d; y = e || f; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
97 { code
: "function foo() { class C { [x || y] = a || b; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
98 { code
: "class C { x = a || b; y() { c || d; } z = e || f; }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
99 { code
: "class C { x() { a || b; } y = c || d; z() { e || f; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
100 { code
: "class C { x = (() => { a || b }) || (() => { c || d }) }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
101 { code
: "class C { x = () => { a || b }; y = () => { c || d } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
102 { code
: "class C { x = a || (() => { b || c }); }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
103 { code
: "class C { x = class { y = a || b; z = c || d; }; }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
104 { code
: "class C { x = a || class { y = b || c; z = d || e; }; }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
105 { code
: "class C { x; y = a; static z; static q = b; }", options
: [1], parserOptions
: { ecmaVersion
: 2022 } },
107 // class static blocks
108 { code
: "function foo() { class C { static { a || b; } static { c || d; } } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
109 { code
: "function foo() { a || b; class C { static { c || d; } } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
110 { code
: "function foo() { class C { static { a || b; } } c || d; }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
111 { code
: "function foo() { class C { static { a || b; } } class D { static { c || d; } } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
112 { code
: "class C { static { a || b; } static { c || d; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
113 { code
: "class C { static { a || b; } static { c || d; } static { e || f; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
114 { code
: "class C { static { () => a || b; c || d; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
115 { code
: "class C { static { a || b; () => c || d; } static { c || d; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
116 { code
: "class C { static { a } }", options
: [1], parserOptions
: { ecmaVersion
: 2022 } },
117 { code
: "class C { static { a } static { b } }", options
: [1], parserOptions
: { ecmaVersion
: 2022 } },
118 { code
: "class C { static { a || b; } } class D { static { c || d; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
119 { code
: "class C { static { a || b; } static c = d || e; }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
120 { code
: "class C { static a = b || c; static { c || d; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
121 { code
: "class C { static { a || b; } c = d || e; }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
122 { code
: "class C { a = b || c; static { d || e; } }", options
: [2], parserOptions
: { ecmaVersion
: 2022 } },
123 { code
: "class C { static { a || b; c || d; } }", options
: [3], parserOptions
: { ecmaVersion
: 2022 } },
124 { code
: "class C { static { if (a || b) c = d || e; } }", options
: [4], parserOptions
: { ecmaVersion
: 2022 } },
126 // object property options
127 { code
: "function b(x) {}", options
: [{ max
: 1 }] }
130 { code
: "function a(x) {}", options
: [0], errors
: [makeError("Function 'a'", 1, 0)] },
131 { code
: "var func = function () {}", options
: [0], errors
: [makeError("Function", 1, 0)] },
132 { code
: "var obj = { a(x) {} }", options
: [0], parserOptions
: { ecmaVersion
: 6 }, errors
: [makeError("Method 'a'", 1, 0)] },
133 { code
: "class Test { a(x) {} }", options
: [0], parserOptions
: { ecmaVersion
: 6 }, errors
: [makeError("Method 'a'", 1, 0)] },
134 { code
: "var a = (x) => {if (true) {return x;}}", options
: [1], parserOptions
: { ecmaVersion
: 6 }, errors
: 1 },
135 { code
: "function a(x) {if (true) {return x;}}", options
: [1], errors
: 1 },
136 { code
: "function a(x) {if (true) {return x;} else {return x+1;}}", options
: [1], errors
: 1 },
137 { code
: "function a(x) {if (true) {return x;} else if (false) {return x+1;} else {return 4;}}", options
: [2], errors
: 1 },
138 { code
: "function a(x) {for(var i = 0; i < 5; i ++) {x ++;} return x;}", options
: [1], errors
: 1 },
139 { code
: "function a(obj) {for(var i in obj) {obj[i] = 3;}}", options
: [1], errors
: 1 },
140 { code
: "function a(obj) {for(var i of obj) {obj[i] = 3;}}", options
: [1], parserOptions
: { ecmaVersion
: 6 }, errors
: 1 },
141 { code
: "function a(x) {for(var i = 0; i < 5; i ++) {if(i % 2 === 0) {x ++;}} return x;}", options
: [2], errors
: 1 },
142 { code
: "function a(obj) {if(obj){ for(var x in obj) {try {x.getThis();} catch (e) {x.getThat();}}} else {return false;}}", options
: [3], errors
: 1 },
143 { code
: "function a(x) {try {x.getThis();} catch (e) {x.getThat();}}", options
: [1], errors
: 1 },
144 { code
: "function a(x) {return x === 4 ? 3 : 5;}", options
: [1], errors
: 1 },
145 { code
: "function a(x) {return x === 4 ? 3 : (x === 3 ? 2 : 1);}", options
: [2], errors
: 1 },
146 { code
: "function a(x) {return x || 4;}", options
: [1], errors
: 1 },
147 { code
: "function a(x) {x && 4;}", options
: [1], errors
: 1 },
148 { code
: "function a(x) {x ?? 4;}", options
: [1], errors
: 1 },
149 { code
: "function a(x) {x ||= 4;}", options
: [1], errors
: 1 },
150 { code
: "function a(x) {x &&= 4;}", options
: [1], errors
: 1 },
151 { code
: "function a(x) {x ??= 4;}", options
: [1], errors
: 1 },
152 { code
: "function a(x) {switch(x){case 1: 1; break; case 2: 2; break; default: 3;}}", options
: [2], errors
: 1 },
153 { code
: "function a(x) {switch(x){case 1: 1; break; case 2: 2; break; default: if(x == 'foo') {5;};}}", options
: [3], errors
: 1 },
154 { code
: "function a(x) {while(true) {'foo';}}", options
: [1], errors
: 1 },
155 { code
: "function a(x) {do {'foo';} while (true)}", options
: [1], errors
: 1 },
156 { code
: "function a(x) {(function() {while(true){'foo';}})(); (function() {while(true){'bar';}})();}", options
: [1], errors
: 2 },
157 { code
: "function a(x) {(function() {while(true){'foo';}})(); (function() {'bar';})();}", options
: [1], errors
: 1 },
158 { code
: "var obj = { a(x) { return x ? 0 : 1; } };", options
: [1], parserOptions
: { ecmaVersion
: 6 }, errors
: [makeError("Method 'a'", 2, 1)] },
159 { code
: "var obj = { a: function b(x) { return x ? 0 : 1; } };", options
: [1], errors
: [makeError("Method 'a'", 2, 1)] },
161 code
: createComplexity(21),
162 errors
: [makeError("Function 'test'", 21, 20)]
165 code
: createComplexity(21),
167 errors
: [makeError("Function 'test'", 21, 20)]
172 code
: "function foo () { a || b; class C { x; } c || d; }",
174 parserOptions
: { ecmaVersion
: 2022 },
175 errors
: [makeError("Function 'foo'", 3, 2)]
178 code
: "function foo () { a || b; class C { x = c; } d || e; }",
180 parserOptions
: { ecmaVersion
: 2022 },
181 errors
: [makeError("Function 'foo'", 3, 2)]
184 code
: "function foo () { a || b; class C { [x || y]; } }",
186 parserOptions
: { ecmaVersion
: 2022 },
187 errors
: [makeError("Function 'foo'", 3, 2)]
190 code
: "function foo () { a || b; class C { [x || y] = c; } }",
192 parserOptions
: { ecmaVersion
: 2022 },
193 errors
: [makeError("Function 'foo'", 3, 2)]
196 code
: "function foo () { class C { [x || y]; } a || b; }",
198 parserOptions
: { ecmaVersion
: 2022 },
199 errors
: [makeError("Function 'foo'", 3, 2)]
202 code
: "function foo () { class C { [x || y] = a; } b || c; }",
204 parserOptions
: { ecmaVersion
: 2022 },
205 errors
: [makeError("Function 'foo'", 3, 2)]
208 code
: "function foo () { class C { [x || y]; [z || q]; } }",
210 parserOptions
: { ecmaVersion
: 2022 },
211 errors
: [makeError("Function 'foo'", 3, 2)]
214 code
: "function foo () { class C { [x || y] = a; [z || q] = b; } }",
216 parserOptions
: { ecmaVersion
: 2022 },
217 errors
: [makeError("Function 'foo'", 3, 2)]
220 code
: "function foo () { a || b; class C { x = c || d; } e || f; }",
222 parserOptions
: { ecmaVersion
: 2022 },
223 errors
: [makeError("Function 'foo'", 3, 2)]
226 code
: "class C { x(){ a || b; } y = c || d || e; z() { f || g; } }",
228 parserOptions
: { ecmaVersion
: 2022 },
229 errors
: [makeError("Class field initializer", 3, 2)]
232 code
: "class C { x = a || b; y() { c || d || e; } z = f || g; }",
234 parserOptions
: { ecmaVersion
: 2022 },
235 errors
: [makeError("Method 'y'", 3, 2)]
238 code
: "class C { x; y() { c || d || e; } z; }",
240 parserOptions
: { ecmaVersion
: 2022 },
241 errors
: [makeError("Method 'y'", 3, 2)]
244 code
: "class C { x = a || b; }",
246 parserOptions
: { ecmaVersion
: 2022 },
247 errors
: [makeError("Class field initializer", 2, 1)]
250 code
: "(class { x = a || b; })",
252 parserOptions
: { ecmaVersion
: 2022 },
253 errors
: [makeError("Class field initializer", 2, 1)]
256 code
: "class C { static x = a || b; }",
258 parserOptions
: { ecmaVersion
: 2022 },
259 errors
: [makeError("Class field initializer", 2, 1)]
262 code
: "(class { x = a ? b : c; })",
264 parserOptions
: { ecmaVersion
: 2022 },
265 errors
: [makeError("Class field initializer", 2, 1)]
268 code
: "class C { x = a || b || c; }",
270 parserOptions
: { ecmaVersion
: 2022 },
271 errors
: [makeError("Class field initializer", 3, 2)]
274 code
: "class C { x = a || b; y = b || c || d; z = e || f; }",
276 parserOptions
: { ecmaVersion
: 2022 },
278 ...makeError("Class field initializer", 3, 2),
286 code
: "class C { x = a || b || c; y = d || e; z = f || g || h; }",
288 parserOptions
: { ecmaVersion
: 2022 },
291 ...makeError("Class field initializer", 3, 2),
298 ...makeError("Class field initializer", 3, 2),
307 code
: "class C { x = () => a || b || c; }",
309 parserOptions
: { ecmaVersion
: 2022 },
310 errors
: [makeError("Method 'x'", 3, 2)]
313 code
: "class C { x = (() => a || b || c) || d; }",
315 parserOptions
: { ecmaVersion
: 2022 },
316 errors
: [makeError("Arrow function", 3, 2)]
319 code
: "class C { x = () => a || b || c; y = d || e; }",
321 parserOptions
: { ecmaVersion
: 2022 },
322 errors
: [makeError("Method 'x'", 3, 2)]
325 code
: "class C { x = () => a || b || c; y = d || e || f; }",
327 parserOptions
: { ecmaVersion
: 2022 },
329 makeError("Method 'x'", 3, 2),
331 ...makeError("Class field initializer", 3, 2),
340 code
: "class C { x = function () { a || b }; y = function () { c || d }; }",
342 parserOptions
: { ecmaVersion
: 2022 },
344 makeError("Method 'x'", 2, 1),
345 makeError("Method 'y'", 2, 1)
349 code
: "class C { x = class { [y || z]; }; }",
351 parserOptions
: { ecmaVersion
: 2022 },
354 ...makeError("Class field initializer", 2, 1),
363 code
: "class C { x = class { [y || z] = a; }; }",
365 parserOptions
: { ecmaVersion
: 2022 },
368 ...makeError("Class field initializer", 2, 1),
377 code
: "class C { x = class { y = a || b; }; }",
379 parserOptions
: { ecmaVersion
: 2022 },
382 ...makeError("Class field initializer", 2, 1),
391 // class static blocks
393 code
: "function foo () { a || b; class C { static {} } c || d; }",
395 parserOptions
: { ecmaVersion
: 2022 },
396 errors
: [makeError("Function 'foo'", 3, 2)]
399 code
: "function foo () { a || b; class C { static { c || d; } } e || f; }",
401 parserOptions
: { ecmaVersion
: 2022 },
402 errors
: [makeError("Function 'foo'", 3, 2)]
405 code
: "class C { static { a || b; } }",
407 parserOptions
: { ecmaVersion
: 2022 },
408 errors
: [makeError("Class static block", 2, 1)]
411 code
: "class C { static { a || b || c; } }",
413 parserOptions
: { ecmaVersion
: 2022 },
414 errors
: [makeError("Class static block", 3, 2)]
417 code
: "class C { static { a || b; c || d; } }",
419 parserOptions
: { ecmaVersion
: 2022 },
420 errors
: [makeError("Class static block", 3, 2)]
423 code
: "class C { static { a || b; c || d; e || f; } }",
425 parserOptions
: { ecmaVersion
: 2022 },
426 errors
: [makeError("Class static block", 4, 3)]
429 code
: "class C { static { a || b; c || d; { e || f; } } }",
431 parserOptions
: { ecmaVersion
: 2022 },
432 errors
: [makeError("Class static block", 4, 3)]
435 code
: "class C { static { if (a || b) c = d || e; } }",
437 parserOptions
: { ecmaVersion
: 2022 },
438 errors
: [makeError("Class static block", 4, 3)]
441 code
: "class C { static { if (a || b) c = (d => e || f)() || (g => h || i)(); } }",
443 parserOptions
: { ecmaVersion
: 2022 },
444 errors
: [makeError("Class static block", 4, 3)]
447 code
: "class C { x(){ a || b; } static { c || d || e; } z() { f || g; } }",
449 parserOptions
: { ecmaVersion
: 2022 },
450 errors
: [makeError("Class static block", 3, 2)]
453 code
: "class C { x = a || b; static { c || d || e; } y = f || g; }",
455 parserOptions
: { ecmaVersion
: 2022 },
456 errors
: [makeError("Class static block", 3, 2)]
459 code
: "class C { static x = a || b; static { c || d || e; } static y = f || g; }",
461 parserOptions
: { ecmaVersion
: 2022 },
462 errors
: [makeError("Class static block", 3, 2)]
465 code
: "class C { static { a || b; } static(){ c || d || e; } static { f || g; } }",
467 parserOptions
: { ecmaVersion
: 2022 },
468 errors
: [makeError("Method 'static'", 3, 2)]
471 code
: "class C { static { a || b; } static static(){ c || d || e; } static { f || g; } }",
473 parserOptions
: { ecmaVersion
: 2022 },
474 errors
: [makeError("Static method 'static'", 3, 2)]
477 code
: "class C { static { a || b; } static x = c || d || e; static { f || g; } }",
479 parserOptions
: { ecmaVersion
: 2022 },
481 ...makeError("Class field initializer", 3, 2),
487 code
: "class C { static { a || b || c || d; } static { e || f || g; } }",
489 parserOptions
: { ecmaVersion
: 2022 },
491 ...makeError("Class static block", 4, 3),
497 code
: "class C { static { a || b || c; } static { d || e || f || g; } }",
499 parserOptions
: { ecmaVersion
: 2022 },
501 ...makeError("Class static block", 4, 3),
507 code
: "class C { static { a || b || c || d; } static { e || f || g || h; } }",
509 parserOptions
: { ecmaVersion
: 2022 },
512 ...makeError("Class static block", 4, 3),
517 ...makeError("Class static block", 4, 3),
524 // object property options
525 { code
: "function a(x) {}", options
: [{ max
: 0 }], errors
: [makeError("Function 'a'", 1, 0)] }