New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NEW RULE] Adding no-async-actions rule [DO NOT MERGE] #424
base: master
Are you sure you want to change the base?
Changes from 3 commits
24ebede
84ffc97
a8dda02
020b127
efc6aaf
8027f82
85e5e05
e849ad4
80cc3aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Do not use async actions | ||
## Rule `no-async-actions` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead, could we throw a lint error only after an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead, could we throw a lint error only after an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. example?: #1421 |
||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit unclear on why we should not use async actions. Can you explain that more and include in the doc here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Me too not very clear about the requirement, i am exploring , will add more info once ready There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add at least a brief explanation of the reasoning in this doc. |
||
|
||
Examples of **incorrect** code for this rule: | ||
```js | ||
actions: { | ||
async handleClick() { | ||
// ... | ||
} | ||
} | ||
``` | ||
|
||
```js | ||
actions: { | ||
handleClick() { | ||
return something.then(() => { /* ... */ }); | ||
} | ||
} | ||
``` | ||
|
||
```js | ||
@action | ||
async handleClick() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why forbid this? This is totally valid |
||
// ... | ||
} | ||
``` | ||
|
||
```js | ||
@action | ||
handleClick() { | ||
return something.then(() => { /* ... */ }); | ||
} | ||
``` | ||
|
||
|
||
Examples of **correct** code for this rule: | ||
```js | ||
actions: { | ||
handleClick() { | ||
return nothingOrSomethingThatIsNotAPromise; | ||
} | ||
} | ||
``` | ||
|
||
|
||
## Further Reading | ||
|
||
See http://ember-concurrency.com/docs/tutorial (scroll down to Version 4) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
'use strict'; | ||
|
||
const utils = require('../utils/utils'); | ||
|
||
|
||
//------------------------------------------------------------------------------ | ||
// General rule - Don't use async actions | ||
//------------------------------------------------------------------------------ | ||
|
||
|
||
const message = 'Do not use async actions'; | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: 'Disallow usage of async actions in components', | ||
category: 'Possible Errors', | ||
recommended: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rules should never be added as recommended since that would be a breaking change. We can consider making it recommended in the future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed the recommended flag |
||
url: 'http://ember-concurrency.com/docs/tutorial' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please rebase on the latest master to pickup the prettier changes. |
||
}, | ||
fixable: null, | ||
}, | ||
|
||
create(context) { | ||
return { | ||
Property(node) { | ||
if (node.key.name === 'actions') { | ||
const props = node.value.properties; | ||
|
||
props.forEach((p) => { | ||
const body = p.value.body.body; | ||
if (p.value.async) { | ||
context.report({ | ||
node: p, | ||
message, | ||
}); | ||
} else if (body.length === 1 && utils.isReturnStatement(body[0])) { | ||
const retSt = body[0]; | ||
if (retSt.argument.type === 'CallExpression' && | ||
retSt.argument.callee.property.name === 'then') { | ||
context.report({ | ||
node: retSt, | ||
message, | ||
}); | ||
} | ||
} | ||
}); | ||
} else if (node.decorators) { | ||
if (node.decorators.find(d => d.expression.name === 'action')) { | ||
if (node.value.async) { | ||
context.report({ | ||
node, | ||
message: 'Do not use async actions' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
}); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
'use strict'; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Requirements | ||
//------------------------------------------------------------------------------ | ||
|
||
const rule = require('../../../lib/rules/no-async-actions.js'); | ||
const RuleTester = require('eslint').RuleTester; | ||
|
||
|
||
//------------------------------------------------------------------------------ | ||
// Tests | ||
//------------------------------------------------------------------------------ | ||
|
||
const message = 'Do not use async actions'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
||
const ruleTester = new RuleTester({ | ||
parserOptions: { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
} | ||
}); | ||
|
||
ruleTester.run('no-async-actions', rule, { | ||
valid: [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need a valid example to ensure this rule does not trigger on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^ still waiting on this rule to be limited to |
||
{ | ||
code: ` | ||
Component.extend({ | ||
actions: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is unreadable without proper indentation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indented propertly |
||
handleClick() { | ||
// ... | ||
} | ||
} | ||
});`, | ||
} | ||
|
||
], | ||
|
||
invalid: [ | ||
{ | ||
code: `Component.extend({ | ||
actions: { | ||
async handleClick() { | ||
// ... | ||
} | ||
} | ||
});`, | ||
output: null, | ||
errors: [{ | ||
message, | ||
}] | ||
}, | ||
{ | ||
code: `Component.extend({ | ||
actions: { | ||
handleClick() { | ||
return something.then(() => { | ||
let hello = "world"; | ||
}); | ||
} | ||
} | ||
});`, | ||
output: null, | ||
errors: [{ | ||
message, | ||
}] | ||
}, | ||
{ | ||
code: `Component.extend({ | ||
@action | ||
async handleClick() { | ||
// ... | ||
} | ||
});`, | ||
output: null, | ||
errors: [{ | ||
message, | ||
}] | ||
}, | ||
{ | ||
code: `Component.extend({ | ||
@action | ||
handleClick() { | ||
return something.then(() => { | ||
let hello = "world"; | ||
}); | ||
} | ||
});`, | ||
output: null, | ||
errors: [{ | ||
message, | ||
}] | ||
}, | ||
|
||
] | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember to run yarn update and add the rule to index.js too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done