package gsp import ( "os" "path/filepath" "testing" ) func TestLoadValidateAndFlatten(t *testing.T) { root := t.TempDir() writeTestFile(t, root, "page.gsp", `id: page.lottery.main type: page resolution: L3 context: Lottery page. with: - id: ui.button.primary context: Main action. - feedback.positive refines: page.lottery.base `) writeTestFile(t, root, "button.gsp", `id: ui.button.primary type: ui resolution: L3 context: Primary button. `) writeTestFile(t, root, "feedback.gsp", `id: feedback.positive type: feedback resolution: L2 context: Positive feedback. `) writeTestFile(t, root, "base.gsp", `id: page.lottery.base resolution: L2 context: Base lottery page. `) project, err := LoadProject(root) if err != nil { t.Fatal(err) } report := project.Validate("") if !report.OK { t.Fatalf("expected valid project, got errors: %+v", report.Errors) } flat := project.Flatten("page.lottery.main", -1, Filter{}) got := ids(flat.Units) want := []string{"page.lottery.main", "page.lottery.base", "feedback.positive", "ui.button.primary"} if !sameStrings(got, want) { t.Fatalf("flatten ids = %v, want %v", got, want) } } func TestValidateMissingReference(t *testing.T) { root := t.TempDir() writeTestFile(t, root, "page.gsp", `id: page.missing with: - ui.missing `) project, err := LoadProject(root) if err != nil { t.Fatal(err) } report := project.Validate("") if report.OK { t.Fatal("expected validation failure") } found := false for _, issue := range report.Errors { if issue.Code == "missing_with" { found = true } } if !found { t.Fatalf("expected missing_with error, got %+v", report.Errors) } } func TestStageCheck(t *testing.T) { root := t.TempDir() writeTestFile(t, root, "page.gsp", `id: page.low resolution: L2 `) project, err := LoadProject(root) if err != nil { t.Fatal(err) } report := project.StageCheck("implement") if report.OK { t.Fatal("expected implement stage check to fail") } if report.Errors[0].Code != "low_resolution" { t.Fatalf("expected low_resolution, got %+v", report.Errors) } } func writeTestFile(t *testing.T, root, name, content string) { t.Helper() path := filepath.Join(root, name) if err := os.WriteFile(path, []byte(content), 0644); err != nil { t.Fatal(err) } } func ids(units []*Unit) []string { out := make([]string, 0, len(units)) for _, unit := range units { out = append(out, unit.ID) } return out } func sameStrings(a, b []string) bool { if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true }