Skip to content

Commit 2110ec6

Browse files
committed
fix(core): update testing lib
1 parent 4a84907 commit 2110ec6

File tree

3 files changed

+71
-53
lines changed

3 files changed

+71
-53
lines changed

libs/core/testing/src/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
1-
// export * from './lib/test-bed';
2-
// export * from './lib/test-canvas';
3-
4-
export default void 0;
1+
export * from './lib/test-bed';
2+
export * from './lib/test-canvas';

libs/core/testing/src/lib/test-bed.ts

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
1-
import { CUSTOM_ELEMENTS_SCHEMA, provideEnvironmentInitializer, Type } from '@angular/core';
1+
import {
2+
ComponentRef,
3+
CUSTOM_ELEMENTS_SCHEMA,
4+
provideEnvironmentInitializer,
5+
RendererFactory2,
6+
Type,
7+
} from '@angular/core';
28
import { ComponentFixture, TestBed } from '@angular/core/testing';
9+
import { ɵDomRendererFactory2 as DomRendererFactory2 } from '@angular/platform-browser';
310
import {
4-
getLocalState,
11+
getInstanceState,
512
injectCanvasRootInitializer,
613
NGT_STORE,
7-
NgtAnyRecord,
8-
NgtCanvasOptions,
9-
NgtEventHandlers,
10-
NgtInstanceNode,
11-
NgtSignalStore,
12-
NgtState,
13-
provideStore,
14+
type NgtAnyRecord,
15+
type NgtCanvasOptions,
16+
type NgtEventHandlers,
17+
type NgtInstanceNode,
18+
NgtRendererFactory2,
19+
type NgtState,
20+
type SignalState,
21+
storeFactory,
1422
} from 'angular-three';
15-
import { Object3D } from 'three';
23+
import type * as THREE from 'three';
1624
import { NgtTestCanvas } from './test-canvas';
1725
import { createMockCanvas } from './utils/mock-canvas';
1826

