diff --git a/packages/compiler-cli/src/codegen.ts b/packages/compiler-cli/src/codegen.ts index 8d19416dd8..d84abbfd29 100644 --- a/packages/compiler-cli/src/codegen.ts +++ b/packages/compiler-cli/src/codegen.ts @@ -38,7 +38,7 @@ export class CodeGenerator { codegen(): Promise { return this.compiler - .compileAll(this.program.getSourceFiles().map( + .compileAllAsync(this.program.getSourceFiles().map( sf => this.ngCompilerHost.getCanonicalFileName(sf.fileName))) .then(generatedModules => { generatedModules.forEach(generatedModule => { diff --git a/packages/compiler-cli/test/diagnostics/mocks.ts b/packages/compiler-cli/test/diagnostics/mocks.ts index 68e7f5ccce..33235d761a 100644 --- a/packages/compiler-cli/test/diagnostics/mocks.ts +++ b/packages/compiler-cli/test/diagnostics/mocks.ts @@ -17,7 +17,11 @@ import {DiagnosticTemplateInfo} from '../../src/diagnostics/expression_diagnosti import {getClassFromStaticSymbol, getClassMembers, getPipesTable, getSymbolQuery} from '../../src/diagnostics/typescript_symbols'; import {Directory, MockAotContext} from '../mocks'; -const packages = path.join(__dirname, '../../../../../packages'); +function calcRootPath() { + const moduleFilename = module.filename.replace(/\\/g, '/'); + const distIndex = moduleFilename.indexOf('/dist/all'); + return moduleFilename.substr(0, distIndex); +} const realFiles = new Map(); @@ -40,7 +44,7 @@ export class MockLanguageServiceHost implements ts.LanguageServiceHost, Compiler strictNullChecks: true, baseUrl: currentDirectory, lib: ['lib.es2015.d.ts', 'lib.dom.d.ts'], - paths: {'@angular/*': [packages + '/*']} + paths: {'@angular/*': [calcRootPath() + '/packages/*']} }; this.context = new MockAotContext(currentDirectory, files) } diff --git a/packages/compiler/src/aot/compiler.ts b/packages/compiler/src/aot/compiler.ts index 3aa6234df4..4a1c854e94 100644 --- a/packages/compiler/src/aot/compiler.ts +++ b/packages/compiler/src/aot/compiler.ts @@ -39,7 +39,7 @@ export class AotCompiler { clearCache() { this._metadataResolver.clearCache(); } - compileAll(rootFiles: string[]): Promise { + compileAllAsync(rootFiles: string[]): Promise { const programSymbols = extractProgramSymbols(this._symbolResolver, rootFiles, this._host); const {ngModuleByPipeOrDirective, files, ngModules} = analyzeAndValidateNgModules(programSymbols, this._host, this._metadataResolver); @@ -56,6 +56,20 @@ export class AotCompiler { }); } + compileAllSync(rootFiles: string[]): GeneratedFile[] { + const programSymbols = extractProgramSymbols(this._symbolResolver, rootFiles, this._host); + const {ngModuleByPipeOrDirective, files, ngModules} = + analyzeAndValidateNgModules(programSymbols, this._host, this._metadataResolver); + ngModules.forEach( + ngModule => this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata( + ngModule.type.reference, true)); + const sourceModules = files.map( + file => this._compileSrcFile( + file.srcUrl, ngModuleByPipeOrDirective, file.directives, file.pipes, file.ngModules, + file.injectables)); + return flatten(sourceModules); + } + private _compileSrcFile( srcFileUrl: string, ngModuleByPipeOrDirective: Map, directives: StaticSymbol[], pipes: StaticSymbol[], ngModules: StaticSymbol[], diff --git a/packages/compiler/src/aot/compiler_host.ts b/packages/compiler/src/aot/compiler_host.ts index ec6c1ff527..e5c2927845 100644 --- a/packages/compiler/src/aot/compiler_host.ts +++ b/packages/compiler/src/aot/compiler_host.ts @@ -17,5 +17,5 @@ export interface AotCompilerHost extends StaticSymbolResolverHost, AotSummaryRes /** * Loads a resource (e.g. html / css) */ - loadResource(path: string): Promise; + loadResource(path: string): Promise|string; } diff --git a/packages/compiler/src/directive_normalizer.ts b/packages/compiler/src/directive_normalizer.ts index 725ef8568a..e9484a34ae 100644 --- a/packages/compiler/src/directive_normalizer.ts +++ b/packages/compiler/src/directive_normalizer.ts @@ -18,7 +18,7 @@ import {ResourceLoader} from './resource_loader'; import {extractStyleUrls, isStyleUrlResolvable} from './style_url_resolver'; import {PreparsedElementType, preparseElement} from './template_parser/template_preparser'; import {UrlResolver} from './url_resolver'; -import {SyncAsyncResult, isDefined, syntaxError} from './util'; +import {SyncAsync, isDefined, syntaxError} from './util'; export interface PrenormalizedTemplateMetadata { ngModuleType: any; @@ -35,7 +35,7 @@ export interface PrenormalizedTemplateMetadata { @CompilerInjectable() export class DirectiveNormalizer { - private _resourceLoaderCache = new Map>(); + private _resourceLoaderCache = new Map>(); constructor( private _resourceLoader: ResourceLoader, private _urlResolver: UrlResolver, @@ -53,19 +53,17 @@ export class DirectiveNormalizer { (stylesheet) => { this._resourceLoaderCache.delete(stylesheet.moduleUrl !); }); } - private _fetch(url: string): Promise { + private _fetch(url: string): SyncAsync { let result = this._resourceLoaderCache.get(url); if (!result) { - result = this._resourceLoader.get(url) !; + result = this._resourceLoader.get(url); this._resourceLoaderCache.set(url, result); } return result; } normalizeTemplate(prenormData: PrenormalizedTemplateMetadata): - SyncAsyncResult { - let normalizedTemplateSync: CompileTemplateMetadata = null !; - let normalizedTemplateAsync: Promise = undefined !; + SyncAsync { if (isDefined(prenormData.template)) { if (isDefined(prenormData.templateUrl)) { throw syntaxError( @@ -75,39 +73,33 @@ export class DirectiveNormalizer { throw syntaxError( `The template specified for component ${stringify(prenormData.componentType)} is not a string`); } - normalizedTemplateSync = this.normalizeTemplateSync(prenormData); - normalizedTemplateAsync = Promise.resolve(normalizedTemplateSync !); } else if (isDefined(prenormData.templateUrl)) { if (typeof prenormData.templateUrl !== 'string') { throw syntaxError( `The templateUrl specified for component ${stringify(prenormData.componentType)} is not a string`); } - normalizedTemplateAsync = this.normalizeTemplateAsync(prenormData); } else { throw syntaxError( `No template specified for component ${stringify(prenormData.componentType)}`); } + return SyncAsync.then( + this.normalizeTemplateOnly(prenormData), + (result: CompileTemplateMetadata) => this.normalizeExternalStylesheets(result)); + } - if (normalizedTemplateSync && normalizedTemplateSync.styleUrls.length === 0) { - // sync case - return new SyncAsyncResult(normalizedTemplateSync); + normalizeTemplateOnly(prenomData: PrenormalizedTemplateMetadata): + SyncAsync { + let template: SyncAsync; + let templateUrl: string; + if (prenomData.template != null) { + template = prenomData.template; + templateUrl = prenomData.moduleUrl; } else { - // async case - return new SyncAsyncResult( - null, normalizedTemplateAsync.then( - (normalizedTemplate) => this.normalizeExternalStylesheets(normalizedTemplate))); + templateUrl = this._urlResolver.resolve(prenomData.moduleUrl, prenomData.templateUrl !); + template = this._fetch(templateUrl); } - } - - normalizeTemplateSync(prenomData: PrenormalizedTemplateMetadata): CompileTemplateMetadata { - return this.normalizeLoadedTemplate(prenomData, prenomData.template !, prenomData.moduleUrl); - } - - normalizeTemplateAsync(prenomData: PrenormalizedTemplateMetadata): - Promise { - const templateUrl = this._urlResolver.resolve(prenomData.moduleUrl, prenomData.templateUrl !); - return this._fetch(templateUrl) - .then((value) => this.normalizeLoadedTemplate(prenomData, value, templateUrl)); + return SyncAsync.then( + template, (template) => this.normalizeLoadedTemplate(prenomData, template, templateUrl)); } normalizeLoadedTemplate( @@ -162,37 +154,42 @@ export class DirectiveNormalizer { } normalizeExternalStylesheets(templateMeta: CompileTemplateMetadata): - Promise { - return this._loadMissingExternalStylesheets(templateMeta.styleUrls) - .then((externalStylesheets) => new CompileTemplateMetadata({ - encapsulation: templateMeta.encapsulation, - template: templateMeta.template, - templateUrl: templateMeta.templateUrl, - styles: templateMeta.styles, - styleUrls: templateMeta.styleUrls, - externalStylesheets: externalStylesheets, - ngContentSelectors: templateMeta.ngContentSelectors, - animations: templateMeta.animations, - interpolation: templateMeta.interpolation, - isInline: templateMeta.isInline, - })); + SyncAsync { + return SyncAsync.then( + this._loadMissingExternalStylesheets(templateMeta.styleUrls), + (externalStylesheets) => new CompileTemplateMetadata({ + encapsulation: templateMeta.encapsulation, + template: templateMeta.template, + templateUrl: templateMeta.templateUrl, + styles: templateMeta.styles, + styleUrls: templateMeta.styleUrls, + externalStylesheets: externalStylesheets, + ngContentSelectors: templateMeta.ngContentSelectors, + animations: templateMeta.animations, + interpolation: templateMeta.interpolation, + isInline: templateMeta.isInline, + })); } private _loadMissingExternalStylesheets( styleUrls: string[], loadedStylesheets: Map = new Map()): - Promise { - return Promise - .all(styleUrls.filter((styleUrl) => !loadedStylesheets.has(styleUrl)) - .map(styleUrl => this._fetch(styleUrl).then((loadedStyle) => { - const stylesheet = this.normalizeStylesheet( - new CompileStylesheetMetadata({styles: [loadedStyle], moduleUrl: styleUrl})); - loadedStylesheets.set(styleUrl, stylesheet); - return this._loadMissingExternalStylesheets( - stylesheet.styleUrls, loadedStylesheets); - }))) - .then((_) => Array.from(loadedStylesheets.values())); + SyncAsync { + return SyncAsync.then( + SyncAsync.all(styleUrls.filter((styleUrl) => !loadedStylesheets.has(styleUrl)) + .map( + styleUrl => SyncAsync.then( + this._fetch(styleUrl), + (loadedStyle) => { + const stylesheet = + this.normalizeStylesheet(new CompileStylesheetMetadata( + {styles: [loadedStyle], moduleUrl: styleUrl})); + loadedStylesheets.set(styleUrl, stylesheet); + return this._loadMissingExternalStylesheets( + stylesheet.styleUrls, loadedStylesheets); + }))), + (_) => Array.from(loadedStylesheets.values())); } normalizeStylesheet(stylesheet: CompileStylesheetMetadata): CompileStylesheetMetadata { diff --git a/packages/compiler/src/jit/compiler.ts b/packages/compiler/src/jit/compiler.ts index 504a78530a..7cf3a447b3 100644 --- a/packages/compiler/src/jit/compiler.ts +++ b/packages/compiler/src/jit/compiler.ts @@ -19,7 +19,7 @@ import {jitStatements} from '../output/output_jit'; import {CompiledStylesheet, StyleCompiler} from '../style_compiler'; import {SummaryResolver} from '../summary_resolver'; import {TemplateParser} from '../template_parser/template_parser'; -import {OutputContext, SyncAsyncResult} from '../util'; +import {OutputContext, SyncAsync} from '../util'; import {ViewCompiler} from '../view_compiler/view_compiler'; @@ -51,20 +51,20 @@ export class JitCompiler implements Compiler { get injector(): Injector { return this._injector; } compileModuleSync(moduleType: Type): NgModuleFactory { - return this._compileModuleAndComponents(moduleType, true).syncResult !; + return SyncAsync.assertSync(this._compileModuleAndComponents(moduleType, true)); } compileModuleAsync(moduleType: Type): Promise> { - return this._compileModuleAndComponents(moduleType, false).asyncResult !; + return Promise.resolve(this._compileModuleAndComponents(moduleType, false)); } compileModuleAndAllComponentsSync(moduleType: Type): ModuleWithComponentFactories { - return this._compileModuleAndAllComponents(moduleType, true).syncResult !; + return SyncAsync.assertSync(this._compileModuleAndAllComponents(moduleType, true)); } compileModuleAndAllComponentsAsync(moduleType: Type): Promise> { - return this._compileModuleAndAllComponents(moduleType, false).asyncResult !; + return Promise.resolve(this._compileModuleAndAllComponents(moduleType, false)); } getNgContentSelectors(component: Type): string[] { @@ -97,36 +97,24 @@ export class JitCompiler implements Compiler { } private _compileModuleAndComponents(moduleType: Type, isSync: boolean): - SyncAsyncResult> { - const loadingPromise = this._loadModules(moduleType, isSync); - const createResult = () => { + SyncAsync> { + return SyncAsync.then(this._loadModules(moduleType, isSync), () => { this._compileComponents(moduleType, null); return this._compileModule(moduleType); - }; - if (isSync) { - return new SyncAsyncResult(createResult()); - } else { - return new SyncAsyncResult(null, loadingPromise.then(createResult)); - } + }); } private _compileModuleAndAllComponents(moduleType: Type, isSync: boolean): - SyncAsyncResult> { - const loadingPromise = this._loadModules(moduleType, isSync); - const createResult = () => { + SyncAsync> { + return SyncAsync.then(this._loadModules(moduleType, isSync), () => { const componentFactories: ComponentFactory[] = []; this._compileComponents(moduleType, componentFactories); return new ModuleWithComponentFactories(this._compileModule(moduleType), componentFactories); - }; - if (isSync) { - return new SyncAsyncResult(createResult()); - } else { - return new SyncAsyncResult(null, loadingPromise.then(createResult)); - } + }); } - private _loadModules(mainModule: any, isSync: boolean): Promise { - const loadingPromises: Promise[] = []; + private _loadModules(mainModule: any, isSync: boolean): SyncAsync { + const loading: Promise[] = []; const mainNgModule = this._metadataResolver.getNgModuleMetadata(mainModule) !; // Note: for runtime compilation, we want to transitively compile all modules, // so we also need to load the declared directives / pipes for all nested modules. @@ -137,13 +125,13 @@ export class JitCompiler implements Compiler { const promise = this._metadataResolver.loadDirectiveMetadata(moduleMeta.type.reference, ref, isSync); if (promise) { - loadingPromises.push(promise); + loading.push(promise); } }); this._filterJitIdentifiers(moduleMeta.declaredPipes) .forEach((ref) => this._metadataResolver.getOrLoadPipeMetadata(ref)); }); - return Promise.all(loadingPromises); + return SyncAsync.all(loading); } private _compileModule(moduleType: Type): NgModuleFactory { diff --git a/packages/compiler/src/metadata_resolver.ts b/packages/compiler/src/metadata_resolver.ts index b5f05651e2..dd7d04afb4 100644 --- a/packages/compiler/src/metadata_resolver.ts +++ b/packages/compiler/src/metadata_resolver.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Attribute, ChangeDetectionStrategy, Component, ComponentFactory, Directive, Host, Inject, Injectable, InjectionToken, ModuleWithProviders, Optional, Provider, Query, RendererType2, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef, ɵConsole as Console, ɵERROR_COMPONENT_TYPE, ɵccf as createComponentFactory, ɵstringify as stringify} from '@angular/core'; +import {Attribute, ChangeDetectionStrategy, Component, ComponentFactory, Directive, Host, Inject, Injectable, InjectionToken, ModuleWithProviders, Optional, Provider, Query, RendererType2, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef, ɵConsole as Console, ɵERROR_COMPONENT_TYPE, ɵccf as createComponentFactory, ɵisPromise as isPromise, ɵstringify as stringify} from '@angular/core'; import {StaticSymbol, StaticSymbolCache} from './aot/static_symbol'; import {ngfactoryFilePath} from './aot/util'; @@ -24,7 +24,7 @@ import {PipeResolver} from './pipe_resolver'; import {ElementSchemaRegistry} from './schema/element_schema_registry'; import {SummaryResolver} from './summary_resolver'; import {getUrlScheme} from './url_resolver'; -import {MODULE_SUFFIX, ValueTransformer, noUndefined, syntaxError, visitValue} from './util'; +import {MODULE_SUFFIX, SyncAsync, ValueTransformer, noUndefined, syntaxError, visitValue} from './util'; export type ErrorCollector = (error: any, type?: any) => void; export const ERROR_COLLECTOR_TOKEN = new InjectionToken('ErrorCollector'); @@ -170,7 +170,7 @@ export class CompileMetadataResolver { return typeSummary && typeSummary.summaryKind === kind ? typeSummary : null; } - loadDirectiveMetadata(ngModuleType: any, directiveType: any, isSync: boolean): Promise|null { + loadDirectiveMetadata(ngModuleType: any, directiveType: any, isSync: boolean): SyncAsync { if (this._directiveCache.has(directiveType)) { return null; } @@ -205,7 +205,7 @@ export class CompileMetadataResolver { } this._directiveCache.set(directiveType, normalizedDirMeta); this._summaryCache.set(directiveType, normalizedDirMeta.toSummary()); - return normalizedDirMeta; + return null; }; if (metadata.isComponent) { @@ -222,16 +222,11 @@ export class CompileMetadataResolver { animations: template.animations, interpolation: template.interpolation }); - if (templateMeta.syncResult) { - createDirectiveMetadata(templateMeta.syncResult); + if (isPromise(templateMeta) && isSync) { + this._reportError(componentStillLoadingError(directiveType), directiveType); return null; - } else { - if (isSync) { - this._reportError(componentStillLoadingError(directiveType), directiveType); - return null; - } - return templateMeta.asyncResult !.then(createDirectiveMetadata); } + return SyncAsync.then(templateMeta, createDirectiveMetadata); } else { // directive createDirectiveMetadata(null); diff --git a/packages/compiler/src/resource_loader.ts b/packages/compiler/src/resource_loader.ts index 38a61fa21f..a0237cd17b 100644 --- a/packages/compiler/src/resource_loader.ts +++ b/packages/compiler/src/resource_loader.ts @@ -11,5 +11,5 @@ * to load templates. */ export class ResourceLoader { - get(url: string): Promise|null { return null; } + get(url: string): Promise|string { return ''; } } diff --git a/packages/compiler/src/util.ts b/packages/compiler/src/util.ts index a076a605da..4c0e7b9cde 100644 --- a/packages/compiler/src/util.ts +++ b/packages/compiler/src/util.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ +import {ɵisPromise as isPromise} from '@angular/core'; + import * as o from './output/output_ast'; export const MODULE_SUFFIX = ''; @@ -80,19 +82,28 @@ export class ValueTransformer implements ValueVisitor { visitOther(value: any, context: any): any { return value; } } -export class SyncAsyncResult { - constructor(public syncResult: T|null, public asyncResult: Promise|null = null) { - if (!asyncResult) { - this.asyncResult = Promise.resolve(syncResult); +export type SyncAsync = T | Promise; + +export const SyncAsync = { + assertSync: (value: SyncAsync): T => { + if (isPromise(value)) { + throw new Error(`Illegal state: value cannot be a promise`); } + return value; + }, + then: (value: SyncAsync, cb: (value: T) => R | Promise| SyncAsync): + SyncAsync => { return isPromise(value) ? value.then(cb) : cb(value);}, + all: (syncAsyncValues: SyncAsync[]): SyncAsync => { + return syncAsyncValues.some(isPromise) ? Promise.all(syncAsyncValues) : syncAsyncValues as T[]; } } -export function syntaxError(msg: string): Error { - const error = Error(msg); - (error as any)[ERROR_SYNTAX_ERROR] = true; - return error; -} +export function syntaxError(msg: string): + Error { + const error = Error(msg); + (error as any)[ERROR_SYNTAX_ERROR] = true; + return error; + } const ERROR_SYNTAX_ERROR = 'ngSyntaxError'; diff --git a/packages/compiler/test/aot/compiler_spec.ts b/packages/compiler/test/aot/compiler_spec.ts index 7859691886..ad68561051 100644 --- a/packages/compiler/test/aot/compiler_spec.ts +++ b/packages/compiler/test/aot/compiler_spec.ts @@ -8,7 +8,6 @@ import {GeneratedFile, toTypeScript} from '@angular/compiler'; import {NodeFlags} from '@angular/core/src/view/index'; -import {async} from '@angular/core/testing'; import {MetadataBundler, MetadataCollector, ModuleMetadata, privateEntriesToIndex} from '@angular/tsc-wrapped'; import * as ts from 'typescript'; @@ -20,11 +19,11 @@ describe('compiler (unbundled Angular)', () => { let angularFiles = setup(); describe('Quickstart', () => { - it('should compile', async(() => compile([QUICKSTART, angularFiles]).then(({genFiles}) => { - expect(genFiles.find(f => /app\.component\.ngfactory\.ts/.test(f.genFileUrl))) - .toBeDefined(); - expect(genFiles.find(f => /app\.module\.ngfactory\.ts/.test(f.genFileUrl))).toBeDefined(); - }))); + it('should compile', () => { + const {genFiles} = compile([QUICKSTART, angularFiles]); + expect(genFiles.find(f => /app\.component\.ngfactory\.ts/.test(f.genFileUrl))).toBeDefined(); + expect(genFiles.find(f => /app\.module\.ngfactory\.ts/.test(f.genFileUrl))).toBeDefined(); + }); }); describe('aot source mapping', () => { @@ -51,12 +50,10 @@ describe('compiler (unbundled Angular)', () => { rootDir = {'app': appDir}; }); - function compileApp(): Promise { - return compile([rootDir, angularFiles]) - .then( - ({genFiles}) => {return genFiles.find( - genFile => - genFile.srcFileUrl === componentPath && genFile.genFileUrl.endsWith('.ts'))}); + function compileApp(): GeneratedFile { + const {genFiles} = compile([rootDir, angularFiles]); + return genFiles.find( + genFile => genFile.srcFileUrl === componentPath && genFile.genFileUrl.endsWith('.ts')); } function findLineAndColumn( @@ -106,102 +103,95 @@ describe('compiler (unbundled Angular)', () => { function declareTests({ngUrl, templateDecorator}: {ngUrl: string, templateDecorator: (template: string) => string}) { - it('should use the right source url in html parse errors', async(() => { - appDir['app.component.ts'] = - createComponentSource(templateDecorator('
\n ')); + it('should use the right source url in html parse errors', () => { + appDir['app.component.ts'] = createComponentSource(templateDecorator('
\n ')); - expectPromiseToThrow( - compileApp(), new RegExp(`Template parse errors[\\s\\S]*${ngUrl}@1:2`)); - })); + expect(() => compileApp()) + .toThrowError(new RegExp(`Template parse errors[\\s\\S]*${ngUrl}@1:2`)); + }); - it('should use the right source url in template parse errors', async(() => { - appDir['app.component.ts'] = createComponentSource( - templateDecorator('
\n
')); + it('should use the right source url in template parse errors', () => { + appDir['app.component.ts'] = + createComponentSource(templateDecorator('
\n
')); - expectPromiseToThrow( - compileApp(), new RegExp(`Template parse errors[\\s\\S]*${ngUrl}@1:7`)); - })); + expect(() => compileApp()) + .toThrowError(new RegExp(`Template parse errors[\\s\\S]*${ngUrl}@1:7`)); + }); - it('should create a sourceMap for the template', async(() => { - const template = 'Hello World!'; + it('should create a sourceMap for the template', () => { + const template = 'Hello World!'; - appDir['app.component.ts'] = createComponentSource(templateDecorator(template)); + appDir['app.component.ts'] = createComponentSource(templateDecorator(template)); - compileApp().then((genFile) => { - const genSource = toTypeScript(genFile); - const sourceMap = extractSourceMap(genSource) !; - expect(sourceMap.file).toEqual(genFile.genFileUrl); + const genFile = compileApp(); + const genSource = toTypeScript(genFile); + const sourceMap = extractSourceMap(genSource) !; + expect(sourceMap.file).toEqual(genFile.genFileUrl); - // the generated file contains code that is not mapped to - // the template but rather to the original source file (e.g. import statements, ...) - const templateIndex = sourceMap.sources.indexOf(ngUrl); - expect(sourceMap.sourcesContent[templateIndex]).toEqual(template); + // the generated file contains code that is not mapped to + // the template but rather to the original source file (e.g. import statements, ...) + const templateIndex = sourceMap.sources.indexOf(ngUrl); + expect(sourceMap.sourcesContent[templateIndex]).toEqual(template); - // for the mapping to the original source file we don't store the source code - // as we want to keep whatever TypeScript / ... produced for them. - const sourceIndex = sourceMap.sources.indexOf(ngComponentPath); - expect(sourceMap.sourcesContent[sourceIndex]).toBe(' '); - }); - })); + // for the mapping to the original source file we don't store the source code + // as we want to keep whatever TypeScript / ... produced for them. + const sourceIndex = sourceMap.sources.indexOf(ngComponentPath); + expect(sourceMap.sourcesContent[sourceIndex]).toBe(' '); + }); - it('should map elements correctly to the source', async(() => { - const template = '
\n
'; + it('should map elements correctly to the source', () => { + const template = '
\n
'; - appDir['app.component.ts'] = createComponentSource(templateDecorator(template)); + appDir['app.component.ts'] = createComponentSource(templateDecorator(template)); - compileApp().then((genFile) => { - const genSource = toTypeScript(genFile); - const sourceMap = extractSourceMap(genSource) !; - expect(originalPositionFor(sourceMap, findLineAndColumn(genSource, `'span'`))) - .toEqual({line: 2, column: 3, source: ngUrl}); - }); - })); + const genFile = compileApp(); + const genSource = toTypeScript(genFile); + const sourceMap = extractSourceMap(genSource) !; + expect(originalPositionFor(sourceMap, findLineAndColumn(genSource, `'span'`))) + .toEqual({line: 2, column: 3, source: ngUrl}); + }); - it('should map bindings correctly to the source', async(() => { - const template = `
\n
`; + it('should map bindings correctly to the source', () => { + const template = `
\n
`; - appDir['app.component.ts'] = createComponentSource(templateDecorator(template)); + appDir['app.component.ts'] = createComponentSource(templateDecorator(template)); - compileApp().then((genFile) => { - const genSource = toTypeScript(genFile); - const sourceMap = extractSourceMap(genSource) !; - expect(originalPositionFor(sourceMap, findLineAndColumn(genSource, `someMethod()`))) - .toEqual({line: 2, column: 9, source: ngUrl}); - }); - })); + const genFile = compileApp(); + const genSource = toTypeScript(genFile); + const sourceMap = extractSourceMap(genSource) !; + expect(originalPositionFor(sourceMap, findLineAndColumn(genSource, `someMethod()`))) + .toEqual({line: 2, column: 9, source: ngUrl}); + }); - it('should map events correctly to the source', async(() => { - const template = `
\n
`; + it('should map events correctly to the source', () => { + const template = `
\n
`; - appDir['app.component.ts'] = createComponentSource(templateDecorator(template)); + appDir['app.component.ts'] = createComponentSource(templateDecorator(template)); - compileApp().then((genFile) => { - const genSource = toTypeScript(genFile); - const sourceMap = extractSourceMap(genSource) !; - expect(originalPositionFor(sourceMap, findLineAndColumn(genSource, `someMethod()`))) - .toEqual({line: 2, column: 9, source: ngUrl}); - }); - })); + const genFile = compileApp(); + const genSource = toTypeScript(genFile); + const sourceMap = extractSourceMap(genSource) !; + expect(originalPositionFor(sourceMap, findLineAndColumn(genSource, `someMethod()`))) + .toEqual({line: 2, column: 9, source: ngUrl}); + }); - it('should map non template parts to the source file', async(() => { - appDir['app.component.ts'] = createComponentSource(templateDecorator('Hello World!')); + it('should map non template parts to the source file', () => { + appDir['app.component.ts'] = createComponentSource(templateDecorator('Hello World!')); - compileApp().then((genFile) => { - const genSource = toTypeScript(genFile); - const sourceMap = extractSourceMap(genSource) !; - expect(originalPositionFor(sourceMap, {line: 1, column: 0})) - .toEqual({line: 1, column: 0, source: ngComponentPath}); - }); - })); + const genFile = compileApp(); + const genSource = toTypeScript(genFile); + const sourceMap = extractSourceMap(genSource) !; + expect(originalPositionFor(sourceMap, {line: 1, column: 0})) + .toEqual({line: 1, column: 0, source: ngComponentPath}); + }); } }); describe('errors', () => { - it('should only warn if not all arguments of an @Injectable class can be resolved', - async(() => { - const FILES: MockDirectory = { - app: { - 'app.ts': ` + it('should only warn if not all arguments of an @Injectable class can be resolved', () => { + const FILES: MockDirectory = { + app: { + 'app.ts': ` import {Injectable} from '@angular/core'; @Injectable() @@ -209,20 +199,19 @@ describe('compiler (unbundled Angular)', () => { constructor(a: boolean) {} } ` - } - }; - const warnSpy = spyOn(console, 'warn'); - compile([FILES, angularFiles]).then(() => { - expect(warnSpy).toHaveBeenCalledWith( - `Warning: Can't resolve all parameters for MyService in /app/app.ts: (?). This will become an error in Angular v5.x`); - }); + } + }; + const warnSpy = spyOn(console, 'warn'); + compile([FILES, angularFiles]); + expect(warnSpy).toHaveBeenCalledWith( + `Warning: Can't resolve all parameters for MyService in /app/app.ts: (?). This will become an error in Angular v5.x`); - })); + }); - it('should be able to supress a null access', async(() => { - const FILES: MockDirectory = { - app: { - 'app.ts': ` + it('should be able to supress a null access', () => { + const FILES: MockDirectory = { + app: { + 'app.ts': ` import {Component, NgModule} from '@angular/core'; interface Person { name: string; } @@ -240,16 +229,16 @@ describe('compiler (unbundled Angular)', () => { }) export class MyModule {} ` - } - }; - compile([FILES, angularFiles], {postCompile: expectNoDiagnostics}); - })); + } + }; + compile([FILES, angularFiles], {postCompile: expectNoDiagnostics}); + }); }); - it('should add the preamble to generated files', async(() => { - const FILES: MockDirectory = { - app: { - 'app.ts': ` + it('should add the preamble to generated files', () => { + const FILES: MockDirectory = { + app: { + 'app.ts': ` import { NgModule, Component } from '@angular/core'; @Component({ template: '' }) @@ -258,24 +247,21 @@ describe('compiler (unbundled Angular)', () => { @NgModule({ declarations: [ AppComponent ] }) export class AppModule { } ` - } - }; - const genFilePreamble = '/* Hello world! */'; - compile([FILES, angularFiles]).then(({genFiles}) => { - const genFile = - genFiles.find(gf => gf.srcFileUrl === '/app/app.ts' && gf.genFileUrl.endsWith('.ts')); - const genSource = toTypeScript(genFile, genFilePreamble); - expect(genSource.startsWith(genFilePreamble)).toBe(true); - }); - - })); + } + }; + const genFilePreamble = '/* Hello world! */'; + const {genFiles} = compile([FILES, angularFiles]); + const genFile = + genFiles.find(gf => gf.srcFileUrl === '/app/app.ts' && gf.genFileUrl.endsWith('.ts')); + const genSource = toTypeScript(genFile, genFilePreamble); + expect(genSource.startsWith(genFilePreamble)).toBe(true); + }); describe('ComponentFactories', () => { - it('should include inputs, outputs and ng-content selectors in the component factory', - async(() => { - const FILES: MockDirectory = { - app: { - 'app.ts': ` + it('should include inputs, outputs and ng-content selectors in the component factory', () => { + const FILES: MockDirectory = { + app: { + 'app.ts': ` import {Component, NgModule, Input, Output} from '@angular/core'; @Component({ @@ -295,31 +281,28 @@ describe('compiler (unbundled Angular)', () => { }) export class MyModule {} ` - } - }; - compile([FILES, angularFiles]).then(({genFiles}) => { - const genFile = genFiles.find(genFile => genFile.srcFileUrl === '/app/app.ts'); - const genSource = toTypeScript(genFile); - const createComponentFactoryCall = - /ɵccf\([^)]*\)/m.exec(genSource) ![0].replace(/\s*/g, ''); - // selector - expect(createComponentFactoryCall).toContain('my-comp'); - // inputs - expect(createComponentFactoryCall).toContain(`{aInputProp:'aInputName'}`); - // outputs - expect(createComponentFactoryCall).toContain(`{aOutputProp:'aOutputName'}`); - // ngContentSelectors - expect(createComponentFactoryCall).toContain(`['*','child']`); - }); - })); + } + }; + const {genFiles} = compile([FILES, angularFiles]); + const genFile = genFiles.find(genFile => genFile.srcFileUrl === '/app/app.ts'); + const genSource = toTypeScript(genFile); + const createComponentFactoryCall = /ɵccf\([^)]*\)/m.exec(genSource) ![0].replace(/\s*/g, ''); + // selector + expect(createComponentFactoryCall).toContain('my-comp'); + // inputs + expect(createComponentFactoryCall).toContain(`{aInputProp:'aInputName'}`); + // outputs + expect(createComponentFactoryCall).toContain(`{aOutputProp:'aOutputName'}`); + // ngContentSelectors + expect(createComponentFactoryCall).toContain(`['*','child']`); + }); }); describe('generated templates', () => { - it('should not call `check` for directives without bindings nor ngDoCheck/ngOnInit', - async(() => { - const FILES: MockDirectory = { - app: { - 'app.ts': ` + it('should not call `check` for directives without bindings nor ngDoCheck/ngOnInit', () => { + const FILES: MockDirectory = { + app: { + 'app.ts': ` import { NgModule, Component } from '@angular/core'; @Component({ template: '' }) @@ -328,16 +311,15 @@ describe('compiler (unbundled Angular)', () => { @NgModule({ declarations: [ AppComponent ] }) export class AppModule { } ` - } - }; - compile([FILES, angularFiles]).then(({genFiles}) => { - const genFile = genFiles.find( - gf => gf.srcFileUrl === '/app/app.ts' && gf.genFileUrl.endsWith('.ts')); - const genSource = toTypeScript(genFile); - expect(genSource).not.toContain('check('); - }); + } + }; + const {genFiles} = compile([FILES, angularFiles]); + const genFile = + genFiles.find(gf => gf.srcFileUrl === '/app/app.ts' && gf.genFileUrl.endsWith('.ts')); + const genSource = toTypeScript(genFile); + expect(genSource).not.toContain('check('); - })); + }); }); describe('inheritance with summaries', () => { @@ -376,16 +358,15 @@ describe('compiler (unbundled Angular)', () => { } }; - return compile([libInput, angularFiles], {useSummaries: true}) - .then(({outDir}) => compile([outDir, appInput, angularFiles], {useSummaries: true})) - .then(({genFiles}) => genFiles.find(gf => gf.srcFileUrl === '/app/main.ts')); + const {outDir: libOutDir} = compile([libInput, angularFiles], {useSummaries: true}); + const {genFiles} = compile([libOutDir, appInput, angularFiles], {useSummaries: true}); + return genFiles.find(gf => gf.srcFileUrl === '/app/main.ts'); } - it('should inherit ctor and lifecycle hooks from classes in other compilation units', - async(() => { - const libInput: MockDirectory = { - 'lib': { - 'base.ts': ` + it('should inherit ctor and lifecycle hooks from classes in other compilation units', () => { + const libInput: MockDirectory = { + 'lib': { + 'base.ts': ` export class AParam {} export class Base { @@ -393,11 +374,11 @@ describe('compiler (unbundled Angular)', () => { ngOnDestroy() {} } ` - } - }; - const appInput: MockDirectory = { - 'app': { - 'main.ts': ` + } + }; + const appInput: MockDirectory = { + 'app': { + 'main.ts': ` import {NgModule, Component} from '@angular/core'; import {Base} from '../lib/base'; @@ -409,21 +390,19 @@ describe('compiler (unbundled Angular)', () => { }) export class MyModule {} ` - } - }; + } + }; - compile([libInput, angularFiles], {useSummaries: true}) - .then(({outDir}) => compile([outDir, appInput, angularFiles], {useSummaries: true})) - .then(({genFiles}) => { - const mainNgFactory = genFiles.find(gf => gf.srcFileUrl === '/app/main.ts'); - const flags = NodeFlags.TypeDirective | NodeFlags.Component | NodeFlags.OnDestroy; - expect(toTypeScript(mainNgFactory)) - .toContain(`${flags},(null as any),0,i1.Extends,[i2.AParam]`); - }); - })); + const {outDir: libOutDir} = compile([libInput, angularFiles], {useSummaries: true}); + const {genFiles} = compile([libOutDir, appInput, angularFiles], {useSummaries: true}); + const mainNgFactory = genFiles.find(gf => gf.srcFileUrl === '/app/main.ts'); + const flags = NodeFlags.TypeDirective | NodeFlags.Component | NodeFlags.OnDestroy; + expect(toTypeScript(mainNgFactory)) + .toContain(`${flags},(null as any),0,i1.Extends,[i2.AParam]`); + }); it('should inherit ctor and lifecycle hooks from classes in other compilation units over 2 levels', - async(() => { + () => { const lib1Input: MockDirectory = { 'lib1': { 'base.ts': ` @@ -463,135 +442,134 @@ describe('compiler (unbundled Angular)', () => { ` } }; - compile([lib1Input, angularFiles], {useSummaries: true}) - .then(({outDir}) => compile([outDir, lib2Input, angularFiles], {useSummaries: true})) - .then(({outDir}) => compile([outDir, appInput, angularFiles], {useSummaries: true})) - .then(({genFiles}) => { - const mainNgFactory = genFiles.find(gf => gf.srcFileUrl === '/app/main.ts'); - const flags = NodeFlags.TypeDirective | NodeFlags.Component | NodeFlags.OnDestroy; - expect(toTypeScript(mainNgFactory)) - .toContain(`${flags},(null as any),0,i1.Extends,[i2.AParam_2]`); - }); - })); + const {outDir: lib1OutDir} = compile([lib1Input, angularFiles], {useSummaries: true}); + const {outDir: lib2OutDir} = + compile([lib1OutDir, lib2Input, angularFiles], {useSummaries: true}); + const {genFiles} = compile([lib2OutDir, appInput, angularFiles], {useSummaries: true}); + const mainNgFactory = genFiles.find(gf => gf.srcFileUrl === '/app/main.ts'); + const flags = NodeFlags.TypeDirective | NodeFlags.Component | NodeFlags.OnDestroy; + expect(toTypeScript(mainNgFactory)) + .toContain(`${flags},(null as any),0,i1.Extends,[i2.AParam_2]`); + }); describe('Injectable', () => { - it('should allow to inherit', async(() => { - compileParentAndChild({ - parentClassDecorator: '@Injectable()', - parentModuleDecorator: '@NgModule({providers: [Base]})', - childClassDecorator: '@Injectable()', - childModuleDecorator: '@NgModule({providers: [Extends]})', - }).then((mainNgFactory) => { expect(mainNgFactory).toBeTruthy(); }); - })); + it('should allow to inherit', () => { + const mainNgFactory = compileParentAndChild({ + parentClassDecorator: '@Injectable()', + parentModuleDecorator: '@NgModule({providers: [Base]})', + childClassDecorator: '@Injectable()', + childModuleDecorator: '@NgModule({providers: [Extends]})', + }); + expect(mainNgFactory).toBeTruthy(); + }); - it('should error if the child class has no matching decorator', async(() => { - compileParentAndChild({ - parentClassDecorator: '@Injectable()', - parentModuleDecorator: '@NgModule({providers: [Base]})', - childClassDecorator: '', - childModuleDecorator: '@NgModule({providers: [Extends]})', - }).then(fail, (e) => { - expect(e.message).toContain( - 'Class Extends in /app/main.ts extends from a Injectable in another compilation unit without duplicating the decorator. ' + - 'Please add a Injectable or Pipe or Directive or Component or NgModule decorator to the class.'); - }); - })); + it('should error if the child class has no matching decorator', () => { + expect(() => compileParentAndChild({ + parentClassDecorator: '@Injectable()', + parentModuleDecorator: '@NgModule({providers: [Base]})', + childClassDecorator: '', + childModuleDecorator: '@NgModule({providers: [Extends]})', + })) + .toThrowError( + 'Class Extends in /app/main.ts extends from a Injectable in another compilation unit without duplicating the decorator. ' + + 'Please add a Injectable or Pipe or Directive or Component or NgModule decorator to the class.'); + }); }); describe('Component', () => { - it('should allow to inherit', async(() => { - compileParentAndChild({ - parentClassDecorator: `@Component({template: ''})`, - parentModuleDecorator: '@NgModule({declarations: [Base]})', - childClassDecorator: `@Component({template: ''})`, - childModuleDecorator: '@NgModule({declarations: [Extends]})', - }).then((mainNgFactory) => { expect(mainNgFactory).toBeTruthy(); }); - })); + it('should allow to inherit', () => { + const mainNgFactory = compileParentAndChild({ + parentClassDecorator: `@Component({template: ''})`, + parentModuleDecorator: '@NgModule({declarations: [Base]})', + childClassDecorator: `@Component({template: ''})`, + childModuleDecorator: '@NgModule({declarations: [Extends]})' + }); + expect(mainNgFactory).toBeTruthy(); + }); - it('should error if the child class has no matching decorator', async(() => { - compileParentAndChild({ - parentClassDecorator: `@Component({template: ''})`, - parentModuleDecorator: '@NgModule({declarations: [Base]})', - childClassDecorator: '', - childModuleDecorator: '@NgModule({declarations: [Extends]})', - }).then(fail, (e) => { - expect(e.message).toContain( - 'Class Extends in /app/main.ts extends from a Directive in another compilation unit without duplicating the decorator. ' + - 'Please add a Directive or Component decorator to the class.'); - }); - })); + it('should error if the child class has no matching decorator', () => { + expect(() => compileParentAndChild({ + parentClassDecorator: `@Component({template: ''})`, + parentModuleDecorator: '@NgModule({declarations: [Base]})', + childClassDecorator: '', + childModuleDecorator: '@NgModule({declarations: [Extends]})', + })) + .toThrowError( + 'Class Extends in /app/main.ts extends from a Directive in another compilation unit without duplicating the decorator. ' + + 'Please add a Directive or Component decorator to the class.'); + }); }); describe('Directive', () => { - it('should allow to inherit', async(() => { - compileParentAndChild({ - parentClassDecorator: `@Directive({selector: '[someDir]'})`, - parentModuleDecorator: '@NgModule({declarations: [Base]})', - childClassDecorator: `@Directive({selector: '[someDir]'})`, - childModuleDecorator: '@NgModule({declarations: [Extends]})', - }).then((mainNgFactory) => { expect(mainNgFactory).toBeTruthy(); }); - })); + it('should allow to inherit', () => { + const mainNgFactory = compileParentAndChild({ + parentClassDecorator: `@Directive({selector: '[someDir]'})`, + parentModuleDecorator: '@NgModule({declarations: [Base]})', + childClassDecorator: `@Directive({selector: '[someDir]'})`, + childModuleDecorator: '@NgModule({declarations: [Extends]})', + }); + expect(mainNgFactory).toBeTruthy(); + }); - it('should error if the child class has no matching decorator', async(() => { - compileParentAndChild({ - parentClassDecorator: `@Directive({selector: '[someDir]'})`, - parentModuleDecorator: '@NgModule({declarations: [Base]})', - childClassDecorator: '', - childModuleDecorator: '@NgModule({declarations: [Extends]})', - }).then(fail, (e) => { - expect(e.message).toContain( - 'Class Extends in /app/main.ts extends from a Directive in another compilation unit without duplicating the decorator. ' + - 'Please add a Directive or Component decorator to the class.'); - }); - })); + it('should error if the child class has no matching decorator', () => { + expect(() => compileParentAndChild({ + parentClassDecorator: `@Directive({selector: '[someDir]'})`, + parentModuleDecorator: '@NgModule({declarations: [Base]})', + childClassDecorator: '', + childModuleDecorator: '@NgModule({declarations: [Extends]})', + })) + .toThrowError( + 'Class Extends in /app/main.ts extends from a Directive in another compilation unit without duplicating the decorator. ' + + 'Please add a Directive or Component decorator to the class.'); + }); }); describe('Pipe', () => { - it('should allow to inherit', async(() => { - compileParentAndChild({ - parentClassDecorator: `@Pipe({name: 'somePipe'})`, - parentModuleDecorator: '@NgModule({declarations: [Base]})', - childClassDecorator: `@Pipe({name: 'somePipe'})`, - childModuleDecorator: '@NgModule({declarations: [Extends]})', - }).then((mainNgFactory) => { expect(mainNgFactory).toBeTruthy(); }); - })); + it('should allow to inherit', () => { + const mainNgFactory = compileParentAndChild({ + parentClassDecorator: `@Pipe({name: 'somePipe'})`, + parentModuleDecorator: '@NgModule({declarations: [Base]})', + childClassDecorator: `@Pipe({name: 'somePipe'})`, + childModuleDecorator: '@NgModule({declarations: [Extends]})', + }); + expect(mainNgFactory).toBeTruthy(); + }); - it('should error if the child class has no matching decorator', async(() => { - compileParentAndChild({ - parentClassDecorator: `@Pipe({name: 'somePipe'})`, - parentModuleDecorator: '@NgModule({declarations: [Base]})', - childClassDecorator: '', - childModuleDecorator: '@NgModule({declarations: [Extends]})', - }).then(fail, (e) => { - expect(e.message).toContain( - 'Class Extends in /app/main.ts extends from a Pipe in another compilation unit without duplicating the decorator. ' + - 'Please add a Pipe decorator to the class.'); - }); - })); + it('should error if the child class has no matching decorator', () => { + expect(() => compileParentAndChild({ + parentClassDecorator: `@Pipe({name: 'somePipe'})`, + parentModuleDecorator: '@NgModule({declarations: [Base]})', + childClassDecorator: '', + childModuleDecorator: '@NgModule({declarations: [Extends]})', + })) + .toThrowError( + 'Class Extends in /app/main.ts extends from a Pipe in another compilation unit without duplicating the decorator. ' + + 'Please add a Pipe decorator to the class.'); + }); }); describe('NgModule', () => { - it('should allow to inherit', async(() => { - compileParentAndChild({ - parentClassDecorator: `@NgModule()`, - parentModuleDecorator: '', - childClassDecorator: `@NgModule()`, - childModuleDecorator: '', - }).then((mainNgFactory) => { expect(mainNgFactory).toBeTruthy(); }); - })); + it('should allow to inherit', () => { + const mainNgFactory = compileParentAndChild({ + parentClassDecorator: `@NgModule()`, + parentModuleDecorator: '', + childClassDecorator: `@NgModule()`, + childModuleDecorator: '', + }); + expect(mainNgFactory).toBeTruthy(); + }); - it('should error if the child class has no matching decorator', async(() => { - compileParentAndChild({ - parentClassDecorator: `@NgModule()`, - parentModuleDecorator: '', - childClassDecorator: '', - childModuleDecorator: '', - }).then(fail, (e) => { - expect(e.message).toContain( - 'Class Extends in /app/main.ts extends from a NgModule in another compilation unit without duplicating the decorator. ' + - 'Please add a NgModule decorator to the class.'); - }); - })); + it('should error if the child class has no matching decorator', () => { + expect(() => compileParentAndChild({ + parentClassDecorator: `@NgModule()`, + parentModuleDecorator: '', + childClassDecorator: '', + childModuleDecorator: '', + })) + .toThrowError( + 'Class Extends in /app/main.ts extends from a NgModule in another compilation unit without duplicating the decorator. ' + + 'Please add a NgModule decorator to the class.'); + }); }); }); }); @@ -624,11 +602,11 @@ describe('compiler (bundled Angular)', () => { }); describe('Quickstart', () => { - it('should compile', async(() => compile([QUICKSTART, angularFiles]).then(({genFiles}) => { - expect(genFiles.find(f => /app\.component\.ngfactory\.ts/.test(f.genFileUrl))) - .toBeDefined(); - expect(genFiles.find(f => /app\.module\.ngfactory\.ts/.test(f.genFileUrl))).toBeDefined(); - }))); + it('should compile', () => { + const {genFiles} = compile([QUICKSTART, angularFiles]); + expect(genFiles.find(f => /app\.component\.ngfactory\.ts/.test(f.genFileUrl))).toBeDefined(); + expect(genFiles.find(f => /app\.module\.ngfactory\.ts/.test(f.genFileUrl))).toBeDefined(); + }); }); describe('Bundled library', () => { @@ -662,7 +640,7 @@ describe('compiler (bundled Angular)', () => { ({fileName, content}) => ({fileName: `/node_modules${fileName}`, content}))); }); - it('should compile', async(() => compile([LIBRARY_USING_APP, libraryFiles, angularFiles]))); + it('should compile', () => compile([LIBRARY_USING_APP, libraryFiles, angularFiles])); }); }); @@ -767,8 +745,3 @@ const LIBRARY_USING_APP: MockDirectory = { } } }; - -function expectPromiseToThrow(p: Promise, msg: RegExp) { - p.then( - () => { throw new Error('Expected to throw'); }, (e) => { expect(e.message).toMatch(msg); }); -} diff --git a/packages/compiler/test/aot/jit_summaries_spec.ts b/packages/compiler/test/aot/jit_summaries_spec.ts index 671a537edd..00033e4f00 100644 --- a/packages/compiler/test/aot/jit_summaries_spec.ts +++ b/packages/compiler/test/aot/jit_summaries_spec.ts @@ -7,7 +7,6 @@ */ import {AotCompiler, AotCompilerHost, AotCompilerOptions, CompileSummaryKind, GeneratedFile, createAotCompiler, toTypeScript} from '@angular/compiler'; -import {fakeAsync, tick} from '@angular/core/testing'; import {MockDirectory, compile, setup} from './test_util'; @@ -16,19 +15,12 @@ describe('aot summaries for jit', () => { function compileApp(rootDir: MockDirectory, options: {useSummaries?: boolean} = {}): {genFiles: GeneratedFile[], outDir: MockDirectory} { - let result: {genFiles: GeneratedFile[], outDir: MockDirectory} = null !; - let error: Error|null = null; - compile([rootDir, angularFiles], options).then((r) => result = r, (e) => error = e); - tick(); - if (error) { - throw error; - } - return result; + return compile([rootDir, angularFiles], options); } - it('should create @Injectable summaries', fakeAsync(() => { - const appDir = { - 'app.module.ts': ` + it('should create @Injectable summaries', () => { + const appDir = { + 'app.module.ts': ` import { Injectable } from '@angular/core'; export class Dep {} @@ -38,23 +30,23 @@ describe('aot summaries for jit', () => { constructor(d: Dep) {} } ` - }; - const rootDir = {'app': appDir}; + }; + const rootDir = {'app': appDir}; - const genFile = - compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genFile = + compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genSource = toTypeScript(genFile); - const genSource = toTypeScript(genFile); - expect(genSource).toContain(`import * as i0 from '/app/app.module'`); - expect(genSource).toContain('export function MyServiceNgSummary()'); - // Note: CompileSummaryKind.Injectable = 3 - expect(genSource).toMatch(/summaryKind:3,\s*type:\{\s*reference:i0.MyService/); - expect(genSource).toContain('token:{identifier:{reference:i0.Dep}}'); - })); + expect(genSource).toContain(`import * as i0 from '/app/app.module'`); + expect(genSource).toContain('export function MyServiceNgSummary()'); + // Note: CompileSummaryKind.Injectable = 3 + expect(genSource).toMatch(/summaryKind:3,\s*type:\{\s*reference:i0.MyService/); + expect(genSource).toContain('token:{identifier:{reference:i0.Dep}}'); + }); - it('should create @Pipe summaries', fakeAsync(() => { - const appDir = { - 'app.module.ts': ` + it('should create @Pipe summaries', () => { + const appDir = { + 'app.module.ts': ` import { Pipe, NgModule } from '@angular/core'; export class Dep {} @@ -67,23 +59,23 @@ describe('aot summaries for jit', () => { @NgModule({declarations: [MyPipe]}) export class MyModule {} ` - }; - const rootDir = {'app': appDir}; + }; + const rootDir = {'app': appDir}; - const genFile = - compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genFile = + compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genSource = toTypeScript(genFile); - const genSource = toTypeScript(genFile); - expect(genSource).toContain(`import * as i0 from '/app/app.module'`); - expect(genSource).toContain('export function MyPipeNgSummary()'); - // Note: CompileSummaryKind.Pipe = 1 - expect(genSource).toMatch(/summaryKind:0,\s*type:\{\s*reference:i0.MyPipe/); - expect(genSource).toContain('token:{identifier:{reference:i0.Dep}}'); - })); + expect(genSource).toContain(`import * as i0 from '/app/app.module'`); + expect(genSource).toContain('export function MyPipeNgSummary()'); + // Note: CompileSummaryKind.Pipe = 1 + expect(genSource).toMatch(/summaryKind:0,\s*type:\{\s*reference:i0.MyPipe/); + expect(genSource).toContain('token:{identifier:{reference:i0.Dep}}'); + }); - it('should create @Directive summaries', fakeAsync(() => { - const appDir = { - 'app.module.ts': ` + it('should create @Directive summaries', () => { + const appDir = { + 'app.module.ts': ` import { Directive, NgModule } from '@angular/core'; export class Dep {} @@ -96,23 +88,23 @@ describe('aot summaries for jit', () => { @NgModule({declarations: [MyDirective]}) export class MyModule {} ` - }; - const rootDir = {'app': appDir}; + }; + const rootDir = {'app': appDir}; - const genFile = - compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genFile = + compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genSource = toTypeScript(genFile); - const genSource = toTypeScript(genFile); - expect(genSource).toContain(`import * as i0 from '/app/app.module'`); - expect(genSource).toContain('export function MyDirectiveNgSummary()'); - // Note: CompileSummaryKind.Directive = 1 - expect(genSource).toMatch(/summaryKind:1,\s*type:\{\s*reference:i0.MyDirective/); - expect(genSource).toContain('token:{identifier:{reference:i0.Dep}}'); - })); + expect(genSource).toContain(`import * as i0 from '/app/app.module'`); + expect(genSource).toContain('export function MyDirectiveNgSummary()'); + // Note: CompileSummaryKind.Directive = 1 + expect(genSource).toMatch(/summaryKind:1,\s*type:\{\s*reference:i0.MyDirective/); + expect(genSource).toContain('token:{identifier:{reference:i0.Dep}}'); + }); - it('should create @NgModule summaries', fakeAsync(() => { - const appDir = { - 'app.module.ts': ` + it('should create @NgModule summaries', () => { + const appDir = { + 'app.module.ts': ` import { NgModule } from '@angular/core'; export class Dep {} @@ -122,23 +114,23 @@ describe('aot summaries for jit', () => { constructor(d: Dep) {} } ` - }; - const rootDir = {'app': appDir}; + }; + const rootDir = {'app': appDir}; - const genFile = - compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genFile = + compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genSource = toTypeScript(genFile); - const genSource = toTypeScript(genFile); - expect(genSource).toContain(`import * as i0 from '/app/app.module'`); - expect(genSource).toContain('export function MyModuleNgSummary()'); - // Note: CompileSummaryKind.NgModule = 2 - expect(genSource).toMatch(/summaryKind:2,\s*type:\{\s*reference:i0.MyModule/); - expect(genSource).toContain('token:{identifier:{reference:i0.Dep}}'); - })); + expect(genSource).toContain(`import * as i0 from '/app/app.module'`); + expect(genSource).toContain('export function MyModuleNgSummary()'); + // Note: CompileSummaryKind.NgModule = 2 + expect(genSource).toMatch(/summaryKind:2,\s*type:\{\s*reference:i0.MyModule/); + expect(genSource).toContain('token:{identifier:{reference:i0.Dep}}'); + }); - it('should embed useClass provider summaries in @Directive summaries', fakeAsync(() => { - const appDir = { - 'app.service.ts': ` + it('should embed useClass provider summaries in @Directive summaries', () => { + const appDir = { + 'app.service.ts': ` import { Injectable } from '@angular/core'; export class Dep {} @@ -148,7 +140,7 @@ describe('aot summaries for jit', () => { constructor(d: Dep) {} } `, - 'app.module.ts': ` + 'app.module.ts': ` import { Directive, NgModule } from '@angular/core'; import { MyService } from './app.service'; @@ -161,22 +153,22 @@ describe('aot summaries for jit', () => { @NgModule({declarations: [MyDirective]}) export class MyModule {} ` - }; - const rootDir = {'app': appDir}; + }; + const rootDir = {'app': appDir}; - const genFile = - compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genFile = + compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genSource = toTypeScript(genFile); - const genSource = toTypeScript(genFile); - expect(genSource).toMatch(/useClass:\{\s*reference:i1.MyService/); - // Note: CompileSummaryKind.Injectable = 3 - expect(genSource).toMatch(/summaryKind:3,\s*type:\{\s*reference:i1.MyService/); - expect(genSource).toContain('token:{identifier:{reference:i1.Dep}}'); - })); + expect(genSource).toMatch(/useClass:\{\s*reference:i1.MyService/); + // Note: CompileSummaryKind.Injectable = 3 + expect(genSource).toMatch(/summaryKind:3,\s*type:\{\s*reference:i1.MyService/); + expect(genSource).toContain('token:{identifier:{reference:i1.Dep}}'); + }); - it('should embed useClass provider summaries into @NgModule summaries', fakeAsync(() => { - const appDir = { - 'app.service.ts': ` + it('should embed useClass provider summaries into @NgModule summaries', () => { + const appDir = { + 'app.service.ts': ` import { Injectable } from '@angular/core'; export class Dep {} @@ -186,7 +178,7 @@ describe('aot summaries for jit', () => { constructor(d: Dep) {} } `, - 'app.module.ts': ` + 'app.module.ts': ` import { NgModule } from '@angular/core'; import { MyService } from './app.service'; @@ -195,23 +187,22 @@ describe('aot summaries for jit', () => { }) export class MyModule {} ` - }; - const rootDir = {'app': appDir}; + }; + const rootDir = {'app': appDir}; - const genFile = - compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genFile = + compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genSource = toTypeScript(genFile); - const genSource = toTypeScript(genFile); - expect(genSource).toMatch(/useClass:\{\s*reference:i1.MyService/); - // Note: CompileSummaryKind.Injectable = 3 - expect(genSource).toMatch(/summaryKind:3,\s*type:\{\s*reference:i1.MyService/); - expect(genSource).toContain('token:{identifier:{reference:i1.Dep}}'); - })); + expect(genSource).toMatch(/useClass:\{\s*reference:i1.MyService/); + // Note: CompileSummaryKind.Injectable = 3 + expect(genSource).toMatch(/summaryKind:3,\s*type:\{\s*reference:i1.MyService/); + expect(genSource).toContain('token:{identifier:{reference:i1.Dep}}'); + }); - it('should reference declared @Directive and @Pipe summaries in @NgModule summaries', - fakeAsync(() => { - const appDir = { - 'app.module.ts': ` + it('should reference declared @Directive and @Pipe summaries in @NgModule summaries', () => { + const appDir = { + 'app.module.ts': ` import { Directive, Pipe, NgModule } from '@angular/core'; @Directive({selector: '[myDir]'}) @@ -223,20 +214,20 @@ describe('aot summaries for jit', () => { @NgModule({declarations: [MyDirective, MyPipe]}) export class MyModule {} ` - }; - const rootDir = {'app': appDir}; + }; + const rootDir = {'app': appDir}; - const genFile = - compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genFile = + compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genSource = toTypeScript(genFile); - const genSource = toTypeScript(genFile); - expect(genSource).toMatch( - /export function MyModuleNgSummary()[^;]*,\s*MyDirectiveNgSummary,\s*MyPipeNgSummary\s*\]\s*;/); - })); + expect(genSource).toMatch( + /export function MyModuleNgSummary()[^;]*,\s*MyDirectiveNgSummary,\s*MyPipeNgSummary\s*\]\s*;/); + }); - it('should reference imported @NgModule summaries in @NgModule summaries', fakeAsync(() => { - const appDir = { - 'app.module.ts': ` + it('should reference imported @NgModule summaries in @NgModule summaries', () => { + const appDir = { + 'app.module.ts': ` import { NgModule } from '@angular/core'; @NgModule() @@ -245,20 +236,20 @@ describe('aot summaries for jit', () => { @NgModule({imports: [MyImportedModule]}) export class MyModule {} ` - }; - const rootDir = {'app': appDir}; + }; + const rootDir = {'app': appDir}; - const genFile = - compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genFile = + compileApp(rootDir).genFiles.find(f => f.genFileUrl === '/app/app.module.ngsummary.ts'); + const genSource = toTypeScript(genFile); - const genSource = toTypeScript(genFile); - expect(genSource).toMatch( - /export function MyModuleNgSummary()[^;]*,\s*MyImportedModuleNgSummary\s*\]\s*;/); - })); + expect(genSource).toMatch( + /export function MyModuleNgSummary()[^;]*,\s*MyImportedModuleNgSummary\s*\]\s*;/); + }); it('should create and use reexports for imported NgModules ' + 'accross compilation units', - fakeAsync(() => { + () => { const lib1In = { 'lib1': { 'module.ts': ` @@ -348,5 +339,5 @@ describe('aot summaries for jit', () => { expect(toTypeScript(lib3ReexportNgSummary)) .toContain( `export {ReexportModule_2NgSummary as ReexportModule_3NgSummary} from '/lib2/reexport.ngsummary'`); - })); + }); }); diff --git a/packages/compiler/test/aot/regression_spec.ts b/packages/compiler/test/aot/regression_spec.ts index 5e187fea24..8c768559a1 100644 --- a/packages/compiler/test/aot/regression_spec.ts +++ b/packages/compiler/test/aot/regression_spec.ts @@ -5,16 +5,15 @@ * 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 {async} from '@angular/core/testing'; import {MockDirectory, compile, expectNoDiagnostics, setup} from './test_util'; describe('regressions', () => { let angularFiles = setup(); - it('should compile components with empty templates', async(() => { - const appDir = { - 'app.module.ts': ` + it('should compile components with empty templates', () => { + const appDir = { + 'app.module.ts': ` import { Component, NgModule } from '@angular/core'; @Component({template: ''}) @@ -23,14 +22,11 @@ describe('regressions', () => { @NgModule({declarations: [EmptyComp]}) export class MyModule {} ` - }; - const rootDir = {'app': appDir}; - compile([rootDir, angularFiles], {postCompile: expectNoDiagnostics}, { - noUnusedLocals: true, - noUnusedParameters: true - }).then((result) => { - expect(result.genFiles.find((f) => f.genFileUrl === '/app/app.module.ngfactory.ts')) - .toBeTruthy(); - }); - })); + }; + const rootDir = {'app': appDir}; + const {genFiles} = compile( + [rootDir, angularFiles], {postCompile: expectNoDiagnostics}, + {noUnusedLocals: true, noUnusedParameters: true}); + expect(genFiles.find((f) => f.genFileUrl === '/app/app.module.ngfactory.ts')).toBeTruthy(); + }); }); diff --git a/packages/compiler/test/aot/test_util.ts b/packages/compiler/test/aot/test_util.ts index 3bfd29620d..f81751fd7d 100644 --- a/packages/compiler/test/aot/test_util.ts +++ b/packages/compiler/test/aot/test_util.ts @@ -399,11 +399,11 @@ export class MockAotCompilerHost implements AotCompilerHost { return importedFile.replace(EXT, ''); } - loadResource(path: string): Promise { + loadResource(path: string): string { if (this.tsHost.fileExists(path)) { - return Promise.resolve(this.tsHost.readFile(path)); + return this.tsHost.readFile(path); } else { - return Promise.reject(new Error(`Resource ${path} not found.`)) + throw new Error(`Resource ${path} not found.`); } } } @@ -604,47 +604,43 @@ export function compile( preCompile?: (program: ts.Program) => void, postCompile?: (program: ts.Program) => void, }& AotCompilerOptions = {}, - tsOptions: ts.CompilerOptions = {}): - Promise<{genFiles: GeneratedFile[], outDir: MockDirectory}> { - // Make sure we always return errors via the promise... - return Promise.resolve(null).then(() => { - // when using summaries, always emit so the next step can use the results. - const emit = options.emit || options.useSummaries; - const preCompile = options.preCompile || expectNoDiagnostics; - const postCompile = options.postCompile || expectNoDiagnostics; - const rootDirArr = toMockFileArray(rootDirs); - const scriptNames = rootDirArr.map(entry => entry.fileName).filter(isSource); + tsOptions: ts.CompilerOptions = {}): {genFiles: GeneratedFile[], outDir: MockDirectory} { + // when using summaries, always emit so the next step can use the results. + const emit = options.emit || options.useSummaries; + const preCompile = options.preCompile || expectNoDiagnostics; + const postCompile = options.postCompile || expectNoDiagnostics; + const rootDirArr = toMockFileArray(rootDirs); + const scriptNames = rootDirArr.map(entry => entry.fileName).filter(isSource); - const host = new MockCompilerHost(scriptNames, arrayToMockDir(rootDirArr)); - const aotHost = new MockAotCompilerHost(host); - if (options.useSummaries) { - aotHost.hideMetadata(); - aotHost.tsFilesOnly(); + const host = new MockCompilerHost(scriptNames, arrayToMockDir(rootDirArr)); + const aotHost = new MockAotCompilerHost(host); + if (options.useSummaries) { + aotHost.hideMetadata(); + aotHost.tsFilesOnly(); + } + const tsSettings = {...settings, ...tsOptions}; + const program = ts.createProgram(host.scriptNames.slice(0), tsSettings, host); + if (preCompile) preCompile(program); + const {compiler, reflector} = createAotCompiler(aotHost, options); + const genFiles = compiler.compileAllSync(program.getSourceFiles().map(sf => sf.fileName)); + genFiles.forEach((file) => { + const source = file.source || toTypeScript(file); + if (isSource(file.genFileUrl)) { + host.addScript(file.genFileUrl, source); + } else { + host.override(file.genFileUrl, source); } - const tsSettings = {...settings, ...tsOptions}; - const scripts = host.scriptNames.slice(0); - const program = ts.createProgram(scripts, tsSettings, host); - if (preCompile) preCompile(program); - const {compiler, reflector} = createAotCompiler(aotHost, options); - return compiler.compileAll(program.getSourceFiles().map(sf => sf.fileName)).then(genFiles => { - genFiles.forEach((file) => { - const source = file.source || toTypeScript(file); - isSource(file.genFileUrl) ? host.addScript(file.genFileUrl, source) : - host.override(file.genFileUrl, source); - }); - const scripts = host.scriptNames.slice(0); - const newProgram = ts.createProgram(scripts, tsSettings, host); - if (postCompile) postCompile(newProgram); - if (emit) { - newProgram.emit(); - } - let outDir: MockDirectory = {}; - if (emit) { - outDir = arrayToMockDir(toMockFileArray([ - host.writtenFiles, host.overrides - ]).filter((entry) => !isSource(entry.fileName))); - } - return {genFiles, outDir}; - }); }); + const newProgram = ts.createProgram(host.scriptNames.slice(0), tsSettings, host); + if (postCompile) postCompile(newProgram); + if (emit) { + newProgram.emit(); + } + let outDir: MockDirectory = {}; + if (emit) { + outDir = arrayToMockDir(toMockFileArray([ + host.writtenFiles, host.overrides + ]).filter((entry) => !isSource(entry.fileName))); + } + return {genFiles, outDir}; } diff --git a/packages/compiler/test/directive_normalizer_spec.ts b/packages/compiler/test/directive_normalizer_spec.ts index 423b701358..114f2672a0 100644 --- a/packages/compiler/test/directive_normalizer_spec.ts +++ b/packages/compiler/test/directive_normalizer_spec.ts @@ -16,7 +16,7 @@ import {ViewEncapsulation} from '@angular/core/src/metadata/view'; import {TestBed} from '@angular/core/testing'; import {AsyncTestCompleter, beforeEach, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal'; -import {SyncAsyncResult, noUndefined} from '../src/util'; +import {noUndefined} from '../src/util'; import {SpyResourceLoader} from './spies'; @@ -46,7 +46,7 @@ function normalizeTemplate(normalizer: DirectiveNormalizer, o: { }); } -function normalizeTemplateAsync(normalizer: DirectiveNormalizer, o: { +function normalizeTemplateOnly(normalizer: DirectiveNormalizer, o: { ngModuleType?: any; componentType?: any; moduleUrl?: string; template?: string | null; templateUrl?: string | null; styles?: string[]; @@ -55,30 +55,7 @@ function normalizeTemplateAsync(normalizer: DirectiveNormalizer, o: { encapsulation?: ViewEncapsulation | null; animations?: CompileAnimationEntryMetadata[]; }) { - return normalizer.normalizeTemplateAsync({ - ngModuleType: noUndefined(o.ngModuleType), - componentType: noUndefined(o.componentType), - moduleUrl: noUndefined(o.moduleUrl), - template: noUndefined(o.template), - templateUrl: noUndefined(o.templateUrl), - styles: noUndefined(o.styles), - styleUrls: noUndefined(o.styleUrls), - interpolation: noUndefined(o.interpolation), - encapsulation: noUndefined(o.encapsulation), - animations: noUndefined(o.animations) - }); -} - -function normalizeTemplateSync(normalizer: DirectiveNormalizer, o: { - ngModuleType?: any; componentType?: any; moduleUrl?: string; template?: string | null; - templateUrl?: string | null; - styles?: string[]; - styleUrls?: string[]; - interpolation?: [string, string] | null; - encapsulation?: ViewEncapsulation | null; - animations?: CompileAnimationEntryMetadata[]; -}): CompileTemplateMetadata { - return normalizer.normalizeTemplateSync({ + return normalizer.normalizeTemplateOnly({ ngModuleType: noUndefined(o.ngModuleType), componentType: noUndefined(o.componentType), moduleUrl: noUndefined(o.moduleUrl), @@ -194,10 +171,10 @@ export function main() { })); }); - describe('normalizeTemplateSync', () => { + describe('normalizeTemplateOnly sync', () => { it('should store the template', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - const template = normalizeTemplateSync(normalizer, { + const template = normalizeTemplateOnly(normalizer, { ngModuleType: null, componentType: SomeComp, moduleUrl: SOME_MODULE_URL, @@ -214,7 +191,7 @@ export function main() { it('should resolve styles on the annotation against the moduleUrl', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - const template = normalizeTemplateSync(normalizer, { + const template = normalizeTemplateOnly(normalizer, { ngModuleType: null, componentType: SomeComp, moduleUrl: SOME_MODULE_URL, @@ -229,7 +206,7 @@ export function main() { it('should resolve styles in the template against the moduleUrl', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - const template = normalizeTemplateSync(normalizer, { + const template = normalizeTemplateOnly(normalizer, { ngModuleType: null, componentType: SomeComp, moduleUrl: SOME_MODULE_URL, @@ -244,7 +221,7 @@ export function main() { it('should use ViewEncapsulation.Emulated by default', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - const template = normalizeTemplateSync(normalizer, { + const template = normalizeTemplateOnly(normalizer, { ngModuleType: null, componentType: SomeComp, moduleUrl: SOME_MODULE_URL, @@ -262,7 +239,7 @@ export function main() { [CompilerConfig, DirectiveNormalizer], (config: CompilerConfig, normalizer: DirectiveNormalizer) => { config.defaultEncapsulation = ViewEncapsulation.None; - const template = normalizeTemplateSync(normalizer, { + const template = normalizeTemplateOnly(normalizer, { ngModuleType: null, componentType: SomeComp, moduleUrl: SOME_MODULE_URL, @@ -284,7 +261,7 @@ export function main() { (async: AsyncTestCompleter, normalizer: DirectiveNormalizer, resourceLoader: MockResourceLoader) => { resourceLoader.expect('package:some/module/sometplurl.html', 'a'); - normalizeTemplateAsync(normalizer, { + (>normalizeTemplateOnly(normalizer, { ngModuleType: null, componentType: SomeComp, moduleUrl: SOME_MODULE_URL, @@ -293,7 +270,7 @@ export function main() { templateUrl: 'sometplurl.html', styles: [], styleUrls: ['test.css'] - }).then((template: CompileTemplateMetadata) => { + })).then((template) => { expect(template.template).toEqual('a'); expect(template.templateUrl).toEqual('package:some/module/sometplurl.html'); expect(template.isInline).toBe(false); @@ -308,7 +285,7 @@ export function main() { (async: AsyncTestCompleter, normalizer: DirectiveNormalizer, resourceLoader: MockResourceLoader) => { resourceLoader.expect('package:some/module/tpl/sometplurl.html', ''); - normalizeTemplateAsync(normalizer, { + (>normalizeTemplateOnly(normalizer, { ngModuleType: null, componentType: SomeComp, moduleUrl: SOME_MODULE_URL, @@ -317,7 +294,7 @@ export function main() { templateUrl: 'tpl/sometplurl.html', styles: [], styleUrls: ['test.css'] - }).then((template: CompileTemplateMetadata) => { + })).then((template) => { expect(template.styleUrls).toEqual(['package:some/module/test.css']); async.done(); }); @@ -331,7 +308,7 @@ export function main() { resourceLoader: MockResourceLoader) => { resourceLoader.expect( 'package:some/module/tpl/sometplurl.html', ''); - normalizeTemplateAsync(normalizer, { + (>normalizeTemplateOnly(normalizer, { ngModuleType: null, componentType: SomeComp, moduleUrl: SOME_MODULE_URL, @@ -340,7 +317,7 @@ export function main() { templateUrl: 'tpl/sometplurl.html', styles: [], styleUrls: [] - }).then((template: CompileTemplateMetadata) => { + })).then((template) => { expect(template.styleUrls).toEqual(['package:some/module/tpl/test.css']); async.done(); }); @@ -362,13 +339,13 @@ export function main() { (async: AsyncTestCompleter, normalizer: DirectiveNormalizer, resourceLoader: SpyResourceLoader) => { programResourceLoaderSpy(resourceLoader, {'package:some/module/test.css': 'a'}); - normalizer - .normalizeExternalStylesheets(compileTemplateMetadata({ - template: '', - templateUrl: '', - styleUrls: ['package:some/module/test.css'] - })) - .then((template: CompileTemplateMetadata) => { + (>normalizer.normalizeExternalStylesheets( + compileTemplateMetadata({ + template: '', + templateUrl: '', + styleUrls: ['package:some/module/test.css'] + }))) + .then((template) => { expect(template.externalStylesheets.length).toBe(1); expect(template.externalStylesheets[0]).toEqual(new CompileStylesheetMetadata({ moduleUrl: 'package:some/module/test.css', @@ -388,13 +365,13 @@ export function main() { 'package:some/module/test.css': 'a@import "test2.css"', 'package:some/module/test2.css': 'b' }); - normalizer - .normalizeExternalStylesheets(compileTemplateMetadata({ - template: '', - templateUrl: '', - styleUrls: ['package:some/module/test.css'] - })) - .then((template: CompileTemplateMetadata) => { + (>normalizer.normalizeExternalStylesheets( + compileTemplateMetadata({ + template: '', + templateUrl: '', + styleUrls: ['package:some/module/test.css'] + }))) + .then((template) => { expect(template.externalStylesheets.length).toBe(2); expect(template.externalStylesheets[0]).toEqual(new CompileStylesheetMetadata({ moduleUrl: 'package:some/module/test.css', @@ -426,8 +403,8 @@ export function main() { }; Promise .all([ - normalizeTemplateAsync(normalizer, prenormMeta), - normalizeTemplateAsync(normalizer, prenormMeta) + normalizeTemplateOnly(normalizer, prenormMeta), + normalizeTemplateOnly(normalizer, prenormMeta) ]) .then((templates: CompileTemplateMetadata[]) => { expect(templates[0].template).toEqual('a'); diff --git a/packages/compiler/test/util_spec.ts b/packages/compiler/test/util_spec.ts index f614f10bb7..149ed6ae1c 100644 --- a/packages/compiler/test/util_spec.ts +++ b/packages/compiler/test/util_spec.ts @@ -7,18 +7,10 @@ */ import {fakeAsync} from '@angular/core/testing/src/fake_async'; -import {SyncAsyncResult, escapeRegExp, splitAtColon, utf8Encode} from '../src/util'; +import {SyncAsync, escapeRegExp, splitAtColon, utf8Encode} from '../src/util'; export function main() { describe('util', () => { - describe('SyncAsyncResult', () => { - it('async value should default to Promise.resolve(syncValue)', fakeAsync(() => { - const syncValue = {}; - const sar = new SyncAsyncResult(syncValue); - sar.asyncResult !.then((v: any) => expect(v).toBe(syncValue)); - })); - }); - describe('splitAtColon', () => { it('should split when a single ":" is present', () => { expect(splitAtColon('a:b', [])).toEqual(['a', 'b']);