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