* feat: Redesign git changes to split stage/unstaged files. Signed-off-by: Paolo Insogna <paolo@cowtech.it> * fixup Signed-off-by: Paolo Insogna <paolo@cowtech.it> * fixup Signed-off-by: Paolo Insogna <paolo@cowtech.it> * refactor: streamline git changes panel * fix: label staged and working diff tabs * fix: isolate staged and working diff files * fix: scope staged and working diff updates * fix: scope git row revert to working changes --------- Signed-off-by: Paolo Insogna <paolo@cowtech.it> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
113 lines
3.5 KiB
TypeScript
113 lines
3.5 KiB
TypeScript
import { describe, expect, test } from "bun:test"
|
|
import type { GitAPI, GitStatus } from "./api/types"
|
|
import { getGitStatus, stageGitFile, stageGitFiles, unstageGitFile, unstageGitFiles } from "./gitApi"
|
|
|
|
const status: GitStatus = {
|
|
current: "main",
|
|
tracking: null,
|
|
ahead: 0,
|
|
behind: 0,
|
|
files: [],
|
|
isClean: true,
|
|
}
|
|
|
|
const withRuntimeGit = async (git: GitAPI, callback: () => Promise<void>) => {
|
|
const previousWindowDescriptor = Object.getOwnPropertyDescriptor(globalThis, "window")
|
|
Object.defineProperty(globalThis, "window", {
|
|
configurable: true,
|
|
value: {
|
|
__OPENCHAMBER_RUNTIME_APIS__: { git },
|
|
},
|
|
})
|
|
|
|
try {
|
|
await callback()
|
|
} finally {
|
|
if (previousWindowDescriptor) {
|
|
Object.defineProperty(globalThis, "window", previousWindowDescriptor)
|
|
} else {
|
|
delete (globalThis as { window?: Window }).window
|
|
}
|
|
}
|
|
}
|
|
|
|
describe("getGitStatus", () => {
|
|
test("forwards light-mode options to runtime git APIs", async () => {
|
|
let received: { directory: string; options?: { mode?: "light" } } | null = null
|
|
const runtimeGit = {
|
|
getGitStatus: async (directory: string, options?: { mode?: "light" }) => {
|
|
received = { directory, options }
|
|
return status
|
|
},
|
|
} as Partial<GitAPI> as GitAPI
|
|
|
|
await withRuntimeGit(runtimeGit, async () => {
|
|
await getGitStatus("/repo", { mode: "light" })
|
|
})
|
|
|
|
expect(received).toEqual({ directory: "/repo", options: { mode: "light" } })
|
|
})
|
|
})
|
|
|
|
describe("git index mutations", () => {
|
|
test("forwards bulk stage requests to runtime git APIs", async () => {
|
|
let received: { directory: string; paths: string[] } | null = null
|
|
const runtimeGit = {
|
|
stageGitFiles: async (directory: string, paths: string[]) => {
|
|
received = { directory, paths }
|
|
},
|
|
} as Partial<GitAPI> as GitAPI
|
|
|
|
await withRuntimeGit(runtimeGit, async () => {
|
|
await stageGitFiles("/repo", ["a.ts", "b.ts"])
|
|
})
|
|
|
|
expect(received).toEqual({ directory: "/repo", paths: ["a.ts", "b.ts"] })
|
|
})
|
|
|
|
test("forwards bulk unstage requests to runtime git APIs", async () => {
|
|
let received: { directory: string; paths: string[] } | null = null
|
|
const runtimeGit = {
|
|
unstageGitFiles: async (directory: string, paths: string[]) => {
|
|
received = { directory, paths }
|
|
},
|
|
} as Partial<GitAPI> as GitAPI
|
|
|
|
await withRuntimeGit(runtimeGit, async () => {
|
|
await unstageGitFiles("/repo", ["a.ts", "b.ts"])
|
|
})
|
|
|
|
expect(received).toEqual({ directory: "/repo", paths: ["a.ts", "b.ts"] })
|
|
})
|
|
|
|
test("keeps single-file stage wrapper routed to runtime single-file API", async () => {
|
|
let received: { directory: string; path: string } | null = null
|
|
const runtimeGit = {
|
|
stageGitFile: async (directory: string, path: string) => {
|
|
received = { directory, path }
|
|
},
|
|
} as Partial<GitAPI> as GitAPI
|
|
|
|
await withRuntimeGit(runtimeGit, async () => {
|
|
await stageGitFile("/repo", "a.ts")
|
|
})
|
|
|
|
expect(received).toEqual({ directory: "/repo", path: "a.ts" })
|
|
})
|
|
|
|
test("keeps single-file unstage wrapper routed to runtime single-file API", async () => {
|
|
let received: { directory: string; path: string } | null = null
|
|
const runtimeGit = {
|
|
unstageGitFile: async (directory: string, path: string) => {
|
|
received = { directory, path }
|
|
},
|
|
} as Partial<GitAPI> as GitAPI
|
|
|
|
await withRuntimeGit(runtimeGit, async () => {
|
|
await unstageGitFile("/repo", "a.ts")
|
|
})
|
|
|
|
expect(received).toEqual({ directory: "/repo", path: "a.ts" })
|
|
})
|
|
})
|