feat(ivy): implement unknown element detection in jit mode (#33419)

In ViewEngine we used to throw an error if we encountered an unknown element while rendering. We have this already for Ivy in AoT, but we didn't in JiT. These changes implement the error for JiT mode.

PR Close #33419
This commit is contained in:
crisbeto
2019-10-26 12:44:03 +02:00
committed by atscott
parent ac9d044cad
commit c83f5013bf
6 changed files with 132 additions and 12 deletions

View File

@ -10,7 +10,7 @@
import '@angular/localize/init';
import {registerLocaleData} from '@angular/common';
import localeRo from '@angular/common/locales/ro';
import {Component, ContentChild, ContentChildren, Directive, HostBinding, Input, LOCALE_ID, QueryList, TemplateRef, Type, ViewChild, ViewContainerRef, Pipe, PipeTransform} from '@angular/core';
import {Component, ContentChild, ContentChildren, Directive, HostBinding, Input, LOCALE_ID, QueryList, TemplateRef, Type, ViewChild, ViewContainerRef, Pipe, PipeTransform, NO_ERRORS_SCHEMA} from '@angular/core';
import {setDelayProjection} from '@angular/core/src/render3/instructions/projection';
import {TestBed} from '@angular/core/testing';
import {loadTranslations, clearTranslations} from '@angular/localize';
@ -22,7 +22,13 @@ import {computeMsgId} from '@angular/compiler';
onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
beforeEach(() => {
TestBed.configureTestingModule({declarations: [AppComp, DirectiveWithTplRef, UppercasePipe]});
TestBed.configureTestingModule({
declarations: [AppComp, DirectiveWithTplRef, UppercasePipe],
// In some of the tests we use made-up tag names for better readability, however they'll
// cause validation errors. Add the `NO_ERRORS_SCHEMA` so that we don't have to declare
// dummy components for each one of them.
schemas: [NO_ERRORS_SCHEMA],
});
});
afterEach(() => {

View File

@ -7,7 +7,7 @@
*/
import {CommonModule} from '@angular/common';
import {Component, NO_ERRORS_SCHEMA, NgModule} from '@angular/core';
import {CUSTOM_ELEMENTS_SCHEMA, Component, NO_ERRORS_SCHEMA, NgModule} from '@angular/core';
import {TestBed} from '@angular/core/testing';
import {modifiedInIvy, onlyInIvy} from '@angular/private/testing';
@ -164,6 +164,86 @@ describe('NgModule', () => {
fixture.detectChanges();
}).not.toThrow();
});
});
it('should throw unknown element error without CUSTOM_ELEMENTS_SCHEMA for element with dash in tag name',
() => {
@Component({template: `<custom-el></custom-el>`})
class MyComp {
}
TestBed.configureTestingModule({declarations: [MyComp]});
expect(() => {
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges();
}).toThrowError(/'custom-el' is not a known element/);
});
it('should throw unknown element error without CUSTOM_ELEMENTS_SCHEMA for element without dash in tag name',
() => {
@Component({template: `<custom></custom>`})
class MyComp {
}
TestBed.configureTestingModule({declarations: [MyComp]});
expect(() => {
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges();
}).toThrowError(/'custom' is not a known element/);
});
it('should not throw unknown element error with CUSTOM_ELEMENTS_SCHEMA', () => {
@Component({template: `<custom-el></custom-el>`})
class MyComp {
}
TestBed.configureTestingModule({
declarations: [MyComp],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
});
expect(() => {
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges();
}).not.toThrow();
});
it('should not throw unknown element error with NO_ERRORS_SCHEMA', () => {
@Component({template: `<custom-el></custom-el>`})
class MyComp {
}
TestBed.configureTestingModule({
declarations: [MyComp],
schemas: [NO_ERRORS_SCHEMA],
});
expect(() => {
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges();
}).not.toThrow();
});
it('should not throw unknown element error if element matches a directive', () => {
@Component({
selector: 'custom-el',
template: '',
})
class CustomEl {
}
@Component({template: `<custom-el></custom-el>`})
class MyComp {
}
TestBed.configureTestingModule({declarations: [MyComp, CustomEl]});
expect(() => {
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges();
}).not.toThrow();
});
});
});