refactor(core): introduce NgModule.schemas

This allows Angular to error on unknown properties,
allowing applications that don’t use custom elements
to get better error reporting.

Part of #10043

BREAKING CHANGE:
- By default, Angular will error during parsing
  on unknown properties,
  even if they are on elements with a `-` in their name
  (aka custom elements). If you application is using
  custom elements, fill the new parameter `@NgModule.schemas`
  with the value `[CUSTOM_ELEMENTS_SCHEMA]`.

  E.g. for bootstrap:
  ```
  bootstrap(MyComponent, {schemas: [CUSTOM_ELEMENTS_SCHEMA]});
  ```
This commit is contained in:
Tobias Bosch
2016-07-25 03:02:57 -07:00
parent f02da4e91a
commit 00b726f695
21 changed files with 249 additions and 101 deletions

View File

@ -8,7 +8,7 @@
import {LowerCasePipe, NgIf} from '@angular/common';
import {XHR} from '@angular/compiler';
import {APP_INITIALIZER, Component, Directive, ExceptionHandler, Inject, Input, NgModule, OnDestroy, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, Pipe, ReflectiveInjector, bootstrapModule, createPlatformFactory, provide} from '@angular/core';
import {APP_INITIALIZER, createPlatformFactory, CUSTOM_ELEMENTS_SCHEMA, Component, Directive, ExceptionHandler, Inject, Input, NgModule, OnDestroy, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, Pipe, ReflectiveInjector, bootstrapModule, createPlatform, provide} from '@angular/core';
import {ApplicationRef, disposePlatform} from '@angular/core/src/application_ref';
import {Console} from '@angular/core/src/console';
import {ComponentRef} from '@angular/core/src/linker/component_factory';
@ -94,6 +94,10 @@ class HelloCmpUsingPlatformDirectiveAndPipe {
show: boolean = false;
}
@Component({selector: 'hello-app', template: '<some-el [someProp]="true">hello world!</some-el>'})
class HelloCmpUsingCustomElement {
}
class _ArrayLogger {
res: any[] = [];
log(s: any): void { this.res.push(s); }
@ -331,5 +335,15 @@ export function main() {
});
}));
it('should allow to pass schemas', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
bootstrap(HelloCmpUsingCustomElement, {
providers: testProviders,
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).then((compRef) => {
expect(el).toHaveText('hello world!');
async.done();
});
}));
});
}

View File

@ -8,7 +8,7 @@
import {NgIf} from '@angular/common';
import {CompilerConfig, XHR} from '@angular/compiler';
import {Component, ComponentFactoryResolver, Directive, Injectable, Input, NgModule, Pipe, ViewMetadata, provide} from '@angular/core';
import {CUSTOM_ELEMENTS_SCHEMA, Component, ComponentFactoryResolver, Directive, Injectable, Input, NgModule, Pipe, ViewMetadata, provide} from '@angular/core';
import {TestComponentBuilder, addProviders, async, configureCompiler, configureModule, doAsyncEntryPointCompilation, fakeAsync, inject, tick, withModule, withProviders} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers';
@ -265,6 +265,30 @@ export function main() {
expect(resolver.resolveComponentFactory(CompUsingModuleDirectiveAndPipe).componentType)
.toBe(CompUsingModuleDirectiveAndPipe);
}));
it('should error on unknown bound properties on custom elements by default',
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty {
}
expect(() => tcb.createSync(ComponentUsingInvalidProperty))
.toThrowError(/Can't bind to 'someUnknownProp'/);
}));
describe('provided schemas', () => {
beforeEach(() => { configureModule({schemas: [CUSTOM_ELEMENTS_SCHEMA]}); });
it('should not error on unknown bound properties on custom elements when using the CUSTOM_ELEMENTS_SCHEMA',
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty {
}
tcb.createSync(ComponentUsingInvalidProperty)
expect(() => tcb.createSync(ComponentUsingInvalidProperty)).not.toThrow();
}));
});
});
describe('per test modules', () => {