Skip to content
Source
Sign inSign up

vcs.test.ts

68 lines2.3 KB

1import type { VcsStatusResult } from "@t3tools/contracts";
2import { AsyncResult, Atom, AtomRegistry } from "effect/reactivity";
3import { describe, expect, it, vi } from "vite-plus/test";
4​
5import { chatGitStatusAtom } from "./vcs";
6​
7vi.mock("../connection/runtime", () => ({ connectionAtomRuntime: {} }));
8vi.mock("@t3tools/client-runtime/state/vcs", () => ({
9 createVcsActionManager: () => ({}),
10 createVcsEnvironmentAtoms: () => ({}),
11 createVcsStatusRevalidationAtomFamily: () => () => null,
12}));
13​
14const status = (changes: Partial<VcsStatusResult> = {}) =>
15 AsyncResult.success({
16 isRepo: true,
17 hasPrimaryRemote: true,
18 isDefaultRef: true,
19 refName: "main",
20 hasWorkingTreeChanges: true,
21 workingTree: { files: [], insertions: 1, deletions: 0 },
22 hasUpstream: true,
23 aheadCount: 0,
24 behindCount: 0,
25 pr: null,
26 ...changes,
27 } satisfies VcsStatusResult);
28​
29describe("chatGitStatusAtom", () => {
30 it("notifies only when a field the chat view reads changes", () => {
31 const registry = AtomRegistry.make();
32 const source = Atom.make<AsyncResult.AsyncResult<VcsStatusResult, never>>(status());
33 const selected = chatGitStatusAtom(source as never);
34 const notified: unknown[] = [];
35 const unsubscribe = registry.subscribe(selected, (value) => notified.push(value));
36 registry.get(selected);
37 notified.length = 0;
38​
39 registry.set(
40 source,
41 status({ workingTree: { files: [], insertions: 2, deletions: 0 }, aheadCount: 1 }),
42 );
43 expect(notified).toEqual([]);
44​
45 registry.set(source, status({ refName: "feature" }));
46 expect(notified).toHaveLength(1);
47​
48 registry.set(source, status({ refName: "feature", hasWorkingTreeChanges: false }));
49 expect(notified).toHaveLength(2);
50​
51 const pr = () => ({
52 number: 42,
53 title: "Feature PR",
54 url: "https://github.com/pingdotgg/t3code/pull/42",
55 baseRef: "main",
56 headRef: "feature",
57 state: "open" as const,
58 });
59 const linked = { refName: "feature", hasWorkingTreeChanges: false };
60 registry.set(source, status({ ...linked, pr: pr() }));
61 expect(notified).toHaveLength(3);
62​
63 // A new object with the same data, as each remote status refresh sends.
64 registry.set(source, status({ ...linked, pr: pr() }));
65 expect(notified).toHaveLength(3);
66 unsubscribe();
67 });
68});