Skip to content

Commit af264c0

Browse files
authored
Merge pull request #1180 from shm11C3/test-assist/usehardwaredata-branch-coverage-85c92020c235ddb5
[Test Improver] test: expand branch coverage for useHardwareData hook
2 parents 34ddc47 + 95446c7 commit af264c0

File tree

1 file changed

+106
-1
lines changed

1 file changed

+106
-1
lines changed

src/features/hardware/hooks/useHardwareData.test.ts

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
// src/features/hardware/hooks/useHardwareData.test.ts
22
import { act, renderHook, waitFor } from "@testing-library/react";
33
import { Provider, useAtom } from "jotai";
4-
import { beforeEach, describe, expect, it, type Mock, vi } from "vitest";
4+
import {
5+
afterEach,
6+
beforeEach,
7+
describe,
8+
expect,
9+
it,
10+
type Mock,
11+
vi,
12+
} from "vitest";
513

614
import { chartConfig } from "@/features/hardware/consts/chart";
715
// Hook groups to test
@@ -13,6 +21,7 @@ import {
1321
cpuUsageHistoryAtom,
1422
gpuFanSpeedAtom,
1523
gpuTempAtom,
24+
gpuUsageSourceAtom,
1625
graphicUsageHistoryAtom,
1726
memoryUsageHistoryAtom,
1827
processorsUsageHistoryAtom,
@@ -234,3 +243,99 @@ describe("useUsageUpdater processors", () => {
234243
});
235244
});
236245
});
246+
247+
describe("useUsageUpdater – error and GpuUsageResult branches", () => {
248+
beforeEach(() => {
249+
vi.clearAllMocks();
250+
});
251+
252+
it("early-returns without updating atom when result is an error", async () => {
253+
// Covers line 69: isResult(result) && isError(result) → return
254+
(commands.getGpuUsage as Mock).mockResolvedValue({
255+
status: "error",
256+
error: "gpu not found",
257+
});
258+
259+
const { result } = renderHook(
260+
() => {
261+
useUsageUpdater("gpu");
262+
const [history] = useAtom(graphicUsageHistoryAtom);
263+
return history;
264+
},
265+
{ wrapper: Provider },
266+
);
267+
268+
await act(async () => {
269+
await Promise.resolve();
270+
});
271+
272+
// Atom should stay empty because early return prevented any update
273+
expect(result.current).toEqual([]);
274+
});
275+
276+
it("extracts usage and source from GpuUsageResult object", async () => {
277+
// Covers lines 84-86: rawData is { usage, source } object
278+
(commands.getGpuUsage as Mock).mockResolvedValue({
279+
status: "ok",
280+
data: { usage: 60, source: "nvidia_smi" },
281+
});
282+
283+
const { result } = renderHook(
284+
() => {
285+
useUsageUpdater("gpu");
286+
const [history] = useAtom(graphicUsageHistoryAtom);
287+
const [source] = useAtom(gpuUsageSourceAtom);
288+
return { history, source };
289+
},
290+
{ wrapper: Provider },
291+
);
292+
293+
await waitFor(() => {
294+
const { history, source } = result.current;
295+
expect(history[history.length - 1]).toEqual(60);
296+
expect(source).toEqual("nvidia_smi");
297+
});
298+
});
299+
});
300+
301+
describe("useHardwareUpdater – interval re-fetch", () => {
302+
beforeEach(() => {
303+
vi.clearAllMocks();
304+
vi.useFakeTimers();
305+
});
306+
307+
afterEach(() => {
308+
vi.useRealTimers();
309+
});
310+
311+
it("re-fetches gpu fan data after interval tick", async () => {
312+
// Covers line 177: the setInterval callback inside useHardwareUpdater
313+
(commands.getNvidiaGpuCooler as Mock).mockResolvedValue({
314+
status: "ok",
315+
data: [{ name: "fan1", value: 1200 }],
316+
});
317+
318+
renderHook(
319+
() => {
320+
useHardwareUpdater("gpu", "fan");
321+
return useAtom(gpuFanSpeedAtom);
322+
},
323+
{ wrapper: Provider },
324+
);
325+
326+
// Initial fetch
327+
await act(async () => {
328+
await Promise.resolve();
329+
});
330+
331+
expect(commands.getNvidiaGpuCooler).toHaveBeenCalledTimes(1);
332+
333+
// Advance by interval (10 s) to trigger re-fetch
334+
await act(async () => {
335+
vi.advanceTimersByTime(10000);
336+
await Promise.resolve();
337+
});
338+
339+
expect(commands.getNvidiaGpuCooler).toHaveBeenCalledTimes(2);
340+
});
341+
});

0 commit comments

Comments
 (0)