Charles Lyding e895fc7c10 refactor(@schematics/angular): move standalone component helpers to a private export for Angular components
The standalone component helper utilities introduced into the `@angular/cdk` via
https://github.com/angular/components/pull/24931 have been added to an export path (`private/components`)
within `@schematics/angular`. The export path is primarily intended for the use of the components schematics
within `@angular/cdk` and `@angular/material`. The API exported from this path is not considered public API,
does not provide SemVer guarantees, and may be modified or removed without a deprecation cycle.
2022-05-26 11:38:13 -07:00

264 lines
8.4 KiB
TypeScript

/**
* @license
* Copyright Google LLC 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 { EmptyTree } from '@angular-devkit/schematics';
import ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript';
import {
addModuleImportToStandaloneBootstrap,
findBootstrapApplicationCall,
importsProvidersFrom,
} from './standalone';
describe('standalone utilities', () => {
let host: EmptyTree;
beforeEach(() => {
host = new EmptyTree();
});
function getSourceFileFrom(path: string) {
return ts.createSourceFile(path, host.readText(path), ts.ScriptTarget.Latest, true);
}
function stripWhitespace(str: string) {
return str.replace(/\s/g, '');
}
function assertContains(source: string, targetString: string) {
expect(stripWhitespace(source)).toContain(stripWhitespace(targetString));
}
describe('findBootstrapApplicationCall', () => {
it('should find a call to `bootstrapApplication`', () => {
host.create(
'/test.ts',
`
import { BrowserModule, bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {
providers: [importProvidersFrom(BrowserModule)]
});
`,
);
expect(findBootstrapApplicationCall(getSourceFileFrom('/test.ts'))).toBeTruthy();
});
it('should find an aliased call to `bootstrapApplication`', () => {
host.create(
'/test.ts',
`
import { BrowserModule, bootstrapApplication as boot } from '@angular/platform-browser';
import { AppComponent } from './app.component';
boot(AppComponent, {
providers: [importProvidersFrom(BrowserModule)]
});
`,
);
expect(findBootstrapApplicationCall(getSourceFileFrom('/test.ts'))).toBeTruthy();
});
it('should return null if there are no bootstrapApplication calls', () => {
host.create(
'/test.ts',
`
import { AppComponent } from './app.component';
console.log(AppComponent);
`,
);
expect(findBootstrapApplicationCall(getSourceFileFrom('/test.ts'))).toBeNull();
});
});
describe('importsProvidersFrom', () => {
it('should find that a bootstrapApplication call imports providers from a module', () => {
host.create(
'/test.ts',
`
import { importProvidersFrom } from '@angular/core';
import { BrowserModule, bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {
providers: [
{provide: foo, useValue: 10},
importProvidersFrom(BrowserModule)
]
});
`,
);
expect(importsProvidersFrom(host, '/test.ts', 'BrowserModule')).toBe(true);
expect(importsProvidersFrom(host, '/test.ts', 'FooModule')).toBe(false);
});
it('should find that a bootstrapApplication call imports providers from a module if importProvidersFrom is aliased', () => {
host.create(
'/test.ts',
`
import { importProvidersFrom as imp } from '@angular/core';
import { BrowserModule, bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {
providers: [imp(BrowserModule)]
});
`,
);
expect(importsProvidersFrom(host, '/test.ts', 'BrowserModule')).toBe(true);
expect(importsProvidersFrom(host, '/test.ts', 'FooModule')).toBe(false);
});
it('should return false if there is no bootstrapApplication calls', () => {
host.create(
'/test.ts',
`
import { AppComponent } from './app.component';
console.log(AppComponent);
`,
);
expect(importsProvidersFrom(host, '/test.ts', 'FooModule')).toBe(false);
});
});
describe('addModuleImportToStandaloneBootstrap', () => {
it('should be able to add a module import to a simple `bootstrapApplication` call', () => {
host.create(
'/test.ts',
`
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent);
`,
);
addModuleImportToStandaloneBootstrap(host, '/test.ts', 'FooModule', '@foo/bar');
const content = stripWhitespace(host.readText('/test.ts'));
assertContains(content, `import {importProvidersFrom} from '@angular/core';`);
assertContains(content, `import {FooModule} from '@foo/bar';`);
assertContains(
content,
`bootstrapApplication(AppComponent, {providers: [importProvidersFrom(FooModule)]});`,
);
});
it('should be able to add a module import to a `bootstrapApplication` call with an empty options object', () => {
host.create(
'/test.ts',
`
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {});
`,
);
addModuleImportToStandaloneBootstrap(host, '/test.ts', 'FooModule', '@foo/bar');
const content = stripWhitespace(host.readText('/test.ts'));
assertContains(content, `import {importProvidersFrom} from '@angular/core';`);
assertContains(content, `import {FooModule} from '@foo/bar';`);
assertContains(
content,
`bootstrapApplication(AppComponent, {providers: [importProvidersFrom(FooModule)]});`,
);
});
it('should be able to add a module import to a `bootstrapApplication` call with a pre-existing `providers` array', () => {
host.create(
'/test.ts',
`
import { enableProdMode } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
enableProdMode();
bootstrapApplication(AppComponent, {
providers: [{provide: 'foo', useValue: 'bar'}]
});
`,
);
addModuleImportToStandaloneBootstrap(host, '/test.ts', 'FooModule', '@foo/bar');
const content = stripWhitespace(host.readText('/test.ts'));
assertContains(content, `import {enableProdMode, importProvidersFrom} from '@angular/core';`);
assertContains(content, `import {FooModule} from '@foo/bar';`);
assertContains(
content,
`bootstrapApplication(AppComponent, {
providers: [
{provide: 'foo', useValue: 'bar'},
importProvidersFrom(FooModule)
]
});`,
);
});
it('should be able to add a module import to a `bootstrapApplication` call with a pre-existing `importProvidersFrom` call', () => {
host.create(
'/test.ts',
`
import { importProvidersFrom } from '@angular/core';
import { bootstrapApplication, BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {
providers: [{provide: 'foo', useValue: 'bar'}, importProvidersFrom(BrowserModule)]
});
`,
);
addModuleImportToStandaloneBootstrap(host, '/test.ts', 'FooModule', '@foo/bar');
const content = stripWhitespace(host.readText('/test.ts'));
assertContains(content, `import {importProvidersFrom} from '@angular/core';`);
assertContains(content, `import {FooModule} from '@foo/bar';`);
assertContains(
content,
`bootstrapApplication(AppComponent, {
providers: [
{provide: 'foo', useValue: 'bar'},
importProvidersFrom(BrowserModule, FooModule)
]
});`,
);
});
it('should throw if there is no `bootstrapModule` call', () => {
host.create(
'/test.ts',
`
import { AppComponent } from './app.component';
console.log(AppComponent);
`,
);
expect(() => {
addModuleImportToStandaloneBootstrap(host, '/test.ts', 'FooModule', '@foo/bar');
}).toThrowError(/Could not find bootstrapApplication call in \/test\.ts/);
});
});
});