-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathgraph-engine.spec.ts
More file actions
106 lines (84 loc) · 2.93 KB
/
Copy pathgraph-engine.spec.ts
File metadata and controls
106 lines (84 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// deck.gl-community
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
import {GraphEngine} from '../../src/core/graph-engine';
import type {GraphLayoutEventDetail} from '../../src/core/graph-layout';
import {Graph} from '../../src/graph/graph';
import {Node} from '../../src/graph/node';
import {Edge} from '../../src/graph/edge';
import {GPUForceLayout} from '../../src/layouts/gpu-force/gpu-force-layout';
class MockWorker {
static lastInstance: MockWorker | null = null;
onmessage: ((event: {data: any}) => void) | null = null;
constructor(_url: string) {
MockWorker.lastInstance = this;
}
postMessage(_data: unknown) {}
terminate() {}
}
describe('core/graph-engine', () => {
const OriginalWorker = globalThis.Worker;
beforeEach(() => {
globalThis.Worker = MockWorker as unknown as typeof Worker;
});
afterEach(() => {
globalThis.Worker = OriginalWorker;
MockWorker.lastInstance = null;
});
it('fires onLayoutStart when GPUForceLayout starts', () => {
const layout = new GPUForceLayout();
const graph = new Graph({
name: 'test',
nodes: [new Node({id: 'a'}), new Node({id: 'b'})],
edges: [new Edge({id: 'edge-a-b', sourceId: 'a', targetId: 'b'})]
});
const engine = new GraphEngine({graph, layout});
const onLayoutStart = vi.fn();
engine.addEventListener('onLayoutStart', onLayoutStart);
engine.run();
expect(onLayoutStart).toHaveBeenCalledTimes(1);
MockWorker.lastInstance?.onmessage?.({
data: {type: 'end', nodes: [], edges: []}
});
engine.stop();
engine.clear();
});
it('updates bounds on each GPU tick event', () => {
const layout = new GPUForceLayout();
const graph = new Graph({
name: 'bounds-test',
nodes: [new Node({id: 'a'}), new Node({id: 'b'})],
edges: [new Edge({id: 'edge-a-b', sourceId: 'a', targetId: 'b'})]
});
const engine = new GraphEngine({graph, layout});
const onLayoutChange = vi.fn();
engine.addEventListener('onLayoutChange', onLayoutChange);
engine.run();
const tickNodes = [
{id: 'a', x: 10, y: 5, fx: null, fy: null, locked: false, collisionRadius: 0},
{id: 'b', x: 110, y: 105, fx: null, fy: null, locked: false, collisionRadius: 0}
];
const tickEdges = [
{
id: 'edge-a-b',
source: tickNodes[0],
target: tickNodes[1]
}
];
MockWorker.lastInstance?.onmessage?.({
data: {type: 'tick', nodes: tickNodes, edges: tickEdges}
});
expect(onLayoutChange).toHaveBeenCalled();
const lastEvent = onLayoutChange.mock.calls.at(-1)?.[0] as CustomEvent<GraphLayoutEventDetail>;
expect(lastEvent?.detail?.bounds).toEqual([
[10, 5],
[110, 105]
]);
MockWorker.lastInstance?.onmessage?.({
data: {type: 'end', nodes: tickNodes, edges: tickEdges}
});
engine.stop();
engine.clear();
});
});