mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-18 03:23:57 +08:00
instead, vendor in the two files we actually need. This reduces our install footprint by 5MB
209 lines
7.1 KiB
TypeScript
209 lines
7.1 KiB
TypeScript
|
|
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
import { tags } from '@angular-devkit/core';
|
|
import { HostTree } from '@angular-devkit/schematics';
|
|
import * as ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript';
|
|
import { Change, InsertChange } from '../utility/change';
|
|
import { getFileContent } from '../utility/test';
|
|
import {
|
|
addDeclarationToModule,
|
|
addExportToModule,
|
|
addProviderToModule,
|
|
addSymbolToNgModuleMetadata,
|
|
} from './ast-utils';
|
|
|
|
|
|
function getTsSource(path: string, content: string): ts.SourceFile {
|
|
return ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
|
|
}
|
|
|
|
function applyChanges(path: string, content: string, changes: Change[]): string {
|
|
const tree = new HostTree();
|
|
tree.create(path, content);
|
|
const exportRecorder = tree.beginUpdate(path);
|
|
for (const change of changes) {
|
|
if (change instanceof InsertChange) {
|
|
exportRecorder.insertLeft(change.pos, change.toAdd);
|
|
}
|
|
}
|
|
tree.commitUpdate(exportRecorder);
|
|
|
|
return getFileContent(tree, path);
|
|
}
|
|
|
|
describe('ast utils', () => {
|
|
let modulePath: string;
|
|
let moduleContent: string;
|
|
beforeEach(() => {
|
|
modulePath = '/src/app/app.module.ts';
|
|
moduleContent = `
|
|
import { BrowserModule } from '@angular/platform-browser';
|
|
import { NgModule } from '@angular/core';
|
|
import { AppComponent } from './app.component';
|
|
|
|
@NgModule({
|
|
declarations: [
|
|
AppComponent
|
|
],
|
|
imports: [
|
|
BrowserModule
|
|
],
|
|
providers: [],
|
|
bootstrap: [AppComponent]
|
|
})
|
|
export class AppModule { }
|
|
`;
|
|
});
|
|
|
|
it('should add export to module', () => {
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addExportToModule(source, modulePath, 'FooComponent', './foo.component');
|
|
const output = applyChanges(modulePath, moduleContent, changes);
|
|
expect(output).toMatch(/import { FooComponent } from '.\/foo.component';/);
|
|
expect(output).toMatch(/exports: \[FooComponent\]/);
|
|
});
|
|
|
|
it('should add export to module if not indented', () => {
|
|
moduleContent = tags.stripIndents`${moduleContent}`;
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addExportToModule(source, modulePath, 'FooComponent', './foo.component');
|
|
const output = applyChanges(modulePath, moduleContent, changes);
|
|
expect(output).toMatch(/import { FooComponent } from '.\/foo.component';/);
|
|
expect(output).toMatch(/exports: \[FooComponent\]/);
|
|
});
|
|
|
|
it('should add declarations to module if not indented', () => {
|
|
moduleContent = tags.stripIndents`${moduleContent}`;
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addDeclarationToModule(source, modulePath, 'FooComponent', './foo.component');
|
|
const output = applyChanges(modulePath, moduleContent, changes);
|
|
expect(output).toMatch(/import { FooComponent } from '.\/foo.component';/);
|
|
expect(output).toMatch(/declarations: \[\nAppComponent,\nFooComponent\n\]/);
|
|
});
|
|
|
|
it('should add metadata', () => {
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addSymbolToNgModuleMetadata(source, modulePath, 'imports', 'HelloWorld');
|
|
expect(changes).not.toBeNull();
|
|
|
|
const output = applyChanges(modulePath, moduleContent, changes || []);
|
|
expect(output).toMatch(/imports: [\s\S]+,\n\s+HelloWorld\n\s+\]/m);
|
|
});
|
|
|
|
it('should add metadata (comma)', () => {
|
|
const moduleContent = `
|
|
import { BrowserModule } from '@angular/platform-browser';
|
|
import { NgModule } from '@angular/core';
|
|
|
|
@NgModule({
|
|
declarations: [
|
|
AppComponent
|
|
],
|
|
imports: [
|
|
BrowserModule,
|
|
],
|
|
providers: [],
|
|
bootstrap: [AppComponent]
|
|
})
|
|
export class AppModule { }
|
|
`;
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addSymbolToNgModuleMetadata(source, modulePath, 'imports', 'HelloWorld');
|
|
expect(changes).not.toBeNull();
|
|
|
|
const output = applyChanges(modulePath, moduleContent, changes || []);
|
|
expect(output).toMatch(/imports: [\s\S]+,\n\s+HelloWorld,\n\s+\]/m);
|
|
});
|
|
|
|
it('should add metadata (missing)', () => {
|
|
const moduleContent = `
|
|
import { BrowserModule } from '@angular/platform-browser';
|
|
import { NgModule } from '@angular/core';
|
|
|
|
@NgModule({
|
|
declarations: [
|
|
AppComponent
|
|
],
|
|
providers: [],
|
|
bootstrap: [AppComponent]
|
|
})
|
|
export class AppModule { }
|
|
`;
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addSymbolToNgModuleMetadata(source, modulePath, 'imports', 'HelloWorld');
|
|
expect(changes).not.toBeNull();
|
|
|
|
const output = applyChanges(modulePath, moduleContent, changes || []);
|
|
expect(output).toMatch(/imports: \[HelloWorld]\r?\n/m);
|
|
});
|
|
|
|
it('should add metadata (empty)', () => {
|
|
const moduleContent = `
|
|
import { BrowserModule } from '@angular/platform-browser';
|
|
import { NgModule } from '@angular/core';
|
|
|
|
@NgModule({
|
|
declarations: [
|
|
AppComponent
|
|
],
|
|
providers: [],
|
|
imports: [],
|
|
bootstrap: [AppComponent]
|
|
})
|
|
export class AppModule { }
|
|
`;
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addSymbolToNgModuleMetadata(source, modulePath, 'imports', 'HelloWorld');
|
|
expect(changes).not.toBeNull();
|
|
|
|
const output = applyChanges(modulePath, moduleContent, changes || []);
|
|
expect(output).toMatch(/imports: \[HelloWorld],\r?\n/m);
|
|
});
|
|
|
|
it('should handle NgModule with no newlines', () => {
|
|
const moduleContent = `
|
|
import { BrowserModule } from '@angular/platform-browser';
|
|
import { NgModule } from '@angular/core';
|
|
|
|
@NgModule({imports: [BrowserModule], declarations: []})
|
|
export class AppModule { }
|
|
`;
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addExportToModule(source, modulePath, 'FooComponent', './foo.component');
|
|
const output = applyChanges(modulePath, moduleContent, changes);
|
|
expect(output).toMatch(/import { FooComponent } from '.\/foo.component';/);
|
|
expect(output).toMatch(/exports: \[FooComponent\]/);
|
|
});
|
|
|
|
it('should add into providers metadata in new line ', () => {
|
|
const moduleContent = `
|
|
import { BrowserModule } from '@angular/platform-browser';
|
|
import { NgModule } from '@angular/core';
|
|
|
|
@NgModule({
|
|
imports: [BrowserModule],
|
|
declarations: [],
|
|
providers: [
|
|
{
|
|
provide: HTTP_INTERCEPTORS,
|
|
useClass: AuthInterceptor,
|
|
multi: true
|
|
}
|
|
]
|
|
})
|
|
export class AppModule { }
|
|
`;
|
|
const source = getTsSource(modulePath, moduleContent);
|
|
const changes = addProviderToModule(source, modulePath, 'LogService', './log.service');
|
|
const output = applyChanges(modulePath, moduleContent, changes);
|
|
expect(output).toMatch(/import { LogService } from '.\/log.service';/);
|
|
expect(output).toMatch(/\},\r?\n\s*LogService\r?\n\s*\]/);
|
|
});
|
|
});
|