You've already forked agentic-coding-workflow
bugfix
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
package orchestrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/yan1h/agent-coding-workflow/internal/project"
|
||||
)
|
||||
|
||||
type fakeGateArtifacts struct {
|
||||
byPhase map[project.Phase]int // phase → 产物数
|
||||
}
|
||||
|
||||
func (f fakeGateArtifacts) ListArtifacts(_ context.Context, _, _ uuid.UUID, phase project.Phase) ([]*project.Artifact, error) {
|
||||
n := f.byPhase[phase]
|
||||
out := make([]*project.Artifact, 0, n)
|
||||
for i := 0; i < n; i++ {
|
||||
out = append(out, &project.Artifact{Phase: phase, Version: i + 1})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type fakeGateIssues struct{ open int }
|
||||
|
||||
func (f fakeGateIssues) CountOpenIssues(_ context.Context, _ uuid.UUID) (int, error) {
|
||||
return f.open, nil
|
||||
}
|
||||
|
||||
func gateRun() *Run {
|
||||
return &Run{ID: uuid.New(), ProjectID: uuid.New(), RequirementID: uuid.New()}
|
||||
}
|
||||
|
||||
func TestGate_PassOnEndTurnWithArtifact(t *testing.T) {
|
||||
g := NewV1Gate(fakeGateArtifacts{byPhase: map[project.Phase]int{project.PhasePlanning: 1}}, nil)
|
||||
step := &Step{Phase: project.PhasePlanning}
|
||||
res, err := g.Evaluate(context.Background(), gateRun(), step, "end_turn")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !res.Pass {
|
||||
t.Errorf("expected pass; got %+v", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGate_RetryOnEndTurnMissingArtifact(t *testing.T) {
|
||||
g := NewV1Gate(fakeGateArtifacts{byPhase: map[project.Phase]int{}}, nil)
|
||||
step := &Step{Phase: project.PhasePlanning}
|
||||
res, err := g.Evaluate(context.Background(), gateRun(), step, "end_turn")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Pass || !res.Retry {
|
||||
t.Errorf("expected no-pass retryable; got %+v", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGate_FailNoRetryOnRefusalAndMaxTokens(t *testing.T) {
|
||||
g := NewV1Gate(fakeGateArtifacts{byPhase: map[project.Phase]int{project.PhasePlanning: 1}}, nil)
|
||||
step := &Step{Phase: project.PhasePlanning}
|
||||
for _, sr := range []string{"refusal", "max_tokens"} {
|
||||
res, err := g.Evaluate(context.Background(), gateRun(), step, sr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Pass || res.Retry {
|
||||
t.Errorf("stopReason %q: expected fail no-retry; got %+v", sr, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGate_RetryOnEmptyOrCancelled(t *testing.T) {
|
||||
g := NewV1Gate(fakeGateArtifacts{byPhase: map[project.Phase]int{project.PhasePlanning: 1}}, nil)
|
||||
step := &Step{Phase: project.PhasePlanning}
|
||||
for _, sr := range []string{"", "cancelled"} {
|
||||
res, err := g.Evaluate(context.Background(), gateRun(), step, sr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Pass || !res.Retry {
|
||||
t.Errorf("stopReason %q: expected retryable; got %+v", sr, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGate_ReviewingRequiresNoOpenIssues(t *testing.T) {
|
||||
arts := fakeGateArtifacts{byPhase: map[project.Phase]int{project.PhaseReviewing: 1}}
|
||||
step := &Step{Phase: project.PhaseReviewing}
|
||||
|
||||
gOpen := NewV1Gate(arts, fakeGateIssues{open: 2})
|
||||
res, _ := gOpen.Evaluate(context.Background(), gateRun(), step, "end_turn")
|
||||
if res.Pass || !res.Retry {
|
||||
t.Errorf("open issues should block reviewing (retryable); got %+v", res)
|
||||
}
|
||||
|
||||
gClean := NewV1Gate(arts, fakeGateIssues{open: 0})
|
||||
res, _ = gClean.Evaluate(context.Background(), gateRun(), step, "end_turn")
|
||||
if !res.Pass {
|
||||
t.Errorf("no open issues should pass reviewing; got %+v", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGate_DonePassesOnEndTurn(t *testing.T) {
|
||||
g := NewV1Gate(nil, nil)
|
||||
step := &Step{Phase: project.PhaseDone}
|
||||
res, _ := g.Evaluate(context.Background(), gateRun(), step, "end_turn")
|
||||
if !res.Pass {
|
||||
t.Errorf("done should pass on end_turn; got %+v", res)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user