package vociferate import ( "os" "path/filepath" "testing" ) func TestNormalizeRepoURL(t *testing.T) { t.Parallel() tests := []struct { name string remoteURL string wantURL string wantOK bool }{ {name: "https", remoteURL: "https://git.hrafn.xyz/aether/vociferate.git", wantURL: "https://git.hrafn.xyz/aether/vociferate", wantOK: true}, {name: "http", remoteURL: "http://teapot:3000/aether/vociferate.git", wantURL: "http://teapot:3000/aether/vociferate", wantOK: true}, {name: "ssh with scheme", remoteURL: "ssh://git@git.hrafn.xyz/aether/vociferate.git", wantURL: "https://git.hrafn.xyz/aether/vociferate", wantOK: true}, {name: "scp style", remoteURL: "git@git.hrafn.xyz:aether/vociferate.git", wantURL: "https://git.hrafn.xyz/aether/vociferate", wantOK: true}, {name: "empty", remoteURL: "", wantURL: "", wantOK: false}, {name: "unsupported scheme", remoteURL: "ftp://example.com/repo.git", wantURL: "", wantOK: false}, {name: "invalid ssh missing user", remoteURL: "ssh://git.hrafn.xyz/aether/vociferate.git", wantURL: "", wantOK: false}, {name: "invalid scp style", remoteURL: "git.hrafn.xyz:aether/vociferate.git", wantURL: "", wantOK: false}, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() gotURL, gotOK := normalizeRepoURL(tt.remoteURL) if gotOK != tt.wantOK { t.Fatalf("normalizeRepoURL(%q) ok = %v, want %v", tt.remoteURL, gotOK, tt.wantOK) } if gotURL != tt.wantURL { t.Fatalf("normalizeRepoURL(%q) url = %q, want %q", tt.remoteURL, gotURL, tt.wantURL) } }) } } func TestParseSemver(t *testing.T) { t.Parallel() tests := []struct { name string input string want semver wantErr bool }{ {name: "valid", input: "1.2.3", want: semver{major: 1, minor: 2, patch: 3}, wantErr: false}, {name: "missing part", input: "1.2", wantErr: true}, {name: "non numeric", input: "1.two.3", wantErr: true}, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := parseSemver(tt.input) if tt.wantErr { if err == nil { t.Fatalf("parseSemver(%q) expected error", tt.input) } return } if err != nil { t.Fatalf("parseSemver(%q) unexpected error: %v", tt.input, err) } if got != tt.want { t.Fatalf("parseSemver(%q) = %+v, want %+v", tt.input, got, tt.want) } }) } } func TestOriginRemoteURLFromGitConfig(t *testing.T) { t.Parallel() t.Run("origin exists", func(t *testing.T) { t.Parallel() config := "[core]\n\trepositoryformatversion = 0\n[remote \"origin\"]\n\turl = git@git.hrafn.xyz:aether/vociferate.git\n" url, ok := originRemoteURLFromGitConfig(config) if !ok { t.Fatal("expected origin url to be found") } if url != "git@git.hrafn.xyz:aether/vociferate.git" { t.Fatalf("unexpected url: %q", url) } }) t.Run("origin missing", func(t *testing.T) { t.Parallel() config := "[core]\n\trepositoryformatversion = 0\n[remote \"upstream\"]\n\turl = git@git.hrafn.xyz:aether/vociferate.git\n" _, ok := originRemoteURLFromGitConfig(config) if ok { t.Fatal("expected origin url to be absent") } }) } func TestDeriveRepositoryURLFromGitConfigFallback(t *testing.T) { t.Setenv("GITHUB_SERVER_URL", "") t.Setenv("GITHUB_REPOSITORY", "") root := t.TempDir() configPath := filepath.Join(root, ".git", "config") if err := os.MkdirAll(filepath.Dir(configPath), 0o755); err != nil { t.Fatalf("mkdir .git: %v", err) } if err := os.WriteFile(configPath, []byte("[remote \"origin\"]\n\turl = git@git.hrafn.xyz:aether/vociferate.git\n"), 0o644); err != nil { t.Fatalf("write git config: %v", err) } url, ok := deriveRepositoryURL(root) if !ok { t.Fatal("expected repository URL from git config") } if url != "https://git.hrafn.xyz/aether/vociferate" { t.Fatalf("unexpected repository URL: %q", url) } }