186 lines · 5.3 KB · TypeScript
RawDownload
import type {  VcsStatusLocalResult,  VcsStatusRemoteResult,  VcsStatusStreamEvent,} from "@t3tools/contracts";import { ORCHESTRATION_WS_METHODS, ThreadId, WS_METHODS } from "@t3tools/contracts";import { describe, expect, it, vi } from "vite-plus/test"; vi.mock("./wsTransport.ts", () => ({  WsTransport: class WsTransport {    dispose = vi.fn(async () => undefined);    reconnect = vi.fn(async () => undefined);    request = vi.fn();    requestStream = vi.fn();    subscribe = vi.fn(() => () => undefined);  },})); import { createWsRpcClient } from "./wsRpcClient.ts";import type { WsTransport } from "./wsTransport.ts"; const baseLocalStatus: VcsStatusLocalResult = {  isRepo: true,  hasPrimaryRemote: true,  isDefaultRef: false,  refName: "feature/demo",  hasWorkingTreeChanges: false,  workingTree: { files: [], insertions: 0, deletions: 0 },}; const baseRemoteStatus: VcsStatusRemoteResult = {  hasUpstream: true,  aheadCount: 0,  behindCount: 0,  pr: null,}; describe("createWsRpcClient", () => {  it("runs beforeReconnect before awaiting transport.reconnect", async () => {    const order: string[] = [];    const transport = {      dispose: vi.fn(async () => undefined),      reconnect: vi.fn(async () => {        order.push("reconnect");      }),      isHeartbeatFresh: vi.fn(() => true),      request: vi.fn(),      requestStream: vi.fn(),      subscribe: vi.fn(() => () => undefined),    } satisfies Pick<      WsTransport,      "dispose" | "isHeartbeatFresh" | "reconnect" | "request" | "requestStream" | "subscribe"    >;     const client = createWsRpcClient(transport as unknown as WsTransport, {      beforeReconnect: () => {        order.push("beforeReconnect");      },    });     await client.reconnect();    expect(order).toEqual(["beforeReconnect", "reconnect"]);  });   it("delegates heartbeat freshness to the transport", () => {    const isHeartbeatFresh = vi.fn(() => true);    const transport = {      dispose: vi.fn(async () => undefined),      reconnect: vi.fn(async () => undefined),      isHeartbeatFresh,      request: vi.fn(),      requestStream: vi.fn(),      subscribe: vi.fn(() => () => undefined),    } satisfies Pick<      WsTransport,      "dispose" | "isHeartbeatFresh" | "reconnect" | "request" | "requestStream" | "subscribe"    >;     const client = createWsRpcClient(transport as unknown as WsTransport);     expect(client.isHeartbeatFresh()).toBe(true);    expect(isHeartbeatFresh).toHaveBeenCalledOnce();  });   it("reduces vcs status stream events into flat status snapshots", () => {    const subscribe = vi.fn(<TValue>(_connect: unknown, listener: (value: TValue) => void) => {      for (const event of [        {          _tag: "snapshot",          local: baseLocalStatus,          remote: null,        },        {          _tag: "remoteUpdated",          remote: baseRemoteStatus,        },        {          _tag: "localUpdated",          local: {            ...baseLocalStatus,            hasWorkingTreeChanges: true,          },        },      ] satisfies VcsStatusStreamEvent[]) {        listener(event as TValue);      }      return () => undefined;    });     const transport = {      dispose: vi.fn(async () => undefined),      reconnect: vi.fn(async () => undefined),      isHeartbeatFresh: vi.fn(() => true),      request: vi.fn(),      requestStream: vi.fn(),      subscribe,    } satisfies Pick<      WsTransport,      "dispose" | "isHeartbeatFresh" | "reconnect" | "request" | "requestStream" | "subscribe"    >;     const client = createWsRpcClient(transport as unknown as WsTransport);    const listener = vi.fn();     client.vcs.onStatus({ cwd: "/repo" }, listener);     expect(listener.mock.calls).toEqual([      [        {          ...baseLocalStatus,          hasUpstream: false,          aheadCount: 0,          behindCount: 0,          aheadOfDefaultCount: 0,          pr: null,        },      ],      [        {          ...baseLocalStatus,          ...baseRemoteStatus,        },      ],      [        {          ...baseLocalStatus,          ...baseRemoteStatus,          hasWorkingTreeChanges: true,        },      ],    ]);  });   it("tags stream subscriptions for targeted resubscribe handling", () => {    const subscribe = vi.fn(() => () => undefined);    const transport = {      dispose: vi.fn(async () => undefined),      reconnect: vi.fn(async () => undefined),      isHeartbeatFresh: vi.fn(() => true),      request: vi.fn(),      requestStream: vi.fn(),      subscribe,    } satisfies Pick<      WsTransport,      "dispose" | "isHeartbeatFresh" | "reconnect" | "request" | "requestStream" | "subscribe"    >;     const client = createWsRpcClient(transport as unknown as WsTransport);    const listener = vi.fn();     client.terminal.onMetadata(listener);    client.vcs.onStatus({ cwd: "/repo" }, listener);    client.server.subscribeConfig(listener);    client.orchestration.subscribeThread({ threadId: ThreadId.make("thread-1") }, listener);     const subscribeCalls = subscribe.mock.calls as unknown as Array<      readonly [unknown, unknown, { readonly tag?: string }?]    >;    expect(subscribeCalls.map((call) => call[2]?.tag)).toEqual([      WS_METHODS.subscribeTerminalMetadata,      WS_METHODS.subscribeVcsStatus,      WS_METHODS.subscribeServerConfig,      ORCHESTRATION_WS_METHODS.subscribeThread,    ]);  });});