112 lines · 2.9 KB · TypeScript
RawDownload
import type { GitStatusResult } from "@t3tools/contracts";import { afterEach, describe, expect, it, vi } from "vitest"; import {  getGitStatusSnapshot,  resetGitStatusStateForTests,  refreshGitStatus,  watchGitStatus,} from "./gitStatusState"; function registerListener<T>(listeners: Set<(event: T) => void>, listener: (event: T) => void) {  listeners.add(listener);  return () => {    listeners.delete(listener);  };} const gitStatusListeners = new Set<(event: GitStatusResult) => void>(); const BASE_STATUS: GitStatusResult = {  isRepo: true,  hasOriginRemote: true,  isDefaultBranch: false,  branch: "feature/push-status",  hasWorkingTreeChanges: false,  workingTree: { files: [], insertions: 0, deletions: 0 },  hasUpstream: true,  aheadCount: 0,  behindCount: 0,  pr: null,}; const gitClient = {  refreshStatus: vi.fn(async (input: { cwd: string }) => ({    ...BASE_STATUS,    branch: `${input.cwd}-refreshed`,  })),  onStatus: vi.fn((input: { cwd: string }, listener: (event: GitStatusResult) => void) =>    registerListener(gitStatusListeners, listener),  ),}; function emitGitStatus(event: GitStatusResult) {  for (const listener of gitStatusListeners) {    listener(event);  }} afterEach(() => {  gitStatusListeners.clear();  gitClient.onStatus.mockClear();  gitClient.refreshStatus.mockClear();  resetGitStatusStateForTests();}); describe("gitStatusState", () => {  it("starts fresh cwd state in a pending state", () => {    expect(getGitStatusSnapshot("/fresh")).toEqual({      data: null,      error: null,      cause: null,      isPending: true,    });  });   it("shares one live subscription per cwd and updates the per-cwd atom snapshot", () => {    const releaseA = watchGitStatus("/repo", gitClient);    const releaseB = watchGitStatus("/repo", gitClient);     expect(gitClient.onStatus).toHaveBeenCalledOnce();    expect(getGitStatusSnapshot("/repo")).toEqual({      data: null,      error: null,      cause: null,      isPending: true,    });     emitGitStatus(BASE_STATUS);     expect(getGitStatusSnapshot("/repo")).toEqual({      data: BASE_STATUS,      error: null,      cause: null,      isPending: false,    });     releaseA();    expect(gitStatusListeners.size).toBe(1);     releaseB();    expect(gitStatusListeners.size).toBe(0);  });   it("refreshes git status through the unary RPC without restarting the stream", async () => {    const release = watchGitStatus("/repo", gitClient);     emitGitStatus(BASE_STATUS);    const refreshed = await refreshGitStatus("/repo", gitClient);     expect(gitClient.onStatus).toHaveBeenCalledOnce();    expect(gitClient.refreshStatus).toHaveBeenCalledWith({ cwd: "/repo" });    expect(refreshed).toEqual({ ...BASE_STATUS, branch: "/repo-refreshed" });    expect(getGitStatusSnapshot("/repo")).toEqual({      data: BASE_STATUS,      error: null,      cause: null,      isPending: false,    });     release();  });});