diff --git a/modules/@angular/compiler-cli/src/main.ts b/modules/@angular/compiler-cli/src/main.ts index 9ec4a6c7ba..67270ff0e8 100644 --- a/modules/@angular/compiler-cli/src/main.ts +++ b/modules/@angular/compiler-cli/src/main.ts @@ -14,6 +14,7 @@ import 'reflect-metadata'; import * as ts from 'typescript'; import * as tsc from '@angular/tsc-wrapped'; +import {SyntaxError} from '@angular/compiler'; import {CodeGenerator} from './codegen'; function codegen( @@ -28,7 +29,7 @@ export function main( const cliOptions = new tsc.NgcCliOptions(args); return tsc.main(project, cliOptions, codegen).then(() => 0).catch(e => { - if (e instanceof tsc.UserError) { + if (e instanceof tsc.UserError || e instanceof SyntaxError) { consoleError(e.message); return Promise.resolve(1); } else { diff --git a/modules/@angular/compiler/index.ts b/modules/@angular/compiler/index.ts index c6674f0e4d..de4e4056f2 100644 --- a/modules/@angular/compiler/index.ts +++ b/modules/@angular/compiler/index.ts @@ -62,4 +62,5 @@ export * from './src/style_compiler'; export * from './src/template_parser/template_parser'; export {ViewCompiler} from './src/view_compiler/view_compiler'; export {AnimationParser} from './src/animation/animation_parser'; +export {SyntaxError} from './src/util'; // This file only reexports content of the `src` folder. Keep it that way. diff --git a/modules/@angular/compiler/src/aot/static_symbol_resolver.ts b/modules/@angular/compiler/src/aot/static_symbol_resolver.ts index b734895678..29867d1c87 100644 --- a/modules/@angular/compiler/src/aot/static_symbol_resolver.ts +++ b/modules/@angular/compiler/src/aot/static_symbol_resolver.ts @@ -88,7 +88,7 @@ export class StaticSymbolResolver { } } else { let value = baseMetadata; - for (var i = 0; i < members.length && value; i++) { + for (let i = 0; i < members.length && value; i++) { value = value[members[i]]; } return new ResolvedStaticSymbol(staticSymbol, value); diff --git a/modules/@angular/compiler/src/compile_metadata.ts b/modules/@angular/compiler/src/compile_metadata.ts index 7f03f03eca..02e16f5dad 100644 --- a/modules/@angular/compiler/src/compile_metadata.ts +++ b/modules/@angular/compiler/src/compile_metadata.ts @@ -127,7 +127,7 @@ export enum CompileSummaryKind { * the directive / module itself. */ export interface CompileTypeSummary { - summaryKind: CompileSummaryKind + summaryKind: CompileSummaryKind; type: CompileTypeMetadata; } diff --git a/modules/@angular/compiler/src/directive_normalizer.ts b/modules/@angular/compiler/src/directive_normalizer.ts index b3af0da518..1bcee76dd1 100644 --- a/modules/@angular/compiler/src/directive_normalizer.ts +++ b/modules/@angular/compiler/src/directive_normalizer.ts @@ -19,7 +19,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} from './util'; +import {SyncAsyncResult, SyntaxError} from './util'; export interface PrenormalizedTemplateMetadata { componentType: any; @@ -71,7 +71,7 @@ export class DirectiveNormalizer { } else if (prenormData.templateUrl) { normalizedTemplateAsync = this.normalizeTemplateAsync(prenormData); } else { - throw new Error( + throw new SyntaxError( `No template specified for component ${stringify(prenormData.componentType)}`); } @@ -105,7 +105,7 @@ export class DirectiveNormalizer { template, stringify(prenomData.componentType), false, interpolationConfig); if (rootNodesAndErrors.errors.length > 0) { const errorString = rootNodesAndErrors.errors.join('\n'); - throw new Error(`Template parse errors:\n${errorString}`); + throw new SyntaxError(`Template parse errors:\n${errorString}`); } const templateMetadataStyles = this.normalizeStylesheet(new CompileStylesheetMetadata({ styles: prenomData.styles, diff --git a/modules/@angular/compiler/src/metadata_resolver.ts b/modules/@angular/compiler/src/metadata_resolver.ts index 310b37b30e..e802b87a75 100644 --- a/modules/@angular/compiler/src/metadata_resolver.ts +++ b/modules/@angular/compiler/src/metadata_resolver.ts @@ -24,7 +24,7 @@ import {ComponentStillLoadingError, LIFECYCLE_HOOKS_VALUES, ReflectorReader, ref import {ElementSchemaRegistry} from './schema/element_schema_registry'; import {SummaryResolver} from './summary_resolver'; import {getUrlScheme} from './url_resolver'; -import {MODULE_SUFFIX, SyncAsyncResult, ValueTransformer, visitValue} from './util'; +import {MODULE_SUFFIX, SyncAsyncResult, SyntaxError, ValueTransformer, visitValue} from './util'; export type ErrorCollector = (error: any, type?: any) => void; export const ERROR_COLLECTOR_TOKEN = new OpaqueToken('ErrorCollector'); @@ -253,7 +253,7 @@ export class CompileMetadataResolver { // Directive if (!selector) { this._reportError( - new Error(`Directive ${stringifyType(directiveType)} has no selector, please add it!`), + new SyntaxError(`Directive ${stringifyType(directiveType)} has no selector, please add it!`), directiveType); selector = 'error'; } @@ -299,7 +299,7 @@ export class CompileMetadataResolver { const dirMeta = this._directiveCache.get(directiveType); if (!dirMeta) { this._reportError( - new Error( + new SyntaxError( `Illegal state: getDirectiveMetadata can only be called after loadNgModuleMetadata for a module that declares it. Directive ${stringifyType(directiveType)}.`), directiveType); } @@ -311,7 +311,7 @@ export class CompileMetadataResolver { this._loadSummary(dirType, cpl.CompileSummaryKind.Directive); if (!dirSummary) { this._reportError( - new Error( + new SyntaxError( `Illegal state: Could not load the summary for directive ${stringifyType(dirType)}.`), dirType); } @@ -394,7 +394,7 @@ export class CompileMetadataResolver { const importedModuleSummary = this.getNgModuleSummary(importedModuleType); if (!importedModuleSummary) { this._reportError( - new Error( + new SyntaxError( `Unexpected ${this._getTypeDescriptor(importedType)} '${stringifyType(importedType)}' imported by the module '${stringifyType(moduleType)}'`), moduleType); return; @@ -402,7 +402,7 @@ export class CompileMetadataResolver { importedModules.push(importedModuleSummary); } else { this._reportError( - new Error( + new SyntaxError( `Unexpected value '${stringifyType(importedType)}' imported by the module '${stringifyType(moduleType)}'`), moduleType); return; @@ -414,7 +414,7 @@ export class CompileMetadataResolver { flattenAndDedupeArray(meta.exports).forEach((exportedType) => { if (!isValidType(exportedType)) { this._reportError( - new Error( + new SyntaxError( `Unexpected value '${stringifyType(exportedType)}' exported by the module '${stringifyType(moduleType)}'`), moduleType); return; @@ -435,7 +435,7 @@ export class CompileMetadataResolver { flattenAndDedupeArray(meta.declarations).forEach((declaredType) => { if (!isValidType(declaredType)) { this._reportError( - new Error( + new SyntaxError( `Unexpected value '${stringifyType(declaredType)}' declared by the module '${stringifyType(moduleType)}'`), moduleType); return; @@ -452,7 +452,7 @@ export class CompileMetadataResolver { this._addTypeToModule(declaredType, moduleType); } else { this._reportError( - new Error( + new SyntaxError( `Unexpected ${this._getTypeDescriptor(declaredType)} '${stringifyType(declaredType)}' declared by the module '${stringifyType(moduleType)}'`), moduleType); return; @@ -471,7 +471,7 @@ export class CompileMetadataResolver { transitiveModule.addExportedPipe(exportedId); } else { this._reportError( - new Error( + new SyntaxError( `Can't export ${this._getTypeDescriptor(exportedId.reference)} ${stringifyType(exportedId.reference)} from ${stringifyType(moduleType)} as it was neither declared nor imported!`), moduleType); } @@ -494,7 +494,7 @@ export class CompileMetadataResolver { flattenAndDedupeArray(meta.bootstrap).forEach(type => { if (!isValidType(type)) { this._reportError( - new Error( + new SyntaxError( `Unexpected value '${stringifyType(type)}' used in the bootstrap property of module '${stringifyType(moduleType)}'`), moduleType); return; @@ -557,7 +557,7 @@ export class CompileMetadataResolver { const oldModule = this._ngModuleOfTypes.get(type); if (oldModule && oldModule !== moduleType) { this._reportError( - new Error( + new SyntaxError( `Type ${stringifyType(type)} is part of the declarations of 2 modules: ${stringifyType(oldModule)} and ${stringifyType(moduleType)}! ` + `Please consider moving ${stringifyType(type)} to a higher module that imports ${stringifyType(oldModule)} and ${stringifyType(moduleType)}. ` + `You can also create a new NgModule that exports and includes ${stringifyType(type)} then import that NgModule in ${stringifyType(oldModule)} and ${stringifyType(moduleType)}.`), @@ -653,7 +653,7 @@ export class CompileMetadataResolver { const pipeMeta = this._pipeCache.get(pipeType); if (!pipeMeta) { this._reportError( - new Error( + new SyntaxError( `Illegal state: getPipeMetadata can only be called after loadNgModuleMetadata for a module that declares it. Pipe ${stringifyType(pipeType)}.`), pipeType); } @@ -665,7 +665,7 @@ export class CompileMetadataResolver { this._loadSummary(pipeType, cpl.CompileSummaryKind.Pipe); if (!pipeSummary) { this._reportError( - new Error( + new SyntaxError( `Illegal state: Could not load the summary for pipe ${stringifyType(pipeType)}.`), pipeType); } @@ -748,7 +748,7 @@ export class CompileMetadataResolver { const depsTokens = dependenciesMetadata.map((dep) => dep ? stringifyType(dep.token) : '?').join(', '); this._reportError( - new Error( + new SyntaxError( `Can't resolve all parameters for ${stringifyType(typeOrFunc)}: (${depsTokens}).`), typeOrFunc); } @@ -797,7 +797,7 @@ export class CompileMetadataResolver { [])) .join(', '); this._reportError( - new Error( + new SyntaxError( `Invalid ${debugInfo ? debugInfo : 'provider'} - only instances of Provider and Type are allowed, got: [${providersInfo}]`), type); } @@ -818,13 +818,14 @@ export class CompileMetadataResolver { if (provider.useFactory || provider.useExisting || provider.useClass) { this._reportError( - new Error(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!`), type); + new SyntaxError(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!`), type); return []; } if (!provider.multi) { this._reportError( - new Error(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!`), type); + new SyntaxError(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!`), + type); return []; } @@ -893,7 +894,7 @@ export class CompileMetadataResolver { } else { if (!q.selector) { this._reportError( - new Error( + new SyntaxError( `Can't construct a query for the property "${propertyName}" of "${stringifyType(typeOrFunc)}" since the query selector wasn't defined.`), typeOrFunc); } @@ -961,7 +962,7 @@ export function componentModuleUrl( const scheme = getUrlScheme(moduleId); return scheme ? moduleId : `package:${moduleId}${MODULE_SUFFIX}`; } else if (moduleId !== null && moduleId !== void 0) { - throw new Error( + throw new SyntaxError( `moduleId should be a string in "${stringifyType(type)}". See https://goo.gl/wIDDiL for more information.\n` + `If you're using Webpack you should inline the template and the styles, see https://goo.gl/X2J8zc.`); } diff --git a/modules/@angular/compiler/src/template_parser/template_parser.ts b/modules/@angular/compiler/src/template_parser/template_parser.ts index edb97a339c..770727f1cf 100644 --- a/modules/@angular/compiler/src/template_parser/template_parser.ts +++ b/modules/@angular/compiler/src/template_parser/template_parser.ts @@ -24,7 +24,7 @@ import {ProviderElementContext, ProviderViewContext} from '../provider_analyzer' import {ElementSchemaRegistry} from '../schema/element_schema_registry'; import {CssSelector, SelectorMatcher} from '../selector'; import {isStyleUrlResolvable} from '../style_url_resolver'; - +import {SyntaxError} from '../util'; import {BindingParser, BoundProperty} from './binding_parser'; import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from './template_ast'; import {PreparsedElementType, preparseElement} from './template_preparser'; @@ -99,7 +99,7 @@ export class TemplateParser { if (errors.length > 0) { const errorString = errors.join('\n'); - throw new Error(`Template parse errors:\n${errorString}`); + throw new SyntaxError(`Template parse errors:\n${errorString}`); } return result.templateAst; diff --git a/modules/@angular/compiler/src/util.ts b/modules/@angular/compiler/src/util.ts index 7ef3db5aa0..f1e60270f8 100644 --- a/modules/@angular/compiler/src/util.ts +++ b/modules/@angular/compiler/src/util.ts @@ -6,8 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ +import {BaseError} from './facade/errors'; import {isPrimitive, isStrictStringMap} from './facade/lang'; - export const MODULE_SUFFIX = ''; const CAMEL_CASE_REGEXP = /([A-Z])/g; @@ -78,3 +78,5 @@ export class SyncAsyncResult { } } } + +export class SyntaxError extends BaseError {} diff --git a/modules/@angular/compiler/test/aot/summary_resolver_spec.ts b/modules/@angular/compiler/test/aot/summary_resolver_spec.ts index 0941c9ac46..76d1aafc8c 100644 --- a/modules/@angular/compiler/test/aot/summary_resolver_spec.ts +++ b/modules/@angular/compiler/test/aot/summary_resolver_spec.ts @@ -7,8 +7,7 @@ */ import {AotSummaryResolver, AotSummaryResolverHost, CompileSummaryKind, CompileTypeSummary, ResolvedStaticSymbol, StaticSymbol, StaticSymbolCache, StaticSymbolResolver} from '@angular/compiler'; -import {AotSummarySerializerHost} from '@angular/compiler/src/aot/summary_serializer'; -import {deserializeSummaries, serializeSummaries} from '@angular/compiler/src/aot/summary_serializer'; +import {AotSummarySerializerHost, deserializeSummaries, serializeSummaries} from '@angular/compiler/src/aot/summary_serializer'; import * as path from 'path'; import {MockStaticSymbolResolverHost, MockSummaryResolver} from './static_symbol_resolver_spec'; diff --git a/modules/@angular/compiler/test/directive_normalizer_spec.ts b/modules/@angular/compiler/test/directive_normalizer_spec.ts index 90e35e4fa4..e32dc1fba3 100644 --- a/modules/@angular/compiler/test/directive_normalizer_spec.ts +++ b/modules/@angular/compiler/test/directive_normalizer_spec.ts @@ -5,7 +5,7 @@ * 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 {SyntaxError} from '@angular/compiler'; import {CompileDirectiveMetadata, CompileStylesheetMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '@angular/compiler/src/compile_metadata'; import {CompilerConfig} from '@angular/compiler/src/config'; import {DirectiveNormalizer} from '@angular/compiler/src/directive_normalizer'; @@ -31,7 +31,7 @@ export function main() { expect(() => normalizer.normalizeTemplate({ componentType: SomeComp, moduleUrl: SOME_MODULE_URL, - })).toThrowError('No template specified for component SomeComp'); + })).toThrowError(SyntaxError, 'No template specified for component SomeComp'); })); }); diff --git a/modules/@angular/compiler/test/metadata_resolver_spec.ts b/modules/@angular/compiler/test/metadata_resolver_spec.ts index caaf40e42a..0bcec64de6 100644 --- a/modules/@angular/compiler/test/metadata_resolver_spec.ts +++ b/modules/@angular/compiler/test/metadata_resolver_spec.ts @@ -15,8 +15,8 @@ import {identifierName} from '../src/compile_metadata'; import {stringify} from '../src/facade/lang'; import {CompileMetadataResolver} from '../src/metadata_resolver'; import {ResourceLoader} from '../src/resource_loader'; +import {SyntaxError} from '../src/util'; import {MockResourceLoader} from '../testing/resource_loader_mock'; - import {MalformedStylesComponent} from './metadata_resolver_fixture'; export function main() { @@ -34,8 +34,9 @@ export function main() { } expect(() => resolver.getDirectiveMetadata(ComponentWithEverythingInline)) - .toThrowError(/Illegal state/); - expect(() => resolver.getPipeMetadata(SomePipe)).toThrowError(/Illegal state/); + .toThrowError(SyntaxError, /Illegal state/); + expect(() => resolver.getPipeMetadata(SomePipe)) + .toThrowError(SyntaxError, /Illegal state/); })); it('should read metadata in sync for components with inline resources', @@ -121,10 +122,10 @@ export function main() { expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true)) .toThrowError( - `moduleId should be a string in "ComponentWithInvalidModuleId". See` + - ` https://goo.gl/wIDDiL for more information.\n` + - `If you're using Webpack you should inline the template and the styles, see` + - ` https://goo.gl/X2J8zc.`); + SyntaxError, `moduleId should be a string in "ComponentWithInvalidModuleId". See` + + ` https://goo.gl/wIDDiL for more information.\n` + + `If you're using Webpack you should inline the template and the styles, see` + + ` https://goo.gl/X2J8zc.`); })); @@ -145,7 +146,7 @@ export function main() { } expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true)) - .toThrowError(`Can't resolve all parameters for MyBrokenComp1: (?).`); + .toThrowError(SyntaxError, `Can't resolve all parameters for MyBrokenComp1: (?).`); })); it('should throw with descriptive error message when a directive is passed to imports', inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => { @@ -155,6 +156,7 @@ export function main() { expect( () => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithImportedComponent, true)) .toThrowError( + SyntaxError, `Unexpected directive 'ComponentWithoutModuleId' imported by the module 'ModuleWithImportedComponent'`); })); @@ -168,6 +170,7 @@ export function main() { } expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithImportedPipe, true)) .toThrowError( + SyntaxError, `Unexpected pipe 'SomePipe' imported by the module 'ModuleWithImportedPipe'`); })); @@ -181,6 +184,7 @@ export function main() { } expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithDeclaredModule, true)) .toThrowError( + SyntaxError, `Unexpected module 'SomeModule' declared by the module 'ModuleWithDeclaredModule'`); })); @@ -191,6 +195,7 @@ export function main() { } expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithNullDeclared, true)) .toThrowError( + SyntaxError, `Unexpected value 'null' declared by the module 'ModuleWithNullDeclared'`); })); @@ -201,6 +206,7 @@ export function main() { } expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithNullImported, true)) .toThrowError( + SyntaxError, `Unexpected value 'null' imported by the module 'ModuleWithNullImported'`); })); @@ -212,7 +218,8 @@ export function main() { } expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true)) - .toThrowError(`Can't resolve all parameters for NonAnnotatedService: (?).`); + .toThrowError( + SyntaxError, `Can't resolve all parameters for NonAnnotatedService: (?).`); })); it('should throw with descriptive error message when one of providers is not present', @@ -223,6 +230,7 @@ export function main() { expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true)) .toThrowError( + SyntaxError, `Invalid providers for "MyBrokenComp3" - only instances of Provider and Type are allowed, got: [SimpleService, ?null?, ...]`); })); @@ -234,6 +242,7 @@ export function main() { expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true)) .toThrowError( + SyntaxError, `Invalid viewProviders for "MyBrokenComp4" - only instances of Provider and Type are allowed, got: [?null?, ...]`); })); @@ -248,11 +257,13 @@ export function main() { expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithNullBootstrap, true)) .toThrowError( + SyntaxError, `Unexpected value 'null' used in the bootstrap property of module 'ModuleWithNullBootstrap'`); expect( () => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithUndefinedBootstrap, true)) .toThrowError( + SyntaxError, `Unexpected value 'undefined' used in the bootstrap property of module 'ModuleWithUndefinedBootstrap'`); })); diff --git a/modules/@angular/compiler/test/template_parser/template_parser_spec.ts b/modules/@angular/compiler/test/template_parser/template_parser_spec.ts index 635a8788b6..e179c7d9dc 100644 --- a/modules/@angular/compiler/test/template_parser/template_parser_spec.ts +++ b/modules/@angular/compiler/test/template_parser/template_parser_spec.ts @@ -5,7 +5,7 @@ * 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 {SyntaxError} from '@angular/compiler'; import {CompileAnimationEntryMetadata, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, tokenReference} from '@angular/compiler/src/compile_metadata'; import {DomElementSchemaRegistry} from '@angular/compiler/src/schema/dom_element_schema_registry'; import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry'; @@ -374,7 +374,7 @@ export function main() { describe('errors', () => { it('should throw error when binding to an unknown property', () => { expect(() => parse('', [])) - .toThrowError(`Template parse errors: + .toThrowError(SyntaxError, `Template parse errors: Can't bind to 'invalidProp' since it isn't a known property of 'my-component'. 1. If 'my-component' is an Angular component and it has 'invalidProp' input, then verify that it is part of this module. 2. If 'my-component' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. @@ -382,14 +382,16 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'. }); it('should throw error when binding to an unknown element w/o bindings', () => { - expect(() => parse('', [])).toThrowError(`Template parse errors: + expect(() => parse('', [])) + .toThrowError(SyntaxError, `Template parse errors: 'unknown' is not a known element: 1. If 'unknown' is an Angular component, then verify that it is part of this module. 2. If 'unknown' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->]"): TestComp@0:0`); }); it('should throw error when binding to an unknown custom element w/o bindings', () => { - expect(() => parse('', [])).toThrowError(`Template parse errors: + expect(() => parse('', [])) + .toThrowError(SyntaxError, `Template parse errors: 'un-known' is not a known element: 1. If 'un-known' is an Angular component, then verify that it is part of this module. 2. If 'un-known' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->]"): TestComp@0:0`); @@ -397,13 +399,13 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'. it('should throw error when binding to an invalid property', () => { expect(() => parse('', [])) - .toThrowError(`Template parse errors: + .toThrowError(SyntaxError, `Template parse errors: Binding to property 'onEvent' is disallowed for security reasons ("][onEvent]="bar">"): TestComp@0:14`); }); it('should throw error when binding to an invalid attribute', () => { expect(() => parse('', [])) - .toThrowError(`Template parse errors: + .toThrowError(SyntaxError, `Template parse errors: Binding to attribute 'onEvent' is disallowed for security reasons ("][attr.onEvent]="bar">"): TestComp@0:14`); }); }); @@ -445,6 +447,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons (" { expect(() => { parse('
', [], [], []); }) .toThrowError( + SyntaxError, /Assigning animation triggers via @prop="exp" attributes with an expression is invalid. Use property bindings \(e.g. \[@prop\]="exp"\) or use an attribute without a value \(e.g. @prop\) instead. \("
\]@someAnimation="value2">"\): TestComp@0:5/); }); @@ -479,6 +482,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons (" { parse('', [dirA]); }) .toThrowError( + SyntaxError, `Template parse errors:\nValue of the host property binding "class.foo" needs to be a string representing an expression but got "null" (object) ("[ERROR ->]"): TestComp@0:0, Directive DirA`); }); @@ -494,6 +498,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons (" { parse('', [dirA]); }) .toThrowError( + SyntaxError, `Template parse errors:\nValue of the host listener "click" needs to be a string representing an expression but got "null" (object) ("[ERROR ->]"): TestComp@0:0, Directive DirA`); }); @@ -940,8 +945,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons (" parse('
', [dirA, dirB])) .toThrowError( - `Template parse errors:\n` + - `Mixing multi and non multi provider is not possible for token service0 ("[ERROR ->]
"): TestComp@0:0`); + SyntaxError, `Template parse errors:\n` + + `Mixing multi and non multi provider is not possible for token service0 ("[ERROR ->]
"): TestComp@0:0`); }); it('should sort providers by their DI order', () => { @@ -1033,6 +1038,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons (" parse('
', [dirA])) .toThrowError( + SyntaxError, 'Template parse errors:\nNo provider for provider0 ("[ERROR ->]
"): TestComp@0:0'); }); @@ -1047,6 +1053,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons (" parse('
', [dirA])) .toThrowError( + SyntaxError, 'Template parse errors:\nNo provider for provider0 ("[ERROR ->]
"): TestComp@0:0'); }); @@ -1098,23 +1105,26 @@ Binding to attribute 'onEvent' is disallowed for security reasons (" { - expect(() => parse('
', [])).toThrowError(`Template parse errors: + expect(() => parse('
', [])) + .toThrowError(SyntaxError, `Template parse errors: There is no directive with "exportAs" set to "dirA" ("
]#a="dirA">
"): TestComp@0:5`); }); it('should report invalid reference names', () => { - expect(() => parse('
', [])).toThrowError(`Template parse errors: + expect(() => parse('
', [])) + .toThrowError(SyntaxError, `Template parse errors: "-" is not allowed in reference names ("
]#a-b>
"): TestComp@0:5`); }); it('should report variables as errors', () => { - expect(() => parse('
', [])).toThrowError(`Template parse errors: + expect(() => parse('
', [])) + .toThrowError(SyntaxError, `Template parse errors: "let-" is only supported on template elements. ("
]let-a>
"): TestComp@0:5`); }); it('should report duplicate reference names', () => { expect(() => parse('
', [])) - .toThrowError(`Template parse errors: + .toThrowError(SyntaxError, `Template parse errors: Reference "#a" is defined several times ("
]#a>
"): TestComp@0:19`); }); @@ -1466,8 +1476,8 @@ Reference "#a" is defined several times ("
]#a>
it('should report when ng-content has non WS content', () => { expect(() => parse('content', [])) .toThrowError( - `Template parse errors:\n` + - ` element cannot have content. ("[ERROR ->]content"): TestComp@0:0`); + SyntaxError, `Template parse errors:\n` + + ` element cannot have content. ("[ERROR ->]content"): TestComp@0:0`); }); it('should treat *attr on a template element as valid', @@ -1477,18 +1487,20 @@ Reference "#a" is defined several times ("
]#a>
() => { expect(() => parse('