test: move remaining fixmeIvy to test level (#27354)

Moves all of the remaning `describe`-level fixme instances to the `it` level.

PR Close #27354
This commit is contained in:
Kristiyan Kostadinov
2018-11-29 23:34:28 +01:00
committed by Igor Minar
parent 36e7bf1b7b
commit 23bc8edf24
11 changed files with 1566 additions and 1451 deletions

View File

@ -16,7 +16,7 @@ import {fixmeIvy} from '@angular/private/testing';
{
// ivy fix in https://github.com/angular/angular/pull/26871
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && describe('Jit Summaries', () => {
describe('Jit Summaries', () => {
let instances: Map<any, Base>;
let summaries: () => any[];
@ -138,146 +138,160 @@ import {fixmeIvy} from '@angular/private/testing';
afterEach(() => { resetTestEnvironmentWithSummaries(); });
it('should use directive metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should use directive metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
@Component({template: '<div someDir></div>'})
class TestComp {
}
@Component({template: '<div someDir></div>'})
class TestComp {
}
TestBed
.configureTestingModule({providers: [SomeDep], declarations: [TestComp, SomeDirective]})
.createComponent(TestComp);
expectInstanceCreated(SomeDirective);
});
TestBed
.configureTestingModule(
{providers: [SomeDep], declarations: [TestComp, SomeDirective]})
.createComponent(TestComp);
expectInstanceCreated(SomeDirective);
});
it('should use pipe metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should use pipe metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
@Component({template: '{{1 | somePipe}}'})
class TestComp {
}
@Component({template: '{{1 | somePipe}}'})
class TestComp {
}
TestBed.configureTestingModule({providers: [SomeDep], declarations: [TestComp, SomePipe]})
.createComponent(TestComp);
expectInstanceCreated(SomePipe);
});
TestBed.configureTestingModule({providers: [SomeDep], declarations: [TestComp, SomePipe]})
.createComponent(TestComp);
expectInstanceCreated(SomePipe);
});
it('should use Service metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should use Service metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.configureTestingModule({
providers: [SomeService, SomeDep],
});
TestBed.get(SomeService);
expectInstanceCreated(SomeService);
});
TestBed.configureTestingModule({
providers: [SomeService, SomeDep],
});
TestBed.get(SomeService);
expectInstanceCreated(SomeService);
});
it('should use NgModule metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should use NgModule metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed
.configureTestingModule(
{providers: [SomeDep], declarations: [TestComp3], imports: [SomeModule]})
.createComponent(TestComp3);
TestBed
.configureTestingModule(
{providers: [SomeDep], declarations: [TestComp3], imports: [SomeModule]})
.createComponent(TestComp3);
expectInstanceCreated(SomeModule);
expectInstanceCreated(SomeDirective);
expectInstanceCreated(SomePipe);
expectInstanceCreated(SomeService);
});
expectInstanceCreated(SomeModule);
expectInstanceCreated(SomeDirective);
expectInstanceCreated(SomePipe);
expectInstanceCreated(SomeService);
});
it('should allow to create private components from imported NgModule summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should allow to create private components from imported NgModule summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent(SomePrivateComponent);
expectInstanceCreated(SomePrivateComponent);
});
TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent(SomePrivateComponent);
expectInstanceCreated(SomePrivateComponent);
});
it('should throw when trying to mock a type with a summary', () => {
resetTestEnvironmentWithSummaries(summaries);
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should throw when trying to mock a type with a summary', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.resetTestingModule();
expect(() => TestBed.overrideComponent(SomePrivateComponent, {add: {}}).compileComponents())
.toThrowError(
'SomePrivateComponent was AOT compiled, so its metadata cannot be changed.');
TestBed.resetTestingModule();
expect(() => TestBed.overrideDirective(SomeDirective, {add: {}}).compileComponents())
.toThrowError('SomeDirective was AOT compiled, so its metadata cannot be changed.');
TestBed.resetTestingModule();
expect(() => TestBed.overridePipe(SomePipe, {add: {name: 'test'}}).compileComponents())
.toThrowError('SomePipe was AOT compiled, so its metadata cannot be changed.');
TestBed.resetTestingModule();
expect(() => TestBed.overrideModule(SomeModule, {add: {}}).compileComponents())
.toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.');
});
TestBed.resetTestingModule();
expect(
() => TestBed.overrideComponent(SomePrivateComponent, {add: {}}).compileComponents())
.toThrowError(
'SomePrivateComponent was AOT compiled, so its metadata cannot be changed.');
TestBed.resetTestingModule();
expect(() => TestBed.overrideDirective(SomeDirective, {add: {}}).compileComponents())
.toThrowError('SomeDirective was AOT compiled, so its metadata cannot be changed.');
TestBed.resetTestingModule();
expect(() => TestBed.overridePipe(SomePipe, {add: {name: 'test'}}).compileComponents())
.toThrowError('SomePipe was AOT compiled, so its metadata cannot be changed.');
TestBed.resetTestingModule();
expect(() => TestBed.overrideModule(SomeModule, {add: {}}).compileComponents())
.toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.');
});
it('should return stack trace and component data on resetTestingModule when error is thrown',
() => {
resetTestEnvironmentWithSummaries();
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should return stack trace and component data on resetTestingModule when error is thrown',
() => {
resetTestEnvironmentWithSummaries();
const fixture = TestBed.configureTestingModule({declarations: [TestCompErrorOnDestroy]})
.createComponent<TestCompErrorOnDestroy>(TestCompErrorOnDestroy);
const fixture =
TestBed.configureTestingModule({declarations: [TestCompErrorOnDestroy]})
.createComponent<TestCompErrorOnDestroy>(TestCompErrorOnDestroy);
const expectedError = 'Error from ngOnDestroy';
const expectedError = 'Error from ngOnDestroy';
const component: TestCompErrorOnDestroy = fixture.componentInstance;
const component: TestCompErrorOnDestroy = fixture.componentInstance;
spyOn(console, 'error');
spyOn(component, 'ngOnDestroy').and.throwError(expectedError);
spyOn(console, 'error');
spyOn(component, 'ngOnDestroy').and.throwError(expectedError);
const expectedObject = {
stacktrace: new Error(expectedError),
component,
};
const expectedObject = {
stacktrace: new Error(expectedError),
component,
};
TestBed.resetTestingModule();
TestBed.resetTestingModule();
expect(console.error)
.toHaveBeenCalledWith('Error during cleanup of component', expectedObject);
});
expect(console.error)
.toHaveBeenCalledWith('Error during cleanup of component', expectedObject);
});
it('should allow to add summaries via configureTestingModule', () => {
resetTestEnvironmentWithSummaries();
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should allow to add summaries via configureTestingModule', () => {
resetTestEnvironmentWithSummaries();
@Component({template: '<div someDir></div>'})
class TestComp {
}
@Component({template: '<div someDir></div>'})
class TestComp {
}
TestBed
.configureTestingModule({
providers: [SomeDep],
declarations: [TestComp, SomeDirective],
aotSummaries: summaries
})
.createComponent(TestComp);
expectInstanceCreated(SomeDirective);
});
TestBed
.configureTestingModule({
providers: [SomeDep],
declarations: [TestComp, SomeDirective],
aotSummaries: summaries
})
.createComponent(TestComp);
expectInstanceCreated(SomeDirective);
});
it('should allow to override a provider', () => {
resetTestEnvironmentWithSummaries(summaries);
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should allow to override a provider', () => {
resetTestEnvironmentWithSummaries(summaries);
const overwrittenValue = {};
const overwrittenValue = {};
const fixture =
TestBed.overrideProvider(SomeDep, {useFactory: () => overwrittenValue, deps: []})
.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent<SomePublicComponent>(SomePublicComponent);
const fixture =
TestBed.overrideProvider(SomeDep, {useFactory: () => overwrittenValue, deps: []})
.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent<SomePublicComponent>(SomePublicComponent);
expect(fixture.componentInstance.dep).toBe(overwrittenValue);
});
expect(fixture.componentInstance.dep).toBe(overwrittenValue);
});
it('should allow to override a template', () => {
resetTestEnvironmentWithSummaries(summaries);
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
it('should allow to override a template', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten');
TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten');
const fixture = TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent(SomePublicComponent);
expectInstanceCreated(SomePublicComponent);
const fixture =
TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent(SomePublicComponent);
expectInstanceCreated(SomePublicComponent);
expect(fixture.nativeElement).toHaveText('overwritten');
});
expect(fixture.nativeElement).toHaveText('overwritten');
});
});
}

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ import {fixmeIvy} from '@angular/private/testing';
{
if (ivyEnabled) {
fixmeIvy('unknown') && describe('ivy', () => { declareTests(); });
describe('ivy', () => { declareTests(); });
} else {
describe('jit', () => { declareTests({useJit: true}); });
describe('no jit', () => { declareTests({useJit: false}); });
@ -52,7 +52,7 @@ function declareTests(config?: {useJit: boolean}) {
afterEach(() => { getDOM().log = originalLog; });
describe('events', () => {
it('should disallow binding to attr.on*', () => {
fixmeIvy('unknown') && it('should disallow binding to attr.on*', () => {
const template = `<div [attr.onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
@ -61,7 +61,7 @@ function declareTests(config?: {useJit: boolean}) {
/Binding to event attribute 'onclick' is disallowed for security reasons, please use \(click\)=.../);
});
it('should disallow binding to on* with NO_ERRORS_SCHEMA', () => {
fixmeIvy('unknown') && it('should disallow binding to on* with NO_ERRORS_SCHEMA', () => {
const template = `<div [onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({
schemas: [NO_ERRORS_SCHEMA]
@ -72,29 +72,30 @@ function declareTests(config?: {useJit: boolean}) {
/Binding to event property 'onclick' is disallowed for security reasons, please use \(click\)=.../);
});
it('should disallow binding to on* unless it is consumed by a directive', () => {
const template = `<div [onPrefixedProp]="ctxProp" [onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({
schemas: [NO_ERRORS_SCHEMA]
});
fixmeIvy('unknown') &&
it('should disallow binding to on* unless it is consumed by a directive', () => {
const template = `<div [onPrefixedProp]="ctxProp" [onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({
schemas: [NO_ERRORS_SCHEMA]
});
// should not throw for inputs starting with "on"
let cmp: ComponentFixture<SecuredComponent> = undefined !;
expect(() => cmp = TestBed.createComponent(SecuredComponent)).not.toThrow();
// should not throw for inputs starting with "on"
let cmp: ComponentFixture<SecuredComponent> = undefined !;
expect(() => cmp = TestBed.createComponent(SecuredComponent)).not.toThrow();
// must bind to the directive not to the property of the div
const value = cmp.componentInstance.ctxProp = {};
cmp.detectChanges();
const div = cmp.debugElement.children[0];
expect(div.injector.get(OnPrefixDir).onclick).toBe(value);
expect(getDOM().getProperty(div.nativeElement, 'onclick')).not.toBe(value);
expect(getDOM().hasAttribute(div.nativeElement, 'onclick')).toEqual(false);
});
// must bind to the directive not to the property of the div
const value = cmp.componentInstance.ctxProp = {};
cmp.detectChanges();
const div = cmp.debugElement.children[0];
expect(div.injector.get(OnPrefixDir).onclick).toBe(value);
expect(getDOM().getProperty(div.nativeElement, 'onclick')).not.toBe(value);
expect(getDOM().hasAttribute(div.nativeElement, 'onclick')).toEqual(false);
});
});
describe('safe HTML values', function() {
it('should not escape values marked as trusted', () => {
fixmeIvy('unknown') && it('should not escape values marked as trusted', () => {
const template = `<a [href]="ctxProp">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
@ -108,7 +109,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getProperty(e, 'href')).toEqual('javascript:alert(1)');
});
it('should error when using the wrong trusted value', () => {
fixmeIvy('unknown') && it('should error when using the wrong trusted value', () => {
const template = `<a [href]="ctxProp">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
@ -120,7 +121,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(() => fixture.detectChanges()).toThrowError(/Required a safe URL, got a Script/);
});
it('should warn when using in string interpolation', () => {
fixmeIvy('unknown') && it('should warn when using in string interpolation', () => {
const template = `<a href="/foo/{{ctxProp}}">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
@ -153,7 +154,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(value).toEqual('unsafe:javascript:alert(1)');
}
it('should escape unsafe properties', () => {
fixmeIvy('unknown') && it('should escape unsafe properties', () => {
const template = `<a [href]="ctxProp">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
@ -161,7 +162,7 @@ function declareTests(config?: {useJit: boolean}) {
checkEscapeOfHrefProperty(fixture, false);
});
it('should escape unsafe attributes', () => {
fixmeIvy('unknown') && it('should escape unsafe attributes', () => {
const template = `<a [attr.href]="ctxProp">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
@ -169,39 +170,41 @@ function declareTests(config?: {useJit: boolean}) {
checkEscapeOfHrefProperty(fixture, true);
});
it('should escape unsafe properties if they are used in host bindings', () => {
@Directive({selector: '[dirHref]'})
class HrefDirective {
// TODO(issue/24571): remove '!'.
@HostBinding('href') @Input()
dirHref !: string;
}
fixmeIvy('unknown') &&
it('should escape unsafe properties if they are used in host bindings', () => {
@Directive({selector: '[dirHref]'})
class HrefDirective {
// TODO(issue/24571): remove '!'.
@HostBinding('href') @Input()
dirHref !: string;
}
const template = `<a [dirHref]="ctxProp">Link Title</a>`;
TestBed.configureTestingModule({declarations: [HrefDirective]});
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
const template = `<a [dirHref]="ctxProp">Link Title</a>`;
TestBed.configureTestingModule({declarations: [HrefDirective]});
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
checkEscapeOfHrefProperty(fixture, false);
});
checkEscapeOfHrefProperty(fixture, false);
});
it('should escape unsafe attributes if they are used in host bindings', () => {
@Directive({selector: '[dirHref]'})
class HrefDirective {
// TODO(issue/24571): remove '!'.
@HostBinding('attr.href') @Input()
dirHref !: string;
}
fixmeIvy('unknown') &&
it('should escape unsafe attributes if they are used in host bindings', () => {
@Directive({selector: '[dirHref]'})
class HrefDirective {
// TODO(issue/24571): remove '!'.
@HostBinding('attr.href') @Input()
dirHref !: string;
}
const template = `<a [dirHref]="ctxProp">Link Title</a>`;
TestBed.configureTestingModule({declarations: [HrefDirective]});
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
const template = `<a [dirHref]="ctxProp">Link Title</a>`;
TestBed.configureTestingModule({declarations: [HrefDirective]});
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
checkEscapeOfHrefProperty(fixture, true);
});
checkEscapeOfHrefProperty(fixture, true);
});
it('should escape unsafe style values', () => {
fixmeIvy('unknown') && it('should escape unsafe style values', () => {
const template = `<div [style.background]="ctxProp">Text</div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);
@ -221,7 +224,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getStyle(e, 'background')).not.toContain('javascript');
});
it('should escape unsafe SVG attributes', () => {
fixmeIvy('unknown') && it('should escape unsafe SVG attributes', () => {
const template = `<svg:circle [xlink:href]="ctxProp">Text</svg:circle>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
@ -229,7 +232,7 @@ function declareTests(config?: {useJit: boolean}) {
.toThrowError(/Can't bind to 'xlink:href'/);
});
it('should escape unsafe HTML values', () => {
fixmeIvy('unknown') && it('should escape unsafe HTML values', () => {
const template = `<div [innerHTML]="ctxProp">Text</div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent);

View File

@ -16,7 +16,7 @@ import {TestBed, fakeAsync, tick} from '@angular/core/testing';
import {fixmeIvy} from '@angular/private/testing';
{
fixmeIvy('unknown') && describe('jit source mapping', () => {
describe('jit source mapping', () => {
let jitSpy: jasmine.Spy;
let resourceLoader: MockResourceLoader;
@ -102,160 +102,167 @@ import {fixmeIvy} from '@angular/private/testing';
function declareTests(
{ngUrl, templateDecorator}:
{ngUrl: string, templateDecorator: (template: string) => { [key: string]: any }}) {
it('should use the right source url in html parse errors', fakeAsync(() => {
@Component({...templateDecorator('<div>\n </error>')})
class MyComp {
}
expect(() => compileAndCreateComponent(MyComp))
.toThrowError(
new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`));
}));
it('should use the right source url in template parse errors', fakeAsync(() => {
@Component({...templateDecorator('<div>\n <div unknown="{{ctxProp}}"></div>')})
class MyComp {
}
expect(() => compileAndCreateComponent(MyComp))
.toThrowError(
new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`));
}));
it('should create a sourceMap for templates', fakeAsync(() => {
const template = `Hello World!`;
@Component({...templateDecorator(template)})
class MyComp {
}
compileAndCreateComponent(MyComp);
const sourceMap = getSourceMap('ng:///DynamicTestModule/MyComp.ngfactory.js');
expect(sourceMap.sources).toEqual([
'ng:///DynamicTestModule/MyComp.ngfactory.js', ngUrl
]);
expect(sourceMap.sourcesContent).toEqual([' ', template]);
}));
it('should report source location for di errors', fakeAsync(() => {
const template = `<div>\n <div someDir></div></div>`;
@Component({...templateDecorator(template)})
class MyComp {
}
@Directive({selector: '[someDir]'})
class SomeDir {
constructor() { throw new Error('Test'); }
}
TestBed.configureTestingModule({declarations: [SomeDir]});
let error: any;
try {
compileAndCreateComponent(MyComp);
} catch (e) {
error = e;
}
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
it('should report di errors with multiple elements and directives', fakeAsync(() => {
const template = `<div someDir></div><div someDir="throw"></div>`;
@Component({...templateDecorator(template)})
class MyComp {
}
@Directive({selector: '[someDir]'})
class SomeDir {
constructor(@Attribute('someDir') someDir: string) {
if (someDir === 'throw') {
throw new Error('Test');
fixmeIvy('unknown') &&
it('should use the right source url in html parse errors', fakeAsync(() => {
@Component({...templateDecorator('<div>\n </error>')})
class MyComp {
}
}
}
TestBed.configureTestingModule({declarations: [SomeDir]});
let error: any;
try {
compileAndCreateComponent(MyComp);
} catch (e) {
error = e;
}
// The error should be logged from the 2nd-element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 1,
column: 19,
source: ngUrl,
});
}));
expect(() => compileAndCreateComponent(MyComp))
.toThrowError(new RegExp(
`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`));
}));
it('should report source location for binding errors', fakeAsync(() => {
const template = `<div>\n <span [title]="createError()"></span></div>`;
fixmeIvy('unknown') &&
it('should use the right source url in template parse errors', fakeAsync(() => {
@Component({...templateDecorator('<div>\n <div unknown="{{ctxProp}}"></div>')})
class MyComp {
}
@Component({...templateDecorator(template)})
class MyComp {
createError() { throw new Error('Test'); }
}
expect(() => compileAndCreateComponent(MyComp))
.toThrowError(new RegExp(
`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`));
}));
const comp = compileAndCreateComponent(MyComp);
fixmeIvy('unknown') && it('should create a sourceMap for templates', fakeAsync(() => {
const template = `Hello World!`;
let error: any;
try {
comp.detectChanges();
} catch (e) {
error = e;
}
// the stack should point to the binding
expect(getSourcePositionForStack(error.stack)).toEqual({
line: 2,
column: 12,
source: ngUrl,
});
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
@Component({...templateDecorator(template)})
class MyComp {
}
it('should report source location for event errors', fakeAsync(() => {
const template = `<div>\n <span (click)="createError()"></span></div>`;
compileAndCreateComponent(MyComp);
@Component({...templateDecorator(template)})
class MyComp {
createError() { throw new Error('Test'); }
}
const sourceMap =
getSourceMap('ng:///DynamicTestModule/MyComp.ngfactory.js');
expect(sourceMap.sources).toEqual([
'ng:///DynamicTestModule/MyComp.ngfactory.js', ngUrl
]);
expect(sourceMap.sourcesContent).toEqual([' ', template]);
}));
const comp = compileAndCreateComponent(MyComp);
let error: any;
const errorHandler = TestBed.get(ErrorHandler);
spyOn(errorHandler, 'handleError').and.callFake((e: any) => error = e);
comp.debugElement.children[0].children[0].triggerEventHandler('click', 'EVENT');
expect(error).toBeTruthy();
// the stack should point to the binding
expect(getSourcePositionForStack(error.stack)).toEqual({
line: 2,
column: 12,
source: ngUrl,
});
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
fixmeIvy('unknown') &&
it('should report source location for di errors', fakeAsync(() => {
const template = `<div>\n <div someDir></div></div>`;
}));
@Component({...templateDecorator(template)})
class MyComp {
}
@Directive({selector: '[someDir]'})
class SomeDir {
constructor() { throw new Error('Test'); }
}
TestBed.configureTestingModule({declarations: [SomeDir]});
let error: any;
try {
compileAndCreateComponent(MyComp);
} catch (e) {
error = e;
}
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
fixmeIvy('unknown') &&
it('should report di errors with multiple elements and directives', fakeAsync(() => {
const template = `<div someDir></div><div someDir="throw"></div>`;
@Component({...templateDecorator(template)})
class MyComp {
}
@Directive({selector: '[someDir]'})
class SomeDir {
constructor(@Attribute('someDir') someDir: string) {
if (someDir === 'throw') {
throw new Error('Test');
}
}
}
TestBed.configureTestingModule({declarations: [SomeDir]});
let error: any;
try {
compileAndCreateComponent(MyComp);
} catch (e) {
error = e;
}
// The error should be logged from the 2nd-element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 1,
column: 19,
source: ngUrl,
});
}));
fixmeIvy('unknown') &&
it('should report source location for binding errors', fakeAsync(() => {
const template = `<div>\n <span [title]="createError()"></span></div>`;
@Component({...templateDecorator(template)})
class MyComp {
createError() { throw new Error('Test'); }
}
const comp = compileAndCreateComponent(MyComp);
let error: any;
try {
comp.detectChanges();
} catch (e) {
error = e;
}
// the stack should point to the binding
expect(getSourcePositionForStack(error.stack)).toEqual({
line: 2,
column: 12,
source: ngUrl,
});
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
fixmeIvy('unknown') &&
it('should report source location for event errors', fakeAsync(() => {
const template = `<div>\n <span (click)="createError()"></span></div>`;
@Component({...templateDecorator(template)})
class MyComp {
createError() { throw new Error('Test'); }
}
const comp = compileAndCreateComponent(MyComp);
let error: any;
const errorHandler = TestBed.get(ErrorHandler);
spyOn(errorHandler, 'handleError').and.callFake((e: any) => error = e);
comp.debugElement.children[0].children[0].triggerEventHandler('click', 'EVENT');
expect(error).toBeTruthy();
// the stack should point to the binding
expect(getSourcePositionForStack(error.stack)).toEqual({
line: 2,
column: 12,
source: ngUrl,
});
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
}
});
}