test(ivy): add testing utility to replace loadDirective (#26316)

PR Close #26316
This commit is contained in:
Kara Erickson 2018-10-05 21:23:41 -07:00 committed by Jason Aden
parent 456f23f76a
commit b0879046b7
10 changed files with 60 additions and 47 deletions

View File

@ -99,7 +99,7 @@ export function getContext(target: any): LContext|null {
if (nodeIndex == -1) {
throw new Error('The provided directive was not found in the application');
}
directives = discoverDirectives(nodeIndex, lViewData);
directives = discoverDirectives(nodeIndex, lViewData, false);
} else {
nodeIndex = findViaNativeElement(lViewData, target as RElement);
if (nodeIndex == -1) {
@ -344,15 +344,18 @@ function getLNodeFromViewData(lViewData: LViewData, lElementIndex: number): LEle
* Returns a list of directives extracted from the given view. Does not contain
* the component.
*
* @param nodeIndex Index of node to search
* @param lViewData The target view data
* @param includeComponents Whether or not to include components in returned directives
*/
export function discoverDirectives(nodeIndex: number, lViewData: LViewData): any[]|null {
export function discoverDirectives(
nodeIndex: number, lViewData: LViewData, includeComponents: boolean): any[]|null {
const directivesAcrossView = lViewData[DIRECTIVES];
if (directivesAcrossView != null) {
const tNode = lViewData[TVIEW].data[nodeIndex] as TNode;
let directiveStartIndex = getDirectiveStartIndex(tNode);
const directiveEndIndex = getDirectiveEndIndex(tNode, directiveStartIndex);
if (tNode.flags & TNodeFlags.isComponent) directiveStartIndex++;
if (!includeComponents && tNode.flags & TNodeFlags.isComponent) directiveStartIndex++;
return directivesAcrossView.slice(directiveStartIndex, directiveEndIndex);
}
return null;

View File

@ -104,7 +104,7 @@ export function getDirectives(target: {}): Array<{}> {
const context = loadContext(target) !;
if (context.directives === undefined) {
context.directives = discoverDirectives(context.nodeIndex, context.lViewData);
context.directives = discoverDirectives(context.nodeIndex, context.lViewData, false);
}
return context.directives || [];

View File

@ -9,7 +9,7 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
import * as $r3$ from '../../../src/core_render3_private_export';
import {ComponentDef} from '../../../src/render3/interfaces/definition';
import {renderComponent, toHtml} from '../render_util';
import {getDirectiveOnNode, renderComponent, toHtml} from '../render_util';
/// See: `normative.md`
@ -161,7 +161,7 @@ describe('queries', () => {
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) {
$r3$.ɵelementStart(0, 'content-query-component');
contentQueryComp = $r3$.ɵloadDirective<ContentQueryComponent>(0);
contentQueryComp = getDirectiveOnNode(0);
$r3$.ɵelement(1, 'div', $e2_attrs$);
$r3$.ɵelementEnd();
}

View File

@ -9,11 +9,11 @@
import {SelectorFlags} from '@angular/core/src/render3/interfaces/projection';
import {AttributeMarker, detectChanges} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, loadDirective, projection, projectionDef, template, text} from '../../src/render3/instructions';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, projection, projectionDef, template, text} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition';
import {NgIf} from './common_with_def';
import {ComponentFixture, createComponent, renderComponent, toHtml} from './render_util';
import {ComponentFixture, createComponent, getDirectiveOnNode, renderComponent, toHtml} from './render_util';
describe('content projection', () => {
it('should project content', () => {
@ -452,7 +452,7 @@ describe('content projection', () => {
elementEnd();
// testing
childCmptInstance = loadDirective(0);
childCmptInstance = getDirectiveOnNode(0);
}
}, 4, 0, [Child]);
@ -504,7 +504,7 @@ describe('content projection', () => {
element(0, 'child');
// testing
childCmptInstance = loadDirective(0);
childCmptInstance = getDirectiveOnNode(0);
}
}, 1, 0, [Child]);
@ -556,7 +556,7 @@ describe('content projection', () => {
if (rf & RenderFlags.Create) {
elementStart(0, 'child');
{
childCmptInstance = loadDirective(0);
childCmptInstance = getDirectiveOnNode(0);
text(1, 'content');
}
elementEnd();
@ -730,7 +730,7 @@ describe('content projection', () => {
}
elementEnd();
// testing
parent = loadDirective(0);
parent = getDirectiveOnNode(0);
}
}, 3, 0, [Parent]);
@ -786,7 +786,7 @@ describe('content projection', () => {
if (rf & RenderFlags.Create) {
elementStart(0, 'child');
{
childCmptInstance = loadDirective(0);
childCmptInstance = getDirectiveOnNode(0);
text(1, 'content');
}
elementEnd();
@ -848,7 +848,7 @@ describe('content projection', () => {
elementEnd();
// testing
child = loadDirective(0);
child = getDirectiveOnNode(0);
}
}, 4, 0, [Child]);
@ -913,7 +913,7 @@ describe('content projection', () => {
elementEnd();
// testing
child = loadDirective(0);
child = getDirectiveOnNode(0);
}
}, 4, 0, [Child]);
@ -1012,7 +1012,7 @@ describe('content projection', () => {
if (rf & RenderFlags.Create) {
elementStart(0, 'child');
{
childCmptInstance = loadDirective(0);
childCmptInstance = getDirectiveOnNode(0);
text(1, 'content');
}
elementEnd();

View File

@ -21,7 +21,7 @@ import {LViewFlags} from '../../src/render3/interfaces/view';
import {ViewRef} from '../../src/render3/view_ref';
import {getRendererFactory2} from './imported_renderer2';
import {ComponentFixture, createComponent, createDirective, renderComponent, toHtml} from './render_util';
import {ComponentFixture, createComponent, createDirective, getDirectiveOnNode, renderComponent, toHtml} from './render_util';
import {NgIf} from './common_with_def';
import {TNODE} from '../../src/render3/interfaces/injector';
@ -1610,7 +1610,7 @@ describe('di', () => {
['myDirective', 'initial', 'exist', 'existValue', 'other', 'ignore']);
}
if (rf & RenderFlags.Update) {
myDirectiveInstance = loadDirective(0);
myDirectiveInstance = getDirectiveOnNode(0);
}
}, 1, 0, [MyDirective]);
@ -1631,7 +1631,7 @@ describe('di', () => {
elementContainerEnd();
}
if (rf & RenderFlags.Update) {
myDirectiveInstance = loadDirective(0);
myDirectiveInstance = getDirectiveOnNode(0);
}
}, 1, 0, [MyDirective]);

View File

@ -10,12 +10,12 @@ import {Directive, OnChanges, OnDestroy, Pipe, PipeTransform} from '@angular/cor
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {defineDirective, definePipe} from '../../src/render3/definition';
import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, load, loadDirective, text, textBinding} from '../../src/render3/instructions';
import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, load, text, textBinding} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition';
import {pipe, pipeBind1, pipeBind3, pipeBind4, pipeBindV} from '../../src/render3/pipe';
import {RenderLog, getRendererFactory2, patchLoggingRenderer2} from './imported_renderer2';
import {ComponentFixture, createComponent, renderToHtml} from './render_util';
import {ComponentFixture, createComponent, getDirectiveOnNode, renderToHtml} from './render_util';
let log: string[] = [];
@ -100,7 +100,7 @@ describe('pipe', () => {
}
if (rf & RenderFlags.Update) {
elementProperty(0, 'elprop', bind(pipeBind1(1, 1, ctx)));
directive = loadDirective(0);
directive = getDirectiveOnNode(0);
}
}
renderToHtml(Template, 'a', 2, 3, [MyDir], [DoublePipe]);

View File

@ -6,10 +6,10 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AttributeMarker, defineComponent, template} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, loadDirective, nextContext} from '../../src/render3/instructions';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, nextContext} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition';
import {pureFunction1, pureFunction2, pureFunction3, pureFunction4, pureFunction5, pureFunction6, pureFunction7, pureFunction8, pureFunctionV} from '../../src/render3/pure_function';
import {ComponentFixture, createComponent, renderToHtml} from '../../test/render3/render_util';
import {ComponentFixture, createComponent, getDirectiveOnNode, renderToHtml} from '../../test/render3/render_util';
import {NgIf} from './common_with_def';
describe('array literals', () => {
@ -176,7 +176,7 @@ describe('array literals', () => {
template: function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementStart(0, 'my-comp');
myComps.push(loadDirective(0));
myComps.push(getDirectiveOnNode(0));
elementEnd();
}
if (rf & RenderFlags.Update) {
@ -275,22 +275,22 @@ describe('array literals', () => {
function Template(rf: RenderFlags, c: any) {
if (rf & RenderFlags.Create) {
elementStart(0, 'my-comp');
f3Comp = loadDirective(0);
f3Comp = getDirectiveOnNode(0);
elementEnd();
elementStart(1, 'my-comp');
f4Comp = loadDirective(1);
f4Comp = getDirectiveOnNode(1);
elementEnd();
elementStart(2, 'my-comp');
f5Comp = loadDirective(2);
f5Comp = getDirectiveOnNode(2);
elementEnd();
elementStart(3, 'my-comp');
f6Comp = loadDirective(3);
f6Comp = getDirectiveOnNode(3);
elementEnd();
elementStart(4, 'my-comp');
f7Comp = loadDirective(4);
f7Comp = getDirectiveOnNode(4);
elementEnd();
elementStart(5, 'my-comp');
f8Comp = loadDirective(5);
f8Comp = getDirectiveOnNode(5);
elementEnd();
}
if (rf & RenderFlags.Update) {
@ -513,7 +513,7 @@ describe('object literals', () => {
let rf1 = embeddedViewStart(0, 1, 4);
if (rf1 & RenderFlags.Create) {
elementStart(0, 'object-comp');
objectComps.push(loadDirective(0));
objectComps.push(getDirectiveOnNode(0));
elementEnd();
}
if (rf1 & RenderFlags.Update) {

View File

@ -20,7 +20,7 @@ import {query, queryRefresh} from '../../src/render3/query';
import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound';
import {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def';
import {ComponentFixture, TemplateFixture, createComponent, createDirective, renderComponent} from './render_util';
import {ComponentFixture, TemplateFixture, createComponent, createDirective, renderComponent, getDirectiveOnNode} from './render_util';
@ -76,8 +76,8 @@ describe('query', () => {
elementEnd();
}
if (rf & RenderFlags.Update) {
child1 = loadDirective(0);
child2 = loadDirective(1);
child1 = getDirectiveOnNode(2);
child2 = getDirectiveOnNode(3);
}
},
4, 0, [Child], [],
@ -151,7 +151,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementStart(1, 'div', ['child', '', 'otherChild', '']);
{ otherChildInstance = loadDirective(1); }
{ otherChildInstance = getDirectiveOnNode(1, 1); }
elementEnd();
}
},
@ -684,7 +684,7 @@ describe('query', () => {
element(1, 'child', null, ['foo', '']);
}
if (rf & RenderFlags.Update) {
childInstance = loadDirective(0);
childInstance = getDirectiveOnNode(1);
}
},
3, 0, [Child], [],
@ -767,7 +767,7 @@ describe('query', () => {
element(1, 'div', ['child', ''], ['foo', 'child']);
}
if (rf & RenderFlags.Update) {
childInstance = loadDirective(0);
childInstance = getDirectiveOnNode(1);
}
},
3, 0, [Child], [],
@ -806,8 +806,8 @@ describe('query', () => {
element(1, 'div', ['child1', '', 'child2', ''], ['foo', 'child1', 'bar', 'child2']);
}
if (rf & RenderFlags.Update) {
child1Instance = loadDirective(0);
child2Instance = loadDirective(1);
child1Instance = getDirectiveOnNode(1, 0);
child2Instance = getDirectiveOnNode(1, 1);
}
},
4, 0, [Child1, Child2], [],
@ -846,7 +846,7 @@ describe('query', () => {
element(2, 'div', ['child', ''], ['foo', 'child', 'bar', 'child']);
}
if (rf & RenderFlags.Update) {
childInstance = loadDirective(0);
childInstance = getDirectiveOnNode(2);
}
},
5, 0, [Child], [],
@ -928,7 +928,7 @@ describe('query', () => {
div = loadElement(1).native;
}
if (rf & RenderFlags.Update) {
childInstance = loadDirective(0);
childInstance = getDirectiveOnNode(1);
}
},
4, 0, [Child], [],

View File

@ -15,15 +15,16 @@ import {stringifyElement} from '@angular/platform-browser/testing/src/browser_ut
import {Injector} from '../../src/di/injector';
import {R3_CHANGE_DETECTOR_REF_FACTORY, R3_ELEMENT_REF_FACTORY, R3_TEMPLATE_REF_FACTORY, R3_VIEW_CONTAINER_REF_FACTORY} from '../../src/ivy_switch/runtime/ivy_switch_on';
import {CreateComponentOptions} from '../../src/render3/component';
import {getContext, isComponentInstance} from '../../src/render3/context_discovery';
import {discoverDirectives, getContext, isComponentInstance} from '../../src/render3/context_discovery';
import {extractDirectiveDef, extractPipeDef} from '../../src/render3/definition';
import {NG_ELEMENT_ID} from '../../src/render3/fields';
import {ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, PublicFeature, RenderFlags, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index';
import {renderTemplate} from '../../src/render3/instructions';
import {_getViewData, renderTemplate} from '../../src/render3/instructions';
import {DirectiveDefList, DirectiveTypesOrFactory, PipeDef, PipeDefList, PipeTypesOrFactory} from '../../src/render3/interfaces/definition';
import {LElementNode} from '../../src/render3/interfaces/node';
import {PlayerHandler} from '../../src/render3/interfaces/player';
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer';
import {HEADER_OFFSET} from '../../src/render3/interfaces/view';
import {Sanitizer} from '../../src/sanitization/security';
import {Type} from '../../src/type';
@ -290,6 +291,15 @@ export function createDirective(
};
}
/** Gets the directive on the given node at the given index */
export function getDirectiveOnNode(nodeIndex: number, dirIndex: number = 0) {
const directives = discoverDirectives(nodeIndex + HEADER_OFFSET, _getViewData(), true);
if (directives == null) {
throw new Error(`No directives exist on node in slot ${nodeIndex}`);
}
return directives[dirIndex];
}
// Verify that DOM is a type of render. This is here for error checking only and has no use.
export const renderer: Renderer3 = null as any as Document;

View File

@ -19,7 +19,7 @@ import {pipe, pipeBind1} from '../../src/render3/pipe';
import {NgForOf} from '../../test/render3/common_with_def';
import {getRendererFactory2} from './imported_renderer2';
import {ComponentFixture, TemplateFixture, createComponent} from './render_util';
import {ComponentFixture, TemplateFixture, createComponent, getDirectiveOnNode} from './render_util';
describe('ViewContainerRef', () => {
let directiveInstance: DirectiveWithVCRef|null;
@ -161,8 +161,8 @@ describe('ViewContainerRef', () => {
element(3, 'div', ['vcref', '']);
// for testing only:
firstDir = loadDirective(0);
secondDir = loadDirective(1);
firstDir = getDirectiveOnNode(2);
secondDir = getDirectiveOnNode(3);
}
function update() {