diff --git a/rules/function-type.js b/rules/function-type.js index 75124353..e97a867f 100644 --- a/rules/function-type.js +++ b/rules/function-type.js @@ -4,25 +4,19 @@ module.exports = function(context) { var utils = require('./utils/utils'); var angularObjectList = ['controller', 'filter', 'factory', 'service']; var configType = context.options[0]; - var message; - - function isArray(item) { - return Object.prototype.toString.call(item) === '[object Array]'; - } + var messageByConfigType = { + anonymous: 'Use anonymous functions instead of named function', + named: 'Use named functions instead of anonymous function' + }; + var message = messageByConfigType[configType]; - if (isArray(context.options[1])) { + if (context.options[1]) { angularObjectList = context.options[1]; } - if (configType === 'anonymous') { - message = 'Use anonymous functions instead of named function'; - } else if (configType === 'named') { - message = 'Use named functions instead of anonymous function'; - } - function checkType(arg) { - return (configType === 'named' && utils.isIdentifierType(arg)) || - (configType === 'anonymous' && utils.isFunctionType(arg)); + return (configType === 'named' && (utils.isIdentifierType(arg) || utils.isNamedInlineFunction(arg))) || + (configType === 'anonymous' && utils.isFunctionType(arg) && !utils.isNamedInlineFunction(arg)); } return { @@ -51,7 +45,13 @@ module.exports = function(context) { }; module.exports.schema = [{ - type: 'string' + enum: [ + 'named', + 'anonymous' + ] }, { - type: 'array' + type: 'array', + items: { + type: 'string' + } }]; diff --git a/rules/utils/utils.js b/rules/utils/utils.js index 9d15c572..a9e14bab 100644 --- a/rules/utils/utils.js +++ b/rules/utils/utils.js @@ -32,6 +32,7 @@ module.exports = { isToStringStatement: isToStringStatement, isArrayType: isArrayType, isFunctionType: isFunctionType, + isNamedInlineFunction: isNamedInlineFunction, isIdentifierType: isIdentifierType, isMemberExpression: isMemberExpression, isLiteralType: isLiteralType, @@ -149,6 +150,16 @@ function isFunctionType(node) { return node !== undefined && node.type === 'FunctionExpression'; } +/** + * Check whether or not a node is an named FunctionExpression. + * + * @param {Object} node The node to check. + * @returns {boolean} Whether or not the node is an named FunctionExpression. + */ +function isNamedInlineFunction(node) { + return this.isFunctionType(node) && node.id && node.id.name && node.id.name.length > 0; +} + /** * Check whether or not a node is an Identifier. * diff --git a/test/function-type.js b/test/function-type.js index 9942a95c..c43f111e 100644 --- a/test/function-type.js +++ b/test/function-type.js @@ -39,6 +39,10 @@ angularObjectList.forEach(function(object) { code: 'function func(Service1) {};app.' + object + '("name", ["Service1", func]);', options: ['anonymous'], errors: [{message: 'Use anonymous functions instead of named function'}] + }, { + code: 'angular.module("myModule").' + object + '("myService", function myService($http, $log) {});', + options: ['anonymous'], + errors: [{message: 'Use anonymous functions instead of named function'}] }); valid.push({ @@ -47,6 +51,9 @@ angularObjectList.forEach(function(object) { }, { code: 'function func(Service1) {};app.' + object + '("name", ["Service1", func]);', options: ['named'] + }, { + code: 'angular.module("myModule").' + object + '("myService", function myService($http, $log) {});', + options: ['named'] }); });