fix: Map expansion now matches nested child steps (gt-8tmz.33)
The map rule was only iterating over top-level steps, missing nested children. Now uses buildStepMap to include all steps at any depth. Added test case for map expansion over nested children. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -112,10 +112,12 @@ func ApplyExpansions(steps []*Step, compose *ComposeRules, parser *Parser) ([]*S
|
||||
return nil, fmt.Errorf("map: %q has no template steps", rule.With)
|
||||
}
|
||||
|
||||
// Find all matching steps
|
||||
// Find all matching steps (including nested children - gt-8tmz.33)
|
||||
// Rebuild stepMap to capture any changes from previous expansions
|
||||
stepMap = buildStepMap(result)
|
||||
var toExpand []*Step
|
||||
for _, step := range result {
|
||||
if MatchGlob(rule.Select, step.ID) && !expanded[step.ID] {
|
||||
for id, step := range stepMap {
|
||||
if MatchGlob(rule.Select, id) && !expanded[id] {
|
||||
toExpand = append(toExpand, step)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +287,59 @@ func TestApplyExpansions(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
// Test map over nested children (gt-8tmz.33)
|
||||
t.Run("map over nested children", func(t *testing.T) {
|
||||
steps := []*Step{
|
||||
{ID: "design", Title: "Design"},
|
||||
{
|
||||
ID: "phase",
|
||||
Title: "Implementation Phase",
|
||||
Children: []*Step{
|
||||
{ID: "implement.auth", Title: "Implement auth"},
|
||||
{ID: "implement.api", Title: "Implement API"},
|
||||
},
|
||||
},
|
||||
{ID: "test", Title: "Test"},
|
||||
}
|
||||
|
||||
compose := &ComposeRules{
|
||||
Map: []*MapRule{
|
||||
{Select: "*.auth", With: "rule-of-five"},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := ApplyExpansions(steps, compose, parser)
|
||||
if err != nil {
|
||||
t.Fatalf("ApplyExpansions failed: %v", err)
|
||||
}
|
||||
|
||||
// The nested implement.auth should be expanded
|
||||
// Result should have: design, phase (with expanded children), test
|
||||
if len(result) != 3 {
|
||||
t.Fatalf("expected 3 top-level steps, got %d", len(result))
|
||||
}
|
||||
|
||||
// Check that phase has expanded children
|
||||
phase := result[1]
|
||||
if phase.ID != "phase" {
|
||||
t.Fatalf("expected phase step, got %q", phase.ID)
|
||||
}
|
||||
|
||||
// implement.auth expanded to 2 steps + implement.api unchanged = 3 children
|
||||
if len(phase.Children) != 3 {
|
||||
t.Fatalf("expected 3 children in phase, got %d: %v", len(phase.Children), getChildIDs(phase.Children))
|
||||
}
|
||||
|
||||
// Verify expanded IDs
|
||||
childIDs := getChildIDs(phase.Children)
|
||||
expectedChildren := []string{"implement.auth.draft", "implement.auth.refine", "implement.api"}
|
||||
for i, exp := range expectedChildren {
|
||||
if childIDs[i] != exp {
|
||||
t.Errorf("phase.Children[%d].ID = %q, want %q", i, childIDs[i], exp)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Test missing formula
|
||||
t.Run("missing expansion formula", func(t *testing.T) {
|
||||
steps := []*Step{{ID: "test", Title: "Test"}}
|
||||
@@ -370,3 +423,12 @@ func TestUpdateDependenciesForExpansion(t *testing.T) {
|
||||
t.Errorf("deploy step DependsOn[1] = %q, want %q", result[2].DependsOn[1], "test")
|
||||
}
|
||||
}
|
||||
|
||||
// getChildIDs extracts IDs from a slice of steps (helper for tests).
|
||||
func getChildIDs(steps []*Step) []string {
|
||||
ids := make([]string, len(steps))
|
||||
for i, s := range steps {
|
||||
ids[i] = s.ID
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user