Skip to content

Commit 518cb8d

Browse files
authored
Merge pull request #76 from radical-data/tests
test: refactor test setup
2 parents da4c448 + e1eb281 commit 518cb8d

6 files changed

Lines changed: 208 additions & 208 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ jobs:
2222
- run: pnpm install --frozen-lockfile
2323
- run: pnpm lint
2424
- run: pnpm check
25+
- run: pnpm test

src/lib/engine/HydraEngine.feedback.test.ts

Lines changed: 22 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,20 @@
11
import { describe, expect, it } from 'vitest';
22

33
import type { IREdge, IRNode } from '../types.js';
4-
import type { TransformMeta } from './graphValidation.js';
4+
import {
5+
createFakeGeneratorsForFeedback,
6+
createFakeHydraOutputsOnly
7+
} from './__testutils__/fakeHydra.js';
8+
import { createTestMeta } from './__testutils__/meta.js';
59
import { HydraEngine } from './HydraEngine.js';
610

7-
function createMeta(): TransformMeta {
8-
const arityByName = new Map<string, 0 | 1 | 2>();
9-
const kindByName = new Map<string, 'src' | 'coord' | 'color' | 'combine' | 'combineCoord'>();
10-
const paramIdsByName = new Map<string, string[]>();
11-
const paramDefaultsByName = new Map<string, unknown[]>();
12-
13-
arityByName.set('osc', 0);
14-
kindByName.set('osc', 'src');
15-
paramIdsByName.set('osc', ['frequency', 'sync', 'offset']);
16-
paramDefaultsByName.set('osc', [2, 0.5, 0]);
17-
18-
arityByName.set('rotate', 1);
19-
kindByName.set('rotate', 'coord');
20-
paramIdsByName.set('rotate', ['angle', 'speed']);
21-
paramDefaultsByName.set('rotate', [0, 0]);
22-
23-
arityByName.set('blend', 2);
24-
kindByName.set('blend', 'combine');
25-
paramIdsByName.set('blend', ['amount']);
26-
paramDefaultsByName.set('blend', [0.5]);
27-
28-
arityByName.set('out', 1);
29-
kindByName.set('out', 'color');
30-
paramIdsByName.set('out', []);
31-
paramDefaultsByName.set('out', []);
32-
33-
return { arityByName, kindByName, paramIdsByName, paramDefaultsByName };
34-
}
35-
36-
// Fake chain objects for testing
37-
type FakeChain = {
38-
kind: string;
39-
transforms: Array<{ op: string; otherChain?: FakeChain; args: unknown[] }>;
40-
outputIndex?: number;
41-
input?: FakeChain;
42-
input0?: FakeChain;
43-
input1?: FakeChain;
44-
rotate: (this: FakeChain, ...args: unknown[]) => FakeChain;
45-
blend: (this: FakeChain, other: FakeChain, ...args: unknown[]) => FakeChain;
46-
[key: string]: unknown;
47-
};
48-
49-
function createFakeGenerators() {
50-
const chains: FakeChain[] = [];
51-
52-
const makeChain = (kind: string): FakeChain => {
53-
const chain: FakeChain = {
54-
kind,
55-
transforms: [],
56-
rotate: function (this: FakeChain, ...args: unknown[]) {
57-
this.transforms.push({ op: 'rotate', args });
58-
return this;
59-
},
60-
blend: function (this: FakeChain, other: FakeChain, ...args: unknown[]) {
61-
this.input0 = this;
62-
this.input1 = other;
63-
// Record the full call signature: other chain + user args
64-
this.transforms.push({ op: 'blend', otherChain: other, args });
65-
return this;
66-
},
67-
out: function () {
68-
// Mock out method to avoid execution errors
69-
return this;
70-
}
71-
};
72-
chains.push(chain);
73-
return chain;
74-
};
75-
76-
const generators = {
77-
osc: (...args: unknown[]) => {
78-
const chain = makeChain('osc');
79-
chain.transforms.push({ op: 'osc', args });
80-
return chain;
81-
},
82-
src: (output: { index?: number }) => {
83-
const chain = makeChain('src');
84-
chain.outputIndex = output.index ?? 0;
85-
chain.transforms.push({ op: 'src', args: [output] });
86-
return chain;
87-
}
88-
};
89-
90-
return { generators, chains };
91-
}
92-
93-
function createFakeHydra(outputCount = 4) {
94-
const outputs = Array.from({ length: outputCount }, (_, i) => ({ index: i }));
95-
return {
96-
outputs,
97-
loop: {
98-
start: () => {},
99-
stop: () => {}
100-
},
101-
hush: () => {},
102-
setResolution: () => {}
103-
};
104-
}
105-
10611
describe('HydraEngine feedback', () => {
10712
it('unary forward + feedback cycle', async () => {
108-
const meta = createMeta();
109-
const { generators, chains } = createFakeGenerators();
13+
const meta = createTestMeta();
14+
const { generators, chains } = createFakeGeneratorsForFeedback();
11015
const engine = new HydraEngine(meta, generators);
11116

112-
const fakeHydra = createFakeHydra();
17+
const fakeHydra = createFakeHydraOutputsOnly();
11318
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11419
(engine as any).hydra = fakeHydra;
11520
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -142,11 +47,11 @@ describe('HydraEngine feedback', () => {
14247
});
14348

14449
it('unary feedback-only node', async () => {
145-
const meta = createMeta();
146-
const { generators, chains } = createFakeGenerators();
50+
const meta = createTestMeta();
51+
const { generators, chains } = createFakeGeneratorsForFeedback();
14752
const engine = new HydraEngine(meta, generators);
14853

149-
const fakeHydra = createFakeHydra();
54+
const fakeHydra = createFakeHydraOutputsOnly();
15055
// eslint-disable-next-line @typescript-eslint/no-explicit-any
15156
(engine as any).hydra = fakeHydra;
15257
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -177,11 +82,11 @@ describe('HydraEngine feedback', () => {
17782
});
17883

17984
it('binary node mixed inputs', async () => {
180-
const meta = createMeta();
181-
const { generators, chains } = createFakeGenerators();
85+
const meta = createTestMeta();
86+
const { generators, chains } = createFakeGeneratorsForFeedback();
18287
const engine = new HydraEngine(meta, generators);
18388

184-
const fakeHydra = createFakeHydra();
89+
const fakeHydra = createFakeHydraOutputsOnly();
18590
// eslint-disable-next-line @typescript-eslint/no-explicit-any
18691
(engine as any).hydra = fakeHydra;
18792
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -216,11 +121,11 @@ describe('HydraEngine feedback', () => {
216121
});
217122

218123
it('binary node pure feedback', async () => {
219-
const meta = createMeta();
220-
const { generators, chains } = createFakeGenerators();
124+
const meta = createTestMeta();
125+
const { generators, chains } = createFakeGeneratorsForFeedback();
221126
const engine = new HydraEngine(meta, generators);
222127

223-
const fakeHydra = createFakeHydra();
128+
const fakeHydra = createFakeHydraOutputsOnly();
224129
// eslint-disable-next-line @typescript-eslint/no-explicit-any
225130
(engine as any).hydra = fakeHydra;
226131
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -267,7 +172,7 @@ describe('HydraEngine feedback', () => {
267172
});
268173

269174
it('runtime error when src generator unavailable', async () => {
270-
const meta = createMeta();
175+
const meta = createTestMeta();
271176
const generators = {
272177
osc: () => ({ transforms: [] }),
273178
rotate: function () {
@@ -280,7 +185,7 @@ describe('HydraEngine feedback', () => {
280185
};
281186
const engine = new HydraEngine(meta, generators);
282187

283-
const fakeHydra = createFakeHydra();
188+
const fakeHydra = createFakeHydraOutputsOnly();
284189
// eslint-disable-next-line @typescript-eslint/no-explicit-any
285190
(engine as any).hydra = fakeHydra;
286191
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -307,11 +212,11 @@ describe('HydraEngine feedback', () => {
307212
});
308213

309214
it('mixer params are not dropped and implicit chain param is not in args', async () => {
310-
const meta = createMeta();
311-
const { generators, chains } = createFakeGenerators();
215+
const meta = createTestMeta();
216+
const { generators, chains } = createFakeGeneratorsForFeedback();
312217
const engine = new HydraEngine(meta, generators);
313218

314-
const fakeHydra = createFakeHydra();
219+
const fakeHydra = createFakeHydraOutputsOnly();
315220
// eslint-disable-next-line @typescript-eslint/no-explicit-any
316221
(engine as any).hydra = fakeHydra;
317222
// eslint-disable-next-line @typescript-eslint/no-explicit-any

src/lib/engine/HydraEngine.specialNodes.test.ts

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,17 @@
1-
import { describe, expect, it, vi } from 'vitest';
1+
import { describe, expect, it } from 'vitest';
22

33
import type { IREdge, IRNode } from '../types.js';
4+
import {
5+
createFakeGeneratorsForSpecialNodes,
6+
createFakeHydraWithCamera
7+
} from './__testutils__/fakeHydra.js';
48
import { HydraEngine } from './HydraEngine.js';
59
import {
610
addCustomSpecsForMeta,
711
buildHydraTransformSpecs,
812
buildMetaFromSpecs
913
} from './transformRegistry.js';
1014

11-
function createFakeHydra() {
12-
const outputs = [{}, {}, {}, {}];
13-
const sources = [{ initCam: vi.fn() }];
14-
return {
15-
outputs,
16-
sources,
17-
setResolution: vi.fn(),
18-
loop: {
19-
start: vi.fn(),
20-
stop: vi.fn()
21-
},
22-
hush: vi.fn()
23-
};
24-
}
25-
26-
function createFakeGenerators() {
27-
const srcChain = {
28-
out: vi.fn()
29-
};
30-
const solidChain = {
31-
out: vi.fn()
32-
};
33-
const oscChain = {
34-
out: vi.fn()
35-
};
36-
37-
return {
38-
src: vi.fn(() => srcChain),
39-
solid: vi.fn(() => solidChain),
40-
osc: vi.fn(() => oscChain)
41-
};
42-
}
43-
4415
describe('HydraEngine special nodes', () => {
4516
it('camera → out calls src(source0) and .out(output0)', async () => {
4617
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -49,10 +20,10 @@ describe('HydraEngine special nodes', () => {
4920
const metaSpecs = addCustomSpecsForMeta(hydraSpecs);
5021
const meta = buildMetaFromSpecs(metaSpecs);
5122

52-
const generators = createFakeGenerators();
23+
const { generators, chains } = createFakeGeneratorsForSpecialNodes();
5324
const engine = new HydraEngine(meta, generators);
5425

55-
const fakeHydra = createFakeHydra();
26+
const fakeHydra = createFakeHydraWithCamera();
5627
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5728
(engine as any).hydra = fakeHydra;
5829
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -78,8 +49,7 @@ describe('HydraEngine special nodes', () => {
7849
expect(generators.src).toHaveBeenCalledWith(fakeHydra.sources[0]);
7950

8051
// Verify .out was called with outputs[0]
81-
const srcChain = generators.src.mock.results[0].value;
82-
expect(srcChain.out).toHaveBeenCalledWith(fakeHydra.outputs[0]);
52+
expect(chains.srcChain.out).toHaveBeenCalledWith(fakeHydra.outputs[0]);
8353
});
8454

8555
it('osc → out(outputIndex=1) routes to outputs[1]', async () => {
@@ -101,10 +71,10 @@ describe('HydraEngine special nodes', () => {
10171
const metaSpecs = addCustomSpecsForMeta(hydraSpecs);
10272
const meta = buildMetaFromSpecs(metaSpecs);
10373

104-
const generators = createFakeGenerators();
74+
const { generators, chains } = createFakeGeneratorsForSpecialNodes();
10575
const engine = new HydraEngine(meta, generators);
10676

107-
const fakeHydra = createFakeHydra();
77+
const fakeHydra = createFakeHydraWithCamera();
10878
// eslint-disable-next-line @typescript-eslint/no-explicit-any
10979
(engine as any).hydra = fakeHydra;
11080
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -127,8 +97,7 @@ describe('HydraEngine special nodes', () => {
12797
expect(generators.osc).toHaveBeenCalled();
12898

12999
// Verify .out was called with outputs[1]
130-
const oscChain = generators.osc.mock.results[0].value;
131-
expect(oscChain.out).toHaveBeenCalledTimes(1);
132-
expect(oscChain.out).toHaveBeenCalledWith(fakeHydra.outputs[1]);
100+
expect(chains.oscChain.out).toHaveBeenCalledTimes(1);
101+
expect(chains.oscChain.out).toHaveBeenCalledWith(fakeHydra.outputs[1]);
133102
});
134103
});

0 commit comments

Comments
 (0)