Repository: ember-cli/eslint-plugin-ember
Pull request #605 (2019-11-21 16:44:31)

Move import utils to separate file
Soon, I'd like to have a complete and consistent suite of utils with clear APIs available for checking imports.

CC: @alexlafroscia


Patch:
diff --git a/lib/rules/new-module-imports.js b/lib/rules/new-module-imports.js
index 017783ce..5db32f55 100644
--- a/lib/rules/new-module-imports.js
+++ b/lib/rules/new-module-imports.js
@@ -2,7 +2,7 @@
 
 const MAPPING = require('ember-rfc176-data');
 const { buildMessage, getFullNames, isDestructuring } = require('../utils/new-module');
-const { getSourceModuleNameForIdentifier } = require('../utils/utils');
+const { getSourceModuleNameForIdentifier } = require('../utils/import');
 
 const GLOBALS = MAPPING.reduce((memo, exportDefinition) => {
   if (exportDefinition.deprecated) {
diff --git a/lib/rules/no-classic-classes.js b/lib/rules/no-classic-classes.js
index 6be70cc5..3849a9b6 100644
--- a/lib/rules/no-classic-classes.js
+++ b/lib/rules/no-classic-classes.js
@@ -1,6 +1,6 @@
 'use strict';
 
-const { getSourceModuleNameForIdentifier } = require('../utils/utils');
+const { getSourceModuleNameForIdentifier } = require('../utils/import');
 const { isObjectExpression } = require('../utils/types');
 
 const ERROR_MESSAGE_NO_CLASSIC_CLASSES =
diff --git a/lib/rules/require-tagless-components.js b/lib/rules/require-tagless-components.js
index 4dc78471..fc5ab51f 100644
--- a/lib/rules/require-tagless-components.js
+++ b/lib/rules/require-tagless-components.js
@@ -1,7 +1,7 @@
 'use strict';
 
 const { isEmberComponent } = require('../utils/ember');
-const { getSourceModuleNameForIdentifier } = require('../utils/utils');
+const { getSourceModuleNameForIdentifier } = require('../utils/import');
 const {
   isCallExpression,
   isIdentifier,
diff --git a/lib/rules/use-ember-data-rfc-395-imports.js b/lib/rules/use-ember-data-rfc-395-imports.js
index 3d033cf5..466501ce 100644
--- a/lib/rules/use-ember-data-rfc-395-imports.js
+++ b/lib/rules/use-ember-data-rfc-395-imports.js
@@ -2,7 +2,7 @@
 
 const MAPPINGS = require('@ember-data/rfc395-data');
 const { buildFix, buildMessage, getFullNames, isDestructuring } = require('../utils/new-module');
-const { getSourceModuleNameForIdentifier } = require('../utils/utils');
+const { getSourceModuleNameForIdentifier } = require('../utils/import');
 
 /**
  * This function returns an object like this:
diff --git a/lib/utils/ember.js b/lib/utils/ember.js
index c417c389..9335bb51 100644
--- a/lib/utils/ember.js
+++ b/lib/utils/ember.js
@@ -1,6 +1,7 @@
 'use strict';
 
 const utils = require('./utils');
+const importUtils = require('./import');
 const types = require('./types');
 const assert = require('assert');
 
@@ -177,7 +178,10 @@ function isEmberCoreModule(context, node, moduleName) {
     if (!node.superClass) {
       return false;
     }
-    const superClassImportPath = utils.getSourceModuleNameForIdentifier(context, node.superClass);
+    const superClassImportPath = importUtils.getSourceModuleNameForIdentifier(
+      context,
+      node.superClass
+    );
 
     if (superClassImportPath === CORE_MODULE_IMPORT_PATHS[moduleName]) {
       return true;
diff --git a/lib/utils/import.js b/lib/utils/import.js
new file mode 100644
index 00000000..1771e646
--- /dev/null
+++ b/lib/utils/import.js
@@ -0,0 +1,44 @@
+'use strict';
+
+const assert = require('assert');
+const { isIdentifier, isImportDeclaration, isMemberExpression } = require('../utils/types');
+
+module.exports = {
+  getSourceModuleNameForIdentifier,
+  getSourceModuleName,
+};
+
+/**
+ * Gets the name of the module that an identifier was imported from,
+ * if it was imported
+ *
+ * @param {Object} context the context of the ESLint rule
+ * @param {node} node the Idenfifier to find an import for
+ * @returns {string | undefined} The name of the module the identifier was imported from, if it was imported
+ */
+function getSourceModuleNameForIdentifier(context, node) {
+  const [program] = context.getAncestors(node);
+  const importDeclaration = program.body
+    .filter(isImportDeclaration)
+    .find(importDeclaration =>
+      importDeclaration.specifiers.some(
+        specifier => specifier.local.name === getSourceModuleName(node)
+      )
+    );
+
+  return importDeclaration ? importDeclaration.source.value : undefined;
+}
+
+function getSourceModuleName(node) {
+  if (isMemberExpression(node) && node.object) {
+    return getSourceModuleName(node.object);
+  } else if (isIdentifier(node)) {
+    return node.name;
+  } else {
+    assert(
+      false,
+      '`getSourceModuleName` should only be called on `MemberExpression` or `Identifier`'
+    );
+    return undefined;
+  }
+}
diff --git a/lib/utils/utils.js b/lib/utils/utils.js
index 10aecd98..f6e72459 100644
--- a/lib/utils/utils.js
+++ b/lib/utils/utils.js
@@ -3,13 +3,11 @@
 const {
   isCallExpression,
   isIdentifier,
-  isImportDeclaration,
   isLiteral,
   isMemberExpression,
   isNewExpression,
   isObjectPattern,
 } = require('../utils/types');
-const assert = require('assert');
 
 module.exports = {
   collectObjectPatternBindings,
@@ -18,8 +16,6 @@ module.exports = {
   getParent,
   getPropertyValue,
   getSize,
-  getSourceModuleName,
-  getSourceModuleNameForIdentifier,
   isEmptyMethod,
   isGlobalCallExpression,
   parseArgs,
@@ -202,41 +198,6 @@ function isEmptyMethod(node) {
   return node.value.body && node.value.body.body && node.value.body.body.length <= 0;
 }
 
-/**
- * Gets the name of the module that an identifier was imported from,
- * if it was imported
- *
- * @param {Object} context the context of the ESLint rule
- * @param {node} node the Idenfifier to find an import for
- * @returns {string | undefined} The name of the module the identifier was imported from, if it was imported
- */
-function getSourceModuleNameForIdentifier(context, node) {
-  const [program] = context.getAncestors(node);
-  const importDeclaration = program.body
-    .filter(isImportDeclaration)
-    .find(importDeclaration =>
-      importDeclaration.specifiers.some(
-        specifier => specifier.local.name === getSourceModuleName(node)
-      )
-    );
-
-  return importDeclaration ? importDeclaration.source.value : undefined;
-}
-
-function getSourceModuleName(node) {
-  if (isMemberExpression(node) && node.object) {
-    return getSourceModuleName(node.object);
-  } else if (isIdentifier(node)) {
-    return node.name;
-  } else {
-    assert(
-      false,
-      '`getSourceModuleName` should only be called on `MemberExpression` or `Identifier`'
-    );
-    return undefined;
-  }
-}
-
 /**
  * Travels up the ancestors of a given node, if the predicate function returns
  * truthy for a given node or ancestor, return that node, otherwise return null


Test patch:
diff --git a/tests/lib/utils/import-test.js b/tests/lib/utils/import-test.js
new file mode 100644
index 00000000..303ce981
--- /dev/null
+++ b/tests/lib/utils/import-test.js
@@ -0,0 +1,18 @@
+const babelEslint = require('babel-eslint');
+const importUtils = require('../../../lib/utils/import');
+
+function parse(code) {
+  return babelEslint.parse(code).body[0].expression;
+}
+
+describe('getSourceModuleName', () => {
+  it('gets the correct module name DS', () => {
+    const node = parse('DS.Model.extend()').callee;
+    expect(importUtils.getSourceModuleName(node)).toEqual('DS');
+  });
+
+  it('gets the correct module name Model', () => {
+    const node = parse('Model.extend()').callee;
+    expect(importUtils.getSourceModuleName(node)).toEqual('Model');
+  });
+});
diff --git a/tests/lib/utils/utils-test.js b/tests/lib/utils/utils-test.js
index 71e67fa5..d4091477 100644
--- a/tests/lib/utils/utils-test.js
+++ b/tests/lib/utils/utils-test.js
@@ -192,15 +192,3 @@ describe('parseCallee', () => {
     expect(parsedCallee).toEqual(['Ember', 'A']);
   });
 });
-
-describe('getSourceModuleName', () => {
-  it('gets the correct module name DS', () => {
-    const node = parse('DS.Model.extend()').callee;
-    expect(utils.getSourceModuleName(node)).toEqual('DS');
-  });
-
-  it('gets the correct module name Model', () => {
-    const node = parse('Model.extend()').callee;
-    expect(utils.getSourceModuleName(node)).toEqual('Model');
-  });
-});
diff --git a/tests/lib/utils/utils/get-source-module-name-for-identifier-test.js b/tests/lib/utils/utils/get-source-module-name-for-identifier-test.js
index b8fc03b9..e2e39e2e 100644
--- a/tests/lib/utils/utils/get-source-module-name-for-identifier-test.js
+++ b/tests/lib/utils/utils/get-source-module-name-for-identifier-test.js
@@ -1,4 +1,4 @@
-const { getSourceModuleNameForIdentifier } = require('../../../../lib/utils/utils');
+const { getSourceModuleNameForIdentifier } = require('../../../../lib/utils/import');
 const { FauxContext } = require('../../../helpers/faux-context');
 const babelEslint = require('babel-eslint');