Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

147 lines
3.6 KiB
Go

package forge
import (
"testing"
"time"
)
func TestClassifyStatus(t *testing.T) {
now := time.Now()
old := now.AddDate(0, 0, -45)
recent := now.AddDate(0, 0, -2)
tests := []struct {
name string
pr PR
defaultBase string
wantState string
wantMismatch bool
wantBlockers []string
}{
{
name: "draft wins over everything",
pr: PR{IsDraft: true, BaseRef: "feature", ReviewDecision: "CHANGES_REQUESTED", UpdatedAt: recent},
wantState: "DRAFT",
// base unset so no mismatch; blockers = draft + changes-requested
wantBlockers: []string{"draft", "changes-requested"},
},
{
name: "base mismatch",
pr: PR{BaseRef: "develop", UpdatedAt: recent},
defaultBase: "main",
wantState: "BASE_MISMATCH",
wantMismatch: true,
wantBlockers: []string{"base-mismatch"},
},
{
name: "changes requested",
pr: PR{BaseRef: "main", ReviewDecision: "CHANGES_REQUESTED", UpdatedAt: recent},
defaultBase: "main",
wantState: "CHANGES_REQUESTED",
wantBlockers: []string{"changes-requested"},
},
{
name: "approved",
pr: PR{BaseRef: "main", ReviewDecision: "APPROVED", UpdatedAt: recent},
defaultBase: "main",
wantState: "APPROVED",
},
{
name: "stale by age",
pr: PR{BaseRef: "main", UpdatedAt: old},
defaultBase: "main",
wantState: "STALE",
},
{
name: "ready",
pr: PR{BaseRef: "main", UpdatedAt: recent},
defaultBase: "main",
wantState: "READY",
},
{
name: "ci failure adds a blocker",
pr: PR{BaseRef: "main", CIRollup: "FAILURE", UpdatedAt: recent},
defaultBase: "main",
wantState: "READY",
wantBlockers: []string{"ci-failure"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ClassifyStatus(tt.pr, tt.defaultBase)
if got.State != tt.wantState {
t.Errorf("State = %q, want %q", got.State, tt.wantState)
}
if got.BaseMismatch != tt.wantMismatch {
t.Errorf("BaseMismatch = %v, want %v", got.BaseMismatch, tt.wantMismatch)
}
if tt.wantBlockers != nil {
if !sameStringSet(got.Blockers, tt.wantBlockers) {
t.Errorf("Blockers = %v, want %v", got.Blockers, tt.wantBlockers)
}
}
})
}
}
func TestRollupCI(t *testing.T) {
tests := []struct {
in string
want string
}{
{"", "NONE"},
{"NONE", "NONE"},
{"FAILURE", "FAILURE"},
{"PENDING", "PENDING"},
{"SUCCESS", "SUCCESS"},
{"garbage", "NONE"},
}
for _, tt := range tests {
if got := RollupCI(PR{CIRollup: tt.in}); got != tt.want {
t.Errorf("RollupCI(%q) = %q, want %q", tt.in, got, tt.want)
}
}
}
func TestCollapseStates(t *testing.T) {
tests := []struct {
name string
states []string
want string
}{
{"empty", nil, "NONE"},
{"all success", []string{"success", "success"}, "SUCCESS"},
{"any failure", []string{"success", "failure"}, "FAILURE"},
{"error counts as failure", []string{"success", "error"}, "FAILURE"},
{"pending no failure", []string{"success", "pending"}, "PENDING"},
{"in_progress is pending", []string{"in_progress"}, "PENDING"},
{"failure beats pending", []string{"pending", "failure"}, "FAILURE"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := collapseStates(tt.states); got != tt.want {
t.Errorf("collapseStates(%v) = %q, want %q", tt.states, got, tt.want)
}
})
}
}
func sameStringSet(a, b []string) bool {
if len(a) != len(b) {
return false
}
seen := map[string]int{}
for _, s := range a {
seen[s]++
}
for _, s := range b {
seen[s]--
}
for _, n := range seen {
if n != 0 {
return false
}
}
return true
}