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