Skip to content

Commit

Permalink
New rule: no-done-fail
Browse files Browse the repository at this point in the history
Fixes #332
  • Loading branch information
edg2s committed Nov 18, 2024
1 parent 0e41a53 commit 06b8480
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Where rules are included in the configs `recommended`, `slim`, `all` or `depreca
* [`no-jquery/no-data`](docs/rules/no-data.md) `all`
* [`no-jquery/no-deferred`](docs/rules/no-deferred.md) `all`
* [`no-jquery/no-delegate`](docs/rules/no-delegate.md) `3.0`, `all`
* [`no-jquery/no-done-fail`](docs/rules/no-done-fail.md) `all`
* [`no-jquery/no-each`](docs/rules/no-each.md)
* [`no-jquery/no-each-collection`](docs/rules/no-each-collection.md) `all`
* [`no-jquery/no-each-util`](docs/rules/no-each-util.md) `all`
Expand Down
27 changes: 27 additions & 0 deletions docs/rules/no-done-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[//]: # (This file is generated by eslint-docgen. Do not edit it directly.)

# no-done-fail

Disallows the [`.done`](https://api.jquery.com/deferred.done/)/[`.fail`](https://api.jquery.com/deferred.fail/) methods. Prefer `.then`.

📋 This rule is enabled in `plugin:no-jquery/all`.

## Rule details

❌ Examples of **incorrect** code:
```js
promise.done( callback );
promise.fail( callback );
```

✔️ Examples of **correct** code:
```js
promise.then( doneCallback, failCallback );
done();
fail();
```

## Resources

* [Rule source](/src/rules/no-done-fail.js)
* [Test source](/tests/rules/no-done-fail.js)
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = {
'no-deferred': require( './rules/no-deferred' ),
'no-delegate': require( './rules/no-delegate' ),
'no-die': require( './rules/no-die' ),
'no-done-fail': require( './rules/no-done-fail' ),
'no-each': require( './rules/no-each' ),
'no-each-collection': require( './rules/no-each-collection' ),
'no-each-util': require( './rules/no-each-util' ),
Expand Down Expand Up @@ -333,8 +334,10 @@ module.exports = {
'no-jquery/no-filter': 'warn',
'no-jquery/no-prop': 'warn',
'no-jquery/no-sub': 'warn',
'no-jquery/no-text': 'warn'
'no-jquery/no-text': 'warn',

// Other methods
'no-jquery/no-done-fail': 'warn'
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/rules/no-done-fail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict';

const utils = require( '../utils.js' );

module.exports = utils.createUniversalMethodRule(
[ 'done', 'fail' ],
( node ) => node === true ?
'Prefer `.then`' :
`Prefer .then to .${ node.callee.property.name }`,
( method ) => `[\`.${ method }\`](https://api.jquery.com/deferred.${ method }/)`
);
42 changes: 42 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,47 @@ function createCollectionOrUtilMethodRule( methods, message, options ) {
} ), description, options.fixable, options.deprecated );
}

/**
* Create a rule for a method on any object
*
* @param {string|string[]} methods Method or list of method names
* @param {string|Function} message Message to report. See createCollectionMethodRule.
* @param {Function} linkGenerator Function to generate a markdown link
* @param {Object} [options] Options. See createCollectionMethodRule.
* for a given function name.
* @return {Object} Rule
*/
function createUniversalMethodRule( methods, message, linkGenerator, options ) {
options = options || {};

options.mode = 'util';

methods = Array.isArray( methods ) ? methods : [ methods ];

let description = 'Disallows the ' + methods.map( linkGenerator ).join( '/' ) + ' ' +
( methods.length > 1 ? 'methods' : 'method' ) + '.';

description += messageSuffix( message );

return createRule( ( context ) => ( {
'CallExpression:exit': ( node ) => {
if ( node.callee.type !== 'MemberExpression' ) {
return;
}
const name = node.callee.property.name;
if ( !methods.includes( name ) ) {
return;
}

context.report( {
node,
message: messageToPlainString( message, node, name, options ),
fix: options.fix && options.fix.bind( this, node, context )
} );
}
} ), description, options.fixable, options.deprecated );
}

function eventShorthandFixer( node, context, fixer ) {
const name = node.callee.property.name;
if ( node.callee.parent.arguments.length ) {
Expand Down Expand Up @@ -580,6 +621,7 @@ module.exports = {
createUtilMethodRule,
createUtilPropertyRule,
createCollectionOrUtilMethodRule,
createUniversalMethodRule,
eventShorthandFixer,
jQueryCollectionLink,
jQueryGlobalLink,
Expand Down
6 changes: 6 additions & 0 deletions test-self/all/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,9 @@ $x.wrap();
$x.wrapAll();
// eslint-disable-next-line self/no-wrap
$x.wrapInner();

// Other methods
// eslint-disable-next-line self/no-done-fail
promise.done();
// eslint-disable-next-line self/no-done-fail
promise.fail();
21 changes: 21 additions & 0 deletions tests/rules/no-done-fail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

const rule = require( '../../src/rules/no-done-fail' );
const RuleTester = require( '../../tools/rule-tester' );

const error = ( method ) => `Prefer .then to .${ method }`;

const ruleTester = new RuleTester();
ruleTester.run( 'no-done-fail', rule, {
valid: [ 'promise.then( doneCallback, failCallback )', 'done()', 'fail()' ],
invalid: [
{
code: 'promise.done( callback )',
errors: [ error( 'done' ) ]
},
{
code: 'promise.fail( callback )',
errors: [ error( 'fail' ) ]
}
]
} );

0 comments on commit 06b8480

Please sign in to comment.