package git import ( "context" "errors" "strings" "testing" ) func TestParseSymrefHead(t *testing.T) { tests := []struct { name string output string want string wantErr string }{ { name: "symref line followed by the hash line", output: "ref: refs/heads/main\tHEAD\n1a2b3c4d5e6f\tHEAD\n", want: "main", }, { name: "branch with a slash", output: "ref: refs/heads/feature/one\tHEAD\n1a2b3c\tHEAD\n", want: "feature/one", }, { name: "detached head answers only a hash", output: "1a2b3c4d5e6f\tHEAD\n", wantErr: "no symref for HEAD", }, { name: "head pointing at a tag is not a default branch", output: "ref: refs/tags/v1.0\tHEAD\n1a2b3c\tHEAD\n", wantErr: "does not point at a branch", }, { name: "symref for another ref is ignored", output: "ref: refs/heads/other\trefs/remotes/origin/main\n1a2b3c\tHEAD\n", wantErr: "no symref for HEAD", }, { name: "empty output", output: "", wantErr: "no symref for HEAD", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := ParseSymrefHead(tt.output) if tt.wantErr != "" { if err == nil || !strings.Contains(err.Error(), tt.wantErr) { t.Fatalf("ParseSymrefHead(%q) = %q, %v; want error containing %q", tt.output, got, err, tt.wantErr) } return } if err != nil { t.Fatalf("ParseSymrefHead(%q): %v", tt.output, err) } if got != tt.want { t.Fatalf("ParseSymrefHead(%q) = %q, want %q", tt.output, got, tt.want) } }) } } type errRunner struct{} func (errRunner) Run(context.Context, string, []string, string, ...string) (string, error) { return "fatal: could not read from remote repository", errors.New("command git failed: exit status 128") } func (errRunner) LookPath(string) (string, error) { return "/usr/bin/git", nil } func TestRemoteHeadWrapsTheGitFailure(t *testing.T) { _, err := RemoteHead(context.Background(), errRunner{}, "/home", "", "https://example.com/a/b.git") if err == nil || !strings.Contains(err.Error(), "ls-remote") { t.Fatalf("RemoteHead error = %v, want it wrapped as ls-remote", err) } } type captureRunner struct{ env []string } func (c *captureRunner) Run(_ context.Context, _ string, env []string, _ string, _ ...string) (string, error) { c.env = env return "ref: refs/heads/main\tHEAD\n1a2b3c\tHEAD\n", nil } func (c *captureRunner) LookPath(string) (string, error) { return "/usr/bin/git", nil } func TestRemoteHeadSendsTheSourceThroughTheConnectProxy(t *testing.T) { runner := &captureRunner{} got, err := RemoteHead(context.Background(), runner, "/home", "127.0.0.1:9", "https://example.com/a/b.git") if err != nil { t.Fatalf("RemoteHead: %v", err) } if got != "main" { t.Fatalf("RemoteHead = %q, want main", got) } want := "HTTPS_PROXY=http://127.0.0.1:9" for _, entry := range runner.env { if entry == want { return } } t.Fatalf("describe ran without the connect proxy: env = %v, want %s", runner.env, want) }