test(core): animation renderer factory in render3 (#20855)
PR Close #20855
This commit is contained in:
parent
bbdea96a66
commit
764fea1344
|
@ -15,6 +15,10 @@ ts_library(
|
|||
"//packages:types",
|
||||
"//packages/core",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-browser/animations",
|
||||
"//packages/animations",
|
||||
"//packages/animations/browser",
|
||||
"//packages/animations/browser/testing",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -170,6 +170,6 @@ describe('encapsulation', () => {
|
|||
renderComponent(WrapperComponentWith, getRendererFactory2(document));
|
||||
expect(containerEl.outerHTML)
|
||||
.toEqual(
|
||||
'<div host="" _nghost-c1=""><leaf _ngcontent-c1="" _nghost-c2=""><span _ngcontent-c2="">bar</span></leaf></div>');
|
||||
'<div host="" _nghost-c2=""><leaf _ngcontent-c2="" _nghost-c3=""><span _ngcontent-c3="">bar</span></leaf></div>');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,8 +6,12 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ɵAnimationEngine, ɵNoopAnimationStyleNormalizer} from '@angular/animations/browser';
|
||||
import {MockAnimationDriver} from '@angular/animations/browser/testing';
|
||||
import {EventEmitter, NgZone, RendererFactory2} from '@angular/core';
|
||||
import {EventManager, ɵDomEventsPlugin, ɵDomRendererFactory2, ɵDomSharedStylesHost} from '@angular/platform-browser';
|
||||
import {ɵAnimationRendererFactory} from '@angular/platform-browser/animations';
|
||||
|
||||
|
||||
// Adapted renderer: it creates a Renderer2 instance and adapts it to Renderer3
|
||||
// TODO: remove once this code is in angular/angular
|
||||
|
@ -52,3 +56,11 @@ export function getRendererFactory2(document: any): RendererFactory2 {
|
|||
new EventManager([new SimpleDomEventsPlugin(document, fakeNgZone)], fakeNgZone);
|
||||
return new ɵDomRendererFactory2(eventManager, new ɵDomSharedStylesHost(document));
|
||||
}
|
||||
|
||||
export function getAnimationRendererFactory2(document: any): RendererFactory2 {
|
||||
const fakeNgZone: NgZone = new NoopNgZone();
|
||||
return new ɵAnimationRendererFactory(
|
||||
getRendererFactory2(document),
|
||||
new ɵAnimationEngine(new MockAnimationDriver(), new ɵNoopAnimationStyleNormalizer()),
|
||||
fakeNgZone);
|
||||
}
|
||||
|
|
|
@ -6,8 +6,12 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
// Needed to run animation tests
|
||||
require('zone.js/dist/zone-node.js');
|
||||
|
||||
if (typeof window == 'undefined') {
|
||||
const createWindow = require('domino').createWindow;
|
||||
const domino = require('domino');
|
||||
const createWindow = domino.createWindow;
|
||||
const window = createWindow('', 'http://localhost');
|
||||
(global as any).document = window.document;
|
||||
|
||||
|
@ -16,4 +20,8 @@ if (typeof window == 'undefined') {
|
|||
// It fails with Domino with TypeError: Cannot assign to read only property
|
||||
// 'stopImmediatePropagation' of object '#<Event>'
|
||||
(global as any).Event = null;
|
||||
|
||||
// For animation tests, see
|
||||
// https://github.com/angular/angular/blob/master/packages/animations/browser/src/render/shared.ts#L140
|
||||
(global as any).Element = domino.impl.Element;
|
||||
}
|
||||
|
|
|
@ -33,8 +33,12 @@ requestAnimationFrame.flush = function() {
|
|||
|
||||
export function resetDOM() {
|
||||
requestAnimationFrame.queue = [];
|
||||
if (containerEl) {
|
||||
document.body.removeChild(containerEl);
|
||||
}
|
||||
containerEl = document.createElement('div');
|
||||
containerEl.setAttribute('host', '');
|
||||
document.body.appendChild(containerEl);
|
||||
host = null;
|
||||
// TODO: assert that the global state is clean (e.g. ngData, previousOrParentNode, etc)
|
||||
}
|
||||
|
|
|
@ -6,13 +6,15 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RendererType2} from '@angular/core';
|
||||
import {AnimationEvent} from '@angular/animations';
|
||||
import {MockAnimationDriver, MockAnimationPlayer} from '@angular/animations/browser/testing';
|
||||
|
||||
import {D, E, e} from '../../src/render3';
|
||||
import {T, defineComponent, detectChanges} from '../../src/render3/index';
|
||||
import {RendererType2, ViewEncapsulation} from '../../src/core';
|
||||
import {D, E, L, T, b, defineComponent, detectChanges, e, p} from '../../src/render3';
|
||||
import {createRendererType2} from '../../src/view';
|
||||
|
||||
import {getRendererFactory2} from './imported_renderer2';
|
||||
import {document, renderComponent, renderToHtml, resetDOM} from './render_util';
|
||||
import {getAnimationRendererFactory2, getRendererFactory2} from './imported_renderer2';
|
||||
import {containerEl, document, renderComponent, renderToHtml} from './render_util';
|
||||
|
||||
describe('renderer factory lifecycle', () => {
|
||||
let logs: string[] = [];
|
||||
|
@ -104,3 +106,99 @@ describe('renderer factory lifecycle', () => {
|
|||
});
|
||||
|
||||
});
|
||||
|
||||
describe('animation renderer factory', () => {
|
||||
let eventLogs: string[] = [];
|
||||
function getLog(): MockAnimationPlayer[] {
|
||||
return MockAnimationDriver.log as MockAnimationPlayer[];
|
||||
}
|
||||
|
||||
function resetLog() { MockAnimationDriver.log = []; }
|
||||
|
||||
beforeEach(() => {
|
||||
eventLogs = [];
|
||||
resetLog();
|
||||
});
|
||||
|
||||
class SomeComponent {
|
||||
static ngComponentDef = defineComponent({
|
||||
type: SomeComponent,
|
||||
tag: 'some-component',
|
||||
template: function(ctx: SomeComponent, cm: boolean) {
|
||||
if (cm) {
|
||||
T(0, 'foo');
|
||||
}
|
||||
},
|
||||
factory: () => new SomeComponent
|
||||
});
|
||||
}
|
||||
|
||||
class SomeComponentWithAnimation {
|
||||
exp: string;
|
||||
callback(event: AnimationEvent) {
|
||||
eventLogs.push(`${event.fromState ? event.fromState : event.toState} - ${event.phaseName}`);
|
||||
}
|
||||
static ngComponentDef = defineComponent({
|
||||
type: SomeComponentWithAnimation,
|
||||
tag: 'some-component',
|
||||
template: function(ctx: SomeComponentWithAnimation, cm: boolean) {
|
||||
if (cm) {
|
||||
E(0, 'div');
|
||||
{
|
||||
L('@myAnimation.start', ctx.callback.bind(ctx));
|
||||
L('@myAnimation.done', ctx.callback.bind(ctx));
|
||||
T(1, 'foo');
|
||||
}
|
||||
e();
|
||||
}
|
||||
p(0, '@myAnimation', b(ctx.exp));
|
||||
},
|
||||
factory: () => new SomeComponentWithAnimation,
|
||||
rendererType: createRendererType2({
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
styles: [],
|
||||
data: {
|
||||
animation: [{
|
||||
type: 7,
|
||||
name: 'myAnimation',
|
||||
definitions: [{
|
||||
type: 1,
|
||||
expr: '* => on',
|
||||
animation:
|
||||
[{type: 4, styles: {type: 6, styles: {opacity: 1}, offset: null}, timings: 10}],
|
||||
options: null
|
||||
}],
|
||||
options: {}
|
||||
}]
|
||||
}
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
it('should work with components without animations', () => {
|
||||
renderComponent(SomeComponent, getAnimationRendererFactory2(document));
|
||||
expect(containerEl.innerHTML).toEqual('foo');
|
||||
});
|
||||
|
||||
it('should work with animated components', (done) => {
|
||||
const factory = getAnimationRendererFactory2(document);
|
||||
const component = renderComponent(SomeComponentWithAnimation, factory);
|
||||
expect(containerEl.innerHTML)
|
||||
.toEqual('<div class="ng-tns-c1-0 ng-trigger ng-trigger-myAnimation">foo</div>');
|
||||
|
||||
component.exp = 'on';
|
||||
detectChanges(component);
|
||||
|
||||
const [player] = getLog();
|
||||
expect(player.keyframes).toEqual([
|
||||
{opacity: '*', offset: 0},
|
||||
{opacity: 1, offset: 1},
|
||||
]);
|
||||
player.finish();
|
||||
|
||||
factory.whenRenderingDone !().then(() => {
|
||||
expect(eventLogs).toEqual(['void - start', 'void - done', 'on - start', 'on - done']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue