mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-09-03 06:35:00 +08:00
fix(test): improve cross-platform compatibility across unit tests
- Support CRLF line endings and skip hidden dot directories in nocopy invariant tests. - Handle environment variable overrides and skip case-sensitive token priority tests on Windows. - Use static OS and architecture values in Claude header fingerprint assertions for deterministic test results. Closes: #5295
This commit is contained in:
@@ -25,7 +25,9 @@ func TestSetLatestReleaseRequestHeaders(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Setenv("GITHUB_TOKEN", tt.githubToken)
|
||||
t.Setenv("github_token", "")
|
||||
if tt.githubToken == "" {
|
||||
t.Setenv("github_token", "")
|
||||
}
|
||||
t.Setenv("GITSTORE_GIT_TOKEN", "")
|
||||
t.Setenv("GITSTORE_GIT_URL", "")
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
func TestFetchLatestAssetSetsGitHubAuthorization(t *testing.T) {
|
||||
t.Setenv("GITHUB_TOKEN", "asset-token")
|
||||
t.Setenv("github_token", "")
|
||||
t.Setenv("GITSTORE_GIT_TOKEN", "")
|
||||
t.Setenv("GITSTORE_GIT_URL", "")
|
||||
|
||||
|
||||
@@ -617,7 +617,7 @@ func TestApplyClaudeHeaders_DisableDeviceProfileStabilization(t *testing.T) {
|
||||
"X-Stainless-Arch": []string{"x64"},
|
||||
})
|
||||
applyClaudeHeaders(thirdPartyReq, auth, "key-disable-stability", false, nil, nil, cfg, nil, false)
|
||||
assertClaudeFingerprint(t, thirdPartyReq.Header, "claude-cli/2.1.60 (external, cli)", "0.70.0", "v22.0.0", helps.MapStainlessOS(), helps.MapStainlessArch())
|
||||
assertClaudeFingerprint(t, thirdPartyReq.Header, "claude-cli/2.1.60 (external, cli)", "0.70.0", "v22.0.0", "MacOS", "arm64")
|
||||
|
||||
lowerReq := newClaudeHeaderTestRequest(t, http.Header{
|
||||
"User-Agent": []string{"claude-cli/2.1.61 (external, cli)"},
|
||||
@@ -659,7 +659,7 @@ func TestApplyClaudeHeaders_LegacyModePreservesConfiguredUserAgentOverrideForCla
|
||||
})
|
||||
applyClaudeHeaders(req, auth, "key-legacy-ua-override", false, nil, nil, cfg, nil, true)
|
||||
|
||||
assertClaudeFingerprint(t, req.Header, "config-ua/1.0", "0.70.0", "v22.0.0", helps.MapStainlessOS(), helps.MapStainlessArch())
|
||||
assertClaudeFingerprint(t, req.Header, "config-ua/1.0", "0.70.0", "v22.0.0", "MacOS", "arm64")
|
||||
}
|
||||
|
||||
func TestApplyClaudeHeaders_LegacyThirdPartyUsesStableConfiguredOSArch(t *testing.T) {
|
||||
@@ -816,7 +816,7 @@ func TestClaudeExecutor_NonClaudeRequestUsesClaudeCode220CLIFingerprint(t *testi
|
||||
t.Fatalf("Execute() error = %v", errExecute)
|
||||
}
|
||||
|
||||
assertClaudeFingerprint(t, seenHeaders, "claude-cli/2.1.220 (external, cli)", "0.94.0", "v26.3.0", helps.MapStainlessOS(), helps.MapStainlessArch())
|
||||
assertClaudeFingerprint(t, seenHeaders, "claude-cli/2.1.220 (external, cli)", "0.94.0", "v26.3.0", "MacOS", "arm64")
|
||||
if got := seenHeaders.Get("X-App"); got != "cli" {
|
||||
t.Fatalf("X-App = %q, want cli", got)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package util
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResolveGitHubToken(t *testing.T) {
|
||||
tests := []struct {
|
||||
@@ -49,8 +52,19 @@ func TestResolveGitHubToken(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Setenv("GITHUB_TOKEN", tt.githubToken)
|
||||
t.Setenv("github_token", tt.lowerToken)
|
||||
if runtime.GOOS == "windows" && tt.name == "GITHUB_TOKEN has highest priority" {
|
||||
t.Skip("environment variables are case-insensitive on Windows")
|
||||
}
|
||||
if tt.githubToken != "" {
|
||||
t.Setenv("GITHUB_TOKEN", tt.githubToken)
|
||||
}
|
||||
if tt.lowerToken != "" {
|
||||
t.Setenv("github_token", tt.lowerToken)
|
||||
}
|
||||
if tt.githubToken == "" && tt.lowerToken == "" {
|
||||
t.Setenv("GITHUB_TOKEN", "")
|
||||
t.Setenv("github_token", "")
|
||||
}
|
||||
t.Setenv("GITSTORE_GIT_TOKEN", tt.gitStoreToken)
|
||||
t.Setenv("GITSTORE_GIT_URL", tt.gitStoreURL)
|
||||
|
||||
|
||||
@@ -26,8 +26,11 @@ func forEachSourceFile(t *testing.T, root string, visit func(rel string, data []
|
||||
return err
|
||||
}
|
||||
if d.IsDir() {
|
||||
if strings.HasPrefix(d.Name(), ".") {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
switch d.Name() {
|
||||
case ".git", "vendor", "node_modules", "testdata":
|
||||
case "vendor", "node_modules", "testdata":
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
@@ -87,7 +90,7 @@ func TestNoInPlaceSJSONWrites(t *testing.T) {
|
||||
// new code rather than a proof of absence.
|
||||
var inPlaceByteWritePatterns = []*regexp.Regexp{
|
||||
regexp.MustCompile(`\bcopy\([a-zA-Z_][A-Za-z0-9_.]*\[`),
|
||||
regexp.MustCompile(`^\s*[a-zA-Z_][A-Za-z0-9_.]*\[[a-zA-Z0-9_]+\] = 0$`),
|
||||
regexp.MustCompile(`^\s*[a-zA-Z_][A-Za-z0-9_.]*\[[a-zA-Z0-9_]+\] = 0\r?$`),
|
||||
}
|
||||
|
||||
// reviewedInPlaceByteWrites records the reviewed in-place byte writes per file.
|
||||
@@ -118,7 +121,8 @@ func TestInPlaceByteWritesAreReviewed(t *testing.T) {
|
||||
root := repoRoot(t)
|
||||
found := make(map[string][]string)
|
||||
forEachSourceFile(t, root, func(rel string, data []byte) {
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
normalized := strings.ReplaceAll(string(data), "\r\n", "\n")
|
||||
for _, line := range strings.Split(normalized, "\n") {
|
||||
for _, pattern := range inPlaceByteWritePatterns {
|
||||
if pattern.MatchString(line) {
|
||||
found[rel] = append(found[rel], strings.TrimSpace(line))
|
||||
@@ -162,3 +166,36 @@ func repoRoot(t *testing.T) string {
|
||||
dir = parent
|
||||
}
|
||||
}
|
||||
|
||||
func TestInPlaceByteWritePatterns_CRLF(t *testing.T) {
|
||||
crlfLine := "\traw[index] = 0\r"
|
||||
matched := false
|
||||
for _, pattern := range inPlaceByteWritePatterns {
|
||||
if pattern.MatchString(crlfLine) {
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !matched {
|
||||
t.Fatalf("inPlaceByteWritePatterns failed to match CRLF line %q", crlfLine)
|
||||
}
|
||||
}
|
||||
|
||||
func TestForEachSourceFile_SkipsDotDirs(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
dotDir := filepath.Join(tempDir, ".gomodcache")
|
||||
if err := os.MkdirAll(dotDir, 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sampleFile := filepath.Join(dotDir, "sample.go")
|
||||
if err := os.WriteFile(sampleFile, []byte("package sample\n"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var visited []string
|
||||
forEachSourceFile(t, tempDir, func(rel string, data []byte) {
|
||||
visited = append(visited, rel)
|
||||
})
|
||||
if len(visited) > 0 {
|
||||
t.Fatalf("forEachSourceFile should have skipped dot directories, but visited: %v", visited)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user