44 lines
1.7 KiB
TypeScript
Vendored
44 lines
1.7 KiB
TypeScript
Vendored
import { describe, expect, it } from "vitest";
|
|
import { createSidebarSearchLoadingTracker } from "@/lib/sidebar/sidebarSearchLoadingTracker";
|
|
|
|
describe("sidebar search loading tracker", () => {
|
|
it("is idle until a search dispatch begins", () => {
|
|
const tracker = createSidebarSearchLoadingTracker();
|
|
expect(tracker.isLoading).toBe(false);
|
|
});
|
|
|
|
it("reports loading while a dispatch is in flight and clears on matching end", () => {
|
|
const tracker = createSidebarSearchLoadingTracker();
|
|
const generation = tracker.begin();
|
|
expect(tracker.isLoading).toBe(true);
|
|
expect(tracker.end(generation)).toBe(true);
|
|
expect(tracker.isLoading).toBe(false);
|
|
});
|
|
|
|
it("ignores a stale end() from a superseded dispatch (fast typing race)", () => {
|
|
// This is the exact race in ConnectionTree.vue's search watcher: each keystroke
|
|
// (after debounce) re-dispatches expansion tasks; a slow earlier dispatch must not
|
|
// clear the spinner set by a newer, still-in-flight dispatch.
|
|
const tracker = createSidebarSearchLoadingTracker();
|
|
const firstGeneration = tracker.begin();
|
|
const secondGeneration = tracker.begin();
|
|
expect(tracker.isLoading).toBe(true);
|
|
|
|
expect(tracker.end(firstGeneration)).toBe(false);
|
|
expect(tracker.isLoading).toBe(true);
|
|
|
|
expect(tracker.end(secondGeneration)).toBe(true);
|
|
expect(tracker.isLoading).toBe(false);
|
|
});
|
|
|
|
it("cancel() immediately clears loading and invalidates any pending end()", () => {
|
|
const tracker = createSidebarSearchLoadingTracker();
|
|
const generation = tracker.begin();
|
|
tracker.cancel();
|
|
expect(tracker.isLoading).toBe(false);
|
|
|
|
expect(tracker.end(generation)).toBe(false);
|
|
expect(tracker.isLoading).toBe(false);
|
|
});
|
|
});
|