Skip to content

Commit 976dad7

Browse files
authored
test(store+utils): add UI reducer, store utils and MIDI export tests (#18)
* test(store): add UI reducer tests for window, theme and clipboard state * test(store): add unit tests for store utilities and helpers * test(utils): add MIDI export binary validation tests * test(store): fix ui reducer test assertions for patternClipboardIds
1 parent 5c466a4 commit 976dad7

3 files changed

Lines changed: 610 additions & 0 deletions

File tree

src/store/reducers/ui.test.js

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { describe, it, expect } from "vitest";
2+
import { uiReducers } from "./ui";
3+
4+
function createUiState() {
5+
return {
6+
ui: {
7+
windows: {
8+
browser: { open: false, z: 1, x: 10, y: 10, width: 200, height: 200, isMaximized: false },
9+
playlist: { open: false, z: 2, x: 20, y: 20, width: 300, height: 300, isMaximized: false },
10+
},
11+
nextZ: 2,
12+
browserTab: "packs",
13+
theme: "default",
14+
fxEditorTarget: null,
15+
patternClipboard: [],
16+
},
17+
project: {
18+
patterns: [{ id: "pat-1" }],
19+
},
20+
};
21+
}
22+
23+
describe("uiReducers", () => {
24+
describe("openWindow", () => {
25+
it("opens a closed window and bumps z-index", () => {
26+
const state = createUiState();
27+
uiReducers.openWindow(state, { payload: "browser" });
28+
expect(state.ui.windows.browser.open).toBe(true);
29+
expect(state.ui.windows.browser.z).toBe(3);
30+
expect(state.ui.nextZ).toBe(3);
31+
});
32+
33+
it("ignores unknown window ids", () => {
34+
const state = createUiState();
35+
uiReducers.openWindow(state, { payload: "unknown" });
36+
expect(state.ui.nextZ).toBe(2);
37+
});
38+
});
39+
40+
describe("closeWindow", () => {
41+
it("closes an open window", () => {
42+
const state = createUiState();
43+
state.ui.windows.browser.open = true;
44+
uiReducers.closeWindow(state, { payload: "browser" });
45+
expect(state.ui.windows.browser.open).toBe(false);
46+
});
47+
});
48+
49+
describe("bringWindowToFront", () => {
50+
it("bumps z-index of existing window", () => {
51+
const state = createUiState();
52+
uiReducers.bringWindowToFront(state, { payload: "browser" });
53+
expect(state.ui.windows.browser.z).toBe(3);
54+
});
55+
56+
it("ignores unknown window ids", () => {
57+
const state = createUiState();
58+
uiReducers.bringWindowToFront(state, { payload: "unknown" });
59+
expect(state.ui.nextZ).toBe(2);
60+
});
61+
});
62+
63+
describe("setWindowRect", () => {
64+
it("updates window position and size", () => {
65+
const state = createUiState();
66+
uiReducers.setWindowRect(state, { payload: { id: "browser", x: 50, y: 60, width: 400, height: 300 } });
67+
expect(state.ui.windows.browser.x).toBe(50);
68+
expect(state.ui.windows.browser.y).toBe(60);
69+
expect(state.ui.windows.browser.width).toBe(400);
70+
expect(state.ui.windows.browser.height).toBe(300);
71+
});
72+
});
73+
74+
describe("toggleWindowMaximize", () => {
75+
it("maximizes window and stores restore rect", () => {
76+
const state = createUiState();
77+
uiReducers.toggleWindowMaximize(state, { payload: { id: "browser", viewport: { width: 1920, height: 1080 } } });
78+
expect(state.ui.windows.browser.isMaximized).toBe(true);
79+
expect(state.ui.windows.browser.restoreRect).toEqual({ x: 10, y: 10, width: 200, height: 200 });
80+
expect(state.ui.windows.browser.width).toBe(1920);
81+
});
82+
83+
it("restores window from maximized state", () => {
84+
const state = createUiState();
85+
uiReducers.toggleWindowMaximize(state, { payload: { id: "browser", viewport: { width: 1920, height: 1080 } } });
86+
uiReducers.toggleWindowMaximize(state, { payload: { id: "browser" } });
87+
expect(state.ui.windows.browser.isMaximized).toBe(false);
88+
expect(state.ui.windows.browser.width).toBe(200);
89+
});
90+
});
91+
92+
describe("setBrowserTab", () => {
93+
it("sets the active browser tab", () => {
94+
const state = createUiState();
95+
uiReducers.setBrowserTab(state, { payload: "plugins" });
96+
expect(state.ui.browserTab).toBe("plugins");
97+
});
98+
});
99+
100+
describe("setTheme", () => {
101+
it("sets a valid theme", () => {
102+
const state = createUiState();
103+
uiReducers.setTheme(state, { payload: "tealslate" });
104+
expect(state.ui.theme).toBe("tealslate");
105+
});
106+
107+
it("falls back to default for invalid theme", () => {
108+
const state = createUiState();
109+
uiReducers.setTheme(state, { payload: "invalid" });
110+
expect(state.ui.theme).toBe("default");
111+
});
112+
});
113+
114+
describe("setPatternClipboard", () => {
115+
it("stores valid pattern ids", () => {
116+
const state = createUiState();
117+
uiReducers.setPatternClipboard(state, { payload: { patternIds: ["pat-1"] } });
118+
expect(state.ui.patternClipboardIds).toEqual(["pat-1"]);
119+
});
120+
121+
it("ignores unknown pattern ids", () => {
122+
const state = createUiState();
123+
uiReducers.setPatternClipboard(state, { payload: { patternIds: ["unknown"] } });
124+
expect(state.ui.patternClipboardIds).toEqual([]);
125+
});
126+
});
127+
});

0 commit comments

Comments
 (0)