Go 71 lines
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)
}
}