Skip to content

Commit

Permalink
docs: migrate rule documentation to docs/rules
Browse files Browse the repository at this point in the history
Related to #109
  • Loading branch information
macklinu committed Feb 23, 2018
1 parent 8c82ddb commit ae2877f
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 258 deletions.
278 changes: 26 additions & 252 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,6 @@ Enforce best practices for JavaScript promises.
* [Installation](#installation)
* [Usage](#usage)
* [Rules](#rules)
* [`catch-or-return`](#catch-or-return)
* [`no-return-wrap`](#no-return-wrap)
* [`param-names`](#param-names)
* [`always-return`](#always-return)
* [`no-native`](#no-native)
* [`no-nesting`](#no-nesting)
* [`no-promise-in-callback`](#no-promise-in-callback)
* [`no-callback-in-promise`](#no-callback-in-promise)
* [`avoid-new`](#avoid-new)
* [`no-return-in-finally`](#no-return-in-finally)
* [`prefer-await-to-then`](#prefer-await-to-then)
* [`prefer-await-to-callbacks`](#prefer-await-to-callbacks)
* [Maintainers](#maintainers)
* [License](#license)

Expand Down Expand Up @@ -88,20 +76,20 @@ or start with the recommended rule set

## Rules

| rule | description | recommended | fixable |
| --------------------------- | -------------------------------------------------------------------------------- | ----------- | -------- |
| `catch-or-return` | Enforces the use of `catch()` on un-returned promises. | :bangbang: | |
| `no-return-wrap` | Avoid wrapping values in `Promise.resolve` or `Promise.reject` when not needed. | :bangbang: | |
| `param-names` | Enforce consistent param names when creating new promises. | :bangbang: | :wrench: |
| `always-return` | Return inside each `then()` to create readable and reusable Promise chains. | :bangbang: | |
| `no-native` | In an ES5 environment, make sure to create a `Promise` constructor before using. | | |
| `no-nesting` | Avoid nested `then()` or `catch()` statements | :warning: | |
| `no-promise-in-callback` | Avoid using promises inside of callbacks | :warning: | |
| `no-callback-in-promise` | Avoid calling `cb()` inside of a `then()` (use [nodeify][] instead) | :warning: | |
| `avoid-new` | Avoid creating `new` promises outside of utility libs (use [pify][] instead) | :warning: | |
| `no-return-in-finally` | Disallow return statements in `finally()` | :warning: | |
| `prefer-await-to-then` | Prefer `await` to `then()` for reading Promise values | :seven: | |
| `prefer-await-to-callbacks` | Prefer async/await to the callback pattern | :seven: | |
| rule | description | recommended | fixable |
| -------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------- | -------- |
| [`catch-or-return`][catch-or-return] | Enforces the use of `catch()` on un-returned promises. | :bangbang: | |
| [`no-return-wrap`][no-return-wrap] | Avoid wrapping values in `Promise.resolve` or `Promise.reject` when not needed. | :bangbang: | |
| [`param-names`][param-names] | Enforce consistent param names when creating new promises. | :bangbang: | :wrench: |
| [`always-return`][always-return] | Return inside each `then()` to create readable and reusable Promise chains. | :bangbang: | |
| [`no-native`][no-native] | In an ES5 environment, make sure to create a `Promise` constructor before using. | | |
| [`no-nesting`][no-nesting] | Avoid nested `then()` or `catch()` statements | :warning: | |
| [`no-promise-in-callback`][no-promise-in-callback] | Avoid using promises inside of callbacks | :warning: | |
| [`no-callback-in-promise`][no-callback-in-promise] | Avoid calling `cb()` inside of a `then()` (use [nodeify][] instead) | :warning: | |
| [`avoid-new` ][avoid-new] | Avoid creating `new` promises outside of utility libs (use [pify][] instead) | :warning: | |
| [`no-return-in-finally`][no-return-in-finally] | Disallow return statements in `finally()` | :warning: | |
| [`prefer-await-to-then`][prefer-await-to-then] | Prefer `await` to `then()` for reading Promise values | :seven: | |
| [`prefer-await-to-callbacks`][prefer-await-to-callbacks] | Prefer async/await to the callback pattern | :seven: | |

**Key**

Expand All @@ -112,232 +100,6 @@ or start with the recommended rule set
| :seven: | ES2017 Async Await rules |
| :wrench: | Rule is fixable with `eslint --fix` |

### `catch-or-return`

Ensure that each time a `then()` is applied to a promise, a `catch()` is applied
as well. Exceptions are made if you are returning that promise.

#### Valid

```js
myPromise.then(doSomething).catch(errors)
myPromise
.then(doSomething)
.then(doSomethingElse)
.catch(errors)
function doSomethingElse() {
return myPromise.then(doSomething)
}
```

#### Invalid

```js
myPromise.then(doSomething)
myPromise.then(doSomething, catchErrors) // catch() may be a little better
function doSomethingElse() {
myPromise.then(doSomething)
}
```

#### Options

##### `allowThen`

You can pass an `{ allowThen: true }` as an option to this rule to allow for
`.then(null, fn)` to be used instead of `catch()` at the end of the promise
chain.

##### `terminationMethod`

You can pass a `{ terminationMethod: 'done' }` as an option to this rule to
require `done()` instead of `catch()` at the end of the promise chain. This is
useful for many non-standard Promise implementations.

You can also pass an array of methods such as
`{ terminationMethod: ['catch', 'asCallback', 'finally'] }`.

This will allow any of

```js
Promise.resolve(1)
.then(() => {
throw new Error('oops')
})
.catch(logerror)
Promise.resolve(1)
.then(() => {
throw new Error('oops')
})
.asCallback(cb)
Promise.resolve(1)
.then(() => {
throw new Error('oops')
})
.finally(cleanUp)
```

### `no-return-wrap`

Ensure that inside a `then()` or a `catch()` we always `return` or `throw` a raw
value instead of wrapping in `Promise.resolve` or `Promise.reject`

#### Valid

```js
myPromise.then(function(val) {
return val * 2
})
myPromise.then(function(val) {
throw 'bad thing'
})
```

#### Invalid

```js
myPromise.then(function(val) {
return Promise.resolve(val * 2)
})
myPromise.then(function(val) {
return Promise.reject('bad thing')
})
```

#### Options

##### `allowReject`

Pass `{ allowReject: true }` as an option to this rule to permit wrapping
returned values with `Promise.reject`, such as when you would use it as another
way to reject the promise.

### `param-names`

Enforce standard parameter names for Promise constructors

:wrench: The `--fix` option on the command line can automatically fix some of
the problems reported by this rule.

#### Valid

```js
new Promise(function (resolve) { ... })
new Promise(function (resolve, reject) { ... })
```

#### Invalid

```js
new Promise(function (reject, resolve) { ... }) // incorrect order
new Promise(function (ok, fail) { ... }) // non-standard parameter names
```

Ensures that `new Promise()` is instantiated with the parameter names
`resolve, reject` to avoid confusion with order such as `reject, resolve`. The
Promise constructor uses the
[RevealingConstructor pattern](https://blog.domenic.me/the-revealing-constructor-pattern/).
Using the same parameter names as the language specification makes code more
uniform and easier to understand.

### `always-return`

Ensure that inside a `then()` you make sure to `return` a new promise or value.
See http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html (rule #5)
for more info on why that's a good idea.

We also allow someone to `throw` inside a `then()` which is essentially the same
as `return Promise.reject()`.

#### Valid

```js
myPromise.then((val) => val * 2));
myPromise.then(function(val) { return val * 2; });
myPromise.then(doSomething); // could be either
myPromise.then((b) => { if (b) { return "yes" } else { return "no" } });
```

#### Invalid

```js
myPromise.then(function(val) {})
myPromise.then(() => {
doSomething()
})
myPromise.then(b => {
if (b) {
return 'yes'
} else {
forgotToReturn()
}
})
```

### `no-native`

Ensure that `Promise` is included fresh in each file instead of relying on the
existence of a native promise implementation. Helpful if you want to use
`bluebird` or if you don't intend to use an ES6 Promise shim.

#### Valid

```js
var Promise = require('bluebird')
var x = Promise.resolve('good')
```

#### Invalid

```js
var x = Promise.resolve('bad')
```

### `no-nesting`

Avoid nested `then()` or `catch()` statements

### `no-promise-in-callback`

Avoid using promises inside of callbacks

### `no-callback-in-promise`

Avoid calling `cb()` inside of a `then()` (use [nodeify][] instead)

### `avoid-new`

Avoid creating `new` promises outside of utility libs (use [pify][] instead)

### `no-return-in-finally`

Disallow return statements inside a callback passed to `finally()`, since
nothing would consume what's returned.

#### Valid

```js
myPromise.finally(function(val) {
console.log('value:', val)
})
```

#### Invalid

```js
myPromise.finally(function(val) {
return val
})
```

### `prefer-await-to-then`

Prefer `await` to `then()` for reading Promise values

### `prefer-await-to-callbacks`

Prefer async/await to the callback pattern

## Maintainers

* Jamund Ferguson - [@xjamundx][]
Expand All @@ -348,6 +110,18 @@ Prefer async/await to the callback pattern
* (c) MMXV jden <mailto:[email protected]> - ISC license.
* (c) 2016 Jamund Ferguson <mailto:[email protected]> - ISC license.

[catch-or-return]: docs/rules/catch-or-return.md
[no-return-wrap]: docs/rules/no-return-wrap.md
[param-names]: docs/rules/param-names.md
[always-return]: docs/rules/always-return.md
[no-native]: docs/rules/no-native.md
[no-nesting]: docs/rules/no-nesting.md
[no-promise-in-callback]: docs/rules/no-promise-in-callback.md
[no-callback-in-promise]: docs/rules/no-callback-in-promise.md
[avoid-new]: docs/rules/avoid-new.md
[no-return-in-finally]: docs/rules/no-return-in-finally.md
[prefer-await-to-then]: docs/rules/prefer-await-to-then.md
[prefer-await-to-callbacks]: docs/rules/prefer-await-to-callbacks.md
[nodeify]: https://www.npmjs.com/package/nodeify
[pify]: https://www.npmjs.com/package/pify
[@macklinu]: https://github.com/macklinu
Expand Down
33 changes: 33 additions & 0 deletions docs/rules/always-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Return inside each `then()` to create readable and reusable Promise chains (always-return)

Ensure that inside a `then()` you make sure to `return` a new promise or value.
See http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html (rule #5)
for more info on why that's a good idea.

We also allow someone to `throw` inside a `then()` which is essentially the same
as `return Promise.reject()`.

#### Valid

```js
myPromise.then((val) => val * 2));
myPromise.then(function(val) { return val * 2; });
myPromise.then(doSomething); // could be either
myPromise.then((b) => { if (b) { return "yes" } else { return "no" } });
```

#### Invalid

```js
myPromise.then(function(val) {})
myPromise.then(() => {
doSomething()
})
myPromise.then(b => {
if (b) {
return 'yes'
} else {
forgotToReturn()
}
})
```
3 changes: 3 additions & 0 deletions docs/rules/avoid-new.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Avoid creating `new` promises outside of utility libs (use [pify][] instead) (avoid-new)

[pify]: https://www.npmjs.com/package/pify
Loading

0 comments on commit ae2877f

Please sign in to comment.