package notes import ( "os" "path/filepath" "testing" "time" ) func TestAdd_WritesFilenameAndVerbatimBody(t *testing.T) { dir := t.TempDir() now := time.Date(2026, 5, 22, 14, 3, 0, 0, time.UTC) body := "check round-robin fairness in queue promotion" path, err := Add(dir, body, now) if err != nil { t.Fatal(err) } wantName := "2026-05-22-140300-check-round-robin-fairness-in.md" if got := filepath.Base(path); got != wantName { t.Errorf("filename = %q, want %q", got, wantName) } b, err := os.ReadFile(path) if err != nil { t.Fatal(err) } if string(b) != body { t.Errorf("body = %q, want verbatim %q", string(b), body) } } func TestAdd_CreatesDirIfMissing(t *testing.T) { dir := filepath.Join(t.TempDir(), "notes") if _, err := Add(dir, "scribble", time.Now()); err != nil { t.Fatal(err) } if info, err := os.Stat(dir); err != nil || !info.IsDir() { t.Errorf("notes dir not created: %v", err) } } func TestAdd_RejectsEmptyText(t *testing.T) { dir := t.TempDir() for _, in := range []string{"", " ", "\t\n"} { if _, err := Add(dir, in, time.Now()); err == nil { t.Errorf("Add(%q) = nil error, want rejection", in) } } } func TestList_NewestFirst(t *testing.T) { dir := t.TempDir() older := time.Date(2026, 5, 21, 9, 11, 0, 0, time.UTC) newer := time.Date(2026, 5, 22, 14, 3, 0, 0, time.UTC) if _, err := Add(dir, "older note", older); err != nil { t.Fatal(err) } if _, err := Add(dir, "newer note", newer); err != nil { t.Fatal(err) } got, err := List(dir) if err != nil { t.Fatal(err) } if len(got) != 2 { t.Fatalf("len = %d, want 2", len(got)) } if got[0].Summary != "newer note" || got[1].Summary != "older note" { t.Errorf("order = [%q, %q], want newest first", got[0].Summary, got[1].Summary) } if !got[0].When.Equal(newer) { t.Errorf("When = %v, want %v parsed from filename", got[0].When, newer) } } func TestList_MissingDirEmpty(t *testing.T) { got, err := List(filepath.Join(t.TempDir(), "absent")) if err != nil { t.Fatalf("err = %v, want nil for missing dir", err) } if len(got) != 0 { t.Errorf("len = %d, want 0", len(got)) } } func TestList_SummaryIsFirstNonBlankLine(t *testing.T) { dir := t.TempDir() if _, err := Add(dir, "\n\n first real line\nsecond line", time.Now()); err != nil { t.Fatal(err) } got, err := List(dir) if err != nil { t.Fatal(err) } if len(got) != 1 || got[0].Summary != "first real line" { t.Errorf("summary = %q, want %q", got[0].Summary, "first real line") } } func TestList_IgnoresNonMarkdown(t *testing.T) { dir := t.TempDir() if _, err := Add(dir, "real note", time.Now()); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "stray.txt"), []byte("x"), 0o644); err != nil { t.Fatal(err) } if err := os.Mkdir(filepath.Join(dir, "sub"), 0o755); err != nil { t.Fatal(err) } got, err := List(dir) if err != nil { t.Fatal(err) } if len(got) != 1 { t.Errorf("len = %d, want 1 (only the .md note)", len(got)) } } func TestSlug(t *testing.T) { cases := []struct{ in, want string }{ {"check round-robin fairness in queue promotion", "check-round-robin-fairness-in"}, {"Hello, World!", "hello-world"}, {"!!!", "note"}, {"", "note"}, {" ", "note"}, {"a", "a"}, } for _, c := range cases { if got := slug(c.in); got != c.want { t.Errorf("slug(%q) = %q, want %q", c.in, got, c.want) } } }