test(ivy): add ComponentFixture for cleaner tests. (#22719)
PR Close #22719
This commit is contained in:
parent
f5a98f41fe
commit
ae19d071bb
|
@ -65,6 +65,7 @@ export {
|
||||||
embeddedViewEnd as v,
|
embeddedViewEnd as v,
|
||||||
detectChanges,
|
detectChanges,
|
||||||
markDirty,
|
markDirty,
|
||||||
|
tick,
|
||||||
} from './instructions';
|
} from './instructions';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
|
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
|
||||||
|
|
||||||
import {CreateComponentOptions} from '../../src/render3/component';
|
import {CreateComponentOptions} from '../../src/render3/component';
|
||||||
import {ComponentTemplate, ComponentType, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent} from '../../src/render3/index';
|
import {ComponentTemplate, ComponentType, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index';
|
||||||
import {NG_HOST_SYMBOL, createLNode, createLView, renderTemplate} from '../../src/render3/instructions';
|
import {NG_HOST_SYMBOL, createLNode, createLView, renderTemplate} from '../../src/render3/instructions';
|
||||||
import {DirectiveDefArgs} from '../../src/render3/interfaces/definition';
|
import {DirectiveDefArgs} from '../../src/render3/interfaces/definition';
|
||||||
import {LElementNode, LNodeFlags} from '../../src/render3/interfaces/node';
|
import {LElementNode, LNodeFlags} from '../../src/render3/interfaces/node';
|
||||||
|
@ -17,6 +17,24 @@ import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from
|
||||||
|
|
||||||
import {getRendererFactory2} from './imported_renderer2';
|
import {getRendererFactory2} from './imported_renderer2';
|
||||||
|
|
||||||
|
export abstract class BaseFixture {
|
||||||
|
hostElement: HTMLElement;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.hostElement = document.createElement('div');
|
||||||
|
this.hostElement.setAttribute('fixture', 'mark');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current state of rendered HTML.
|
||||||
|
*/
|
||||||
|
get html(): string {
|
||||||
|
return (this.hostElement as any as Element)
|
||||||
|
.innerHTML.replace(/ style=""/g, '')
|
||||||
|
.replace(/ class=""/g, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
/**
|
/**
|
||||||
* Fixture for testing template functions in a convenient way.
|
* Fixture for testing template functions in a convenient way.
|
||||||
|
@ -26,11 +44,8 @@ function noop() {}
|
||||||
* - maintaining the template state between invocations,
|
* - maintaining the template state between invocations,
|
||||||
* - access to the render `html`.
|
* - access to the render `html`.
|
||||||
*/
|
*/
|
||||||
export class TemplateFixture {
|
export class TemplateFixture extends BaseFixture {
|
||||||
hostElement: HTMLElement;
|
|
||||||
|
|
||||||
hostNode: LElementNode;
|
hostNode: LElementNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param createBlock Instructions which go into the creation block:
|
* @param createBlock Instructions which go into the creation block:
|
||||||
|
@ -39,8 +54,8 @@ export class TemplateFixture {
|
||||||
* `if (creationMode) { ... } __here__`.
|
* `if (creationMode) { ... } __here__`.
|
||||||
*/
|
*/
|
||||||
constructor(private createBlock: () => void, private updateBlock: () => void = noop) {
|
constructor(private createBlock: () => void, private updateBlock: () => void = noop) {
|
||||||
|
super();
|
||||||
this.updateBlock = updateBlock || function() {};
|
this.updateBlock = updateBlock || function() {};
|
||||||
this.hostElement = document.createElement('div');
|
|
||||||
this.hostNode = renderTemplate(this.hostElement, (ctx: any, cm: boolean) => {
|
this.hostNode = renderTemplate(this.hostElement, (ctx: any, cm: boolean) => {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
this.createBlock();
|
this.createBlock();
|
||||||
|
@ -59,15 +74,44 @@ export class TemplateFixture {
|
||||||
this.hostNode.native, updateBlock || this.updateBlock, null !, domRendererFactory3,
|
this.hostNode.native, updateBlock || this.updateBlock, null !, domRendererFactory3,
|
||||||
this.hostNode);
|
this.hostNode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Current state of rendered HTML.
|
/**
|
||||||
*/
|
* Fixture for testing Components in a convenient way.
|
||||||
get html(): string {
|
*/
|
||||||
return (this.hostNode.native as any as Element).innerHTML.replace(/ style=""/g, '');
|
export class ComponentFixture<T> extends BaseFixture {
|
||||||
|
component: T;
|
||||||
|
requestAnimationFrame: {(fn: () => void): void; flush(): void; queue: (() => void)[];};
|
||||||
|
|
||||||
|
constructor(private componentType: ComponentType<T>) {
|
||||||
|
super();
|
||||||
|
this.requestAnimationFrame = function(fn: () => void) {
|
||||||
|
requestAnimationFrame.queue.push(fn);
|
||||||
|
} as any;
|
||||||
|
this.requestAnimationFrame.queue = [];
|
||||||
|
this.requestAnimationFrame.flush = function() {
|
||||||
|
while (requestAnimationFrame.queue.length) {
|
||||||
|
requestAnimationFrame.queue.shift() !();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.component = _renderComponent(componentType, {
|
||||||
|
host: this.hostElement,
|
||||||
|
scheduler: this.requestAnimationFrame,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
update(): void {
|
||||||
|
tick(this.component);
|
||||||
|
this.requestAnimationFrame.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The methods below use global state and we should stop using them.
|
||||||
|
// Fixtures above are preferred way of testing Components and Templates
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
export const document = ((global || window) as any).document;
|
export const document = ((global || window) as any).document;
|
||||||
export let containerEl: HTMLElement = null !;
|
export let containerEl: HTMLElement = null !;
|
||||||
|
@ -104,6 +148,9 @@ export function resetDOM() {
|
||||||
// TODO: assert that the global state is clean (e.g. ngData, previousOrParentNode, etc)
|
// TODO: assert that the global state is clean (e.g. ngData, previousOrParentNode, etc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use `TemplateFixture` or `ComponentFixture`
|
||||||
|
*/
|
||||||
export function renderToHtml(
|
export function renderToHtml(
|
||||||
template: ComponentTemplate<any>, ctx: any, providedRendererFactory?: RendererFactory3) {
|
template: ComponentTemplate<any>, ctx: any, providedRendererFactory?: RendererFactory3) {
|
||||||
host = renderTemplate(
|
host = renderTemplate(
|
||||||
|
@ -113,6 +160,9 @@ export function renderToHtml(
|
||||||
|
|
||||||
beforeEach(resetDOM);
|
beforeEach(resetDOM);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use `TemplateFixture` or `ComponentFixture`
|
||||||
|
*/
|
||||||
export function renderComponent<T>(type: ComponentType<T>, opts?: CreateComponentOptions): T {
|
export function renderComponent<T>(type: ComponentType<T>, opts?: CreateComponentOptions): T {
|
||||||
return _renderComponent(type, {
|
return _renderComponent(type, {
|
||||||
rendererFactory: opts && opts.rendererFactory || testRendererFactory,
|
rendererFactory: opts && opts.rendererFactory || testRendererFactory,
|
||||||
|
@ -122,6 +172,9 @@ export function renderComponent<T>(type: ComponentType<T>, opts?: CreateComponen
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use `TemplateFixture` or `ComponentFixture`
|
||||||
|
*/
|
||||||
export function toHtml<T>(componentOrElement: T | RElement): string {
|
export function toHtml<T>(componentOrElement: T | RElement): string {
|
||||||
const node = (componentOrElement as any)[NG_HOST_SYMBOL] as LElementNode;
|
const node = (componentOrElement as any)[NG_HOST_SYMBOL] as LElementNode;
|
||||||
if (node) {
|
if (node) {
|
||||||
|
|
Loading…
Reference in New Issue