repository.test.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import { describe, expect, test } from "bun:test"
  2. import path from "path"
  3. import { pathToFileURL } from "url"
  4. import { Global } from "@kirincode-ai/core/global"
  5. import {
  6. InvalidRepositoryBranchError,
  7. InvalidRepositoryReferenceError,
  8. UnsupportedLocalRepositoryError,
  9. isFileRepositoryReference,
  10. isRemoteRepositoryReference,
  11. parseRemoteRepositoryReference,
  12. parseRepositoryReference,
  13. repositoryCacheIdentity,
  14. repositoryCachePath,
  15. sameRepositoryReference,
  16. validateRepositoryBranch,
  17. } from "../../src/util/repository"
  18. describe("util.repository", () => {
  19. test("parses github shorthand and preserves cache path", () => {
  20. const reference = parseRemoteRepositoryReference("owner/repo")
  21. expect(reference).toMatchObject({
  22. host: "github.com",
  23. path: "owner/repo",
  24. segments: ["owner", "repo"],
  25. owner: "owner",
  26. repo: "repo",
  27. label: "owner/repo",
  28. })
  29. expect(repositoryCachePath(reference)).toBe(path.join(Global.Path.repos, "github.com", "owner", "repo"))
  30. expect(repositoryCacheIdentity(reference)).toBe("github.com/owner/repo")
  31. })
  32. test("parses host path and scp remote references", () => {
  33. const hostPath = parseRemoteRepositoryReference("gitlab.com/group/repo")
  34. const scp = parseRemoteRepositoryReference("git@github.com:owner/repo.git")
  35. expect(hostPath).toMatchObject({
  36. host: "gitlab.com",
  37. path: "group/repo",
  38. remote: "https://gitlab.com/group/repo.git",
  39. label: "gitlab.com/group/repo",
  40. })
  41. expect(scp).toMatchObject({
  42. host: "github.com",
  43. path: "owner/repo",
  44. remote: "git@github.com:owner/repo.git",
  45. label: "owner/repo",
  46. })
  47. })
  48. test("keeps local file repositories distinct from remote repositories", () => {
  49. const localPath = path.resolve("repo.git")
  50. const reference = parseRepositoryReference(pathToFileURL(localPath).href)
  51. expect(reference).toMatchObject({
  52. host: "file",
  53. protocol: "file:",
  54. label: localPath,
  55. })
  56. expect(reference && isFileRepositoryReference(reference)).toBe(true)
  57. expect(reference && isRemoteRepositoryReference(reference)).toBe(false)
  58. expect(() => parseRemoteRepositoryReference(pathToFileURL(localPath).href)).toThrow(
  59. "Local file repositories are not supported",
  60. )
  61. expect(() => parseRemoteRepositoryReference(pathToFileURL(localPath).href)).toThrow(UnsupportedLocalRepositoryError)
  62. })
  63. test("rejects invalid remote repository references with typed errors", () => {
  64. expect(() => parseRemoteRepositoryReference("not-a-repo")).toThrow(InvalidRepositoryReferenceError)
  65. expect(() => parseRemoteRepositoryReference("git@github.com:../../../etc/passwd")).toThrow(
  66. InvalidRepositoryReferenceError,
  67. )
  68. })
  69. test("compares cache identity independent of input spelling", () => {
  70. const shorthand = parseRemoteRepositoryReference("owner/repo")
  71. const url = parseRemoteRepositoryReference("https://github.com/owner/repo.git")
  72. const hostPath = parseRemoteRepositoryReference("github.com/owner/repo")
  73. expect(sameRepositoryReference(shorthand, url)).toBe(true)
  74. expect(sameRepositoryReference(shorthand, hostPath)).toBe(true)
  75. })
  76. test("validates repository branch names", () => {
  77. expect(() => validateRepositoryBranch("feature/docs.v1")).not.toThrow()
  78. expect(() => validateRepositoryBranch("-bad")).toThrow("Branch must contain only alphanumeric characters")
  79. expect(() => validateRepositoryBranch("bad..branch")).toThrow("Branch must contain only alphanumeric characters")
  80. expect(() => validateRepositoryBranch("bad branch")).toThrow("Branch must contain only alphanumeric characters")
  81. expect(() => validateRepositoryBranch("bad branch")).toThrow(InvalidRepositoryBranchError)
  82. })
  83. })