chore: import upstream snapshot with attribution
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
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
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user