Skip to content

Commit 883fef5

Browse files
committed
test(testing-view): add tests for charts store slice
1 parent 1a3cde5 commit 883fef5

16 files changed

Lines changed: 437 additions & 108 deletions
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { beforeEach, describe, expect, it } from "vitest";
2+
import { config } from "../../../../../config";
3+
import { WORKSPACE_ID, createTestStore } from "./helpers";
4+
5+
let store: ReturnType<typeof createTestStore>;
6+
7+
beforeEach(() => {
8+
store = createTestStore();
9+
});
10+
11+
describe("addChart", () => {
12+
it("adds a chart to the specified workspace", () => {
13+
store.getState().addChart(WORKSPACE_ID);
14+
15+
expect(store.getState().charts[WORKSPACE_ID]).toHaveLength(1);
16+
});
17+
18+
it("returns the new chart's ID", () => {
19+
const id = store.getState().addChart(WORKSPACE_ID);
20+
21+
expect(store.getState().charts[WORKSPACE_ID][0].id).toBe(id);
22+
});
23+
24+
it("initializes the chart with an empty series array", () => {
25+
const id = store.getState().addChart(WORKSPACE_ID);
26+
const chart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === id);
27+
28+
expect(chart?.series).toStrictEqual([]);
29+
});
30+
31+
it("initializes the chart with the default history limit", () => {
32+
const id = store.getState().addChart(WORKSPACE_ID);
33+
const chart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === id);
34+
35+
expect(chart?.historyLimit).toBe(config.DEFAULT_CHART_HISTORY_LIMIT);
36+
});
37+
38+
it("does not affect other workspaces", () => {
39+
const chartsBefore = store.getState().charts["workspace-2"];
40+
store.getState().addChart(WORKSPACE_ID);
41+
42+
expect(store.getState().charts["workspace-2"]).toStrictEqual(chartsBefore);
43+
});
44+
45+
it("each call adds a distinct chart", () => {
46+
const id1 = store.getState().addChart(WORKSPACE_ID);
47+
const id2 = store.getState().addChart(WORKSPACE_ID);
48+
49+
expect(id1).not.toBe(id2);
50+
expect(store.getState().charts[WORKSPACE_ID]).toHaveLength(2);
51+
});
52+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { beforeEach, describe, expect, it } from "vitest";
2+
import { WORKSPACE_ID, addChart, createTestStore } from "./helpers";
3+
4+
let store: ReturnType<typeof createTestStore>;
5+
let chartId: string;
6+
7+
beforeEach(() => {
8+
store = createTestStore();
9+
chartId = addChart(store);
10+
});
11+
12+
describe("setChartHistoryLimit", () => {
13+
it("updates the history limit for the correct chart", () => {
14+
store.getState().setChartHistoryLimit(WORKSPACE_ID, chartId, 500);
15+
16+
const chart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === chartId);
17+
expect(chart?.historyLimit).toBe(500);
18+
});
19+
20+
it("does not affect other charts in the same workspace", () => {
21+
const otherId = addChart(store);
22+
const otherLimitBefore = store.getState().charts[WORKSPACE_ID].find((c) => c.id === otherId)?.historyLimit;
23+
24+
store.getState().setChartHistoryLimit(WORKSPACE_ID, chartId, 500);
25+
26+
const otherChart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === otherId);
27+
expect(otherChart?.historyLimit).toBe(otherLimitBefore);
28+
});
29+
30+
it("does not affect charts in other workspaces", () => {
31+
const otherChartId = addChart(store, "workspace-2");
32+
const otherLimitBefore = store.getState().charts["workspace-2"].find((c) => c.id === otherChartId)?.historyLimit;
33+
34+
store.getState().setChartHistoryLimit(WORKSPACE_ID, chartId, 500);
35+
36+
const otherChart = store.getState().charts["workspace-2"].find((c) => c.id === otherChartId);
37+
expect(otherChart?.historyLimit).toBe(otherLimitBefore);
38+
});
39+
});
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { beforeEach, describe, expect, it } from "vitest";
2+
import { SERIES_A, SERIES_B, SERIES_ENUM, WORKSPACE_ID, addChart, createTestStore } from "./helpers";
3+
4+
let store: ReturnType<typeof createTestStore>;
5+
let chartId: string;
6+
7+
beforeEach(() => {
8+
store = createTestStore();
9+
chartId = addChart(store);
10+
});
11+
12+
// ─── addSeriesToChart ─────────────────────────────────────────────────────────
13+
14+
describe("addSeriesToChart", () => {
15+
it("adds a series to the correct chart", () => {
16+
store.getState().addSeriesToChart(WORKSPACE_ID, chartId, SERIES_A);
17+
18+
const chart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === chartId);
19+
expect(chart?.series).toHaveLength(1);
20+
expect(chart?.series[0]).toStrictEqual(SERIES_A);
21+
});
22+
23+
it("appends multiple series in order", () => {
24+
store.getState().addSeriesToChart(WORKSPACE_ID, chartId, SERIES_A);
25+
store.getState().addSeriesToChart(WORKSPACE_ID, chartId, SERIES_B);
26+
27+
const chart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === chartId);
28+
expect(chart?.series).toStrictEqual([SERIES_A, SERIES_B]);
29+
});
30+
31+
it("supports enum series", () => {
32+
store.getState().addSeriesToChart(WORKSPACE_ID, chartId, SERIES_ENUM);
33+
34+
const chart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === chartId);
35+
expect(chart?.series[0].enumOptions).toStrictEqual(["Idle", "Running", "Fault"]);
36+
});
37+
38+
it("does not affect other charts in the same workspace", () => {
39+
const otherId = addChart(store);
40+
store.getState().addSeriesToChart(WORKSPACE_ID, chartId, SERIES_A);
41+
42+
const otherChart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === otherId);
43+
expect(otherChart?.series).toHaveLength(0);
44+
});
45+
46+
it("does not affect charts in other workspaces", () => {
47+
const otherChartId = addChart(store, "workspace-2");
48+
store.getState().addSeriesToChart(WORKSPACE_ID, chartId, SERIES_A);
49+
50+
const otherChart = store.getState().charts["workspace-2"].find((c) => c.id === otherChartId);
51+
expect(otherChart?.series).toHaveLength(0);
52+
});
53+
});
54+
55+
// ─── removeSeriesFromChart ────────────────────────────────────────────────────
56+
57+
describe("removeSeriesFromChart", () => {
58+
beforeEach(() => {
59+
store.getState().addSeriesToChart(WORKSPACE_ID, chartId, SERIES_A);
60+
store.getState().addSeriesToChart(WORKSPACE_ID, chartId, SERIES_B);
61+
});
62+
63+
it("removes the series with the given variable name", () => {
64+
store.getState().removeSeriesFromChart(WORKSPACE_ID, chartId, SERIES_A.variable);
65+
66+
const chart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === chartId);
67+
expect(chart?.series.find((s) => s.variable === SERIES_A.variable)).toBeUndefined();
68+
});
69+
70+
it("keeps other series in the same chart", () => {
71+
store.getState().removeSeriesFromChart(WORKSPACE_ID, chartId, SERIES_A.variable);
72+
73+
const chart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === chartId);
74+
expect(chart?.series).toHaveLength(1);
75+
expect(chart?.series[0]).toStrictEqual(SERIES_B);
76+
});
77+
78+
it("does not affect other charts", () => {
79+
const otherId = addChart(store);
80+
store.getState().addSeriesToChart(WORKSPACE_ID, otherId, SERIES_A);
81+
82+
store.getState().removeSeriesFromChart(WORKSPACE_ID, chartId, SERIES_A.variable);
83+
84+
const otherChart = store.getState().charts[WORKSPACE_ID].find((c) => c.id === otherId);
85+
expect(otherChart?.series).toHaveLength(1);
86+
});
87+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { beforeEach, describe, expect, it } from "vitest";
2+
import { WORKSPACE_ID, addChart, createTestStore } from "./helpers";
3+
4+
let store: ReturnType<typeof createTestStore>;
5+
6+
beforeEach(() => {
7+
store = createTestStore();
8+
});
9+
10+
describe("clearCharts", () => {
11+
it("removes all charts from the active workspace", () => {
12+
addChart(store);
13+
addChart(store);
14+
15+
store.getState().clearCharts();
16+
17+
expect(store.getState().charts[WORKSPACE_ID]).toHaveLength(0);
18+
});
19+
20+
it("does not affect charts in other workspaces", () => {
21+
addChart(store, "workspace-2");
22+
addChart(store);
23+
24+
store.getState().clearCharts();
25+
26+
expect(store.getState().charts["workspace-2"]).toHaveLength(1);
27+
});
28+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { beforeEach, describe, expect, it } from "vitest";
2+
import { WORKSPACE_ID, addChart, createTestStore } from "./helpers";
3+
4+
let store: ReturnType<typeof createTestStore>;
5+
6+
beforeEach(() => {
7+
store = createTestStore();
8+
});
9+
10+
describe("getActiveWorkspaceCharts", () => {
11+
it("returns the charts for the active workspace", () => {
12+
const id = addChart(store);
13+
14+
const charts = store.getState().getActiveWorkspaceCharts();
15+
expect(charts).toHaveLength(1);
16+
expect(charts[0].id).toBe(id);
17+
});
18+
19+
it("returns an empty array when the workspace has no charts", () => {
20+
expect(store.getState().getActiveWorkspaceCharts()).toStrictEqual([]);
21+
});
22+
23+
it("reflects the active workspace — switching workspaces returns different charts", () => {
24+
addChart(store);
25+
26+
const workspace2 = store.getState().workspaces[1];
27+
store.getState().setActiveWorkspace(workspace2);
28+
29+
expect(store.getState().getActiveWorkspaceCharts()).toHaveLength(0);
30+
});
31+
32+
it("updates after a chart is added", () => {
33+
expect(store.getState().getActiveWorkspaceCharts()).toHaveLength(0);
34+
35+
addChart(store);
36+
37+
expect(store.getState().getActiveWorkspaceCharts()).toHaveLength(1);
38+
});
39+
40+
it("updates after a chart is removed", () => {
41+
const id = addChart(store);
42+
store.getState().removeChart(WORKSPACE_ID, id);
43+
44+
expect(store.getState().getActiveWorkspaceCharts()).toStrictEqual([]);
45+
});
46+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { create } from "zustand";
2+
import { createChartsSlice } from "../chartsSlice";
3+
import { createAppSlice } from "../../../../store/slices/appSlice";
4+
import { createCatalogSlice } from "../../../../store/slices/catalogSlice";
5+
import { createConnectionsSlice } from "../../../../store/slices/connectionsSlice";
6+
import { createMessagesSlice } from "../../../../store/slices/messagesSlice";
7+
import { createTelemetrySlice } from "../../../../store/slices/telemetrySlice";
8+
import { createRightSidebarSlice } from "../../../workspace/store/rightSidebarSlice";
9+
import { createWorkspacesSlice } from "../../../workspace/store/workspacesSlice";
10+
import { createFilteringSlice } from "../../../filtering/store/filteringSlice";
11+
import type { Store } from "../../../../store/store";
12+
import type { WorkspaceChartSeries } from "../../types/charts";
13+
14+
export const createTestStore = () =>
15+
create<Store>()((...a) => ({
16+
...createAppSlice(...a),
17+
...createCatalogSlice(...a),
18+
...createWorkspacesSlice(...a),
19+
...createTelemetrySlice(...a),
20+
...createRightSidebarSlice(...a),
21+
...createConnectionsSlice(...a),
22+
...createMessagesSlice(...a),
23+
...createChartsSlice(...a),
24+
...createFilteringSlice(...a),
25+
}));
26+
27+
export const WORKSPACE_ID = "workspace-1";
28+
29+
export const SERIES_A: WorkspaceChartSeries = {
30+
packetId: 1,
31+
variable: "speed",
32+
};
33+
34+
export const SERIES_B: WorkspaceChartSeries = {
35+
packetId: 2,
36+
variable: "temperature",
37+
};
38+
39+
export const SERIES_ENUM: WorkspaceChartSeries = {
40+
packetId: 3,
41+
variable: "state",
42+
enumOptions: ["Idle", "Running", "Fault"],
43+
};
44+
45+
/** Adds a chart to the given workspace and returns its ID. */
46+
export function addChart(
47+
store: ReturnType<typeof createTestStore>,
48+
workspaceId = WORKSPACE_ID,
49+
) {
50+
return store.getState().addChart(workspaceId);
51+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { beforeEach, describe, expect, it } from "vitest";
2+
import { WORKSPACE_ID, addChart, createTestStore } from "./helpers";
3+
4+
let store: ReturnType<typeof createTestStore>;
5+
6+
beforeEach(() => {
7+
store = createTestStore();
8+
});
9+
10+
describe("removeChart", () => {
11+
it("removes the correct chart", () => {
12+
const id = addChart(store);
13+
store.getState().removeChart(WORKSPACE_ID, id);
14+
15+
expect(store.getState().charts[WORKSPACE_ID]).toHaveLength(0);
16+
});
17+
18+
it("does not remove other charts in the same workspace", () => {
19+
const id1 = addChart(store);
20+
const id2 = addChart(store);
21+
22+
store.getState().removeChart(WORKSPACE_ID, id1);
23+
24+
const remaining = store.getState().charts[WORKSPACE_ID];
25+
expect(remaining).toHaveLength(1);
26+
expect(remaining[0].id).toBe(id2);
27+
});
28+
29+
it("does not affect charts in other workspaces", () => {
30+
const id = addChart(store, "workspace-2");
31+
addChart(store);
32+
33+
store.getState().removeChart(WORKSPACE_ID, store.getState().charts[WORKSPACE_ID][0].id);
34+
35+
expect(store.getState().charts["workspace-2"].find((c) => c.id === id)).toBeDefined();
36+
});
37+
38+
it("does nothing when the chart ID does not exist", () => {
39+
addChart(store);
40+
const countBefore = store.getState().charts[WORKSPACE_ID].length;
41+
42+
store.getState().removeChart(WORKSPACE_ID, "non-existent-id");
43+
44+
expect(store.getState().charts[WORKSPACE_ID]).toHaveLength(countBefore);
45+
});
46+
});

0 commit comments

Comments
 (0)