mirror of
https://github.com/doum1004/llmwiki-cli.git
synced 2026-05-01 08:26:12 +02:00
- Enhance git.test.ts with tests for commit messages with special characters, log limits, diff outputs, branch retrieval, remote addition, file deletion staging, conflict detection, and file-specific logs. - Introduce github.test.ts to validate GitHub API functions including repository listing, filtering, error handling, and repository creation with various scenarios. - Expand index-manager.test.ts to cover entry addition, duplicate handling, reading from missing files, entry removal, and case-insensitive category matching. - Update links.test.ts to ensure proper link resolution, handling of self-referential links, and multiple links to the same target. - Add lint.test.ts for frontmatter edge cases, including handling empty frontmatter, invalid YAML, and ensuring parseable output. - Enhance log-manager.test.ts with tests for empty logs, filtering by type and count, log creation, timestamp format, and preserving entry formats. - Extend read-write.test.ts to skip certain directories, handle deeply nested paths, and ensure consistent path formatting across platforms. - Improve search.test.ts to escape regex characters, filter by directory, manage snippet generation, enforce default limits, and handle searches in empty wikis.
189 lines
6.4 KiB
TypeScript
189 lines
6.4 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from "bun:test";
|
|
import { mkdtemp, rm, writeFile } from "fs/promises";
|
|
import { join } from "path";
|
|
import { tmpdir } from "os";
|
|
import * as git from "../src/lib/git.ts";
|
|
|
|
let testDir: string;
|
|
|
|
beforeEach(async () => {
|
|
testDir = await mkdtemp(join(tmpdir(), "llmwiki-git-"));
|
|
await git.init(testDir);
|
|
// Configure git user for commits
|
|
const { execFile } = await import("child_process");
|
|
const { promisify } = await import("util");
|
|
const exec = promisify(execFile);
|
|
await exec("git", ["config", "user.email", "test@test.com"], { cwd: testDir });
|
|
await exec("git", ["config", "user.name", "Test"], { cwd: testDir });
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await rm(testDir, { recursive: true, force: true });
|
|
});
|
|
|
|
describe("git operations", () => {
|
|
it("commit with changes creates commit", async () => {
|
|
await writeFile(join(testDir, "test.md"), "content", "utf-8");
|
|
await git.addAll(testDir);
|
|
const result = await git.commit(testDir, "test commit");
|
|
expect(result.ok).toBe(true);
|
|
expect(result.output).toContain("test commit");
|
|
});
|
|
|
|
it("commit with no changes reports nothing to commit", async () => {
|
|
// Make an initial commit first
|
|
await writeFile(join(testDir, "init.md"), "init", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "initial");
|
|
|
|
// Try committing with no changes
|
|
const result = await git.commit(testDir, "empty");
|
|
expect(result.ok).toBe(false);
|
|
expect(result.output).toContain("nothing to commit");
|
|
});
|
|
|
|
it("log returns formatted history", async () => {
|
|
await writeFile(join(testDir, "a.md"), "a", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "first commit");
|
|
|
|
await writeFile(join(testDir, "b.md"), "b", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "second commit");
|
|
|
|
const result = await git.log(testDir);
|
|
expect(result.ok).toBe(true);
|
|
expect(result.output).toContain("first commit");
|
|
expect(result.output).toContain("second commit");
|
|
});
|
|
|
|
it("logFile shows history for specific file", async () => {
|
|
await writeFile(join(testDir, "a.md"), "a", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "add a");
|
|
|
|
await writeFile(join(testDir, "b.md"), "b", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "add b");
|
|
|
|
const result = await git.logFile(testDir, "a.md");
|
|
expect(result.ok).toBe(true);
|
|
expect(result.output).toContain("add a");
|
|
expect(result.output).not.toContain("add b");
|
|
});
|
|
|
|
it("diff shows uncommitted changes", async () => {
|
|
await writeFile(join(testDir, "file.md"), "original", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "initial");
|
|
|
|
await writeFile(join(testDir, "file.md"), "modified", "utf-8");
|
|
const result = await git.diff(testDir);
|
|
expect(result.ok).toBe(true);
|
|
expect(result.output).toContain("modified");
|
|
});
|
|
|
|
it("hasRemote returns false for local repo", async () => {
|
|
const result = await git.hasRemote(testDir);
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it("commit message with special characters", async () => {
|
|
await writeFile(join(testDir, "test.md"), "content", "utf-8");
|
|
await git.addAll(testDir);
|
|
const result = await git.commit(testDir, 'fix: handle "quotes" & <angles>');
|
|
expect(result.ok).toBe(true);
|
|
const logResult = await git.log(testDir);
|
|
expect(logResult.output).toContain("fix: handle");
|
|
});
|
|
|
|
it("log respects limit parameter", async () => {
|
|
for (let i = 0; i < 5; i++) {
|
|
await writeFile(join(testDir, `f${i}.md`), `content ${i}`, "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, `commit ${i}`);
|
|
}
|
|
const result = await git.log(testDir, 2);
|
|
expect(result.ok).toBe(true);
|
|
const lines = result.output.split("\n").filter(Boolean);
|
|
expect(lines).toHaveLength(2);
|
|
});
|
|
|
|
it("log on empty repo returns error", async () => {
|
|
const result = await git.log(testDir);
|
|
expect(result.ok).toBe(false);
|
|
});
|
|
|
|
it("diff with ref shows specific commit", async () => {
|
|
await writeFile(join(testDir, "file.md"), "v1", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "first");
|
|
|
|
await writeFile(join(testDir, "file.md"), "v2", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "second");
|
|
|
|
const logResult = await git.log(testDir, 1);
|
|
const hash = logResult.output.split(" ")[0]!;
|
|
const result = await git.diff(testDir, hash);
|
|
expect(result.ok).toBe(true);
|
|
expect(result.output).toContain("second");
|
|
});
|
|
|
|
it("diff with no changes returns empty output", async () => {
|
|
await writeFile(join(testDir, "file.md"), "content", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "initial");
|
|
|
|
const result = await git.diff(testDir);
|
|
expect(result.ok).toBe(true);
|
|
expect(result.output).toBe("");
|
|
});
|
|
|
|
it("currentBranch returns branch name", async () => {
|
|
await writeFile(join(testDir, "init.md"), "init", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "initial");
|
|
|
|
const branch = await git.currentBranch(testDir);
|
|
expect(["main", "master"]).toContain(branch);
|
|
});
|
|
|
|
it("addRemote adds a remote", async () => {
|
|
const result = await git.addRemote(testDir, "origin", "https://example.com/repo.git");
|
|
expect(result.ok).toBe(true);
|
|
const hasRemoteNow = await git.hasRemote(testDir);
|
|
expect(hasRemoteNow).toBe(true);
|
|
});
|
|
|
|
it("addAll stages file deletions", async () => {
|
|
await writeFile(join(testDir, "delete-me.md"), "to be deleted", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "add file");
|
|
|
|
const { rm: rmFile } = await import("fs/promises");
|
|
await rmFile(join(testDir, "delete-me.md"));
|
|
await git.addAll(testDir);
|
|
const result = await git.commit(testDir, "delete file");
|
|
expect(result.ok).toBe(true);
|
|
});
|
|
|
|
it("hasConflicts returns false when no conflicts", async () => {
|
|
await writeFile(join(testDir, "file.md"), "content", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "initial");
|
|
|
|
const result = await git.hasConflicts(testDir);
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it("logFile returns empty for file with no commits", async () => {
|
|
await writeFile(join(testDir, "a.md"), "a", "utf-8");
|
|
await git.addAll(testDir);
|
|
await git.commit(testDir, "add a");
|
|
|
|
const result = await git.logFile(testDir, "nonexistent.md");
|
|
expect(result.output).toBe("");
|
|
});
|
|
});
|