]> git.proxmox.com Git - pve-eslint.git/blame - eslint/tests/lib/rules/no-setter-return.js
import 8.3.0 source
[pve-eslint.git] / eslint / tests / lib / rules / no-setter-return.js
CommitLineData
eb39fafa
DC
1/**
2 * @fileoverview Tests for the no-setter-return rule
3 * @author Milos Djermanovic
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Requirements
10//------------------------------------------------------------------------------
11
12const rule = require("../../../lib/rules/no-setter-return");
13const { RuleTester } = require("../../../lib/rule-tester");
14
15//------------------------------------------------------------------------------
16// Helpers
17//------------------------------------------------------------------------------
18
19/**
20 * Creates an error object.
21 * @param {number} [column] Reported column.
22 * @param {string} [type= "ReturnStatement"] Reported node type.
23 * @returns {Object} The error object.
24 */
25function error(column, type = "ReturnStatement") {
26 const errorObject = {
27 messageId: "returnsValue",
28 type
29 };
30
31 if (column) {
32 errorObject.column = column;
33 }
34
35 return errorObject;
36}
37
38//------------------------------------------------------------------------------
39// Tests
40//------------------------------------------------------------------------------
41
609c276f 42const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2022 } });
eb39fafa
DC
43
44ruleTester.run("no-setter-return", rule, {
45 valid: [
46
47 //------------------------------------------------------------------------------
48 // General
49 //------------------------------------------------------------------------------
50
51 // not a setter
52 "function foo() { return 1; }",
53 "function set(val) { return 1; }",
54 "var foo = function() { return 1; };",
55 "var foo = function set() { return 1; };",
56 "var set = function() { return 1; };",
57 "var set = function set(val) { return 1; };",
58 "var set = val => { return 1; };",
59 "var set = val => 1;",
60
61 // setters do not have effect on other functions (test function info tracking)
62 "({ set a(val) { }}); function foo() { return 1; }",
63 "({ set a(val) { }}); (function () { return 1; });",
64 "({ set a(val) { }}); (() => { return 1; });",
65 "({ set a(val) { }}); (() => 1);",
66
67 // does not report global return
68 {
69 code: "return 1;",
70 env: { node: true }
71 },
72 {
73 code: "return 1;",
74 parserOptions: { ecmaFeatures: { globalReturn: true } }
75 },
76 {
77 code: "return 1; function foo(){ return 1; } return 1;",
78 env: { node: true }
79 },
80 {
81 code: "function foo(){} return 1; var bar = function*(){ return 1; }; return 1; var baz = () => {}; return 1;",
82 env: { node: true }
83 },
84
85 //------------------------------------------------------------------------------
86 // Object literals and classes
87 //------------------------------------------------------------------------------
88
89 // return without a value is allowed
90 "({ set foo(val) { return; } })",
91 "({ set foo(val) { if (val) { return; } } })",
92 "class A { set foo(val) { return; } }",
93 "(class { set foo(val) { if (val) { return; } else { return; } return; } })",
94 "class A { set foo(val) { try {} catch(e) { return; } } }",
95
96 // not a setter
97 "({ get foo() { return 1; } })",
98 "({ get set() { return 1; } })",
99 "({ set(val) { return 1; } })",
100 "({ set: function(val) { return 1; } })",
101 "({ foo: function set(val) { return 1; } })",
102 "({ set: function set(val) { return 1; } })",
103 "({ set: (val) => { return 1; } })",
104 "({ set: (val) => 1 })",
105 "set = { foo(val) { return 1; } };",
106 "class A { constructor(val) { return 1; } }",
107 "class set { constructor(val) { return 1; } }",
108 "class set { foo(val) { return 1; } }",
109 "var set = class { foo(val) { return 1; } }",
110 "(class set { foo(val) { return 1; } })",
111 "class A { get foo() { return val; } }",
112 "class A { get set() { return val; } }",
113 "class A { set(val) { return 1; } }",
114 "class A { static set(val) { return 1; } }",
115 "({ set: set = function set(val) { return 1; } } = {})",
116 "({ set: set = (val) => 1 } = {})",
609c276f 117 "class C { set; foo() { return 1; } }",
eb39fafa
DC
118
119 // not returning from the setter
120 "({ set foo(val) { function foo(val) { return 1; } } })",
121 "({ set foo(val) { var foo = function(val) { return 1; } } })",
122 "({ set foo(val) { var foo = (val) => { return 1; } } })",
123 "({ set foo(val) { var foo = (val) => 1; } })",
124 "({ set [function() { return 1; }](val) {} })",
125 "({ set [() => { return 1; }](val) {} })",
126 "({ set [() => 1](val) {} })",
127 "({ set foo(val = function() { return 1; }) {} })",
128 "({ set foo(val = v => 1) {} })",
129 "(class { set foo(val) { function foo(val) { return 1; } } })",
130 "(class { set foo(val) { var foo = function(val) { return 1; } } })",
131 "(class { set foo(val) { var foo = (val) => { return 1; } } })",
132 "(class { set foo(val) { var foo = (val) => 1; } })",
133 "(class { set [function() { return 1; }](val) {} })",
134 "(class { set [() => { return 1; }](val) {} })",
135 "(class { set [() => 1](val) {} })",
136 "(class { set foo(val = function() { return 1; }) {} })",
137 "(class { set foo(val = (v) => 1) {} })",
138
139 //------------------------------------------------------------------------------
140 // Property descriptors
141 //------------------------------------------------------------------------------
142
143 // return without a value is allowed
144 "Object.defineProperty(foo, 'bar', { set(val) { return; } })",
145 {
146 code: "Reflect.defineProperty(foo, 'bar', { set(val) { if (val) { return; } } })",
147 env: { es6: true }
148 },
149 "Object.defineProperties(foo, { bar: { set(val) { try { return; } catch(e){} } } })",
150 "Object.create(foo, { bar: { set: function(val) { return; } } })",
151
152 // not a setter
153 "x = { set(val) { return 1; } }",
154 "x = { foo: { set(val) { return 1; } } }",
155 "Object.defineProperty(foo, 'bar', { value(val) { return 1; } })",
156 {
157 code: "Reflect.defineProperty(foo, 'bar', { value: function set(val) { return 1; } })",
158 env: { es6: true }
159 },
160 "Object.defineProperties(foo, { bar: { [set](val) { return 1; } } })",
161 "Object.create(foo, { bar: { 'set ': function(val) { return 1; } } })",
162 "Object.defineProperty(foo, 'bar', { [`set `]: (val) => { return 1; } })",
163 {
164 code: "Reflect.defineProperty(foo, 'bar', { Set(val) { return 1; } })",
165 env: { es6: true }
166 },
167 "Object.defineProperties(foo, { bar: { value: (val) => 1 } })",
168 "Object.create(foo, { set: { value: function(val) { return 1; } } })",
169 "Object.defineProperty(foo, 'bar', { baz(val) { return 1; } })",
170 {
171 code: "Reflect.defineProperty(foo, 'bar', { get(val) { return 1; } })",
172 env: { es6: true }
173 },
174 "Object.create(foo, { set: function(val) { return 1; } })",
175 "Object.defineProperty(foo, { set: (val) => 1 })",
176
177 // not returning from the setter
178 "Object.defineProperty(foo, 'bar', { set(val) { function foo() { return 1; } } })",
179 {
180 code: "Reflect.defineProperty(foo, 'bar', { set(val) { var foo = function() { return 1; } } })",
181 env: { es6: true }
182 },
183 "Object.defineProperties(foo, { bar: { set(val) { () => { return 1 }; } } })",
184 "Object.create(foo, { bar: { set: (val) => { (val) => 1; } } })",
185
186 // invalid index
187 "Object.defineProperty(foo, 'bar', 'baz', { set(val) { return 1; } })",
188 "Object.defineProperty(foo, { set(val) { return 1; } }, 'bar')",
189 "Object.defineProperty({ set(val) { return 1; } }, foo, 'bar')",
190 {
191 code: "Reflect.defineProperty(foo, 'bar', 'baz', { set(val) { return 1; } })",
192 env: { es6: true }
193 },
194 {
195 code: "Reflect.defineProperty(foo, { set(val) { return 1; } }, 'bar')",
196 env: { es6: true }
197 },
198 {
199 code: "Reflect.defineProperty({ set(val) { return 1; } }, foo, 'bar')",
200 env: { es6: true }
201 },
202 "Object.defineProperties(foo, bar, { baz: { set(val) { return 1; } } })",
203 "Object.defineProperties({ bar: { set(val) { return 1; } } }, foo)",
204 "Object.create(foo, bar, { baz: { set(val) { return 1; } } })",
205 "Object.create({ bar: { set(val) { return 1; } } }, foo)",
206
207 // not targeted method name
208 "Object.DefineProperty(foo, 'bar', { set(val) { return 1; } })",
209 {
210 code: "Reflect.DefineProperty(foo, 'bar', { set(val) { if (val) { return 1; } } })",
211 env: { es6: true }
212 },
213 "Object.DefineProperties(foo, { bar: { set(val) { try { return 1; } catch(e){} } } })",
214 "Object.Create(foo, { bar: { set: function(val) { return 1; } } })",
215
216 // not targeted object name
217 "object.defineProperty(foo, 'bar', { set(val) { return 1; } })",
218 {
219 code: "reflect.defineProperty(foo, 'bar', { set(val) { if (val) { return 1; } } })",
220 env: { es6: true }
221 },
222 {
223 code: "Reflect.defineProperties(foo, { bar: { set(val) { try { return 1; } catch(e){} } } })",
224 env: { es6: true }
225 },
226 "object.create(foo, { bar: { set: function(val) { return 1; } } })",
227
228 // global object doesn't exist
229 "Reflect.defineProperty(foo, 'bar', { set(val) { if (val) { return 1; } } })",
230 "/* globals Object:off */ Object.defineProperty(foo, 'bar', { set(val) { return 1; } })",
231 {
232 code: "Object.defineProperties(foo, { bar: { set(val) { try { return 1; } catch(e){} } } })",
233 globals: { Object: "off" }
234 },
235
236 // global object is shadowed
237 "let Object; Object.defineProperty(foo, 'bar', { set(val) { return 1; } })",
238 {
239 code: "function f() { Reflect.defineProperty(foo, 'bar', { set(val) { if (val) { return 1; } } }); var Reflect;}",
240 env: { es6: true }
241 },
242 "function f(Object) { Object.defineProperties(foo, { bar: { set(val) { try { return 1; } catch(e){} } } }) }",
243 "if (x) { const Object = getObject(); Object.create(foo, { bar: { set: function(val) { return 1; } } }) }",
244 "x = function Object() { Object.defineProperty(foo, 'bar', { set(val) { return 1; } }) }"
245 ],
246
247 invalid: [
248
249 //------------------------------------------------------------------------------
250 // Object literals and classes
251 //------------------------------------------------------------------------------
252
253 // full error test
254 {
255 code: "({ set a(val){ return val + 1; } })",
256 errors: [{ messageId: "returnsValue", type: "ReturnStatement", column: 16, endColumn: 31 }]
257 },
258
259 // basic tests
260 {
261 code: "({ set a(val) { return 1; } })",
262 errors: [error()]
263 },
264 {
265 code: "class A { set a(val) { return 1; } }",
266 errors: [error()]
267 },
268 {
269 code: "class A { static set a(val) { return 1; } }",
270 errors: [error()]
271 },
272 {
273 code: "(class { set a(val) { return 1; } })",
274 errors: [error()]
275 },
276
277 // any value
278 {
279 code: "({ set a(val) { return val; } })",
280 errors: [error()]
281 },
282 {
283 code: "class A { set a(val) { return undefined; } }",
284 errors: [error()]
285 },
286 {
287 code: "(class { set a(val) { return null; } })",
288 errors: [error()]
289 },
290 {
291 code: "({ set a(val) { return x + y; } })",
292 errors: [error()]
293 },
294 {
295 code: "class A { set a(val) { return foo(); } }",
296 errors: [error()]
297 },
298 {
299 code: "(class { set a(val) { return this._a; } })",
300 errors: [error()]
301 },
302 {
303 code: "({ set a(val) { return this.a; } })",
304 errors: [error()]
305 },
306
307 // any location
308 {
309 code: "({ set a(val) { if (foo) { return 1; }; } })",
310 errors: [error()]
311 },
312 {
313 code: "class A { set a(val) { try { return 1; } catch(e) {} } }",
314 errors: [error()]
315 },
316 {
317 code: "(class { set a(val) { while (foo){ if (bar) break; else return 1; } } })",
318 errors: [error()]
319 },
320
321 // multiple invalid in same object literal/class
322 {
323 code: "({ set a(val) { return 1; }, set b(val) { return 1; } })",
324 errors: [error(17), error(43)]
325 },
326 {
327 code: "class A { set a(val) { return 1; } set b(val) { return 1; } }",
328 errors: [error(24), error(49)]
329 },
330 {
331 code: "(class { set a(val) { return 1; } static set b(val) { return 1; } })",
332 errors: [error(23), error(55)]
333 },
334
335 // multiple invalid in the same setter
336 {
337 code: "({ set a(val) { if(val) { return 1; } else { return 2 }; } })",
338 errors: [error(27), error(46)]
339 },
340 {
341 code: "class A { set a(val) { switch(val) { case 1: return x; case 2: return y; default: return z } } }",
342 errors: [error(46), error(64), error(83)]
343 },
344 {
345 code: "(class { static set a(val) { if (val > 0) { this._val = val; return val; } return false; } })",
346 errors: [error(62), error(76)]
347 },
348
349 // valid and invalid in the same setter
350 {
351 code: "({ set a(val) { if(val) { return 1; } else { return; }; } })",
352 errors: [error(27)]
353 },
354 {
355 code: "class A { set a(val) { switch(val) { case 1: return x; case 2: return; default: return z } } }",
356 errors: [error(46), error(81)]
357 },
358 {
359 code: "(class { static set a(val) { if (val > 0) { this._val = val; return; } return false; } })",
360 errors: [error(72)]
361 },
362
363 // inner functions do not have effect
364 {
365 code: "({ set a(val) { function b(){} return b(); } })",
366 errors: [error(32)]
367 },
368 {
369 code: "class A { set a(val) { return () => {}; } }",
370 errors: [error(24)]
371 },
372 {
373 code: "(class { set a(val) { function b(){ return 1; } return 2; } })",
374 errors: [error(49)]
375 },
376 {
377 code: "({ set a(val) { function b(){ return; } return 1; } })",
378 errors: [error(41)]
379 },
380 {
381 code: "class A { set a(val) { var x = function() { return 1; }; return 2; } }",
382 errors: [error(58)]
383 },
384 {
385 code: "(class { set a(val) { var x = () => { return; }; return 2; } })",
386 errors: [error(50)]
387 },
388
389 // other functions and global returns do not have effect (test function info tracking)
390 {
391 code: "function f(){}; ({ set a(val) { return 1; } });",
392 errors: [error()]
393 },
394 {
395 code: "x = function f(){}; class A { set a(val) { return 1; } };",
396 errors: [error()]
397 },
398 {
399 code: "x = () => {}; A = class { set a(val) { return 1; } };",
400 errors: [error()]
401 },
402 {
403 code: "return; ({ set a(val) { return 1; } }); return 2;",
404 env: { node: true },
405 errors: [error(25)]
406 },
407
408 //------------------------------------------------------------------------------
409 // Property descriptors
410 //------------------------------------------------------------------------------
411
412 // basic tests
413 {
414 code: "Object.defineProperty(foo, 'bar', { set(val) { return 1; } })",
415 errors: [error()]
416 },
417 {
418 code: "Reflect.defineProperty(foo, 'bar', { set(val) { return 1; } })",
419 env: { es6: true },
420 errors: [error()]
421 },
422 {
423 code: "Object.defineProperties(foo, { baz: { set(val) { return 1; } } })",
424 errors: [error()]
425 },
426 {
427 code: "Object.create(null, { baz: { set(val) { return 1; } } })",
428 errors: [error()]
429 },
430
431 // arrow implicit return// basic tests
432 {
433 code: "Object.defineProperty(foo, 'bar', { set: val => val })",
434 errors: [error(49, "Identifier")]
435 },
436 {
437 code: "Reflect.defineProperty(foo, 'bar', { set: val => f(val) })",
438 env: { es6: true },
439 errors: [error(50, "CallExpression")]
440 },
441 {
442 code: "Object.defineProperties(foo, { baz: { set: val => a + b } })",
443 errors: [error(51, "BinaryExpression")]
444 },
445 {
446 code: "Object.create({}, { baz: { set: val => this._val } })",
447 errors: [error(40, "MemberExpression")]
448 },
449
450 // various locations, value types and multiple invalid/valid in same setter.
451 {
452 code: "Object.defineProperty(foo, 'bar', { set(val) { if (val) { return; } return false; }, get(val) { return 1; } })",
453 errors: [error(69)]
454 },
455 {
456 code: "Reflect.defineProperty(foo, 'bar', { set(val) { try { return f(val) } catch (e) { return e }; } })",
457 env: { es6: true },
458 errors: [error(55), error(83)]
459 },
460 {
461 code: "Object.defineProperties(foo, { bar: { get(){ return null; }, set(val) { return null; } } })",
462 errors: [error(73)]
463 },
464 {
465 code: "Object.create(null, { baz: { set(val) { return this._val; return; return undefined; } } })",
466 errors: [error(41), error(67)]
467 },
468
469 // multiple invalid in the same descriptors object
470 {
471 code: "Object.defineProperties(foo, { baz: { set(val) { return 1; } }, bar: { set(val) { return 1; } } })",
472 errors: [error(50), error(83)]
473 },
474 {
475 code: "Object.create({}, { baz: { set(val) { return 1; } }, bar: { set: (val) => 1 } })",
476 errors: [
477 error(39),
478 error(75, "Literal")
479 ]
480 },
481
482 // various syntax for properties
483 {
484 code: "Object['defineProperty'](foo, 'bar', { set: function bar(val) { return 1; } })",
485 errors: [error()]
486 },
487 {
488 code: "Reflect.defineProperty(foo, 'bar', { 'set'(val) { return 1; } })",
489 env: { es6: true },
490 errors: [error()]
491 },
492 {
493 code: "Object[`defineProperties`](foo, { baz: { ['set'](val) { return 1; } } })",
494 errors: [error()]
495 },
496 {
497 code: "Object.create({}, { baz: { [`set`]: (val) => { return 1; } } })",
498 errors: [error()]
499 },
500
501 // edge cases for global objects
502 {
503 code: "Object.defineProperty(foo, 'bar', { set: function Object(val) { return 1; } })",
504 errors: [error()]
505 },
506 {
507 code: "Object.defineProperty(foo, 'bar', { set: function(Object) { return 1; } })",
508 errors: [error()]
6f036462
TL
509 },
510
511 // Optional chaining
512 {
513 code: "Object?.defineProperty(foo, 'bar', { set(val) { return 1; } })",
514 parserOptions: { ecmaVersion: 2020 },
515 errors: [error()]
516 },
517 {
518 code: "(Object?.defineProperty)(foo, 'bar', { set(val) { return 1; } })",
519 parserOptions: { ecmaVersion: 2020 },
520 errors: [error()]
eb39fafa
DC
521 }
522 ]
523});