@@ -26,6 +34,7 @@ export class NgtTestBed {
2634
static create<T extends Type<any>>(
2735
sceneGraph: T,
2836
{
37+
sceneGraphInputs = {},
2938
mockCanvasOptions = {},
3039
canvasConfiguration = {},
3140
errorOnUnknownElements,
@@ -35,6 +44,7 @@ export class NgtTestBed {
3544
teardown,
3645
deferBlockBehavior,
3746
}: {
47+
sceneGraphInputs?: NgtAnyRecord;
3848
mockCanvasOptions?: { width?: number; height?: number; beforeReturn?: (canvas: HTMLCanvasElement) => void };
3949
canvasConfiguration?: Partial<Omit<NgtCanvasOptions, 'frameloop' | 'size' | 'events'>>;
4050
} & Omit<Parameters<TestBed['configureTestingModule']>[0], 'schemas'> = {},
@@ -43,23 +53,28 @@ export class NgtTestBed {
4353

4454
const fixture = TestBed.configureTestingModule({
4555
providers: [
46-
provideStore(),
56+
{
57+
provide: RendererFactory2,
58+
useFactory: (delegate: RendererFactory2) => new NgtRendererFactory2(delegate),
59+
deps: [DomRendererFactory2],
60+
},
61+
{ provide: NGT_STORE, useFactory: storeFactory },
4762
provideEnvironmentInitializer(() => {
4863
const initializerFn = (() => {
4964
const initRoot = injectCanvasRootInitializer();
5065

5166
return () => {
5267
const configurator = initRoot(mockedCanvas);
5368
configurator.configure({
69+
...canvasConfiguration,
70+
events: undefined,
5471
frameloop: 'never',
5572
size: {
5673
width: mockCanvasOptions.width ?? mockedCanvas.width ?? 1280,
5774
height: mockCanvasOptions.height ?? mockedCanvas.height ?? 800,
5875
top: 0,
5976
left: 0,
6077
},
61-
...canvasConfiguration,
62-
events: undefined,
6378
});
6479
};
6580
})();
@@ -76,6 +91,7 @@ export class NgtTestBed {
7691
}).createComponent(NgtTestCanvas);
7792

7893
fixture.componentRef.setInput('sceneGraph', sceneGraph);
94+
fixture.componentRef.setInput('sceneGraphInputs', sceneGraphInputs);
7995
fixture.detectChanges();
8096

8197
const store = TestBed.inject(NGT_STORE);
@@ -85,8 +101,9 @@ export class NgtTestBed {
85101
return {
86102
store,
87103
fixture,
104+
sceneGraphComponentRef: fixture.componentInstance.sceneRef as ComponentRef<T>,
88105
scene: store.snapshot.scene,
89-
sceneInstanceNode: getLocalState(store.snapshot.scene)!,
106+
sceneInstanceNode: getInstanceState(store.snapshot.scene)!,
90107
canvas: mockedCanvas,
91108
destroy: fixture.componentInstance.destroy.bind(fixture.componentInstance),
92109
fireEvent: this.createEventFirer(store, fixture),
@@ -95,12 +112,12 @@ export class NgtTestBed {
95112
};
96113
}
97114

98-
static createToGraph(store: NgtSignalStore<NgtState>) {
115+
static createToGraph(store: SignalState<NgtState>) {
99116
function graphify(type: string, name: string, children: NgtTestGraphedObject[]): NgtTestGraphedObject {
100117
return { type, name, children };
101118
}
102119

103-
function toGraph(node: Object3D): NgtTestGraphedObject[] {
120+
function toGraph(node: THREE.Object3D): NgtTestGraphedObject[] {
104121
return node.children.map((child) => graphify(child.type, child.name || '', toGraph(child)));
105122
}
106123

@@ -110,7 +127,7 @@ export class NgtTestBed {
110127
};
111128
}
112129

113-
static createAdvance(store: NgtSignalStore<NgtState>) {
130+
static createAdvance(store: SignalState<NgtState>) {
114131
return async (frames: number, delta: number | number[] = 1) => {
115132
const state = store.snapshot;
116133
const subscribers = state.internal.subscribers;
@@ -141,17 +158,17 @@ export class NgtTestBed {
141158
};
142159
}
143160

144-
static createEventFirer(store: NgtSignalStore<NgtState>, fixture: ComponentFixture<NgtTestCanvas>) {
161+
static createEventFirer(store: SignalState<NgtState>, fixture: ComponentFixture<NgtTestCanvas>) {
145162
let autoDetectChanges = true;
146163

147164
async function fireEvent(el: NgtInstanceNode, eventName: keyof NgtEventHandlers, eventData: NgtAnyRecord = {}) {
148-
const localState = getLocalState(el);
149-
if (!localState) {
165+
const instanceState = getInstanceState(el);
166+
if (!instanceState) {
150167
console.warn(`[NGT Test] ${el} has no local state`);
151168
return;
152169
}
153170

154-
const handler = localState.handlers[eventName];
171+
const handler = instanceState.handlers[eventName];
155172
if (!handler) {
156173
console.warn(`[NGT Test] ${el} has no ${eventName} handler`);
157174
return;
Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,59 @@
11
import {
2-
afterNextRender,
32
ChangeDetectionStrategy,
43
Component,
54
ComponentRef,
6-
createEnvironmentInjector,
75
DestroyRef,
86
effect,
9-
EnvironmentInjector,
107
inject,
11-
Injector,
128
input,
139
Type,
10+
viewChild,
1411
ViewContainerRef,
1512
} from '@angular/core';
16-
import { extend, injectStore, provideNgtRenderer } from 'angular-three';
13+
import { extend, injectStore, NGT_CANVAS_CONTENT_FLAG, NGT_RENDERER_NODE_FLAG, NgtAnyRecord } from 'angular-three';
1714
import * as THREE from 'three';
1815

1916
@Component({
2017
selector: 'ngt-test-canvas',
21-
template: '',
18+
template: `
19+
<ng-container #anchor />
20+
`,
2221
changeDetection: ChangeDetectionStrategy.OnPush,
2322
})
2423
export class NgtTestCanvas {
25-
sceneGraph = input.required<Type<any>>();
24+
sceneGraph = input.required<Type<unknown>>();
25+
sceneGraphInputs = input<NgtAnyRecord>({});
2626

27-
private ref?: ComponentRef<any>;
28-
private environmentInjector?: EnvironmentInjector;
27+
private anchorRef = viewChild.required('anchor', { read: ViewContainerRef });
28+
29+
private store = injectStore();
30+
31+
sceneRef?: ComponentRef<unknown>;
2932

3033
constructor() {
3134
extend(THREE);
3235

33-
const vcr = inject(ViewContainerRef);
34-
const parentEnvironmentInjector = inject(EnvironmentInjector);
35-
const parentInjector = inject(Injector);
36-
const store = injectStore();
36+
effect(() => {
37+
const anchor = this.anchorRef();
38+
const sceneGraph = this.sceneGraph();
39+
if (!sceneGraph) return;
40+
41+
const sceneGraphInputs = this.sceneGraphInputs();
42+
43+
const anchorComment = anchor.element.nativeElement;
44+
anchorComment.data = NGT_CANVAS_CONTENT_FLAG;
45+
anchorComment[NGT_CANVAS_CONTENT_FLAG] = this.store;
46+
if (anchorComment[NGT_RENDERER_NODE_FLAG]) {
47+
anchorComment[NGT_RENDERER_NODE_FLAG][5] = this.store.snapshot.scene;
48+
}
3749

38-
afterNextRender(() => {
39-
effect(
40-
() => {
41-
const sceneGraph = this.sceneGraph();
50+
this.sceneRef = anchor.createComponent(sceneGraph);
4251

43-
this.environmentInjector = createEnvironmentInjector([provideNgtRenderer(store)], parentEnvironmentInjector);
52+
for (const key in sceneGraphInputs) {
53+
this.sceneRef.setInput(key, sceneGraphInputs[key]);
54+
}
4455

45-
this.ref = vcr.createComponent(sceneGraph, {
46-
environmentInjector: this.environmentInjector,
47-
injector: parentInjector,
48-
});
49-
this.ref.changeDetectorRef.detectChanges();
50-
},
51-
{ injector: parentInjector },
52-
);
56+
this.sceneRef.changeDetectorRef.detectChanges();
5357
});
5458

5559
inject(DestroyRef).onDestroy(() => {
@@ -58,7 +62,6 @@ export class NgtTestCanvas {
5862
}
5963

6064
destroy() {
61-
this.environmentInjector?.destroy();
62-
this.ref?.destroy();
65+
this.sceneRef?.destroy();
6366
}
6467
}

0 commit comments

Comments
 (0)