Skip to content

Commit 5810bc3

Browse files
committed
add tests
1 parent d5d013c commit 5810bc3

File tree

1 file changed

+98
-2
lines changed

1 file changed

+98
-2
lines changed

chartlets.js/packages/lib/src/plugins/vega/hooks/useSignalListeners.test.ts

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
* https://opensource.org/licenses/MIT.
55
*/
66

7-
import { describe, it, expect } from "vitest";
7+
import { describe, it, expect, vi } from "vitest";
88
import { renderHook, act } from "@testing-library/react";
99
import type { TopLevelSpec } from "vega-lite";
1010
import { useSignalListeners } from "./useSignalListeners";
1111
import { createChangeHandler } from "@/plugins/mui/common.test";
12+
import type { Result as VegaEmbedResult } from "vega-embed";
1213

1314
const chart: TopLevelSpec = {
1415
$schema: "https://vega.github.io/schema/vega-lite/v6.json",
@@ -72,7 +73,7 @@ describe("useSignalListeners", () => {
7273
expect(signalHandlers["sel_interval"]).toBeTypeOf("function");
7374
expect(signalHandlers["sel_point_a"]).toBeTypeOf("function");
7475
// "wheel" not supported
75-
expect(signalHandlers["sel_point_b"]).toBeUndefined();
76+
expect(signalHandlers["sel_interval_b"]).toBeUndefined();
7677
});
7778

7879
it("should call onChange", () => {
@@ -95,4 +96,99 @@ describe("useSignalListeners", () => {
9596
value: [1, 2, 3],
9697
});
9798
});
99+
100+
it("should register signal listeners on embed", () => {
101+
const { result } = renderHook(() =>
102+
useSignalListeners(chartWithSelect, "VegaChart", "my_chart", () => {}),
103+
);
104+
105+
const view = createMockView();
106+
107+
act(() => {
108+
result.current.onEmbed({ view } as unknown as VegaEmbedResult);
109+
});
110+
111+
// Supported signals: sel_point, sel_interval, sel_point_a
112+
expect(view.addSignalListener).toHaveBeenCalledTimes(3);
113+
114+
const names = view.addSignalListener.mock.calls.map(([name]) => name);
115+
expect(names).toEqual(
116+
expect.arrayContaining(["sel_point", "sel_interval", "sel_point_a"]),
117+
);
118+
119+
// Unsupported "wheel" should not be registered
120+
expect(names).not.toContain("sel_interval_b");
121+
});
122+
123+
it("should remove old listeners when embedding again", () => {
124+
const { result } = renderHook(() =>
125+
useSignalListeners(chartWithSelect, "VegaChart", "my_chart", () => {}),
126+
);
127+
128+
const view1 = createMockView();
129+
const view2 = createMockView();
130+
131+
act(() => {
132+
result.current.onEmbed({ view: view1 } as unknown as VegaEmbedResult);
133+
});
134+
135+
const attachedToView1 = view1.addSignalListener.mock.calls.map(
136+
([name, fn]) => ({ name, fn }),
137+
);
138+
139+
act(() => {
140+
result.current.onEmbed({ view: view2 } as unknown as VegaEmbedResult);
141+
});
142+
143+
expect(view1.removeSignalListener).toHaveBeenCalledTimes(
144+
attachedToView1.length,
145+
);
146+
147+
for (const { name, fn } of attachedToView1) {
148+
expect(view1.removeSignalListener).toHaveBeenCalledWith(name, fn);
149+
}
150+
151+
expect(view2.addSignalListener).toHaveBeenCalledTimes(3);
152+
});
153+
154+
it("should cleanup listeners on unmount", () => {
155+
const { result, unmount } = renderHook(() =>
156+
useSignalListeners(chartWithSelect, "VegaChart", "my_chart", () => {}),
157+
);
158+
159+
const view = createMockView();
160+
161+
act(() => {
162+
result.current.onEmbed({ view } as unknown as VegaEmbedResult);
163+
});
164+
165+
const attached = view.addSignalListener.mock.calls.map(([name, fn]) => ({
166+
name,
167+
fn,
168+
}));
169+
170+
unmount();
171+
172+
expect(view.removeSignalListener).toHaveBeenCalledTimes(attached.length);
173+
for (const { name, fn } of attached) {
174+
expect(view.removeSignalListener).toHaveBeenCalledWith(name, fn);
175+
}
176+
});
177+
178+
it("should do nothing if embed result has no view", () => {
179+
const { result } = renderHook(() =>
180+
useSignalListeners(chartWithSelect, "VegaChart", "my_chart", () => {}),
181+
);
182+
183+
act(() => {
184+
result.current.onEmbed({} as unknown as VegaEmbedResult);
185+
});
186+
});
98187
});
188+
189+
function createMockView() {
190+
return {
191+
addSignalListener: vi.fn(),
192+
removeSignalListener: vi.fn(),
193+
};
194+
}

0 commit comments

Comments
 (0)