Skip to content

Commit

Permalink
feat: add no-multiple-resolved rule (#369)
Browse files Browse the repository at this point in the history
* feat: add `no-multiple-resolved` rule

* fix index.js

* minor refactor
  • Loading branch information
ota-meshi committed Oct 1, 2022
1 parent df25e3c commit 3a6fdbe
Show file tree
Hide file tree
Showing 6 changed files with 796 additions and 1 deletion.
310 changes: 310 additions & 0 deletions __tests__/no-multiple-resolved.js
@@ -0,0 +1,310 @@
'use strict'

const rule = require('../rules/no-multiple-resolved')
const RuleTester = require('eslint').RuleTester
const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 2020,
},
})

ruleTester.run('no-multiple-resolved', rule, {
valid: [
`new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
} else {
resolve(value)
}
})
})`,
`new Promise((resolve, reject) => {
if (error) {
reject(error)
} else {
resolve(value)
}
})`,
`new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
return
}
resolve(value)
})
})`,
`new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
}
if (!error) {
resolve(value)
}
})
})`,
`new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
}
if (error) {
return
}
resolve(value)
})
})`,
`
new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
}
if (!error) {
// process
} else {
// process
}
if(!error) {
resolve(value)
}
})
})`,
`
new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
return
}
if (!error) {
// process
} else {
// process
}
resolve(value)
})
})`,
],

invalid: [
{
code: `
new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
}
resolve(value)
})
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is potentially resolved on line 5.',
line: 8,
},
],
},
{
code: `
new Promise((resolve, reject) => {
if (error) {
reject(error)
}
resolve(value)
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is potentially resolved on line 4.',
line: 7,
},
],
},
{
code: `
new Promise((resolve, reject) => {
reject(error)
resolve(value)
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is already resolved on line 3.',
line: 4,
},
],
},
{
code: `
new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
}
if (!error) {
// process
} else {
// process
}
resolve(value)
})
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is potentially resolved on line 5.',
line: 13,
},
],
},
{
code: `
new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
if (foo) {
if (bar) reject(error)
}
}
resolve(value)
})
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is potentially resolved on line 6.',
line: 10,
},
],
},
{
code: `
new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
} else {
return
}
resolve(value)
})
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is already resolved on line 5.',
line: 10,
},
],
},
{
code: `
new Promise((resolve, reject) => {
if(foo) {
if (error) {
reject(error)
} else {
return
}
resolve(value)
}
resolve(value)
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is already resolved on line 5.',
line: 9,
},
{
message:
'Promise should not be resolved multiple times. Promise is potentially resolved on line 9.',
line: 12,
},
],
},
{
code: `
new Promise((resolve, reject) => {
if (foo) {
reject(error)
} else {
resolve(value)
}
if(bar) {
resolve(value)
}
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is already resolved on line 4.',
line: 9,
},
],
},
{
code: `
new Promise((resolve, reject) => {
while (error) {
reject(error)
}
resolve(value)
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is potentially resolved on line 4.',
line: 6,
},
],
},
{
code: `
new Promise((resolve, reject) => {
try {
reject(error)
} finally {
resolve(value)
}
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is already resolved on line 4.',
line: 6,
},
],
},
{
code: `
new Promise((resolve, reject) => {
try {
if (error) {
reject(error)
}
} finally {
resolve(value)
}
})`,
errors: [
{
message:
'Promise should not be resolved multiple times. Promise is potentially resolved on line 5.',
line: 8,
},
],
},
],
})
32 changes: 32 additions & 0 deletions docs/rules/no-multiple-resolved.md
@@ -0,0 +1,32 @@
# Disallow creating new promises with paths that resolve multiple times (no-multiple-resolved)

This rule warns of paths that resolve multiple times in executor functions that
Promise constructors.

#### Valid

```js
new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
} else {
resolve(value)
}
})
})
```

#### Invalid

```js
new Promise((resolve, reject) => {
fn((error, value) => {
if (error) {
reject(error)
}

resolve(value) // Both `reject` and `resolve` may be called.
})
})
```
1 change: 1 addition & 0 deletions index.js
Expand Up @@ -16,6 +16,7 @@ module.exports = {
'no-new-statics': require('./rules/no-new-statics'),
'no-return-in-finally': require('./rules/no-return-in-finally'),
'valid-params': require('./rules/valid-params'),
'no-multiple-resolved': require('./rules/no-multiple-resolved'),
},
rulesConfig: {
'param-names': 1,
Expand Down

0 comments on commit 3a6fdbe

Please sign in to comment.