package changeset_test import ( "os" "path/filepath" "testing" "github.com/thokra/stamp/internal/changeset" ) func TestParseYAMLFrontmatter(t *testing.T) { content := `--- bumps: my-app: minor my-lib: patch --- Added a cool feature. - Detail one ` cs, err := changeset.ParseBytes("add-feature", []byte(content)) if err != nil { t.Fatalf("unexpected error: %v", err) } if cs.Slug != "add-feature" { t.Errorf("expected slug=add-feature, got %s", cs.Slug) } if cs.Bumps["my-app"] != changeset.BumpMinor { t.Errorf("expected my-app=minor, got %s", cs.Bumps["my-app"]) } if cs.Bumps["my-lib"] != changeset.BumpPatch { t.Errorf("expected my-lib=patch, got %s", cs.Bumps["my-lib"]) } if cs.Description == "" { t.Error("expected non-empty description") } } func TestParseTOMLFrontmatter(t *testing.T) { content := `+++ [bumps] my-app = "major" +++ Breaking change. ` cs, err := changeset.ParseBytes("breaking", []byte(content)) if err != nil { t.Fatalf("unexpected error: %v", err) } if cs.Bumps["my-app"] != changeset.BumpMajor { t.Errorf("expected my-app=major, got %s", cs.Bumps["my-app"]) } } func TestParse_InvalidBumpType(t *testing.T) { content := "---\nbumps:\n my-app: invalid\n---\ndesc\n" _, err := changeset.ParseBytes("test", []byte(content)) if err == nil { t.Fatal("expected error for invalid bump type") } } func TestParse_MissingFrontmatter(t *testing.T) { _, err := changeset.ParseBytes("test", []byte("just some text")) if err == nil { t.Fatal("expected error for missing frontmatter") } } func TestParse_UnterminatedYAML(t *testing.T) { content := "---\nbumps:\n my-app: minor\n" _, err := changeset.ParseBytes("test", []byte(content)) if err == nil { t.Fatal("expected error for unterminated YAML frontmatter") } } func TestWriteAndReadAll(t *testing.T) { dir := t.TempDir() bumps := map[string]changeset.BumpType{ "my-app": changeset.BumpMinor, } if err := changeset.Write(dir, "my-slug", bumps, "A change description"); err != nil { t.Fatalf("Write failed: %v", err) } path := filepath.Join(dir, "my-slug.md") if _, err := os.Stat(path); err != nil { t.Fatalf("expected file to exist: %v", err) } all, err := changeset.ReadAll(dir) if err != nil { t.Fatalf("ReadAll failed: %v", err) } if len(all) != 1 { t.Fatalf("expected 1 changeset, got %d", len(all)) } if all[0].Bumps["my-app"] != changeset.BumpMinor { t.Errorf("expected my-app=minor") } } func TestDeleteAll(t *testing.T) { dir := t.TempDir() bumps := map[string]changeset.BumpType{"x": changeset.BumpPatch} _ = changeset.Write(dir, "to-delete", bumps, "bye") if err := changeset.DeleteAll(dir); err != nil { t.Fatalf("DeleteAll failed: %v", err) } all, _ := changeset.ReadAll(dir) if len(all) != 0 { t.Errorf("expected 0 changesets after delete, got %d", len(all)) } } func TestGenerateSlug(t *testing.T) { slugs := map[string]bool{} for i := 0; i < 20; i++ { s := changeset.GenerateSlug() if s == "" { t.Error("expected non-empty slug") } slugs[s] = true } // With 25 adjectives × 28 nouns = 700 combos, expect most to be unique across 20 runs. if len(slugs) < 5 { t.Errorf("expected more unique slugs, got %d unique from 20 runs", len(slugs)) } }