test(ivy): update root causes for @angular/core TestBed failures (#27479)
PR Close #27479
This commit is contained in:
parent
26433509f9
commit
821fecb413
@ -625,23 +625,22 @@ function declareTests(config?: {useJit: boolean}) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents()) {
|
||||||
fixmeIvy('unknown').it(
|
it('should allow to destroy a component from within a host event handler',
|
||||||
'should allow to destroy a component from within a host event handler',
|
fakeAsync(() => {
|
||||||
fakeAsync(() => {
|
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithHostEvent]]]});
|
||||||
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithHostEvent]]]});
|
const template = '<push-cmp-with-host-event></push-cmp-with-host-event>';
|
||||||
const template = '<push-cmp-with-host-event></push-cmp-with-host-event>';
|
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
const fixture = TestBed.createComponent(MyComp);
|
||||||
const fixture = TestBed.createComponent(MyComp);
|
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const cmpEl = fixture.debugElement.children[0];
|
const cmpEl = fixture.debugElement.children[0];
|
||||||
const cmp: PushCmpWithHostEvent = cmpEl.injector.get(PushCmpWithHostEvent);
|
const cmp: PushCmpWithHostEvent = cmpEl.injector.get(PushCmpWithHostEvent);
|
||||||
cmp.ctxCallback = (_: any) => fixture.destroy();
|
cmp.ctxCallback = (_: any) => fixture.destroy();
|
||||||
|
|
||||||
expect(() => cmpEl.triggerEventHandler('click', <Event>{})).not.toThrow();
|
expect(() => cmpEl.triggerEventHandler('click', <Event>{})).not.toThrow();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fixmeIvy('FW-758: OnPush events not marking view dirty when using renderer2')
|
fixmeIvy('FW-758: OnPush events not marking view dirty when using renderer2')
|
||||||
|
@ -136,8 +136,8 @@ function declareTests(config?: {useJit: boolean}) {
|
|||||||
expect(dir.text).toEqual('container');
|
expect(dir.text).toEqual('container');
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('unknown').it(
|
fixmeIvy('FW-795: Queries with descendants: true don\'t descent into <ng-container>')
|
||||||
'should contain all direct child directives in a <ng-container> (content dom)', () => {
|
.it('should contain all direct child directives in a <ng-container> (content dom)', () => {
|
||||||
const template =
|
const template =
|
||||||
'<needs-content-children #q><ng-container><div text="foo"></div></ng-container></needs-content-children>';
|
'<needs-content-children #q><ng-container><div text="foo"></div></ng-container></needs-content-children>';
|
||||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
|||||||
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, ContentChild, ContentChildren, Directive, QueryList, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef, asNativeElements} from '@angular/core';
|
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, ContentChild, ContentChildren, Directive, QueryList, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef, asNativeElements} from '@angular/core';
|
||||||
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
|
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
|
||||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
import {fixmeIvy, modifiedInIvy} from '@angular/private/testing';
|
import {fixmeIvy, ivyEnabled, modifiedInIvy} from '@angular/private/testing';
|
||||||
import {Subject} from 'rxjs';
|
import {Subject} from 'rxjs';
|
||||||
|
|
||||||
import {stringify} from '../../src/util';
|
import {stringify} from '../../src/util';
|
||||||
@ -637,35 +637,66 @@ describe('Query API', () => {
|
|||||||
expect(q.query.length).toBe(0);
|
expect(q.query.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('unknown').it(
|
modifiedInIvy('https://github.com/angular/angular/issues/15117 fixed in ivy')
|
||||||
'should not throw if a content template is queried and created in the view during change detection',
|
.it('should not throw if a content template is queried and created in the view during change detection',
|
||||||
() => {
|
() => {
|
||||||
@Component(
|
@Component({
|
||||||
{selector: 'auto-projecting', template: '<div *ngIf="true; then: content"></div>'})
|
selector: 'auto-projecting',
|
||||||
class AutoProjecting {
|
template: '<div *ngIf="true; then: content"></div>'
|
||||||
// TODO(issue/24571):
|
})
|
||||||
// remove '!'.
|
class AutoProjecting {
|
||||||
@ContentChild(TemplateRef)
|
// TODO(issue/24571):
|
||||||
content !: TemplateRef<any>;
|
// remove '!'.
|
||||||
|
@ContentChild(TemplateRef)
|
||||||
|
content !: TemplateRef<any>;
|
||||||
|
|
||||||
// TODO(issue/24571):
|
// TODO(issue/24571):
|
||||||
// remove '!'.
|
// remove '!'.
|
||||||
@ContentChildren(TextDirective)
|
@ContentChildren(TextDirective)
|
||||||
query !: QueryList<TextDirective>;
|
query !: QueryList<TextDirective>;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestBed.configureTestingModule({declarations: [AutoProjecting]});
|
TestBed.configureTestingModule({declarations: [AutoProjecting]});
|
||||||
const template =
|
const template =
|
||||||
'<auto-projecting #q><ng-template><div text="1"></div></ng-template></auto-projecting>';
|
'<auto-projecting #q><ng-template><div text="1"></div></ng-template></auto-projecting>';
|
||||||
const view = createTestCmpAndDetectChanges(MyComp0, template);
|
const view = createTestCmpAndDetectChanges(MyComp0, template);
|
||||||
|
|
||||||
const q = view.debugElement.children[0].references !['q'];
|
const q = view.debugElement.children[0].references !['q'];
|
||||||
// This should be 1, but due to
|
// This should be 1, but due to
|
||||||
// https://github.com/angular/angular/issues/15117
|
// https://github.com/angular/angular/issues/15117
|
||||||
// this is 0.
|
// this is 0.
|
||||||
expect(q.query.length).toBe(0);
|
expect(q.query.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (ivyEnabled) {
|
||||||
|
// The fixed version of the "should not throw if a content template is queried and created in
|
||||||
|
// the view during change detection" test. This test is a different as ivy fixes
|
||||||
|
// https://github.com/angular/angular/issues/15117 present in the view engine.
|
||||||
|
it('should not throw if a content template is queried and created in the view during change detection - fixed in ivy',
|
||||||
|
() => {
|
||||||
|
@Component(
|
||||||
|
{selector: 'auto-projecting', template: '<div *ngIf="true; then: content"></div>'})
|
||||||
|
class AutoProjecting {
|
||||||
|
// TODO(issue/24571):
|
||||||
|
// remove '!'.
|
||||||
|
@ContentChild(TemplateRef)
|
||||||
|
content !: TemplateRef<any>;
|
||||||
|
|
||||||
|
// TODO(issue/24571):
|
||||||
|
// remove '!'.
|
||||||
|
@ContentChildren(TextDirective)
|
||||||
|
query !: QueryList<TextDirective>;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({declarations: [AutoProjecting]});
|
||||||
|
const template =
|
||||||
|
'<auto-projecting #q><ng-template><div text="1"></div></ng-template></auto-projecting>';
|
||||||
|
const view = createTestCmpAndDetectChanges(MyComp0, template);
|
||||||
|
|
||||||
|
const q = view.debugElement.children[0].references !['q'];
|
||||||
|
expect(q.query.length).toBe(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -32,15 +32,16 @@ function declareTests(config?: {useJit: boolean}) {
|
|||||||
describe('platform pipes', () => {
|
describe('platform pipes', () => {
|
||||||
beforeEach(() => { TestBed.configureCompiler({...config}); });
|
beforeEach(() => { TestBed.configureCompiler({...config}); });
|
||||||
|
|
||||||
fixmeIvy('unknown').it('should overwrite them by custom pipes', () => {
|
fixmeIvy('FW-798: Handle pipes with duplicate names')
|
||||||
TestBed.configureTestingModule({declarations: [CustomPipe]});
|
.it('should overwrite them by custom pipes', () => {
|
||||||
const template = '{{true | somePipe}}';
|
TestBed.configureTestingModule({declarations: [CustomPipe]});
|
||||||
TestBed.overrideComponent(MyComp1, {set: {template}});
|
const template = '{{true | somePipe}}';
|
||||||
const fixture = TestBed.createComponent(MyComp1);
|
TestBed.overrideComponent(MyComp1, {set: {template}});
|
||||||
|
const fixture = TestBed.createComponent(MyComp1);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.nativeElement).toHaveText('someCustomPipe');
|
expect(fixture.nativeElement).toHaveText('someCustomPipe');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('expressions', () => {
|
describe('expressions', () => {
|
||||||
@ -351,36 +352,37 @@ function declareTests(config?: {useJit: boolean}) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('unknown').it(
|
fixmeIvy('FW-797: @ContentChildren results are assigned after @Input bindings')
|
||||||
'should support @ContentChild and @Input on the same property for static queries', () => {
|
.it('should support @ContentChild and @Input on the same property for static queries',
|
||||||
@Directive({selector: 'test'})
|
() => {
|
||||||
class Test {
|
@Directive({selector: 'test'})
|
||||||
// TODO(issue/24571): remove '!'.
|
class Test {
|
||||||
@Input() @ContentChild(TemplateRef) tpl !: TemplateRef<any>;
|
// TODO(issue/24571): remove '!'.
|
||||||
}
|
@Input() @ContentChild(TemplateRef) tpl !: TemplateRef<any>;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
template: `
|
template: `
|
||||||
<test></test><br>
|
<test></test><br>
|
||||||
<test><ng-template>Custom as a child</ng-template></test><br>
|
<test><ng-template>Custom as a child</ng-template></test><br>
|
||||||
<ng-template #custom>Custom as a binding</ng-template>
|
<ng-template #custom>Custom as a binding</ng-template>
|
||||||
<test [tpl]="custom"></test><br>
|
<test [tpl]="custom"></test><br>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class App {
|
class App {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fixture =
|
const fixture =
|
||||||
TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App);
|
TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const testDirs =
|
const testDirs = fixture.debugElement.queryAll(By.directive(Test))
|
||||||
fixture.debugElement.queryAll(By.directive(Test)).map(el => el.injector.get(Test));
|
.map(el => el.injector.get(Test));
|
||||||
expect(testDirs[0].tpl).toBeUndefined();
|
expect(testDirs[0].tpl).toBeUndefined();
|
||||||
expect(testDirs[1].tpl).toBeDefined();
|
expect(testDirs[1].tpl).toBeDefined();
|
||||||
expect(testDirs[2].tpl).toBeDefined();
|
expect(testDirs[2].tpl).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not add ng-version for dynamically created components', () => {
|
it('should not add ng-version for dynamically created components', () => {
|
||||||
@Component({template: ''})
|
@Component({template: ''})
|
||||||
|
@ -102,167 +102,167 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||||||
function declareTests(
|
function declareTests(
|
||||||
{ngUrl, templateDecorator}:
|
{ngUrl, templateDecorator}:
|
||||||
{ngUrl: string, templateDecorator: (template: string) => { [key: string]: any }}) {
|
{ngUrl: string, templateDecorator: (template: string) => { [key: string]: any }}) {
|
||||||
fixmeIvy('unknown').it(
|
fixmeIvy('FW-682: Compiler error handling')
|
||||||
'should use the right source url in html parse errors', fakeAsync(() => {
|
.it('should use the right source url in html parse errors', fakeAsync(() => {
|
||||||
@Component({...templateDecorator('<div>\n </error>')})
|
@Component({...templateDecorator('<div>\n </error>')})
|
||||||
class MyComp {
|
class MyComp {
|
||||||
}
|
|
||||||
|
|
||||||
expect(() => compileAndCreateComponent(MyComp))
|
|
||||||
.toThrowError(
|
|
||||||
new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`));
|
|
||||||
}));
|
|
||||||
|
|
||||||
fixmeIvy('unknown').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`));
|
|
||||||
}));
|
|
||||||
|
|
||||||
fixmeIvy('unknown').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]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
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]});
|
expect(() => compileAndCreateComponent(MyComp))
|
||||||
let error: any;
|
.toThrowError(new RegExp(
|
||||||
try {
|
`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`));
|
||||||
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(
|
fixmeIvy('FW-682: Compiler error handling')
|
||||||
'should report source location for binding errors', fakeAsync(() => {
|
.it('should use the right source url in template parse errors', fakeAsync(() => {
|
||||||
const template = `<div>\n <span [title]="createError()"></span></div>`;
|
@Component({...templateDecorator('<div>\n <div unknown="{{ctxProp}}"></div>')})
|
||||||
|
class MyComp {
|
||||||
|
}
|
||||||
|
|
||||||
@Component({...templateDecorator(template)})
|
expect(() => compileAndCreateComponent(MyComp))
|
||||||
class MyComp {
|
.toThrowError(new RegExp(
|
||||||
createError() { throw new Error('Test'); }
|
`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`));
|
||||||
}
|
}));
|
||||||
|
|
||||||
const comp = compileAndCreateComponent(MyComp);
|
fixmeIvy('FW-223: Generate source maps during template compilation')
|
||||||
|
.it('should create a sourceMap for templates', fakeAsync(() => {
|
||||||
|
const template = `Hello World!`;
|
||||||
|
|
||||||
let error: any;
|
@Component({...templateDecorator(template)})
|
||||||
try {
|
class MyComp {
|
||||||
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(
|
compileAndCreateComponent(MyComp);
|
||||||
'should report source location for event errors', fakeAsync(() => {
|
|
||||||
const template = `<div>\n <span (click)="createError()"></span></div>`;
|
|
||||||
|
|
||||||
@Component({...templateDecorator(template)})
|
const sourceMap = getSourceMap('ng:///DynamicTestModule/MyComp.ngfactory.js');
|
||||||
class MyComp {
|
expect(sourceMap.sources).toEqual([
|
||||||
createError() { throw new Error('Test'); }
|
'ng:///DynamicTestModule/MyComp.ngfactory.js', ngUrl
|
||||||
}
|
]);
|
||||||
|
expect(sourceMap.sourcesContent).toEqual([' ', template]);
|
||||||
|
}));
|
||||||
|
|
||||||
const comp = compileAndCreateComponent(MyComp);
|
|
||||||
|
|
||||||
let error: any;
|
fixmeIvy('FW-223: Generate source maps during template compilation')
|
||||||
const errorHandler = TestBed.get(ErrorHandler);
|
.it('should report source location for di errors', fakeAsync(() => {
|
||||||
spyOn(errorHandler, 'handleError').and.callFake((e: any) => error = e);
|
const template = `<div>\n <div someDir></div></div>`;
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
}));
|
@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('FW-223: Generate source maps during template compilation')
|
||||||
|
.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('FW-223: Generate source maps during template compilation')
|
||||||
|
.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('FW-223: Generate source maps during template compilation')
|
||||||
|
.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,
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user