refactor: reduce CRAP scores in router/workflow/notification
- llm_router.go: Extract getStringFromMap, firstNonEmpty, paramResolver - buildCronSpec: 12 → 4 complexity - buildParameters: 9 → 5 complexity - routing_workflow.go: Extract stateMachine, stateResult types - RoutingWorkflow: 11 → 6 complexity - Separate executeTask/executePass/executeFail - notification.go: Extract checker interface pattern - DeploymentPreCheckActivity: 10 → 5 complexity - goCheckers() returns language-specific checkers - Added 7 new test cases for helper functions - Coverage: internal/routing 63.6% → 66.0%
This commit is contained in:
@@ -278,6 +278,193 @@ func TestBuildRetryPolicy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStringFromMap(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
m map[string]interface{}
|
||||
key string
|
||||
expected string
|
||||
}{
|
||||
{"nil map", nil, "key", ""},
|
||||
{"missing key", map[string]interface{}{"a": "b"}, "key", ""},
|
||||
{"found string", map[string]interface{}{"key": "value"}, "key", "value"},
|
||||
{"non-string value", map[string]interface{}{"key": 123}, "key", ""},
|
||||
{"empty string", map[string]interface{}{"key": ""}, "key", ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := getStringFromMap(tt.m, tt.key)
|
||||
if got != tt.expected {
|
||||
t.Errorf("getStringFromMap() = %q, want %q", got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFirstNonEmpty(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
values []string
|
||||
expected string
|
||||
}{
|
||||
{"all empty", []string{"", "", ""}, ""},
|
||||
{"first non-empty", []string{"first", "second"}, "first"},
|
||||
{"second non-empty", []string{"", "second", "third"}, "second"},
|
||||
{"last non-empty", []string{"", "", "last"}, "last"},
|
||||
{"no values", []string{}, ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := firstNonEmpty(tt.values...)
|
||||
if got != tt.expected {
|
||||
t.Errorf("firstNonEmpty() = %q, want %q", got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCommonInputField(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expected bool
|
||||
}{
|
||||
{"repo", true},
|
||||
{"path", true},
|
||||
{"branch", true},
|
||||
{"unknown", false},
|
||||
{"Repository", false}, // case-sensitive
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := isCommonInputField(tt.name)
|
||||
if got != tt.expected {
|
||||
t.Errorf("isCommonInputField(%q) = %v, want %v", tt.name, got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildCronSpecScheduleSources(t *testing.T) {
|
||||
kb, err := LoadKnowledgeBaseFromDefaultPath()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load knowledge base: %v", err)
|
||||
}
|
||||
|
||||
router := &LLMRouter{knowledgeBase: kb}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
intentSchedule string
|
||||
intentTimezone string
|
||||
paramSchedule string
|
||||
paramTimezone string
|
||||
wantSchedule string
|
||||
wantTimezone string
|
||||
}{
|
||||
{
|
||||
name: "from intent",
|
||||
intentSchedule: "0 2 * * *",
|
||||
intentTimezone: "PST",
|
||||
wantSchedule: "0 2 * * *",
|
||||
wantTimezone: "PST",
|
||||
},
|
||||
{
|
||||
name: "from params",
|
||||
paramSchedule: "0 3 * * *",
|
||||
paramTimezone: "EST",
|
||||
wantSchedule: "0 3 * * *",
|
||||
wantTimezone: "EST",
|
||||
},
|
||||
{
|
||||
name: "default UTC",
|
||||
wantSchedule: "",
|
||||
wantTimezone: "UTC",
|
||||
},
|
||||
{
|
||||
name: "intent priority",
|
||||
intentSchedule: "0 1 * * *",
|
||||
intentTimezone: "UTC",
|
||||
paramSchedule: "0 2 * * *",
|
||||
paramTimezone: "PST",
|
||||
wantSchedule: "0 1 * * *",
|
||||
wantTimezone: "UTC",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
intent := &Intent{
|
||||
Activities: []string{"CloneRepoActivity"},
|
||||
Parameters: map[string]interface{}{},
|
||||
IsCron: true,
|
||||
CronSchedule: tt.intentSchedule,
|
||||
CronTimezone: tt.intentTimezone,
|
||||
WorkflowName: "test",
|
||||
}
|
||||
if tt.paramSchedule != "" {
|
||||
intent.Parameters["cronSchedule"] = tt.paramSchedule
|
||||
}
|
||||
if tt.paramTimezone != "" {
|
||||
intent.Parameters["cronTimezone"] = tt.paramTimezone
|
||||
}
|
||||
|
||||
input := LLMRouterInput{Message: "test"}
|
||||
spec, err := router.buildCronSpec(intent, input)
|
||||
if err != nil {
|
||||
t.Fatalf("buildCronSpec failed: %v", err)
|
||||
}
|
||||
|
||||
if spec.Schedule != tt.wantSchedule {
|
||||
t.Errorf("schedule = %q, want %q", spec.Schedule, tt.wantSchedule)
|
||||
}
|
||||
if spec.Timezone != tt.wantTimezone {
|
||||
t.Errorf("timezone = %q, want %q", spec.Timezone, tt.wantTimezone)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamResolverFromPrevOutput(t *testing.T) {
|
||||
kb, err := LoadKnowledgeBaseFromDefaultPath()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load knowledge base: %v", err)
|
||||
}
|
||||
|
||||
resolver := ¶mResolver{
|
||||
intent: &Intent{
|
||||
Activities: []string{"CloneRepoActivity", "AnalyzeCodeActivity"},
|
||||
Parameters: map[string]interface{}{},
|
||||
},
|
||||
kb: kb,
|
||||
prevState: "CloneRepoActivity",
|
||||
}
|
||||
|
||||
// Should find matching output from CloneRepoActivity
|
||||
got := resolver.fromPrevOutput("path")
|
||||
if got == nil {
|
||||
t.Error("expected to find path from prev output")
|
||||
}
|
||||
if got != "${CloneRepoActivity.output.path}" {
|
||||
t.Errorf("got %v, want ${CloneRepoActivity.output.path}", got)
|
||||
}
|
||||
|
||||
// Should not find non-existent output
|
||||
got = resolver.fromPrevOutput("nonexistent")
|
||||
if got != nil {
|
||||
t.Errorf("expected nil for nonexistent, got %v", got)
|
||||
}
|
||||
|
||||
// Empty prevState should return nil
|
||||
resolver.prevState = ""
|
||||
got = resolver.fromPrevOutput("path")
|
||||
if got != nil {
|
||||
t.Errorf("expected nil for empty prevState, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntentJSONMarshal(t *testing.T) {
|
||||
intent := &Intent{
|
||||
Activities: []string{"CloneRepoActivity"},
|
||||
|
||||
Reference in New Issue
Block a user