package cockpit import ( "strings" "testing" ) func TestCursorRender_Structure(t *testing.T) { pb := loadHandover(t) out, err := cursorRenderer{}.Render(pb) if err != nil { t.Fatalf("Render: %v", err) } got := string(out) if !strings.HasPrefix(got, "---\ndescription: ") { t.Errorf("output does not open with .mdc frontmatter:\n%s", got[:min(120, len(got))]) } for _, want := range []string{"globs:", "alwaysApply: false", advisoryBanner, "## " + headingForbidden, "## " + headingAllowed, "## " + headingOutput} { if !strings.Contains(got, want) { t.Errorf("rendered .mdc missing %q", want) } } // Every forbidden phrase must appear verbatim (honesty: can't silently drop). for _, ph := range pb.Intent.Forbidden { if !strings.Contains(got, ph) { t.Errorf("rendered .mdc missing forbidden phrase %q", ph) } } // Every step heading is present. if n := strings.Count(got, "## "+headingStep); n < len(pb.Steps) { t.Errorf("rendered .mdc has %d step headings, want >= %d", n, len(pb.Steps)) } } func TestCursorRender_Deterministic(t *testing.T) { pb := loadHandover(t) a, err := cursorRenderer{}.Render(pb) if err != nil { t.Fatal(err) } b, err := cursorRenderer{}.Render(pb) if err != nil { t.Fatal(err) } if string(a) != string(b) { t.Error("cursor render not deterministic") } } func TestCursorRelPath(t *testing.T) { pb := loadHandover(t) if got := (cursorRenderer{}).RelPath(pb); got != ".cursor/rules/handover.mdc" { t.Errorf("RelPath = %q, want .cursor/rules/handover.mdc", got) } } func TestCursorRender_RejectsMultilineDescription(t *testing.T) { pb := loadHandover(t) pb.Description = "line one\nline two" if _, err := (cursorRenderer{}).Render(pb); err == nil { t.Error("expected an error for a multi-line description") } } func TestCursorEnforcement(t *testing.T) { if got := (cursorRenderer{}).Enforcement(); got != EnforcementAdvisory { t.Errorf("cursor enforcement = %v, want advisory", got) } }