Skip to content

Commit

Permalink
fix: add rule documentation
Browse files Browse the repository at this point in the history
Resolves #61
  • Loading branch information
macklinu committed Feb 7, 2018
1 parent 0095432 commit 45b966c
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 82 deletions.
18 changes: 18 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict'

module.exports = {
env: {
node: true
},
parserOptions: {
ecmaVersion: 6
},
plugins: [
'eslint-plugin'
],
rules: {
'eslint-plugin/require-meta-docs-url': ['error', {
'pattern': 'https://github.com/xjamundx/eslint-plugin-promise#{{name}}'
}]
}
}
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ node_js:
- 4
- 6
- 8
script:
- npm run test
- npm run lint
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
"repository": "git@github.com:xjamundx/eslint-plugin-promise.git",
"scripts": {
"pretest": "standard",
"test": "mocha test"
"test": "mocha test",
"lint": "eslint index.js rules test"
},
"devDependencies": {
"eslint": "^4.17.0",
"eslint-plugin-eslint-plugin": "^1.4.0",
"mocha": "^5.0.0",
"standard": "^7.1.2"
},
Expand Down
5 changes: 5 additions & 0 deletions rules/always-return.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ function peek (arr) {
}

module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#always-return'
}
},
create: function (context) {
// funcInfoStack is a stack representing the stack of currently executing
// functions
Expand Down
17 changes: 12 additions & 5 deletions rules/avoid-new.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@

'use strict'

module.exports = function (context) {
return {
NewExpression: function (node) {
if (node.callee.name === 'Promise') {
context.report(node, 'Avoid creating new promises.')
module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#avoid-new'
}
},
create: function (context) {
return {
NewExpression: function (node) {
if (node.callee.name === 'Promise') {
context.report(node, 'Avoid creating new promises.')
}
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions rules/catch-or-return.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
var isPromise = require('./lib/is-promise')

module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#catch-or-return'
}
},
create: function (context) {
var options = context.options[0] || {}
var allowThen = options.allowThen
Expand Down
5 changes: 5 additions & 0 deletions rules/lib/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
'eslint-plugin/require-meta-docs-url': 'off'
}
}
39 changes: 23 additions & 16 deletions rules/no-callback-in-promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,31 @@ var hasPromiseCallback = require('./lib/has-promise-callback')
var isInsidePromise = require('./lib/is-inside-promise')
var isCallback = require('./lib/is-callback')

module.exports = function (context) {
return {
CallExpression: function (node) {
var options = context.options[0] || {}
var exceptions = options.exceptions || []
if (!isCallback(node, exceptions)) {
// in general we send you packing if you're not a callback
// but we also need to watch out for whatever.then(cb)
if (hasPromiseCallback(node)) {
var name = node.arguments && node.arguments[0] && node.arguments[0].name
if (name === 'callback' || name === 'cb' || name === 'next' || name === 'done') {
context.report(node.arguments[0], 'Avoid calling back inside of a promise.')
module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#no-callback-in-promise'
}
},
create: function (context) {
return {
CallExpression: function (node) {
var options = context.options[0] || {}
var exceptions = options.exceptions || []
if (!isCallback(node, exceptions)) {
// in general we send you packing if you're not a callback
// but we also need to watch out for whatever.then(cb)
if (hasPromiseCallback(node)) {
var name = node.arguments && node.arguments[0] && node.arguments[0].name
if (name === 'callback' || name === 'cb' || name === 'next' || name === 'done') {
context.report(node.arguments[0], 'Avoid calling back inside of a promise.')
}
}
return
}
if (context.getAncestors().some(isInsidePromise)) {
context.report(node, 'Avoid calling back inside of a promise.')
}
return
}
if (context.getAncestors().some(isInsidePromise)) {
context.report(node, 'Avoid calling back inside of a promise.')
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions rules/no-native.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ function isDeclared (scope, ref) {
}

module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#no-native'
}
},
create: function (context) {
var MESSAGE = '"{{name}}" is not defined.'

Expand Down
19 changes: 13 additions & 6 deletions rules/no-nesting.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@
var hasPromiseCallback = require('./lib/has-promise-callback')
var isInsidePromise = require('./lib/is-inside-promise')

module.exports = function (context) {
return {
CallExpression: function (node) {
if (!hasPromiseCallback(node)) return
if (context.getAncestors().some(isInsidePromise)) {
context.report(node, 'Avoid nesting promises.')
module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#no-nesting'
}
},
create: function (context) {
return {
CallExpression: function (node) {
if (!hasPromiseCallback(node)) return
if (context.getAncestors().some(isInsidePromise)) {
context.report(node, 'Avoid nesting promises.')
}
}
}
}
Expand Down
29 changes: 18 additions & 11 deletions rules/no-promise-in-callback.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@
var isPromise = require('./lib/is-promise')
var isInsideCallback = require('./lib/is-inside-callback')

module.exports = function (context) {
return {
CallExpression: function (node) {
if (!isPromise(node)) return
module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#no-promise-in-callback'
}
},
create: function (context) {
return {
CallExpression: function (node) {
if (!isPromise(node)) return

// if i'm returning the promise, it's probably not really a callback
// function, and I should be okay....
if (node.parent.type === 'ReturnStatement') return
// if i'm returning the promise, it's probably not really a callback
// function, and I should be okay....
if (node.parent.type === 'ReturnStatement') return

// what about if the parent is an ArrowFunctionExpression
// would that imply an implicit return?
// what about if the parent is an ArrowFunctionExpression
// would that imply an implicit return?

if (context.getAncestors().some(isInsideCallback)) {
context.report(node.callee, 'Avoid using promises inside of callbacks.')
if (context.getAncestors().some(isInsideCallback)) {
context.report(node.callee, 'Avoid using promises inside of callbacks.')
}
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions rules/no-return-in-finally.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
var isPromise = require('./lib/is-promise')

module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#no-return-in-finally'
}
},
create: function (context) {
return {
CallExpression: function (node) {
Expand Down
5 changes: 5 additions & 0 deletions rules/no-return-wrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ function isInPromise (context) {
}

module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#no-return-wrap'
}
},
create: function (context) {
var options = context.options[0] || {}
var allowReject = options.allowReject
Expand Down
5 changes: 5 additions & 0 deletions rules/param-names.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
'use strict'

module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#param-names'
}
},
create: function (context) {
return {
NewExpression: function (node) {
Expand Down
69 changes: 38 additions & 31 deletions rules/prefer-await-to-callbacks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,48 @@

var errorMessage = 'Avoid callbacks. Prefer Async/Await.'

module.exports = function (context) {
function checkLastParamsForCallback (node) {
var len = node.params.length - 1
var lastParam = node.params[len]
if (lastParam && (lastParam.name === 'callback' || lastParam.name === 'cb')) {
context.report(lastParam, errorMessage)
module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#prefer-await-to-callbacks'
}
}
function isInsideYieldOrAwait () {
return context.getAncestors().some(function (parent) {
return parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
})
}
return {
CallExpression: function (node) {
// callbacks aren't allowed
if (node.callee.name === 'cb' || node.callee.name === 'callback') {
context.report(node, errorMessage)
return
},
create: function (context) {
function checkLastParamsForCallback (node) {
var len = node.params.length - 1
var lastParam = node.params[len]
if (lastParam && (lastParam.name === 'callback' || lastParam.name === 'cb')) {
context.report(lastParam, errorMessage)
}
}
function isInsideYieldOrAwait () {
return context.getAncestors().some(function (parent) {
return parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
})
}
return {
CallExpression: function (node) {
// callbacks aren't allowed
if (node.callee.name === 'cb' || node.callee.name === 'callback') {
context.report(node, errorMessage)
return
}

// thennables aren't allowed either
var args = node.arguments
var num = args.length - 1
var arg = num > -1 && node.arguments && node.arguments[num]
if (arg && arg.type === 'FunctionExpression' || arg.type === 'ArrowFunctionExpression') {
if (arg.params && arg.params[0] && arg.params[0].name === 'err') {
if (!isInsideYieldOrAwait()) {
context.report(arg, errorMessage)
// thennables aren't allowed either
var args = node.arguments
var num = args.length - 1
var arg = num > -1 && node.arguments && node.arguments[num]
if (arg && arg.type === 'FunctionExpression' || arg.type === 'ArrowFunctionExpression') {
if (arg.params && arg.params[0] && arg.params[0].name === 'err') {
if (!isInsideYieldOrAwait()) {
context.report(arg, errorMessage)
}
}
}
}
},
FunctionDeclaration: checkLastParamsForCallback,
FunctionExpression: checkLastParamsForCallback,
ArrowFunctionExpression: checkLastParamsForCallback
},
FunctionDeclaration: checkLastParamsForCallback,
FunctionExpression: checkLastParamsForCallback,
ArrowFunctionExpression: checkLastParamsForCallback
}
}
}
31 changes: 19 additions & 12 deletions rules/prefer-await-to-then.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,26 @@

'use strict'

module.exports = function (context) {
return {
MemberExpression: function (node) {
// you can then() if you are inside of a yield or await
if (context.getAncestors().some(function (parent) {
return parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
})) {
return
}
module.exports = {
meta: {
docs: {
url: 'https://github.com/xjamundx/eslint-plugin-promise#prefer-await-to-then'
}
},
create: function (context) {
return {
MemberExpression: function (node) {
// you can then() if you are inside of a yield or await
if (context.getAncestors().some(function (parent) {
return parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
})) {
return
}

// if you're a then expression then you're probably a promise
if (node.property && node.property.name === 'then') {
context.report(node.property, 'Prefer await to then().')
// if you're a then expression then you're probably a promise
if (node.property && node.property.name === 'then') {
context.report(node.property, 'Prefer await to then().')
}
}
}
}
Expand Down

0 comments on commit 45b966c

Please sign in to comment.