cli_version_test.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package claude
  2. import "testing"
  3. func TestIsSupportedCLIVersion(t *testing.T) {
  4. cases := []struct {
  5. name string
  6. version string
  7. want bool
  8. }{
  9. {"内置基线本身", CLICurrentVersion, true},
  10. {"高于基线的补丁位", "2.1.259", true},
  11. {"高于基线的次版本", "2.2.0", true},
  12. {"高于基线的主版本", "3.0.0", true},
  13. {"低于基线", "2.1.219", false},
  14. {"远低于基线", "1.0.0", false},
  15. {"空值", "", false},
  16. {"只有两段", "2.2", false},
  17. {"带 v 前缀", "v2.2.0", false},
  18. {"预发布后缀", "2.2.0-local", false},
  19. {"构建元数据", "2.2.0+build1", false},
  20. {"哨兵版本带后缀", "999.0.0-local", false},
  21. {"纯数字哨兵仍然合法(形态没问题,运维自负)", "999.0.0", true},
  22. {"非数字", "abc", false},
  23. {"多余的段", "2.2.0.1", false},
  24. }
  25. for _, tc := range cases {
  26. t.Run(tc.name, func(t *testing.T) {
  27. if got := IsSupportedCLIVersion(tc.version); got != tc.want {
  28. t.Fatalf("IsSupportedCLIVersion(%q) = %v, want %v", tc.version, got, tc.want)
  29. }
  30. })
  31. }
  32. }
  33. func TestResolveCLIVersion(t *testing.T) {
  34. cases := []struct {
  35. name string
  36. raw string
  37. want string
  38. }{
  39. {"未配置时用内置基线", "", CLICurrentVersion},
  40. {"只有空白等同未配置", " ", CLICurrentVersion},
  41. {"合法覆盖生效", "2.1.259", "2.1.259"},
  42. {"两侧空白被裁掉", " 2.1.259 ", "2.1.259"},
  43. {"非法值回落基线", "not-a-version", CLICurrentVersion},
  44. {"向下覆盖被拒", "2.0.0", CLICurrentVersion},
  45. {"预发布后缀被拒(会毒化账号指纹)", "2.2.0-local", CLICurrentVersion},
  46. }
  47. for _, tc := range cases {
  48. t.Run(tc.name, func(t *testing.T) {
  49. if got := resolveCLIVersion(tc.raw); got != tc.want {
  50. t.Fatalf("resolveCLIVersion(%q) = %q, want %q", tc.raw, got, tc.want)
  51. }
  52. })
  53. }
  54. }
  55. // 伪装身份的自洽性:User-Agent 头里的版本号必须与 CLIVersion() 一致。
  56. // 两者由不同代码路径写入同一个请求,不一致会被上游判为非正版客户端。
  57. func TestDefaultHeadersUserAgentMatchesCLIVersion(t *testing.T) {
  58. want := "claude-cli/" + CLIVersion() + " (external, cli)"
  59. if got := DefaultHeaders["User-Agent"]; got != want {
  60. t.Fatalf("DefaultHeaders[User-Agent] = %q, want %q", got, want)
  61. }
  62. }
  63. // 没有配置覆盖时,CLIVersion() 必须等于内置基线——保证本 PR 对既有部署零行为变化。
  64. func TestCLIVersionDefaultsToBuiltinPin(t *testing.T) {
  65. if got := CLIVersion(); got != CLICurrentVersion {
  66. t.Fatalf("CLIVersion() = %q, want built-in pin %q (测试进程未设置 %s)", got, CLICurrentVersion, CLIVersionEnv)
  67. }
  68. }