-
-
Notifications
You must be signed in to change notification settings - Fork 204
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
074e7d5
commit d36bcbc
Showing
7 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Disallows the actions hash in components and controllers (no-actions-hash) | ||
|
||
Ember Octane includes a rethink of event handling in Ember. The `actions` hash and `{{action}}` modifier and helper are no longer needed. To provide the correct context to functions (binding), you should now use the `@action` decorator. In templates, the `{{on}}` modifier can be used to set up event handlers and the `{{fn}}` helper can be used for partial application. | ||
|
||
|
||
## Rule Detail | ||
|
||
Use the `@action` decorator or `foo: action(function() {}))` syntax instead of an `actions` hash. | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```js | ||
// Bad | ||
export default Component.extend({ | ||
actions: { | ||
foo() { | ||
} | ||
}, | ||
}); | ||
|
||
export class MyComponent extends Component { | ||
actions = { | ||
foo() { | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```js | ||
// Good | ||
export default Component.extend({ | ||
foo: action(function() { | ||
}) | ||
}); | ||
|
||
export class MyComponent extends Component { | ||
@action | ||
foo() { | ||
} | ||
} | ||
``` | ||
|
||
## Further Reading | ||
- [`{{on}}` Modifier RFC](https://github.com/emberjs/rfcs/pull/471) | ||
- [`{{fn}}` Helper RFC](https://github.com/emberjs/rfcs/pull/470) | ||
- [Ember Octane Update: What's up with `@action`?](https://www.pzuraq.com/ember-octane-update-action/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
const ember = require('../utils/ember'); | ||
|
||
const ERROR_MESSAGE = 'Use the @action decorator instead of declaring an actions hash'; | ||
|
||
module.exports = { | ||
ERROR_MESSAGE, | ||
meta: { | ||
docs: { | ||
description: 'Disallows the actions hash in components, controllers and routes', | ||
category: 'Ember Object', | ||
recommended: false, | ||
}, | ||
fixable: null, // or "code" or "whitespace" | ||
url: | ||
'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/no-actions-hash.md', | ||
}, | ||
|
||
create: context => { | ||
const filePath = context.getFilename(); | ||
let inClassWhichCanContainActions = false; | ||
|
||
function _inClassWhichCanContainActions(node, filePath) { | ||
return ( | ||
inClassWhichCanContainActions || | ||
ember.isEmberComponent(node, filePath) || | ||
ember.isEmberController(node, filePath) || | ||
ember.isEmberRoute(node, filePath) | ||
); | ||
} | ||
|
||
return { | ||
ClassDeclaration(node) { | ||
inClassWhichCanContainActions = _inClassWhichCanContainActions(node, filePath); | ||
}, | ||
CallExpression(node) { | ||
inClassWhichCanContainActions = _inClassWhichCanContainActions(node, filePath); | ||
}, | ||
ObjectExpression(node) { | ||
if (!inClassWhichCanContainActions) { | ||
return; | ||
} | ||
|
||
node.properties.forEach(property => { | ||
if (property.key.name === 'actions') { | ||
context.report(node, ERROR_MESSAGE); | ||
} | ||
}); | ||
}, | ||
ClassProperty(node) { | ||
if (!inClassWhichCanContainActions) { | ||
return; | ||
} | ||
|
||
if (node.value.type === 'ObjectExpression' && node.key.name === 'actions') { | ||
context.report(node, ERROR_MESSAGE); | ||
} | ||
}, | ||
}; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
//------------------------------------------------------------------------------ | ||
// Requirements | ||
//------------------------------------------------------------------------------ | ||
|
||
const rule = require('../../../lib/rules/no-actions-hash'); | ||
const RuleTester = require('eslint').RuleTester; | ||
|
||
const { ERROR_MESSAGE } = rule; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Tests | ||
//------------------------------------------------------------------------------ | ||
|
||
const ruleTester = new RuleTester({ | ||
parser: require.resolve('babel-eslint'), | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
}); | ||
ruleTester.run('no-actions-hash', rule, { | ||
valid: [ | ||
` | ||
export default Component.extend({ | ||
foo: action(function() {}) | ||
}); | ||
`, | ||
` | ||
export default class MyComponent extends Component { | ||
@action | ||
foo() {} | ||
} | ||
`, | ||
` | ||
export default Controller.extend({ | ||
foo: action(function() {}) | ||
}); | ||
`, | ||
` | ||
export default class MyController extends Controller { | ||
@action | ||
foo() {} | ||
} | ||
`, | ||
` | ||
export default Route.extend({ | ||
foo: action(function() {}) | ||
}); | ||
`, | ||
` | ||
export default class MyRoute extends Route { | ||
@action | ||
foo() {} | ||
} | ||
`, | ||
` | ||
export default class MyLovelyClass extends LovelyClass { | ||
actions = { | ||
foo() { | ||
} | ||
} | ||
} | ||
`, | ||
], | ||
|
||
invalid: [ | ||
{ | ||
code: ` | ||
export default Component.extend({ | ||
actions: { | ||
}, | ||
}); | ||
`, | ||
errors: [{ message: ERROR_MESSAGE }], | ||
}, | ||
{ | ||
code: ` | ||
export default class MyComponent extends Component { | ||
actions = { | ||
foo() { | ||
} | ||
} | ||
} | ||
`, | ||
errors: [{ message: ERROR_MESSAGE }], | ||
}, | ||
{ | ||
code: ` | ||
export default Controller.extend({ | ||
actions: { | ||
}, | ||
}); | ||
`, | ||
errors: [{ message: ERROR_MESSAGE }], | ||
}, | ||
{ | ||
code: ` | ||
export default class MyController extends Controller { | ||
actions = { | ||
foo() { | ||
} | ||
} | ||
} | ||
`, | ||
errors: [{ message: ERROR_MESSAGE }], | ||
}, | ||
{ | ||
code: ` | ||
export default Route.extend({ | ||
actions: { | ||
}, | ||
}); | ||
`, | ||
errors: [{ message: ERROR_MESSAGE }], | ||
}, | ||
{ | ||
code: ` | ||
export default class MyRoute extends Route { | ||
actions = { | ||
foo() { | ||
} | ||
} | ||
} | ||
`, | ||
errors: [{ message: ERROR_MESSAGE }], | ||
}, | ||
], | ||
}); |