fix(schematics): incorrectly throws if NgModule uses namespaced decorator (#15298)

Currently if the developer defines the primary app `NgModule` using a namespaced
import (e.g. "@ngCore.NgModule`), the Material schematics will incorrectly not detect
that module as the logic that resolves the decorator name of a class declaration
is flawed.

This is because it incorrectly traverses a `PropertyAccessExpression`, while the
accessed property name is exposed at the root level `PropertyAccessExpression`.

This commit fixes this and also adds additional unit tests for the `hasNgModuleImport`
utility function. (We have integration tests for this; but we don't test that special case)
This commit is contained in:
Paul Gschwendtner
2019-03-04 19:58:47 +01:00
committed by Joey Perrott
parent ae41a0ad69
commit da8987b6fd
2 changed files with 39 additions and 1 deletions
@@ -0,0 +1,38 @@
import {HostTree} from '@angular-devkit/schematics';
import {UnitTestTree} from '@angular-devkit/schematics/testing';
import {hasNgModuleImport} from './ng-module-imports';
describe('NgModule import utils', () => {
let host: UnitTestTree;
beforeEach(() => {
host = new UnitTestTree(new HostTree());
});
describe('hasNgModuleImport', () => {
it('should properly detect imports', () => {
host.create('/test.ts', `
@NgModule({
imports: [TestModule],
})
export class MyModule {}
`);
expect(hasNgModuleImport(host, '/test.ts', 'TestModule')).toBe(true);
expect(hasNgModuleImport(host, '/test.ts', 'NotExistent')).toBe(false);
});
it(`should detect imports for NgModule's using a namespaced identifier`, () => {
host.create('/test.ts', `
@myImport.NgModule({
imports: [TestModule],
})
export class MyModule {}
`);
expect(hasNgModuleImport(host, '/test.ts', 'TestModule')).toBe(true);
expect(hasNgModuleImport(host, '/test.ts', 'NotExistent')).toBe(false);
});
});
});
@@ -49,7 +49,7 @@ function resolveIdentifierOfExpression(expression: ts.Expression): ts.Identifier
if (ts.isIdentifier(expression)) {
return expression;
} else if (ts.isPropertyAccessExpression(expression)) {
return resolveIdentifierOfExpression(expression.expression);
return expression.name;
}
return null;
}