mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-05 08:10:14 +00:00
348 lines
11 KiB
TypeScript
348 lines
11 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
|
|
import { ExecException } from "child_process"
|
|
|
|
import { jest } from "@jest/globals"
|
|
|
|
import { searchCommits, getCommitInfo, getWorkingState } from "../git"
|
|
|
|
type ExecFunction = (
|
|
command: string,
|
|
options: { cwd?: string },
|
|
callback: (error: ExecException | null, result?: { stdout: string; stderr: string }) => void,
|
|
) => void
|
|
|
|
type PromisifiedExec = (command: string, options?: { cwd?: string }) => Promise<{ stdout: string; stderr: string }>
|
|
|
|
// Mock child_process.exec
|
|
jest.mock("child_process", () => ({
|
|
exec: jest.fn(),
|
|
}))
|
|
|
|
// Mock util.promisify to return our own mock function
|
|
jest.mock("util", () => ({
|
|
promisify: jest.fn((fn: ExecFunction): PromisifiedExec => {
|
|
return async (command: string, options?: { cwd?: string }) => {
|
|
// Call the original mock to maintain the mock implementation
|
|
return new Promise((resolve, reject) => {
|
|
fn(
|
|
command,
|
|
options || {},
|
|
(error: ExecException | null, result?: { stdout: string; stderr: string }) => {
|
|
if (error) {
|
|
reject(error)
|
|
} else {
|
|
resolve(result!)
|
|
}
|
|
},
|
|
)
|
|
})
|
|
}
|
|
}),
|
|
}))
|
|
|
|
// Mock extract-text
|
|
jest.mock("../../integrations/misc/extract-text", () => ({
|
|
truncateOutput: jest.fn((text) => text),
|
|
}))
|
|
|
|
describe("git utils", () => {
|
|
// Get the mock with proper typing
|
|
const { exec } = jest.requireMock("child_process") as { exec: jest.MockedFunction<ExecFunction> }
|
|
const cwd = "/test/path"
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
describe("searchCommits", () => {
|
|
const mockCommitData = [
|
|
"abc123def456",
|
|
"abc123",
|
|
"fix: test commit",
|
|
"John Doe",
|
|
"2024-01-06",
|
|
"def456abc789",
|
|
"def456",
|
|
"feat: new feature",
|
|
"Jane Smith",
|
|
"2024-01-05",
|
|
].join("\n")
|
|
|
|
it("should return commits when git is installed and repo exists", async () => {
|
|
// Set up mock responses
|
|
const responses = new Map([
|
|
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
|
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
|
[
|
|
'git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short --grep="test" --regexp-ignore-case',
|
|
{ stdout: mockCommitData, stderr: "" },
|
|
],
|
|
])
|
|
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
// Find matching response
|
|
for (const [cmd, response] of responses) {
|
|
if (command === cmd) {
|
|
callback(null, response)
|
|
return
|
|
}
|
|
}
|
|
callback(new Error(`Unexpected command: ${command}`))
|
|
})
|
|
|
|
const result = await searchCommits("test", cwd)
|
|
|
|
// First verify the result is correct
|
|
expect(result).toHaveLength(2)
|
|
expect(result[0]).toEqual({
|
|
hash: "abc123def456",
|
|
shortHash: "abc123",
|
|
subject: "fix: test commit",
|
|
author: "John Doe",
|
|
date: "2024-01-06",
|
|
})
|
|
|
|
// Then verify all commands were called correctly
|
|
expect(exec).toHaveBeenCalledWith("git --version", {}, expect.any(Function))
|
|
expect(exec).toHaveBeenCalledWith("git rev-parse --git-dir", { cwd }, expect.any(Function))
|
|
expect(exec).toHaveBeenCalledWith(
|
|
'git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short --grep="test" --regexp-ignore-case',
|
|
{ cwd },
|
|
expect.any(Function),
|
|
)
|
|
})
|
|
|
|
it("should return empty array when git is not installed", async () => {
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
if (command === "git --version") {
|
|
callback(new Error("git not found"))
|
|
return
|
|
}
|
|
callback(new Error("Unexpected command"))
|
|
})
|
|
|
|
const result = await searchCommits("test", cwd)
|
|
expect(result).toEqual([])
|
|
expect(exec).toHaveBeenCalledWith("git --version", {}, expect.any(Function))
|
|
})
|
|
|
|
it("should return empty array when not in a git repository", async () => {
|
|
const responses = new Map([
|
|
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
|
["git rev-parse --git-dir", null], // null indicates error should be called
|
|
])
|
|
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
const response = responses.get(command)
|
|
if (response === null) {
|
|
callback(new Error("not a git repository"))
|
|
} else if (response) {
|
|
callback(null, response)
|
|
} else {
|
|
callback(new Error("Unexpected command"))
|
|
}
|
|
})
|
|
|
|
const result = await searchCommits("test", cwd)
|
|
expect(result).toEqual([])
|
|
expect(exec).toHaveBeenCalledWith("git --version", {}, expect.any(Function))
|
|
expect(exec).toHaveBeenCalledWith("git rev-parse --git-dir", { cwd }, expect.any(Function))
|
|
})
|
|
|
|
it("should handle hash search when grep search returns no results", async () => {
|
|
const responses = new Map([
|
|
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
|
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
|
[
|
|
'git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short --grep="abc123" --regexp-ignore-case',
|
|
{ stdout: "", stderr: "" },
|
|
],
|
|
[
|
|
'git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short --author-date-order abc123',
|
|
{ stdout: mockCommitData, stderr: "" },
|
|
],
|
|
])
|
|
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
for (const [cmd, response] of responses) {
|
|
if (command === cmd) {
|
|
callback(null, response)
|
|
return
|
|
}
|
|
}
|
|
callback(new Error("Unexpected command"))
|
|
})
|
|
|
|
const result = await searchCommits("abc123", cwd)
|
|
expect(result).toHaveLength(2)
|
|
expect(result[0]).toEqual({
|
|
hash: "abc123def456",
|
|
shortHash: "abc123",
|
|
subject: "fix: test commit",
|
|
author: "John Doe",
|
|
date: "2024-01-06",
|
|
})
|
|
})
|
|
})
|
|
|
|
describe("getCommitInfo", () => {
|
|
const mockCommitInfo = [
|
|
"abc123def456",
|
|
"abc123",
|
|
"fix: test commit",
|
|
"John Doe",
|
|
"2024-01-06",
|
|
"Detailed description",
|
|
].join("\n")
|
|
const mockStats = "1 file changed, 2 insertions(+), 1 deletion(-)"
|
|
const mockDiff = "@@ -1,1 +1,2 @@\n-old line\n+new line"
|
|
|
|
it("should return formatted commit info", async () => {
|
|
const responses = new Map([
|
|
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
|
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
|
[
|
|
'git show --format="%H%n%h%n%s%n%an%n%ad%n%b" --no-patch abc123',
|
|
{ stdout: mockCommitInfo, stderr: "" },
|
|
],
|
|
['git show --stat --format="" abc123', { stdout: mockStats, stderr: "" }],
|
|
['git show --format="" abc123', { stdout: mockDiff, stderr: "" }],
|
|
])
|
|
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
for (const [cmd, response] of responses) {
|
|
if (command.startsWith(cmd)) {
|
|
callback(null, response)
|
|
return
|
|
}
|
|
}
|
|
callback(new Error("Unexpected command"))
|
|
})
|
|
|
|
const result = await getCommitInfo("abc123", cwd)
|
|
expect(result).toContain("Commit: abc123")
|
|
expect(result).toContain("Author: John Doe")
|
|
expect(result).toContain("Files Changed:")
|
|
expect(result).toContain("Full Changes:")
|
|
})
|
|
|
|
it("should return error message when git is not installed", async () => {
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
if (command === "git --version") {
|
|
callback(new Error("git not found"))
|
|
return
|
|
}
|
|
callback(new Error("Unexpected command"))
|
|
})
|
|
|
|
const result = await getCommitInfo("abc123", cwd)
|
|
expect(result).toBe("Git is not installed")
|
|
})
|
|
|
|
it("should return error message when not in a git repository", async () => {
|
|
const responses = new Map([
|
|
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
|
["git rev-parse --git-dir", null], // null indicates error should be called
|
|
])
|
|
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
const response = responses.get(command)
|
|
if (response === null) {
|
|
callback(new Error("not a git repository"))
|
|
} else if (response) {
|
|
callback(null, response)
|
|
} else {
|
|
callback(new Error("Unexpected command"))
|
|
}
|
|
})
|
|
|
|
const result = await getCommitInfo("abc123", cwd)
|
|
expect(result).toBe("Not a git repository")
|
|
})
|
|
})
|
|
|
|
describe("getWorkingState", () => {
|
|
const mockStatus = " M src/file1.ts\n?? src/file2.ts"
|
|
const mockDiff = "@@ -1,1 +1,2 @@\n-old line\n+new line"
|
|
|
|
it("should return working directory changes", async () => {
|
|
const responses = new Map([
|
|
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
|
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
|
["git status --short", { stdout: mockStatus, stderr: "" }],
|
|
["git diff HEAD", { stdout: mockDiff, stderr: "" }],
|
|
])
|
|
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
for (const [cmd, response] of responses) {
|
|
if (command === cmd) {
|
|
callback(null, response)
|
|
return
|
|
}
|
|
}
|
|
callback(new Error("Unexpected command"))
|
|
})
|
|
|
|
const result = await getWorkingState(cwd)
|
|
expect(result).toContain("Working directory changes:")
|
|
expect(result).toContain("src/file1.ts")
|
|
expect(result).toContain("src/file2.ts")
|
|
})
|
|
|
|
it("should return message when working directory is clean", async () => {
|
|
const responses = new Map([
|
|
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
|
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
|
["git status --short", { stdout: "", stderr: "" }],
|
|
])
|
|
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
for (const [cmd, response] of responses) {
|
|
if (command === cmd) {
|
|
callback(null, response)
|
|
return
|
|
}
|
|
}
|
|
callback(new Error("Unexpected command"))
|
|
})
|
|
|
|
const result = await getWorkingState(cwd)
|
|
expect(result).toBe("No changes in working directory")
|
|
})
|
|
|
|
it("should return error message when git is not installed", async () => {
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
if (command === "git --version") {
|
|
callback(new Error("git not found"))
|
|
return
|
|
}
|
|
callback(new Error("Unexpected command"))
|
|
})
|
|
|
|
const result = await getWorkingState(cwd)
|
|
expect(result).toBe("Git is not installed")
|
|
})
|
|
|
|
it("should return error message when not in a git repository", async () => {
|
|
const responses = new Map([
|
|
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
|
["git rev-parse --git-dir", null], // null indicates error should be called
|
|
])
|
|
|
|
exec.mockImplementation((command: string, options: { cwd?: string }, callback: Function) => {
|
|
const response = responses.get(command)
|
|
if (response === null) {
|
|
callback(new Error("not a git repository"))
|
|
} else if (response) {
|
|
callback(null, response)
|
|
} else {
|
|
callback(new Error("Unexpected command"))
|
|
}
|
|
})
|
|
|
|
const result = await getWorkingState(cwd)
|
|
expect(result).toBe("Not a git repository")
|
|
})
|
|
})
|
|
})
|