@@ -22,7 +22,7 @@ const { RuleTester } = require("../../../lib/rule-tester");
22
22
* @param {string } [type="ReturnStatement"] Reported node type.
23
23
* @returns {Object } The error object.
24
24
*/
25
- function error ( column , type = "ReturnStatement" ) {
25
+ function eReturnsValue ( column , type = "ReturnStatement" ) {
26
26
const errorObject = {
27
27
messageId : "returnsValue" ,
28
28
type
@@ -35,6 +35,26 @@ function error(column, type = "ReturnStatement") {
35
35
return errorObject ;
36
36
}
37
37
38
+
39
+ /**
40
+ * Creates invalid object
41
+ * @param {Object } [properties] suggestion properties
42
+ * @param {string } [properties.code] code
43
+ * @param {number } [properties.options] rule options
44
+ * @param {string[] } [fixes] Code suggestions
45
+ * @returns {Object } The invalid object.
46
+ */
47
+ function suggestion ( properties , fixes = [ ] ) {
48
+ return {
49
+ ...properties ,
50
+ errors : [ {
51
+ suggestions : fixes . map ( fix => ( {
52
+ output : fix
53
+ } ) )
54
+ } ]
55
+ } ;
56
+ }
57
+
38
58
//------------------------------------------------------------------------------
39
59
// Tests
40
60
//------------------------------------------------------------------------------
@@ -149,7 +169,37 @@ ruleTester.run("no-promise-executor-return", rule, {
149
169
{
150
170
code : "new Promise(function (resolve, reject) {}); return 1;" ,
151
171
env : { node : true }
152
- }
172
+ } ,
173
+
174
+ /*
175
+ * allowVoid: true
176
+ * `=> void` and `return void` are allowed
177
+ */
178
+ {
179
+ code : "new Promise((r) => void cbf(r));" ,
180
+ options : [ {
181
+ allowVoid : true
182
+ } ]
183
+ } ,
184
+ {
185
+ code : "new Promise(r => void 0)" ,
186
+ options : [ {
187
+ allowVoid : true
188
+ } ]
189
+ } ,
190
+ {
191
+ code : "new Promise(r => { return void 0 })" ,
192
+ options : [ {
193
+ allowVoid : true
194
+ } ]
195
+ } ,
196
+ {
197
+ code : "new Promise(r => { if (foo) { return void 0 } return void 0 })" ,
198
+ options : [ {
199
+ allowVoid : true
200
+ } ]
201
+ } ,
202
+ "new Promise(r => {0})"
153
203
] ,
154
204
155
205
invalid : [
@@ -161,143 +211,376 @@ ruleTester.run("no-promise-executor-return", rule, {
161
211
} ,
162
212
{
163
213
code : "new Promise((resolve, reject) => resolve(1))" ,
164
- errors : [ { message : "Return values from promise executor functions cannot be read." , type : "CallExpression" , column : 34 , endColumn : 44 } ]
214
+ options : [ {
215
+ allowVoid : true
216
+ } ] ,
217
+ errors : [ {
218
+ message : "Return values from promise executor functions cannot be read." ,
219
+ type : "CallExpression" ,
220
+ column : 34 ,
221
+ endColumn : 44 ,
222
+ suggestions : [
223
+ { output : "new Promise((resolve, reject) => void resolve(1))" } ,
224
+ { output : "new Promise((resolve, reject) => {resolve(1)})" }
225
+ ]
226
+ } ]
227
+ } ,
228
+ {
229
+ code : "new Promise((resolve, reject) => { return 1 })" ,
230
+ options : [ {
231
+ allowVoid : true
232
+ } ] ,
233
+ errors : [ {
234
+ message : "Return values from promise executor functions cannot be read." ,
235
+ type : "ReturnStatement" ,
236
+ column : 36 ,
237
+ endColumn : 44 ,
238
+ suggestions : [
239
+ { output : "new Promise((resolve, reject) => { return void 1 })" }
240
+ ]
241
+ } ]
165
242
} ,
166
243
244
+ // suggestions arrow function expression
245
+ suggestion ( {
246
+ code : "new Promise(r => 1)" ,
247
+ options : [ {
248
+ allowVoid : true
249
+ } ]
250
+ } , [
251
+ "new Promise(r => void 1)" ,
252
+ "new Promise(r => {1})"
253
+ ] ) ,
254
+ suggestion ( {
255
+ code : "new Promise(r => 1 ? 2 : 3)" ,
256
+ options : [ {
257
+ allowVoid : true
258
+ } ]
259
+ } , [
260
+ "new Promise(r => void (1 ? 2 : 3))" ,
261
+ "new Promise(r => {1 ? 2 : 3})"
262
+ ] ) ,
263
+ suggestion ( {
264
+ code : "new Promise(r => (1 ? 2 : 3))" ,
265
+ options : [ {
266
+ allowVoid : true
267
+ } ]
268
+ } , [
269
+ "new Promise(r => void (1 ? 2 : 3))" ,
270
+ "new Promise(r => {(1 ? 2 : 3)})"
271
+ ] ) ,
272
+ suggestion ( {
273
+ code :
274
+ "new Promise(r => (1))" ,
275
+ options : [ {
276
+ allowVoid : true
277
+ } ]
278
+ } , [
279
+ "new Promise(r => void (1))" ,
280
+ "new Promise(r => {(1)})"
281
+ ] ) ,
282
+ suggestion ( {
283
+ code :
284
+ "new Promise(r => () => {})" ,
285
+ options : [ {
286
+ allowVoid : true
287
+ } ]
288
+ } , [
289
+ "new Promise(r => void (() => {}))" ,
290
+ "new Promise(r => {() => {}})"
291
+ ] ) ,
292
+
293
+ // primitives
294
+ suggestion ( {
295
+ code :
296
+ "new Promise(r => null)" ,
297
+ options : [ {
298
+ allowVoid : true
299
+ } ]
300
+ } , [
301
+ "new Promise(r => void null)" ,
302
+ "new Promise(r => {null})"
303
+ ] ) ,
304
+ suggestion ( {
305
+ code :
306
+ "new Promise(r => null)" ,
307
+ options : [ {
308
+ allowVoid : false
309
+ } ]
310
+ } , [
311
+ "new Promise(r => {null})"
312
+ ] ) ,
313
+
314
+ // inline comments
315
+ suggestion ( {
316
+ code :
317
+ "new Promise(r => /*hi*/ ~0)" ,
318
+ options : [ {
319
+ allowVoid : true
320
+ } ]
321
+ } , [
322
+ "new Promise(r => /*hi*/ void ~0)" ,
323
+ "new Promise(r => /*hi*/ {~0})"
324
+ ] ) ,
325
+ suggestion ( {
326
+ code :
327
+ "new Promise(r => /*hi*/ ~0)" ,
328
+ options : [ {
329
+ allowVoid : false
330
+ } ]
331
+ } , [
332
+ "new Promise(r => /*hi*/ {~0})"
333
+ ] ) ,
334
+
335
+ // suggestions function
336
+ suggestion ( {
337
+ code :
338
+ "new Promise(r => { return 0 })" ,
339
+ options : [ {
340
+ allowVoid : true
341
+ } ]
342
+ } , [
343
+ "new Promise(r => { return void 0 })"
344
+ ] ) ,
345
+ suggestion ( {
346
+ code :
347
+ "new Promise(r => { return 0 })" ,
348
+ options : [ {
349
+ allowVoid : false
350
+ } ]
351
+ } ) ,
352
+
353
+ // multiple returns
354
+ suggestion ( {
355
+ code :
356
+ "new Promise(r => { if (foo) { return void 0 } return 0 })" ,
357
+ options : [ {
358
+ allowVoid : true
359
+ } ]
360
+ } , [
361
+ "new Promise(r => { if (foo) { return void 0 } return void 0 })"
362
+ ] ) ,
363
+
364
+ // return assignment
365
+ suggestion ( {
366
+ code : "new Promise(resolve => { return (foo = resolve(1)); })" ,
367
+ options : [ {
368
+ allowVoid : true
369
+ } ]
370
+ } , [
371
+ "new Promise(resolve => { return void (foo = resolve(1)); })"
372
+ ] ) ,
373
+ suggestion ( {
374
+ code : "new Promise(resolve => r = resolve)" ,
375
+ options : [ {
376
+ allowVoid : true
377
+ } ]
378
+ } , [
379
+ "new Promise(resolve => void (r = resolve))" ,
380
+ "new Promise(resolve => {r = resolve})"
381
+ ] ) ,
382
+
383
+ // return<immediate token> (range check)
384
+ suggestion ( {
385
+ code :
386
+ "new Promise(r => { return(1) })" ,
387
+ options : [ {
388
+ allowVoid : true
389
+ } ]
390
+ } , [
391
+ "new Promise(r => { return void (1) })"
392
+ ] ) ,
393
+ suggestion ( {
394
+ code :
395
+ "new Promise(r =>1)" ,
396
+ options : [ {
397
+ allowVoid : true
398
+ } ]
399
+ } , [
400
+ "new Promise(r =>void 1)" ,
401
+ "new Promise(r =>{1})"
402
+ ] ) ,
403
+
404
+ // snapshot
405
+ suggestion ( {
406
+ code :
407
+ "new Promise(r => ((1)))" ,
408
+ options : [ {
409
+ allowVoid : true
410
+ } ]
411
+ } , [
412
+ "new Promise(r => void ((1)))" ,
413
+ "new Promise(r => {((1))})"
414
+ ] ) ,
415
+
167
416
// other basic tests
168
417
{
169
418
code : "new Promise(function foo(resolve, reject) { return 1; })" ,
170
- errors : [ error ( ) ]
419
+ errors : [ eReturnsValue ( ) ]
171
420
} ,
172
421
{
173
422
code : "new Promise((resolve, reject) => { return 1; })" ,
174
- errors : [ error ( ) ]
423
+ errors : [ eReturnsValue ( ) ]
175
424
} ,
176
425
177
426
// any returned value
178
427
{
179
428
code : "new Promise(function (resolve, reject) { return undefined; })" ,
180
- errors : [ error ( ) ]
429
+ errors : [ eReturnsValue ( ) ]
181
430
} ,
182
431
{
183
432
code : "new Promise((resolve, reject) => { return null; })" ,
184
- errors : [ error ( ) ]
433
+ errors : [ eReturnsValue ( ) ]
185
434
} ,
186
435
{
187
436
code : "new Promise(function (resolve, reject) { return false; })" ,
188
- errors : [ error ( ) ]
437
+ errors : [ eReturnsValue ( ) ]
189
438
} ,
190
439
{
191
440
code : "new Promise((resolve, reject) => resolve)" ,
192
- errors : [ error ( 34 , "Identifier" ) ]
441
+ errors : [ eReturnsValue ( 34 , "Identifier" ) ]
193
442
} ,
194
443
{
195
444
code : "new Promise((resolve, reject) => null)" ,
196
- errors : [ error ( 34 , "Literal" ) ]
445
+ errors : [ eReturnsValue ( 34 , "Literal" ) ]
197
446
} ,
198
447
{
199
448
code : "new Promise(function (resolve, reject) { return resolve(foo); })" ,
200
- errors : [ error ( ) ]
449
+ errors : [ eReturnsValue ( ) ]
201
450
} ,
202
451
{
203
452
code : "new Promise((resolve, reject) => { return reject(foo); })" ,
204
- errors : [ error ( ) ]
453
+ errors : [ eReturnsValue ( ) ]
205
454
} ,
206
455
{
207
456
code : "new Promise((resolve, reject) => x + y)" ,
208
- errors : [ error ( 34 , "BinaryExpression" ) ]
457
+ errors : [ eReturnsValue ( 34 , "BinaryExpression" ) ]
209
458
} ,
210
459
{
211
460
code : "new Promise((resolve, reject) => { return Promise.resolve(42); })" ,
212
- errors : [ error ( ) ]
461
+ errors : [ eReturnsValue ( ) ]
213
462
} ,
214
463
215
464
// any return statement location
216
465
{
217
466
code : "new Promise(function (resolve, reject) { if (foo) { return 1; } })" ,
218
- errors : [ error ( ) ]
467
+ errors : [ eReturnsValue ( ) ]
219
468
} ,
220
469
{
221
470
code : "new Promise((resolve, reject) => { try { return 1; } catch(e) {} })" ,
222
- errors : [ error ( ) ]
471
+ errors : [ eReturnsValue ( ) ]
223
472
} ,
224
473
{
225
474
code : "new Promise(function (resolve, reject) { while (foo){ if (bar) break; else return 1; } })" ,
226
- errors : [ error ( ) ]
475
+ errors : [ eReturnsValue ( ) ]
476
+ } ,
477
+
478
+ // `return void` is not allowed without `allowVoid: true`
479
+ {
480
+ code : "new Promise(() => { return void 1; })" ,
481
+ errors : [ eReturnsValue ( ) ]
482
+ } ,
483
+
484
+ {
485
+ code : "new Promise(() => (1))" ,
486
+ errors : [ eReturnsValue ( 20 , "Literal" ) ]
487
+ } ,
488
+ {
489
+ code : "() => new Promise(() => ({}));" ,
490
+ errors : [ eReturnsValue ( 26 , "ObjectExpression" ) ]
227
491
} ,
228
492
229
493
// absence of arguments has no effect
230
494
{
231
495
code : "new Promise(function () { return 1; })" ,
232
- errors : [ error ( ) ]
496
+ errors : [ eReturnsValue ( ) ]
233
497
} ,
234
498
{
235
499
code : "new Promise(() => { return 1; })" ,
236
- errors : [ error ( ) ]
500
+ errors : [ eReturnsValue ( ) ]
237
501
} ,
238
502
{
239
503
code : "new Promise(() => 1)" ,
240
- errors : [ error ( 19 , "Literal" ) ]
504
+ errors : [ eReturnsValue ( 19 , "Literal" ) ]
241
505
} ,
242
506
243
507
// various scope tracking tests
244
508
{
245
509
code : "function foo() {} new Promise(function () { return 1; });" ,
246
- errors : [ error ( 45 ) ]
510
+ errors : [ eReturnsValue ( 45 ) ]
247
511
} ,
248
512
{
249
513
code : "function foo() { return; } new Promise(() => { return 1; });" ,
250
- errors : [ error ( 48 ) ]
514
+ errors : [ eReturnsValue ( 48 ) ]
251
515
} ,
252
516
{
253
517
code : "function foo() { return 1; } new Promise(() => { return 2; });" ,
254
- errors : [ error ( 50 ) ]
518
+ errors : [ eReturnsValue ( 50 ) ]
255
519
} ,
256
520
{
257
521
code : "function foo () { return new Promise(function () { return 1; }); }" ,
258
- errors : [ error ( 52 ) ]
522
+ errors : [ eReturnsValue ( 52 ) ]
259
523
} ,
260
524
{
261
525
code : "function foo() { return new Promise(() => { bar(() => { return 1; }); return false; }); }" ,
262
- errors : [ error ( 71 ) ]
526
+ errors : [ eReturnsValue ( 71 ) ]
263
527
} ,
264
528
{
265
529
code : "() => new Promise(() => { if (foo) { return 0; } else bar(() => { return 1; }); })" ,
266
- errors : [ error ( 38 ) ]
530
+ errors : [ eReturnsValue ( 38 ) ]
267
531
} ,
268
532
{
269
533
code : "function foo () { return 1; return new Promise(function () { return 2; }); return 3;}" ,
270
- errors : [ error ( 62 ) ]
534
+ errors : [ eReturnsValue ( 62 ) ]
271
535
} ,
272
536
{
273
537
code : "() => 1; new Promise(() => { return 1; })" ,
274
- errors : [ error ( 30 ) ]
538
+ errors : [ eReturnsValue ( 30 ) ]
275
539
} ,
276
540
{
277
541
code : "new Promise(function () { return 1; }); function foo() { return 1; } " ,
278
- errors : [ error ( 27 ) ]
542
+ errors : [ eReturnsValue ( 27 ) ]
279
543
} ,
280
544
{
281
545
code : "() => new Promise(() => { return 1; });" ,
282
- errors : [ error ( 27 ) ]
546
+ errors : [ eReturnsValue ( 27 ) ]
283
547
} ,
284
548
{
285
549
code : "() => new Promise(() => 1);" ,
286
- errors : [ error ( 25 , "Literal" ) ]
550
+ errors : [ eReturnsValue ( 25 , "Literal" ) ]
287
551
} ,
288
552
{
289
553
code : "() => new Promise(() => () => 1);" ,
290
- errors : [ error ( 25 , "ArrowFunctionExpression" ) ]
554
+ errors : [ eReturnsValue ( 25 , "ArrowFunctionExpression" ) ]
555
+ } ,
556
+ {
557
+ code : "() => new Promise(() => async () => 1);" ,
558
+ parserOptions : { ecmaVersion : 2017 } ,
559
+
560
+ // for async
561
+ errors : [ eReturnsValue ( 25 , "ArrowFunctionExpression" ) ]
562
+ } ,
563
+ {
564
+ code : "() => new Promise(() => function () {});" ,
565
+ errors : [ eReturnsValue ( 25 , "FunctionExpression" ) ]
566
+ } ,
567
+ {
568
+ code : "() => new Promise(() => function foo() {});" ,
569
+ errors : [ eReturnsValue ( 25 , "FunctionExpression" ) ]
570
+ } ,
571
+ {
572
+ code : "() => new Promise(() => []);" ,
573
+ errors : [ eReturnsValue ( 25 , "ArrayExpression" ) ]
291
574
} ,
292
575
293
576
// edge cases for global Promise reference
294
577
{
295
578
code : "new Promise((Promise) => { return 1; })" ,
296
- errors : [ error ( ) ]
579
+ errors : [ eReturnsValue ( ) ]
297
580
} ,
298
581
{
299
582
code : "new Promise(function Promise(resolve, reject) { return 1; })" ,
300
- errors : [ error ( ) ]
583
+ errors : [ eReturnsValue ( ) ]
301
584
}
302
585
]
303
586
} ) ;
0 commit comments