test(ivy): update root causes for @angular/core TestBed failures (#27627)
PR Close #27627
This commit is contained in:
parent
fc6dc78fe9
commit
28ceca0163
|
@ -996,32 +996,33 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
|||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown').it(
|
||||
'should not call ngAfterViewInit again if it throws', fakeAsync(() => {
|
||||
const ctx =
|
||||
createCompFixture('<div testDirective="dir" throwOn="ngAfterViewInit"></div>');
|
||||
fixmeIvy(
|
||||
'FW-830: Exception thrown in ngAfterViewInit triggers ngAfterViewInit re-execution')
|
||||
.it('should not call ngAfterViewInit again if it throws', fakeAsync(() => {
|
||||
const ctx = createCompFixture(
|
||||
'<div testDirective="dir" throwOn="ngAfterViewInit"></div>');
|
||||
|
||||
let errored = false;
|
||||
// First pass fails, but ngAfterViewInit should be called.
|
||||
try {
|
||||
ctx.detectChanges(false);
|
||||
} catch (e) {
|
||||
errored = true;
|
||||
}
|
||||
expect(errored).toBe(true);
|
||||
let errored = false;
|
||||
// First pass fails, but ngAfterViewInit should be called.
|
||||
try {
|
||||
ctx.detectChanges(false);
|
||||
} catch (e) {
|
||||
errored = true;
|
||||
}
|
||||
expect(errored).toBe(true);
|
||||
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual(['dir.ngAfterViewInit']);
|
||||
directiveLog.clear();
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual(['dir.ngAfterViewInit']);
|
||||
directiveLog.clear();
|
||||
|
||||
// Second change detection also fails, but this time ngAfterViewInit should not be
|
||||
// called.
|
||||
try {
|
||||
ctx.detectChanges(false);
|
||||
} catch (e) {
|
||||
throw new Error('Second detectChanges() should not have run detection.');
|
||||
}
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
|
||||
}));
|
||||
// Second change detection also fails, but this time ngAfterViewInit should not be
|
||||
// called.
|
||||
try {
|
||||
ctx.detectChanges(false);
|
||||
} catch (e) {
|
||||
throw new Error('Second detectChanges() should not have run detection.');
|
||||
}
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('ngAfterViewChecked', () => {
|
||||
|
@ -1185,14 +1186,14 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
|||
/Previous value: 'changed: undefined'\. Current value: 'changed: 1'/g);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown').it(
|
||||
'should warn when the view has been created in a cd hook', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<div *gh9882>{{ a }}</div>', TestData);
|
||||
ctx.componentInstance.a = 1;
|
||||
expect(() => ctx.detectChanges())
|
||||
.toThrowError(
|
||||
/It seems like the view has been created after its parent and its children have been dirty checked/);
|
||||
}));
|
||||
fixmeIvy('FW-831: Views created in a cd hooks throw in view engine')
|
||||
.it('should warn when the view has been created in a cd hook', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<div *gh9882>{{ a }}</div>', TestData);
|
||||
ctx.componentInstance.a = 1;
|
||||
expect(() => ctx.detectChanges())
|
||||
.toThrowError(
|
||||
/It seems like the view has been created after its parent and its children have been dirty checked/);
|
||||
}));
|
||||
|
||||
it('should not throw when two arrays are structurally the same', fakeAsync(() => {
|
||||
const ctx = _bindSimpleValue('a', TestData);
|
||||
|
@ -1537,110 +1538,111 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
|||
childThrows: LifetimeMethods;
|
||||
}
|
||||
|
||||
fixmeIvy('unknown').describe('calling init', () => {
|
||||
function initialize(options: Options) {
|
||||
@Component({selector: 'my-child', template: ''})
|
||||
class MyChild {
|
||||
private thrown = LifetimeMethods.None;
|
||||
fixmeIvy('FW-832: View engine supports recursive detectChanges() calls')
|
||||
.describe('calling init', () => {
|
||||
function initialize(options: Options) {
|
||||
@Component({selector: 'my-child', template: ''})
|
||||
class MyChild {
|
||||
private thrown = LifetimeMethods.None;
|
||||
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@Input() inp !: boolean;
|
||||
@Output() outp = new EventEmitter<any>();
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@Input() inp !: boolean;
|
||||
@Output() outp = new EventEmitter<any>();
|
||||
|
||||
constructor() {}
|
||||
constructor() {}
|
||||
|
||||
ngDoCheck() { this.check(LifetimeMethods.ngDoCheck); }
|
||||
ngOnInit() { this.check(LifetimeMethods.ngOnInit); }
|
||||
ngOnChanges() { this.check(LifetimeMethods.ngOnChanges); }
|
||||
ngAfterViewInit() { this.check(LifetimeMethods.ngAfterViewInit); }
|
||||
ngAfterContentInit() { this.check(LifetimeMethods.ngAfterContentInit); }
|
||||
ngDoCheck() { this.check(LifetimeMethods.ngDoCheck); }
|
||||
ngOnInit() { this.check(LifetimeMethods.ngOnInit); }
|
||||
ngOnChanges() { this.check(LifetimeMethods.ngOnChanges); }
|
||||
ngAfterViewInit() { this.check(LifetimeMethods.ngAfterViewInit); }
|
||||
ngAfterContentInit() { this.check(LifetimeMethods.ngAfterContentInit); }
|
||||
|
||||
private check(method: LifetimeMethods) {
|
||||
log(`MyChild::${LifetimeMethods[method]}()`);
|
||||
private check(method: LifetimeMethods) {
|
||||
log(`MyChild::${LifetimeMethods[method]}()`);
|
||||
|
||||
if ((options.childRecursion & method) !== 0) {
|
||||
if (logged.length < 20) {
|
||||
this.outp.emit(null);
|
||||
} else {
|
||||
fail(`Unexpected MyChild::${LifetimeMethods[method]} recursion`);
|
||||
if ((options.childRecursion & method) !== 0) {
|
||||
if (logged.length < 20) {
|
||||
this.outp.emit(null);
|
||||
} else {
|
||||
fail(`Unexpected MyChild::${LifetimeMethods[method]} recursion`);
|
||||
}
|
||||
}
|
||||
if ((options.childThrows & method) !== 0) {
|
||||
if ((this.thrown & method) === 0) {
|
||||
this.thrown |= method;
|
||||
log(`<THROW from MyChild::${LifetimeMethods[method]}>()`);
|
||||
throw new Error(`Throw from MyChild::${LifetimeMethods[method]}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((options.childThrows & method) !== 0) {
|
||||
if ((this.thrown & method) === 0) {
|
||||
this.thrown |= method;
|
||||
log(`<THROW from MyChild::${LifetimeMethods[method]}>()`);
|
||||
throw new Error(`Throw from MyChild::${LifetimeMethods[method]}`);
|
||||
|
||||
@Component({
|
||||
selector: 'my-component',
|
||||
template: `<my-child [inp]='true' (outp)='onOutp()'></my-child>`
|
||||
})
|
||||
class MyComponent {
|
||||
constructor(private changeDetectionRef: ChangeDetectorRef) {}
|
||||
ngDoCheck() { this.check(LifetimeMethods.ngDoCheck); }
|
||||
ngOnInit() { this.check(LifetimeMethods.ngOnInit); }
|
||||
ngAfterViewInit() { this.check(LifetimeMethods.ngAfterViewInit); }
|
||||
ngAfterContentInit() { this.check(LifetimeMethods.ngAfterContentInit); }
|
||||
onOutp() {
|
||||
log('<RECURSION START>');
|
||||
this.changeDetectionRef.detectChanges();
|
||||
log('<RECURSION DONE>');
|
||||
}
|
||||
|
||||
private check(method: LifetimeMethods) {
|
||||
log(`MyComponent::${LifetimeMethods[method]}()`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'my-component',
|
||||
template: `<my-child [inp]='true' (outp)='onOutp()'></my-child>`
|
||||
})
|
||||
class MyComponent {
|
||||
constructor(private changeDetectionRef: ChangeDetectorRef) {}
|
||||
ngDoCheck() { this.check(LifetimeMethods.ngDoCheck); }
|
||||
ngOnInit() { this.check(LifetimeMethods.ngOnInit); }
|
||||
ngAfterViewInit() { this.check(LifetimeMethods.ngAfterViewInit); }
|
||||
ngAfterContentInit() { this.check(LifetimeMethods.ngAfterContentInit); }
|
||||
onOutp() {
|
||||
log('<RECURSION START>');
|
||||
this.changeDetectionRef.detectChanges();
|
||||
log('<RECURSION DONE>');
|
||||
TestBed.configureTestingModule({declarations: [MyChild, MyComponent]});
|
||||
|
||||
return createCompFixture(`<my-component></my-component>`);
|
||||
}
|
||||
|
||||
private check(method: LifetimeMethods) {
|
||||
log(`MyComponent::${LifetimeMethods[method]}()`);
|
||||
}
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [MyChild, MyComponent]});
|
||||
|
||||
return createCompFixture(`<my-component></my-component>`);
|
||||
}
|
||||
|
||||
function ensureOneInit(options: Options) {
|
||||
const ctx = initialize(options);
|
||||
function ensureOneInit(options: Options) {
|
||||
const ctx = initialize(options);
|
||||
|
||||
|
||||
const throws = options.childThrows != LifetimeMethods.None;
|
||||
if (throws) {
|
||||
log(`<CYCLE 0 START>`);
|
||||
expect(() => {
|
||||
// Expect child to throw.
|
||||
const throws = options.childThrows != LifetimeMethods.None;
|
||||
if (throws) {
|
||||
log(`<CYCLE 0 START>`);
|
||||
expect(() => {
|
||||
// Expect child to throw.
|
||||
ctx.detectChanges();
|
||||
}).toThrow();
|
||||
log(`<CYCLE 0 END>`);
|
||||
log(`<CYCLE 1 START>`);
|
||||
}
|
||||
ctx.detectChanges();
|
||||
}).toThrow();
|
||||
log(`<CYCLE 0 END>`);
|
||||
log(`<CYCLE 1 START>`);
|
||||
}
|
||||
ctx.detectChanges();
|
||||
if (throws) log(`<CYCLE 1 DONE>`);
|
||||
expectOnceAndOnlyOnce('MyComponent::ngOnInit()');
|
||||
expectOnceAndOnlyOnce('MyChild::ngOnInit()');
|
||||
expectOnceAndOnlyOnce('MyComponent::ngAfterViewInit()');
|
||||
expectOnceAndOnlyOnce('MyComponent::ngAfterContentInit()');
|
||||
expectOnceAndOnlyOnce('MyChild::ngAfterViewInit()');
|
||||
expectOnceAndOnlyOnce('MyChild::ngAfterContentInit()');
|
||||
}
|
||||
if (throws) log(`<CYCLE 1 DONE>`);
|
||||
expectOnceAndOnlyOnce('MyComponent::ngOnInit()');
|
||||
expectOnceAndOnlyOnce('MyChild::ngOnInit()');
|
||||
expectOnceAndOnlyOnce('MyComponent::ngAfterViewInit()');
|
||||
expectOnceAndOnlyOnce('MyComponent::ngAfterContentInit()');
|
||||
expectOnceAndOnlyOnce('MyChild::ngAfterViewInit()');
|
||||
expectOnceAndOnlyOnce('MyChild::ngAfterContentInit()');
|
||||
}
|
||||
|
||||
forEachMethod(LifetimeMethods.InitMethodsAndChanges, method => {
|
||||
it(`should ensure that init hooks are called once an only once with recursion in ${LifetimeMethods[method]} `,
|
||||
() => {
|
||||
// Ensure all the init methods are called once.
|
||||
ensureOneInit({childRecursion: method, childThrows: LifetimeMethods.None});
|
||||
});
|
||||
});
|
||||
forEachMethod(LifetimeMethods.All, method => {
|
||||
it(`should ensure that init hooks are called once an only once with a throw in ${LifetimeMethods[method]} `,
|
||||
() => {
|
||||
// Ensure all the init methods are called once.
|
||||
// the first cycle throws but the next cycle should complete the inits.
|
||||
ensureOneInit({childRecursion: LifetimeMethods.None, childThrows: method});
|
||||
});
|
||||
});
|
||||
});
|
||||
forEachMethod(LifetimeMethods.InitMethodsAndChanges, method => {
|
||||
it(`should ensure that init hooks are called once an only once with recursion in ${LifetimeMethods[method]} `,
|
||||
() => {
|
||||
// Ensure all the init methods are called once.
|
||||
ensureOneInit({childRecursion: method, childThrows: LifetimeMethods.None});
|
||||
});
|
||||
});
|
||||
forEachMethod(LifetimeMethods.All, method => {
|
||||
it(`should ensure that init hooks are called once an only once with a throw in ${LifetimeMethods[method]} `,
|
||||
() => {
|
||||
// Ensure all the init methods are called once.
|
||||
// the first cycle throws but the next cycle should complete the inits.
|
||||
ensureOneInit({childRecursion: LifetimeMethods.None, childThrows: method});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -699,33 +699,32 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
expect(cmp.prop).toEqual('two');
|
||||
});
|
||||
|
||||
if (getDOM().supportsDOMEvents()) {
|
||||
fixmeIvy('unknown').it(
|
||||
'should be checked when an async pipe requests a check', fakeAsync(() => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, PushCmpWithAsyncPipe], imports: [CommonModule]});
|
||||
const template = '<push-cmp-with-async #cmp></push-cmp-with-async>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixmeIvy(
|
||||
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template')
|
||||
.it('should be checked when an async pipe requests a check', fakeAsync(() => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, PushCmpWithAsyncPipe], imports: [CommonModule]});
|
||||
const template = '<push-cmp-with-async #cmp></push-cmp-with-async>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
tick();
|
||||
tick();
|
||||
|
||||
const cmp: PushCmpWithAsyncPipe =
|
||||
fixture.debugElement.children[0].references !['cmp'];
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
const cmp: PushCmpWithAsyncPipe =
|
||||
fixture.debugElement.children[0].references !['cmp'];
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
|
||||
cmp.resolve(2);
|
||||
tick();
|
||||
cmp.resolve(2);
|
||||
tick();
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(2);
|
||||
}));
|
||||
}
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(2);
|
||||
}));
|
||||
});
|
||||
|
||||
it('should create a component that injects an @Host', () => {
|
||||
|
@ -1871,79 +1870,83 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
|
||||
if (getDOM().supportsDOMEvents()) {
|
||||
describe('svg', () => {
|
||||
fixmeIvy('unknown').it('should support svg elements', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const template = '<svg><use xlink:href="Port" /></svg>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixmeIvy('FW-672: SVG attribute xlink:href is output as :xlink:href (extra ":")')
|
||||
.it('should support svg elements', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const template = '<svg><use xlink:href="Port" /></svg>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
const el = fixture.nativeElement;
|
||||
const svg = getDOM().childNodes(el)[0];
|
||||
const use = getDOM().childNodes(svg)[0];
|
||||
expect(getDOM().getProperty(<Element>svg, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/2000/svg');
|
||||
expect(getDOM().getProperty(<Element>use, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/2000/svg');
|
||||
const el = fixture.nativeElement;
|
||||
const svg = getDOM().childNodes(el)[0];
|
||||
const use = getDOM().childNodes(svg)[0];
|
||||
expect(getDOM().getProperty(<Element>svg, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/2000/svg');
|
||||
expect(getDOM().getProperty(<Element>use, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/2000/svg');
|
||||
|
||||
const firstAttribute = getDOM().getProperty(<Element>use, 'attributes')[0];
|
||||
expect(firstAttribute.name).toEqual('xlink:href');
|
||||
expect(firstAttribute.namespaceURI).toEqual('http://www.w3.org/1999/xlink');
|
||||
});
|
||||
const firstAttribute = getDOM().getProperty(<Element>use, 'attributes')[0];
|
||||
expect(firstAttribute.name).toEqual('xlink:href');
|
||||
expect(firstAttribute.namespaceURI).toEqual('http://www.w3.org/1999/xlink');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown').it('should support foreignObjects with document fragments', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const template =
|
||||
'<svg><foreignObject><xhtml:div><p>Test</p></xhtml:div></foreignObject></svg>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixmeIvy('FW-811: Align HTML namespaces between Ivy and Render2')
|
||||
.it('should support foreignObjects with document fragments', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const template =
|
||||
'<svg><foreignObject><xhtml:div><p>Test</p></xhtml:div></foreignObject></svg>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
const el = fixture.nativeElement;
|
||||
const svg = getDOM().childNodes(el)[0];
|
||||
const foreignObject = getDOM().childNodes(svg)[0];
|
||||
const p = getDOM().childNodes(foreignObject)[0];
|
||||
expect(getDOM().getProperty(<Element>svg, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/2000/svg');
|
||||
expect(getDOM().getProperty(<Element>foreignObject, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/2000/svg');
|
||||
expect(getDOM().getProperty(<Element>p, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/1999/xhtml');
|
||||
});
|
||||
const el = fixture.nativeElement;
|
||||
const svg = getDOM().childNodes(el)[0];
|
||||
const foreignObject = getDOM().childNodes(svg)[0];
|
||||
const p = getDOM().childNodes(foreignObject)[0];
|
||||
expect(getDOM().getProperty(<Element>svg, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/2000/svg');
|
||||
expect(getDOM().getProperty(<Element>foreignObject, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/2000/svg');
|
||||
expect(getDOM().getProperty(<Element>p, 'namespaceURI'))
|
||||
.toEqual('http://www.w3.org/1999/xhtml');
|
||||
});
|
||||
});
|
||||
|
||||
describe('attributes', () => {
|
||||
|
||||
fixmeIvy('unknown').it('should support attributes with namespace', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
|
||||
const template = '<svg:use xlink:href="#id" />';
|
||||
TestBed.overrideComponent(SomeCmp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(SomeCmp);
|
||||
fixmeIvy('FW-672: SVG attribute xlink:href is output as :xlink:href (extra ":")')
|
||||
.it('should support attributes with namespace', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
|
||||
const template = '<svg:use xlink:href="#id" />';
|
||||
TestBed.overrideComponent(SomeCmp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(SomeCmp);
|
||||
|
||||
const useEl = getDOM().firstChild(fixture.nativeElement);
|
||||
expect(getDOM().getAttributeNS(useEl, 'http://www.w3.org/1999/xlink', 'href'))
|
||||
.toEqual('#id');
|
||||
});
|
||||
const useEl = getDOM().firstChild(fixture.nativeElement);
|
||||
expect(getDOM().getAttributeNS(useEl, 'http://www.w3.org/1999/xlink', 'href'))
|
||||
.toEqual('#id');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown').it('should support binding to attributes with namespace', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
|
||||
const template = '<svg:use [attr.xlink:href]="value" />';
|
||||
TestBed.overrideComponent(SomeCmp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(SomeCmp);
|
||||
fixmeIvy('FW-672: SVG attribute xlink:href is output as :xlink:href (extra ":")')
|
||||
.it('should support binding to attributes with namespace', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
|
||||
const template = '<svg:use [attr.xlink:href]="value" />';
|
||||
TestBed.overrideComponent(SomeCmp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(SomeCmp);
|
||||
|
||||
const cmp = fixture.componentInstance;
|
||||
const useEl = getDOM().firstChild(fixture.nativeElement);
|
||||
const cmp = fixture.componentInstance;
|
||||
const useEl = getDOM().firstChild(fixture.nativeElement);
|
||||
|
||||
cmp.value = '#id';
|
||||
fixture.detectChanges();
|
||||
cmp.value = '#id';
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getDOM().getAttributeNS(useEl, 'http://www.w3.org/1999/xlink', 'href'))
|
||||
.toEqual('#id');
|
||||
expect(getDOM().getAttributeNS(useEl, 'http://www.w3.org/1999/xlink', 'href'))
|
||||
.toEqual('#id');
|
||||
|
||||
cmp.value = null;
|
||||
fixture.detectChanges();
|
||||
cmp.value = null;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getDOM().hasAttributeNS(useEl, 'http://www.w3.org/1999/xlink', 'href'))
|
||||
.toEqual(false);
|
||||
});
|
||||
expect(getDOM().hasAttributeNS(useEl, 'http://www.w3.org/1999/xlink', 'href'))
|
||||
.toEqual(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -81,21 +81,22 @@ describe('projection', () => {
|
|||
expect(main.nativeElement).toHaveText('');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown').it('should support multiple content tags', () => {
|
||||
TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]});
|
||||
TestBed.overrideComponent(MainComp, {
|
||||
set: {
|
||||
template: '<multiple-content-tags>' +
|
||||
'<div>B</div>' +
|
||||
'<div>C</div>' +
|
||||
'<div class="left">A</div>' +
|
||||
'</multiple-content-tags>'
|
||||
}
|
||||
});
|
||||
const main = TestBed.createComponent(MainComp);
|
||||
fixmeIvy('FW-833: Directive / projected node matching against class name')
|
||||
.it('should support multiple content tags', () => {
|
||||
TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]});
|
||||
TestBed.overrideComponent(MainComp, {
|
||||
set: {
|
||||
template: '<multiple-content-tags>' +
|
||||
'<div>B</div>' +
|
||||
'<div>C</div>' +
|
||||
'<div class="left">A</div>' +
|
||||
'</multiple-content-tags>'
|
||||
}
|
||||
});
|
||||
const main = TestBed.createComponent(MainComp);
|
||||
|
||||
expect(main.nativeElement).toHaveText('(A, BC)');
|
||||
});
|
||||
expect(main.nativeElement).toHaveText('(A, BC)');
|
||||
});
|
||||
|
||||
it('should redistribute only direct children', () => {
|
||||
TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]});
|
||||
|
|
Loading…
Reference in New Issue