forked from ember-cli/eslint-plugin-ember
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding return-from-computed recommended rule. Fixes ember-cli#247.
- Loading branch information
Garrett Murphey
committed
Jun 11, 2018
1 parent
04c7696
commit d29eb8b
Showing
5 changed files
with
159 additions
and
1 deletion.
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,44 @@ | ||
## Always return a value from a computed property function | ||
|
||
### Rule name: `return-from-computed` | ||
|
||
When using computed properties always return a value. | ||
|
||
```javascript | ||
import Ember from 'ember'; | ||
|
||
const { | ||
Component, | ||
computed | ||
} = Ember; | ||
|
||
export default Component.extend({ | ||
firstName: null, | ||
lastName: null, | ||
|
||
// GOOD | ||
fullName: computed('firstName', 'lastName', { | ||
get(key) { | ||
return `${this.get('firstName')} ${this.get('lastName')}`; | ||
}, | ||
set(key, value) { | ||
let [firstName, lastName] = value.split(/\s+/); | ||
this.set('firstName', firstName); | ||
this.set('lastName', lastName); | ||
return value; | ||
} | ||
}), | ||
|
||
// BAD | ||
fullName: computed('firstName', 'lastName', { | ||
get(key) { | ||
return `${this.get('firstName')} ${this.get('lastName')}`; | ||
}, | ||
set(key, value) { | ||
let [firstName, lastName] = value.split(/\s+/); | ||
this.set('firstName', firstName); | ||
this.set('lastName', lastName); | ||
} | ||
}) | ||
}); | ||
``` |
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,53 @@ | ||
'use strict'; | ||
|
||
const utils = require('../utils/utils'); | ||
|
||
//------------------------------------------------------------------------------ | ||
// General rule - Don't introduce side-effects in computed properties | ||
//------------------------------------------------------------------------------ | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: 'Warns about missing return statements in computed properties', | ||
category: 'Possible Errors', | ||
recommended: true, | ||
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/no-side-effects.md' | ||
}, | ||
fixable: null, // or "code" or "whitespace" | ||
}, | ||
|
||
create(context) { | ||
const message = 'Return a value from computed property'; | ||
|
||
const report = function (node) { | ||
context.report(node, message); | ||
}; | ||
|
||
return { | ||
'CallExpression[callee.name="computed"]': function (node) { | ||
const objExps = utils.findNodes(node.arguments, 'ObjectExpression'); | ||
const fnExps = utils.findNodes(node.arguments, 'FunctionExpression'); | ||
|
||
if (objExps.length) { | ||
const computedObj = objExps[0]; | ||
const props = computedObj.properties; | ||
|
||
props.forEach(({ value }) => { | ||
if (utils.isFunctionExpression(value) && !utils.findNodes(value.body.body, 'ReturnStatement').length) { | ||
report(value); | ||
} | ||
}); | ||
} | ||
|
||
if (fnExps.length) { | ||
const computedFn = fnExps[0]; | ||
|
||
if (!utils.findNodes(computedFn.body.body, 'ReturnStatement').length) { | ||
report(computedFn); | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
}; |
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,59 @@ | ||
// ------------------------------------------------------------------------------ | ||
// Requirements | ||
// ------------------------------------------------------------------------------ | ||
|
||
const rule = require('../../../lib/rules/return-from-computed'); | ||
const RuleTester = require('eslint').RuleTester; | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Tests | ||
// ------------------------------------------------------------------------------ | ||
|
||
const eslintTester = new RuleTester(); | ||
eslintTester.run('return-from-computed', rule, { | ||
valid: [ | ||
{ | ||
code: 'let foo = computed("test.length", { get() { return ""; }, set() { return ""; }})', | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
}, | ||
{ | ||
code: 'let foo = computed("test", function() { return ""; })', | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
} | ||
], | ||
invalid: [ | ||
{ | ||
code: 'let foo = computed("test", function() { })', | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
errors: [{ | ||
message: 'Return a value from computed property' | ||
}] | ||
}, | ||
{ | ||
code: 'let foo = computed("test", function() { if (true) { return ""; } })', | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
errors: [{ | ||
message: 'Return a value from computed property' | ||
}] | ||
}, | ||
{ | ||
code: 'let foo = computed("test", { get() {}, set() {} })', | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
errors: [ | ||
{ | ||
message: 'Return a value from computed property' | ||
}, | ||
{ | ||
message: 'Return a value from computed property' | ||
} | ||
] | ||
}, | ||
{ | ||
code: 'let foo = computed("test", function() { })', | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
errors: [{ | ||
message: 'Return a value from computed property' | ||
}] | ||
} | ||
], | ||
}); |