fix(angular): correctly add provider to module if last element was object literal

addProviderToModule incorrectly added the desired provider if the last element in the providers
array was an object literal
This commit is contained in:
Zachary Williams 2019-10-03 22:48:23 -05:00 committed by Victor Savkin
parent 936801df9d
commit e9a6b20537
2 changed files with 116 additions and 3 deletions

View File

@ -0,0 +1,112 @@
import { InsertChange } from '@nrwl/workspace/src/utils/ast-utils';
import { createSourceFile, ScriptTarget } from 'typescript';
import { addProviderToModule } from './ast-utils';
describe('ast-utils', () => {
describe('_addSymbolToNgModuleMetadata', () => {
const moduleImport = `import { NgModule } from '@angular/core';`;
const fileName = 'app.module.ts';
const createTemplate = (content: string, close: string) => ({
start: content.length,
text: content + close
});
const createStockModule = (content: string) =>
createSourceFile(fileName, content, ScriptTarget.Latest, true);
it('should add provider to module without existing providers', () => {
const toAdd = 'MyProvider';
const { start, text } = createTemplate(
moduleImport + '@NgModule({',
'})'
);
const source = createStockModule(text);
const change = addProviderToModule(source, fileName, toAdd);
const expectedChange = [
new InsertChange(fileName, start, ` providers: [${toAdd}]\n`)
];
expect(change).toEqual(expectedChange);
});
it('should add provider to module with existing empty providers', () => {
const toAdd = 'MyProvider';
const { start, text } = createTemplate(
moduleImport + '@NgModule({providers:[',
']})'
);
const source = createStockModule(text);
const change = addProviderToModule(source, fileName, toAdd);
const expectedChange = [new InsertChange(fileName, start, toAdd)];
expect(change).toEqual(expectedChange);
});
it('should add provider to module with existing providers', () => {
const toAdd = 'MyProvider';
let template = createTemplate(
moduleImport + '@NgModule({providers:[ProviderOne,ProviderTwo',
']})'
);
let source = createStockModule(template.text);
let change = addProviderToModule(source, fileName, toAdd);
let expectedChange = [
new InsertChange(fileName, template.start, `, ${toAdd}`)
];
expect(change).toEqual(expectedChange);
template = createTemplate(
moduleImport +
'@NgModule({providers:[{provide:MyClass,useExisting:MyExistingClass}',
']})'
);
source = createStockModule(template.text);
change = addProviderToModule(source, fileName, toAdd);
expectedChange = [
new InsertChange(fileName, template.start, `, ${toAdd}`)
];
expect(change).toEqual(expectedChange);
template = createTemplate(
moduleImport + '@NgModule({providers:[someCondition ? MyProvider : []',
']})'
);
source = createStockModule(template.text);
change = addProviderToModule(source, fileName, toAdd);
expectedChange = [
new InsertChange(fileName, template.start, `, ${toAdd}`)
];
expect(change).toEqual(expectedChange);
template = createTemplate(
moduleImport +
'@NgModule({providers:[[NestedProvider1, NestedProvider2]',
']})'
);
source = createStockModule(template.text);
change = addProviderToModule(source, fileName, toAdd);
expectedChange = [
new InsertChange(fileName, template.start, `, ${toAdd}`)
];
expect(change).toEqual(expectedChange);
template = createTemplate(
moduleImport + '@NgModule({providers:[...ExistingProviders',
']})'
);
source = createStockModule(template.text);
change = addProviderToModule(source, fileName, toAdd);
expectedChange = [
new InsertChange(fileName, template.start, `, ${toAdd}`)
];
expect(change).toEqual(expectedChange);
});
});
});

View File

@ -216,7 +216,8 @@ function _addSymbolToNgModuleMetadata(
return [];
}
if (Array.isArray(node)) {
const isArray = Array.isArray(node);
if (isArray) {
const nodeArray = (node as {}) as Array<ts.Node>;
const symbolsArray = nodeArray.map(node => node.getText());
if (symbolsArray.includes(expression)) {
@ -228,7 +229,7 @@ function _addSymbolToNgModuleMetadata(
let toInsert: string;
let position = node.getEnd();
if (node.kind == ts.SyntaxKind.ObjectLiteralExpression) {
if (!isArray && node.kind == ts.SyntaxKind.ObjectLiteralExpression) {
// We haven't found the field in the metadata declaration. Insert a new
// field.
const expr = node as ts.ObjectLiteralExpression;
@ -248,7 +249,7 @@ function _addSymbolToNgModuleMetadata(
toInsert = `, ${metadataField}: [${expression}]`;
}
}
} else if (node.kind == ts.SyntaxKind.ArrayLiteralExpression) {
} else if (!isArray && node.kind == ts.SyntaxKind.ArrayLiteralExpression) {
// We found the field but it's empty. Insert it just before the `]`.
position--;
toInsert = `${expression}`;