fix(ivy): inconsistent value returned by DebugNode.context (#31442)

Fixes Ivy's return value for `DebugNode.context` not being consistent for the case where there is both a structural directive and a component on a node. In `ViewEngine` the instance of the component would be returned, whereas in Ivy the context of the directive is returned.

Also adds a couple of extra test cases for how `DebugNode.context` deals with directives.

This PR resolves FW-1343.

PR Close #31442
This commit is contained in:
crisbeto 2019-07-07 12:17:37 +02:00 committed by Jason Aden
parent 23e0d65471
commit 989ebcbb62
2 changed files with 48 additions and 1 deletions

View File

@ -220,7 +220,9 @@ class DebugNode__POST_R3__ implements DebugNode {
return nativeElement &&
(getComponent(nativeElement as Element) || getViewComponent(nativeElement));
}
get context(): any { return getContext(this.nativeNode as Element); }
get context(): any {
return getComponent(this.nativeNode as Element) || getContext(this.nativeNode as Element);
}
get listeners(): DebugEventListener[] {
return getListeners(this.nativeNode as Element).filter(isBrowserEvents);

View File

@ -7,6 +7,7 @@
*/
import {CommonModule, NgIfContext} from '@angular/common';
import {Component, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA, Renderer2, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core';
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
@ -644,6 +645,50 @@ class TestCmptWithPropBindings {
});
});
describe('context on DebugNode', () => {
it('should return component associated with the node if both a structural directive and a component match the node',
() => {
@Component({selector: 'example-component', template: ''})
class ExampleComponent {
}
TestBed.configureTestingModule(
{imports: [CommonModule], declarations: [ExampleComponent]});
TestBed.overrideTemplate(
TestApp, '<example-component *ngIf="true"></example-component>');
const fixture = TestBed.createComponent(TestApp);
fixture.detectChanges();
const debugNode = fixture.debugElement.query(By.directive(ExampleComponent));
expect(debugNode.context instanceof ExampleComponent).toBe(true);
});
it('should return structural directive context if there is a structural directive on the node',
() => {
TestBed.configureTestingModule({imports: [CommonModule]});
TestBed.overrideTemplate(TestApp, '<span *ngIf="true"></span>');
const fixture = TestBed.createComponent(TestApp);
fixture.detectChanges();
const debugNode = fixture.debugElement.query(By.css('span'));
expect(debugNode.context instanceof NgIfContext).toBe(true);
});
it('should return the containing component if there is no structural directive or component on the node',
() => {
TestBed.configureTestingModule({declarations: [MyDir]});
TestBed.overrideTemplate(TestApp, '<span mydir></span>');
const fixture = TestBed.createComponent(TestApp);
fixture.detectChanges();
const debugNode = fixture.debugElement.query(By.directive(MyDir));
expect(debugNode.context instanceof TestApp).toBe(true);
});
});
it('should be able to query for elements that are not in the same DOM tree anymore', () => {
fixture = TestBed.createComponent(SimpleContentComp);
fixture.detectChanges();