Repository: ember-cli/eslint-plugin-ember (js)

Issue:
[7.7.0] `getSourceModuleName` should only be called on `MemberExpression` or `Identifier`
After updating, I get that error:

```
Build Error (broccoli-persistent-filter:EslintValidationFilter) in components/application-header.ts

`getSourceModuleName` should only be called on `MemberExpression` or `Identifier`
Occurred while linting /home/boris/project/app/components/application-header.ts:24
```

That line is as follows:

```typescript
@classic
@tagName('nav')
@classNames('navbar', 'navbar-default', 'navbar-fixed-top')
export default class extends Component.extend(ResizeAware) {
```

The last line is `24`.

Pull request:
Fix issue causing assert to fire in `getSourceModuleName` util function
Fixes #614.

@bmish I just tried out 7.7.0 in our app and I started seeing the following assertion `'getSourceModuleName' should only be called on 'MemberExpression' or 'Identifier'` firing on the following code:

```js
export default class MyModel extends Model.extend(SomeMixin) {
  ...
}
```

I've put together a patch for that here

Patch:
diff --git a/lib/utils/import.js b/lib/utils/import.js
index 1771e646..0829645f 100644
--- a/lib/utils/import.js
+++ b/lib/utils/import.js
@@ -1,7 +1,12 @@
 'use strict';
 
 const assert = require('assert');
-const { isIdentifier, isImportDeclaration, isMemberExpression } = require('../utils/types');
+const {
+  isCallExpression,
+  isIdentifier,
+  isImportDeclaration,
+  isMemberExpression,
+} = require('../utils/types');
 
 module.exports = {
   getSourceModuleNameForIdentifier,
@@ -30,14 +35,16 @@ function getSourceModuleNameForIdentifier(context, node) {
 }
 
 function getSourceModuleName(node) {
-  if (isMemberExpression(node) && node.object) {
+  if (isCallExpression(node) && node.callee) {
+    return getSourceModuleName(node.callee);
+  } else 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`'
+      '`getSourceModuleName` should only be called on a `CallExpression`, `MemberExpression` or `Identifier`'
     );
     return undefined;
   }


Test patch:
diff --git a/tests/lib/utils/import-test.js b/tests/lib/utils/import-test.js
index 303ce981..3af62770 100644
--- a/tests/lib/utils/import-test.js
+++ b/tests/lib/utils/import-test.js
@@ -6,13 +6,18 @@ function parse(code) {
 }
 
 describe('getSourceModuleName', () => {
-  it('gets the correct module name DS', () => {
+  it('gets the correct module name with MemberExpression', () => {
     const node = parse('DS.Model.extend()').callee;
     expect(importUtils.getSourceModuleName(node)).toEqual('DS');
   });
 
-  it('gets the correct module name Model', () => {
+  it('gets the correct module name with Identifier', () => {
     const node = parse('Model.extend()').callee;
     expect(importUtils.getSourceModuleName(node)).toEqual('Model');
   });
+
+  it('gets the correct module name with CallExpression', () => {
+    const node = parse('Model.extend()');
+    expect(importUtils.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 e2e39e2e..1877aa97 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
@@ -84,4 +84,17 @@ describe('when the identifier is imported', () => {
 
     expect(getSourceModuleNameForIdentifier(context, node)).toEqual('some-path');
   });
+
+  test('Model.extend(Mixin)', () => {
+    const context = new FauxContext(`
+      import Mixin from './my-mixin';
+      import Model from '@ember-data/model';
+
+      export default class SomeClass extends Model.extend(Mixin) {}
+    `);
+
+    const node = babelEslint.parse('Model.extend(Mixin)').body[0].expression;
+
+    expect(getSourceModuleNameForIdentifier(context, node)).toEqual('@ember-data/model');
+  });
 });