Преглед на файлове

test: 添加 Git 工具函数单元测试 (测试计划 08)

为 normalizeGitRemoteUrl 添加 18 个测试用例,覆盖 SSH、HTTPS、
ssh://、CCR 代理 URL 格式、大小写规范化及边界条件。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
claude-code-best преди 3 седмици
родител
ревизия
3df4b95ff9
променени са 1 файла, в които са добавени 124 реда и са изтрити 0 реда
  1. 124 0
      src/utils/__tests__/git.test.ts

+ 124 - 0
src/utils/__tests__/git.test.ts

@@ -0,0 +1,124 @@
+import { describe, expect, test } from "bun:test";
+import { normalizeGitRemoteUrl } from "../git";
+
+describe("normalizeGitRemoteUrl", () => {
+  describe("SSH format (git@host:owner/repo)", () => {
+    test("normalizes basic SSH URL", () => {
+      expect(normalizeGitRemoteUrl("git@github.com:owner/repo.git")).toBe(
+        "github.com/owner/repo"
+      );
+    });
+
+    test("handles SSH URL without .git suffix", () => {
+      expect(normalizeGitRemoteUrl("git@github.com:owner/repo")).toBe(
+        "github.com/owner/repo"
+      );
+    });
+
+    test("handles nested paths", () => {
+      expect(normalizeGitRemoteUrl("git@gitlab.com:group/sub/repo.git")).toBe(
+        "gitlab.com/group/sub/repo"
+      );
+    });
+  });
+
+  describe("HTTPS format", () => {
+    test("normalizes basic HTTPS URL", () => {
+      expect(
+        normalizeGitRemoteUrl("https://github.com/owner/repo.git")
+      ).toBe("github.com/owner/repo");
+    });
+
+    test("handles HTTPS without .git suffix", () => {
+      expect(normalizeGitRemoteUrl("https://github.com/owner/repo")).toBe(
+        "github.com/owner/repo"
+      );
+    });
+
+    test("handles HTTP URL", () => {
+      expect(normalizeGitRemoteUrl("http://github.com/owner/repo.git")).toBe(
+        "github.com/owner/repo"
+      );
+    });
+
+    test("handles HTTPS with auth", () => {
+      expect(
+        normalizeGitRemoteUrl("https://user@github.com/owner/repo.git")
+      ).toBe("github.com/owner/repo");
+    });
+  });
+
+  describe("ssh:// format", () => {
+    test("normalizes ssh:// URL", () => {
+      expect(
+        normalizeGitRemoteUrl("ssh://git@github.com/owner/repo")
+      ).toBe("github.com/owner/repo");
+    });
+
+    test("handles ssh:// with .git suffix", () => {
+      expect(
+        normalizeGitRemoteUrl("ssh://git@github.com/owner/repo.git")
+      ).toBe("github.com/owner/repo");
+    });
+  });
+
+  describe("CCR proxy URLs", () => {
+    test("handles legacy proxy format (assumes github.com)", () => {
+      expect(
+        normalizeGitRemoteUrl(
+          "http://local_proxy@127.0.0.1:16583/git/owner/repo"
+        )
+      ).toBe("github.com/owner/repo");
+    });
+
+    test("handles GHE proxy format (host in path)", () => {
+      expect(
+        normalizeGitRemoteUrl(
+          "http://local_proxy@127.0.0.1:16583/git/ghe.company.com/owner/repo"
+        )
+      ).toBe("ghe.company.com/owner/repo");
+    });
+
+    test("handles localhost proxy", () => {
+      expect(
+        normalizeGitRemoteUrl(
+          "http://proxy@localhost:8080/git/owner/repo"
+        )
+      ).toBe("github.com/owner/repo");
+    });
+  });
+
+  describe("case normalization", () => {
+    test("converts to lowercase", () => {
+      expect(normalizeGitRemoteUrl("git@GitHub.COM:Owner/Repo.git")).toBe(
+        "github.com/owner/repo"
+      );
+    });
+
+    test("converts HTTPS to lowercase", () => {
+      expect(
+        normalizeGitRemoteUrl("https://GitHub.COM/Owner/Repo.git")
+      ).toBe("github.com/owner/repo");
+    });
+  });
+
+  describe("edge cases", () => {
+    test("returns null for empty string", () => {
+      expect(normalizeGitRemoteUrl("")).toBeNull();
+    });
+
+    test("returns null for whitespace only", () => {
+      expect(normalizeGitRemoteUrl("   ")).toBeNull();
+    });
+
+    test("returns null for unrecognized format", () => {
+      expect(normalizeGitRemoteUrl("not-a-url")).toBeNull();
+    });
+
+    test("trims whitespace before parsing", () => {
+      expect(
+        normalizeGitRemoteUrl("  git@github.com:owner/repo.git  ")
+      ).toBe("github.com/owner/repo");
+    });
+  });
+});