Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-ember

Package Overview
Dependencies
Maintainers
5
Versions
189
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-ember - npm Package Compare versions

Comparing version 5.0.3 to 5.1.0

23

CHANGELOG.md

@@ -0,1 +1,24 @@

# Changelog
## v5.1.0 (2018-03-11)
#### :rocket: Enhancement
* [#172](https://github.com/ember-cli/eslint-plugin-ember/pull/172) Add `--fix` support to `order-in-*` rules. ([@PrzemoRevolve](https://github.com/PrzemoRevolve))
#### :bug: Bug Fix
* [#233](https://github.com/ember-cli/eslint-plugin-ember/pull/233) Fix init order in controllers and routes. ([@ro0gr](https://github.com/ro0gr))
* [#198](https://github.com/ember-cli/eslint-plugin-ember/pull/198) Add new scenarios for `require-super-in-init` rule. ([@clcuevas](https://github.com/clcuevas))
* [#205](https://github.com/ember-cli/eslint-plugin-ember/pull/205) add willInsertElement component lifecycle hook. ([@hakubo](https://github.com/hakubo))
#### Committers: 8
- Claudia Cuevas ([clcuevas](https://github.com/clcuevas))
- Jakub Olek ([hakubo](https://github.com/hakubo))
- Jason Williams ([jaswilli](https://github.com/jaswilli))
- Przemysław Nowak ([PrzemoRevolve](https://github.com/PrzemoRevolve))
- Ricardo Mendes ([locks](https://github.com/locks))
- Ruslan Grabovoy ([ro0gr](https://github.com/ro0gr))
- Sylvain MINA ([sly7-7](https://github.com/sly7-7))
- [verim1990](https://github.com/verim1990)
## v5.0.3 (2017-12-21)

@@ -2,0 +25,0 @@

4

docs/rules/no-function-prototype-extensions.md

@@ -5,3 +5,3 @@ ## Do not use Ember's `function` prototype extensions

Use computed property syntax, observer syntax or module hooks instead of `.property()`, `.observe()` or `.on()` in Ember modules.
Use computed property syntax, observer syntax or module hooks instead of `.property()`, `.observes()` or `.on()` in Ember modules.

@@ -12,3 +12,3 @@ ```javascript

abc: function() { /* custom logic */ }.property('xyz'),
def: function() { /* custom logic */ }.observe('xyz'),
def: function() { /* custom logic */ }.observes('xyz'),
ghi: function() { /* custom logic */ }.on('didInsertElement'),

@@ -15,0 +15,0 @@

@@ -16,8 +16,12 @@ ## Don't introduce side-effects in computed properties

export default Component.extend({
users: [
{ name: 'Foo', age: 15 },
{ name: 'Bar', age: 16 },
{ name: 'Baz', age: 15 }
],
init() {
this.users = [
{ name: 'Foo', age: 15 },
{ name: 'Bar', age: 16 },
{ name: 'Baz', age: 15 }
];
this._super(...arguments);
},
// GOOD:

@@ -24,0 +28,0 @@ fifteen: filterBy('users', 'age', 15),

@@ -19,2 +19,3 @@ ## Organize your components

'willRender',
'willInsertElement',
'didInsertElement',

@@ -45,2 +46,3 @@ 'didRender',

'willRender',
'willInsertElement',
'didInsertElement',

@@ -47,0 +49,0 @@ 'didRender',

@@ -27,3 +27,3 @@ ## Use `Ember.get` and `Ember.set`

```javascript
// Bad
// Not recommended
this.get('fooProperty');

@@ -36,5 +36,4 @@ this.set('fooProperty', 'bar');

// Good
const {
// Recommended
import {
get,

@@ -45,4 +44,6 @@ set,

setProperties
} = Ember;
} from '@ember/object';
// ...
get(this, 'fooProperty');

@@ -49,0 +50,0 @@ set(this, 'fooProperty', 'bar');

@@ -22,3 +22,3 @@ 'use strict';

const functionPrototypeExtensionNames = ['property', 'observe', 'on'];
const functionPrototypeExtensionNames = ['property', 'observes', 'on'];

@@ -25,0 +25,0 @@ const isFunctionPrototypeExtension = function (property) {

@@ -40,2 +40,9 @@ 'use strict';

if (
utils.isIdentifier(fnCallee) &&
fnCallee.name === 'set') {
report(fnExpression);
return;
}
if (
utils.isMemberExpression(fnCallee) &&

@@ -42,0 +49,0 @@ utils.isThisExpression(fnCallee.object) &&

@@ -19,2 +19,3 @@ 'use strict';

'willRender',
'willInsertElement',
'didInsertElement',

@@ -43,3 +44,3 @@ 'didRender',

},
fixable: null // or "code" or "whitespace"
fixable: 'code' // or "code" or "whitespace"
},

@@ -58,2 +59,3 @@

'willRender',
'willInsertElement',
'didInsertElement',

@@ -60,0 +62,0 @@ 'didRender',

@@ -15,2 +15,3 @@ 'use strict';

'property',
'init',
'single-line-function',

@@ -34,3 +35,3 @@ 'multi-line-function',

},
fixable: null, // or "code" or "whitespace"
fixable: 'code', // or "code" or "whitespace"
},

@@ -37,0 +38,0 @@

@@ -28,3 +28,3 @@ 'use strict';

},
fixable: null, // or "code" or "whitespace"
fixable: 'code', // or "code" or "whitespace"
},

@@ -31,0 +31,0 @@

@@ -13,2 +13,3 @@ 'use strict';

'property',
'init',
'single-line-function',

@@ -41,3 +42,3 @@ 'multi-line-function',

},
fixable: null // or "code" or "whitespace"
fixable: 'code' // or "code" or "whitespace"
},

@@ -44,0 +45,0 @@

@@ -6,2 +6,54 @@ 'use strict';

/**
* Locates nodes with either an ExpressionStatement or ReturnStatement
* given name.
* @param {Array} nodeBody Array of nodes.
* @returns {Array} Array of nodes with given names.
*/
function findStmtNodes(nodeBody) {
const nodes = [];
const fnExpressions = utils.findNodes(nodeBody, 'ExpressionStatement');
const returnStatement = utils.findNodes(nodeBody, 'ReturnStatement');
if (fnExpressions.length !== 0) {
fnExpressions.forEach((item) => {
nodes.push(item);
});
}
if (returnStatement.length !== 0) {
returnStatement.forEach((item) => {
nodes.push(item);
});
}
return nodes;
}
/**
* Checks whether a node has the '_super' property.
* @param {Array} nodes An array of nodes.
* @returns {Boolean}
*/
function checkForSuper(nodes) {
if (nodes.length === 0) return false;
return nodes.some((n) => {
if (utils.isCallExpression(n.expression)) {
const fnCallee = n.expression.callee;
return utils.isMemberExpression(fnCallee) &&
utils.isThisExpression(fnCallee.object) &&
utils.isIdentifier(fnCallee.property) &&
fnCallee.property.name === '_super';
} else if (utils.isReturnStatement(n)) {
if (!n.argument || !utils.isCallExpression(n.argument)) return false;
const fnCallee = n.argument.callee;
return fnCallee.property.name === '_super';
}
return false;
});
}
//----------------------------------------------

@@ -35,3 +87,4 @@ // General rule - Call _super in init lifecycle hooks

!ember.isEmberRoute(node, filePath) &&
!ember.isEmberMixin(node, filePath)) return;
!ember.isEmberMixin(node, filePath) &&
!ember.isEmberService(node, filePath)) return;

@@ -42,13 +95,4 @@ const initProperty = ember.getModuleProperties(node).find(property => property.key.name === 'init');

const initPropertyBody = initProperty.value.body.body;
const fnExpressions = utils.findNodes(initPropertyBody, 'ExpressionStatement');
const hasSuper = fnExpressions.some((fnExpression) => {
if (!utils.isCallExpression(fnExpression.expression)) return false;
const fnCallee = fnExpression.expression.callee;
return utils.isMemberExpression(fnCallee) &&
utils.isThisExpression(fnCallee.object) &&
utils.isIdentifier(fnCallee.property) &&
fnCallee.property.name === '_super';
});
const nodes = findStmtNodes(initPropertyBody);
const hasSuper = checkForSuper(nodes);
if (!hasSuper) { report(initProperty); }

@@ -55,0 +99,0 @@ }

@@ -13,4 +13,5 @@ 'use strict';

isEmberController,
isEmberMixin,
isEmberRoute,
isEmberMixin,
isEmberService,

@@ -36,12 +37,7 @@ isSingleLineFn,

isComponentLifecycleHookName,
isComponentLifecycleHook,
isComponentCustomFunction,
isRoute,
isRouteCustomFunction,
isRouteProperty,
isRouteDefaultProp,
isControllerProperty,
isControllerDefaultProp,

@@ -148,7 +144,12 @@ parseDependentKeys,

function isEmberMixin(node, filePath) {
return isEmberCoreModule(node, 'Mixin', filePath);
}
function isEmberRoute(node, filePath) {
return isEmberCoreModule(node, 'Route', filePath);
}
function isEmberMixin(node, filePath) {
return isEmberCoreModule(node, 'Mixin', filePath);
function isEmberService(node, filePath) {
return isEmberCoreModule(node, 'Service', filePath);
}

@@ -219,5 +220,5 @@

return [
'init',
'didReceiveAttrs',
'willRender',
'willInsertElement',
'didInsertElement',

@@ -239,7 +240,2 @@ 'didRender',

function isComponentCustomFunction(property) {
return isFunctionExpression(property.value) &&
!isComponentLifecycleHookName(property.key.name);
}
function isRoute(node) {

@@ -267,10 +263,4 @@ return utils.isMemberExpression(node.callee) &&

function isRouteCustomFunction(property) {
return isFunctionExpression(property.value) &&
!isRouteLifecycleHookName(property.key.name);
}
function isRouteProperty(name) {
return [
'init',
'actions',

@@ -296,3 +286,2 @@ 'concatenatedProperties',

return [
'init',
'actions',

@@ -299,0 +288,0 @@ 'concatenatedProperties',

@@ -46,2 +46,3 @@ 'use strict';

willDestroyElement: 'lifecycle hook',
willInsertElement: 'lifecycle hook',
willRender: 'lifecycle hook',

@@ -60,2 +61,6 @@ willUpdate: 'lifecycle hook'

if (node.key.name === 'init') {
return 'init';
}
if (parentType === 'component') {

@@ -189,4 +194,56 @@ if (ember.isComponentLifecycleHook(node)) {

context.report(property,
`The ${typeName} should be above the ${nextTypeName} on line ${nextSourceLine}`);
context.report({
node: property,
message: `The ${typeName} should be above the ${nextTypeName} on line ${nextSourceLine}`,
fix: (fixer) => {
// for capturing the moved property and EOL character to insert ',' in between
const propertyWithEOL = /(.+)(\s+)$/;
const sourceCode = context.getSourceCode();
const foundProperty = firstPropertyOfNextType.node;
let nextToken = property;
let optionalComma = '';
let isLastProperty = false;
// including EOL character(s)
do {
const previousToken = nextToken;
nextToken = sourceCode.getTokenAfter(nextToken, { includeComments: true });
if (!nextToken) {
nextToken = previousToken;
}
// adding a trailing comma when it's the last property defined
if (nextToken.value === '}') {
isLastProperty = true;
if (previousToken.value !== ',') {
optionalComma = ',';
}
}
} while (nextToken.value === ',');
// additional whitespace is needed only when it's the last property
const whitespaceCount = isLastProperty ? property.loc.start.column : 0;
const propertyOffset = getCommentOffsetBefore(property, sourceCode);
const foundPropertyOffset = getCommentOffsetBefore(foundProperty, sourceCode);
const offset = nextToken.start - property.end;
const textBetween = property.start - propertyOffset - foundProperty.end - whitespaceCount;
const replaceTextRange = [foundProperty.start - foundPropertyOffset, nextToken.start];
const movedProperty = sourceCode.getText(property, propertyOffset, offset);
const restText = sourceCode.getText(foundProperty, foundPropertyOffset, textBetween);
// adding the optional comma between the property and newline
const replaceWithComma = `$1${optionalComma}$2`;
const movedPropertyWithComma = movedProperty.replace(propertyWithEOL, replaceWithComma);
const optionalWhitespace = (new Array(whitespaceCount + 1)).join(' ');
const outputText = movedPropertyWithComma + optionalWhitespace + restText;
return fixer.replaceTextRange(replaceTextRange, outputText);
}
});
} else {

@@ -202,2 +259,19 @@ maxOrder = order;

function getCommentOffsetBefore(property, sourceCode) {
const commentBlockRegExp = /^\/\*(.|\s)*\*\/$/m;
const commentLineRegExp = /^\/\/.*$/;
const previousToken = sourceCode.getTokenBefore(property, { includeComments: true });
const previousTokenText = sourceCode.getText(previousToken);
// including comments above the moved property
const isLineComment = previousToken.type === 'Line' && commentLineRegExp.test(previousTokenText);
const isBlockComment = previousToken.type === 'Block' && commentBlockRegExp.test(previousTokenText);
if (isLineComment || isBlockComment) {
return property.start - previousToken.start;
}
return 0;
}
function addBackwardsPosition(order, newPosition, targetPosition) {

@@ -204,0 +278,0 @@ const positionOrder = order.slice();

@@ -31,2 +31,3 @@ 'use strict';

isBinaryExpression,
isReturnStatement
};

@@ -201,2 +202,12 @@

/**
* Check whether or not a node is a ReturnStatement
*
* @param {Object} node The node to check.
* @return {Boolean} Whether or not the node is a ReturnStatement.
*/
function isReturnStatement(node) {
return node !== undefined && node.type && node.type === 'ReturnStatement';
}
/**
* Check whether or not a node is an ThisExpression.

@@ -203,0 +214,0 @@ *

{
"name": "eslint-plugin-ember",
"version": "5.0.3",
"version": "5.1.0",
"description": "Eslint plugin for Ember.js apps",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -124,6 +124,6 @@ # eslint-plugin-ember

|:---|:--------|:------------|
| | [order-in-components](./docs/rules/order-in-components.md) | Enforces proper order of properties in components |
| | [order-in-controllers](./docs/rules/order-in-controllers.md) | Enforces proper order of properties in controllers |
| | [order-in-models](./docs/rules/order-in-models.md) | Enforces proper order of properties in models |
| | [order-in-routes](./docs/rules/order-in-routes.md) | Enforces proper order of properties in routes |
| :wrench: | [order-in-components](./docs/rules/order-in-components.md) | Enforces proper order of properties in components |
| :wrench: | [order-in-controllers](./docs/rules/order-in-controllers.md) | Enforces proper order of properties in controllers |
| :wrench: | [order-in-models](./docs/rules/order-in-models.md) | Enforces proper order of properties in models |
| :wrench: | [order-in-routes](./docs/rules/order-in-routes.md) | Enforces proper order of properties in routes |
| :white_check_mark: | [use-brace-expansion](./docs/rules/use-brace-expansion.md) | Enforces usage of brace expansion |

@@ -130,0 +130,0 @@

@@ -85,3 +85,3 @@ // ------------------------------------------------------------------------------

{
code: 'export default Controller.extend({test: function() {}.observe("abc")});',
code: 'export default Controller.extend({test: function() {}.observes("abc")});',
parserOptions: { ecmaVersion: 6, sourceType: 'module' },

@@ -88,0 +88,0 @@ errors: [{

@@ -27,4 +27,10 @@ // ------------------------------------------------------------------------------

}],
}, {
code: 'prop: computed("test", function() {set(this, "testAmount", test.length); return "";})',
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'Don\'t introduce side-effects in computed properties',
}],
},
],
});

@@ -174,2 +174,4 @@ // ------------------------------------------------------------------------------

},
willInsertElement() {
},
didInsertElement() {

@@ -754,4 +756,27 @@ },

}]
},
{
code: `export default Component.extend({
levelOfHappiness: computed("attitude", "health", () => {
}),
vehicle: alias("car"),
actions: {}
});`,
output: `export default Component.extend({
vehicle: alias("car"),
levelOfHappiness: computed("attitude", "health", () => {
}),
actions: {}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "vehicle" single-line function should be above the "levelOfHappiness" multi-line function on line 2',
line: 5
}]
}
]
});

@@ -112,2 +112,3 @@ // ------------------------------------------------------------------------------

foo: service(),
someProp: null,
init() {

@@ -303,3 +304,3 @@ this._super(...arguments);

errors: [{
message: 'The inherited "init" property should be above the actions hash on line 4',
message: 'The "init" lifecycle hook should be above the actions hash on line 4',
line: 7

@@ -320,3 +321,3 @@ }]

errors: [{
message: 'The inherited "init" property should be above the "customFoo" empty method on line 4',
message: 'The "init" lifecycle hook should be above the "customFoo" empty method on line 4',
line: 5

@@ -336,7 +337,57 @@ }]

errors: [{
message: 'The "foo" service injection should be above the inherited "init" property on line 3',
message: 'The "foo" service injection should be above the "init" lifecycle hook on line 3',
line: 6
}]
},
{
code: `
export default Controller.extend({
init() {
this._super(...arguments);
},
someProp: null
});
`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "someProp" property should be above the "init" lifecycle hook on line 3',
line: 6
}]
},
{
code:
// whitespace is preserved inside `` and it's breaking the test
`export default Controller.extend({
queryParams: [],
currentUser: service(),
});`,
output:
`export default Controller.extend({
currentUser: service(),
queryParams: [],
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "currentUser" service injection should be above the "queryParams" property on line 2',
line: 3,
}],
},
{
code: `export default Controller.extend({
test: "asd",
queryParams: [],
actions: {}
});`,
output: `export default Controller.extend({
queryParams: [],
test: "asd",
actions: {}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "queryParams" property should be above the "test" property on line 2',
line: 3,
}],
}
],
});

@@ -86,3 +86,3 @@ // ------------------------------------------------------------------------------

b: belongsTo("c", { async: false }),
convertA(paramA) {
convertA(paramA) {
}

@@ -94,3 +94,3 @@ });`,

code: `export default DS.Model.extend({
convertA(paramA) {
convertA(paramA) {
},

@@ -220,4 +220,22 @@ a: attr("string"),

}],
},
}, {
code: `export default Model.extend({
behaviors: hasMany("behaviour"),
shape: attr("string"),
mood: computed("health", "hunger", function() {
})
});`,
output: `export default Model.extend({
shape: attr("string"),
behaviors: hasMany("behaviour"),
mood: computed("health", "hunger", function() {
})
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "shape" attribute should be above the "behaviors" relationship on line 2',
line: 3,
}],
}
],
});

@@ -401,3 +401,3 @@ // ------------------------------------------------------------------------------

errors: [{
message: 'The inherited "init" property should be above the actions hash on line 4',
message: 'The "init" lifecycle hook should be above the actions hash on line 4',
line: 5

@@ -418,3 +418,3 @@ }]

errors: [{
message: 'The inherited "init" property should be above the "customFoo" empty method on line 4',
message: 'The "init" lifecycle hook should be above the "customFoo" empty method on line 4',
line: 5

@@ -434,7 +434,189 @@ }]

errors: [{
message: 'The "foo" service injection should be above the inherited "init" property on line 3',
message: 'The "foo" service injection should be above the "init" lifecycle hook on line 3',
line: 6
}]
},
{
code: `
export default Route.extend({
init() {
this._super(...arguments);
},
someProp: null
});
`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "someProp" property should be above the "init" lifecycle hook on line 3',
line: 6
}]
},
{
code: `export default Route.extend({
queryParams: {},
currentUser: service(),
customProp: "test",
beforeModel() {},
model() {},
vehicle: alias("car"),
actions: {},
_customAction() {}
});`,
output: `export default Route.extend({
currentUser: service(),
queryParams: {},
customProp: "test",
vehicle: alias("car"),
beforeModel() {},
model() {},
actions: {},
_customAction() {}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "currentUser" service injection should be above the inherited "queryParams" property on line 2',
line: 3
}, {
message: 'The "vehicle" single-line function should be above the "beforeModel" lifecycle hook on line 5',
line: 7
}]
},
{
code: `export default Route.extend({
customProp: "test",
// queryParams line comment
queryParams: {},
model() {},
/**
* actions block comment
*/
actions: {},
_customAction() {}
});`,
output: `export default Route.extend({
// queryParams line comment
queryParams: {},
customProp: "test",
model() {},
/**
* actions block comment
*/
actions: {},
_customAction() {}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The inherited "queryParams" property should be above the "customProp" property on line 2',
line: 4
}]
},
{
code: `export default Route.extend({
customProp: "test",
model() {},
/**
* beforeModel block comment
*/
beforeModel() {},
/**
* actions block comment
*/
actions: {},
_customAction() {}
});`,
output: `export default Route.extend({
customProp: "test",
/**
* beforeModel block comment
*/
beforeModel() {},
model() {},
/**
* actions block comment
*/
actions: {},
_customAction() {}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "beforeModel" lifecycle hook should be above the "model" hook on line 3',
line: 7
}]
},
{
code:
// whitespace is preserved inside `` and it's breaking the test
`export default Route.extend({
customProp: "test",
/**
* actions block comment
*/
actions: {},
/**
* beforeModel block comment
*/
beforeModel() {}
});`,
output:
`export default Route.extend({
customProp: "test",
/**
* beforeModel block comment
*/
beforeModel() {},
/**
* actions block comment
*/
actions: {},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "beforeModel" lifecycle hook should be above the actions hash on line 6',
line: 10
}]
},
{
code:
// whitespace is preserved inside `` and it's breaking the test
`export default Route.extend({
model() {},
test: "asd"
});`,
output:
`export default Route.extend({
test: "asd",
model() {},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "test" property should be above the "model" hook on line 2',
line: 3
}]
},
{
code: `export default Route.extend({
model() {},
test: "asd",
actions: {}
});`,
output: `export default Route.extend({
test: "asd",
model() {},
actions: {}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{
message: 'The "test" property should be above the "model" hook on line 3',
line: 5
}]
}
]
});

@@ -18,2 +18,82 @@ // ------------------------------------------------------------------------------

{
code: `export default Component.extend({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Route.extend({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Controller.extend({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Mixin.extend({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Service.extend({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Component({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Route({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Controller({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Mixin({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: `export default Service({
init() {
return this._super(...arguments);
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' }
},
{
code: 'export default Component.extend();',

@@ -35,2 +115,6 @@ parserOptions: { ecmaVersion: 6, sourceType: 'module' },

{
code: 'export default Service.extend();',
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
},
{
code: `export default Component({

@@ -68,2 +152,10 @@ init() {

{
code: `export default Service({
init() {
this._super(...arguments);
},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
},
{
code: `export default Component({

@@ -76,2 +168,34 @@ init: function() {

},
{
code: `export default Route({
init: function() {
this._super(...arguments);
},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
},
{
code: `export default Controller({
init: function() {
this._super(...arguments);
},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
},
{
code: `export default Mixin({
init: function() {
this._super(...arguments);
},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
},
{
code: `export default Service({
init: function() {
this._super(...arguments);
},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
}
],

@@ -183,3 +307,209 @@ invalid: [

},
{
code: `export default Service.extend({
init() {},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }],
},
{
code: `export default Service.extend({
init() {
this.set('prop', 'value');
},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }],
},
{
code: `export default Service.extend({
init() {
this.set('prop', 'value');
this.set('prop2', 'value2');
},
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }],
},
{
code: `export default Component.extend({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Route.extend({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Controller.extend({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Mixin.extend({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Service.extend({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Component({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Route({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Controller({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Mixin({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Service({
init() {
return;
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Component.extend({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Route.extend({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Controller.extend({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Mixin.extend({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Service.extend({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Component({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Route({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Controller({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Mixin({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
},
{
code: `export default Service({
init() {
return 'meh';
}
});`,
parserOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [{ message, line: 2 }]
}
],
});

@@ -225,2 +225,35 @@ 'use strict';

describe('isEmberService', () => {
it('should check if it\'s an Ember Service', () => {
let node;
node = parse('Ember.Service.extend()');
expect(
emberUtils.isEmberService(node),
'it should detect Service when using Ember.Service'
).toBeTruthy();
node = parse('Service.extend()');
expect(
emberUtils.isEmberService(node),
'it should detect Service when using local module Service'
).toBeTruthy();
});
it('should check if it\'s an Ember Service even if it uses custom name', () => {
const node = parse('CustomService.extend()');
const filePath = 'example-app/services/path/to/some-feature.js';
expect(
emberUtils.isEmberService(node),
'it shouldn\'t detect Service when no file path is proviced'
).toBeFalsy();
expect(
emberUtils.isEmberService(node, filePath),
'it should detect Service when file path is provided'
).toBeTruthy();
});
});
describe('isInjectedServiceProp', () => {

@@ -227,0 +260,0 @@ let node;

@@ -137,2 +137,10 @@ 'use strict';

describe('isReturnStatement', () => {
const node = babelEslint.parse('return').body[0];
it('should check if node is a return statement', () => {
expect(utils.isReturnStatement(node)).toBeTruthy();
});
});
describe('isThisExpression', () => {

@@ -139,0 +147,0 @@ const node = parse('this');

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc