package main_test import ( _ "embed" "iter" "slices" "testing" "github.com/matryer/is" cal "go.sour.is/cal" ) func TestEntryParse(t *testing.T) { tests := []struct { entry cal.Entry string string }{ { cal.Entry{ Slate: cal.Slate{ Date: cal.Date{Year: 2024, Month: 5, Day: 14}, }, Title: "make food", Task: cal.Task{ Priority: cal.Priority('A'), }, }, "2024-05-14 [ ] (A) make food", }, { cal.Entry{ Slate: cal.Slate{ Date: cal.Date{Year: 2024, Month: 5, Day: 14}, }, Title: "make food", Event: cal.Event{ StartsAt: cal.Time{Valid: true, Hour: 12}, EndsAt: cal.Time{Valid: true, Hour: 13}, }, }, "2024-05-14 12:00-13:00 make food", }, { cal.Entry{ Slate: cal.Slate{ Date: cal.Date{Year: 2024, Month: 5, Day: 14}, }, Title: "make food", Task: cal.Task{ Priority: cal.Priority('A'), }, Event: cal.Event{ StartsAt: cal.Time{Valid: true, Hour: 12}, EndsAt: cal.Time{Valid: true, Hour: 13}, }, }, "2024-05-14 [ ] (A) 12:00-13:00 make food", }, { cal.Entry{ Slate: cal.Slate{ Date: cal.Date{ Year: 2024, Month: 5, DayOfWeek: []cal.Day{ cal.NewDay(cal.Wednesday, 0), }, }, }, }, "2024-05 Wed", }, { cal.Entry{ Title: "make food", Task: cal.Task{ Priority: cal.Priority('A'), }, }, "[ ] (A) make food", }, { cal.Entry{ Title: "make food @dinner +mealprep due:2024-05-14", Task: cal.Task{ Priority: cal.Priority('A'), }, Contexts: cal.NewSet("dinner"), Projects: cal.NewSet("mealprep"), Attributes: map[string][]string{ "due": {"2024-05-14"}, }, }, "[ ] (A) make food @dinner +mealprep due:2024-05-14", }, { cal.Entry{ Note: "this is a note", }, "- this is a note", }, { cal.Entry{ Note: "this is a note", Slate: cal.Slate{ Date: cal.Date{ Year: 2024, Month: 5, DayOfWeek: []cal.Day{ cal.NewDay(cal.Wednesday, 0), }, }, }, }, "2024-05 Wed - this is a note", }, } for _, tt := range tests { t.Run(tt.string, func(t *testing.T) { is := is.New(t) var entry cal.Entry i, err := entry.Parse(tt.string) is.NoErr(err) compareEntry(t, entry, tt.entry) is.Equal(i, len(tt.string)) }) } } func compareEntry(t *testing.T, a, b cal.Entry) { t.Helper() is := is.New(t) is.Equal(a.Slate, b.Slate) is.Equal(a.Title, b.Title) if !a.Task.IsZero() { is.Equal(a.Task, b.Task) } else { is.True(b.Task.IsZero()) } if !a.Event.IsZero() { is.True(!b.Event.IsZero()) is.Equal(a.Event, b.Event) } else { is.True(b.Event.IsZero()) } if len(a.Contexts) > 0 { is.Equal(a.Contexts, b.Contexts) } if len(a.Projects) > 0 { is.Equal(a.Projects, b.Projects) } if len(a.Attributes) > 0 { is.Equal(a.Attributes, b.Attributes) } } func TestEntriesParse(t *testing.T) { tests := []struct { string string entries cal.Entries }{ { string: `2024-05-14 [ ] (A) make food 2024-05 Wed [ ] one [x] 5 two [ ] (A) three 2025 Jan1 8-9 four`, entries: cal.NewEntries( cal.Entry{ Slate: cal.Slate{ Date: cal.Date{Year: 2024, Month: 5, Day: 14}, }, Title: "make food", Task: cal.Task{ Priority: cal.Priority('A'), }, }, cal.Entry{ Slate: cal.Slate{ Date: cal.Date{Year: 2024, Month: 5, DayOfWeek: []cal.Day{ cal.NewDay(cal.Wednesday, 0), }}, }, Title: "one", Task: cal.Task{}, }, cal.Entry{ Slate: cal.Slate{ Date: cal.Date{Year: 2024, Month: 5, DayOfWeek: []cal.Day{ cal.NewDay(cal.Wednesday, 0), }}, }, Title: "two", Task: cal.Task{ Done: true, }, Event: cal.Event{ StartsAt: cal.Time{Valid: true, Hour: 5}, }, }, cal.Entry{ Slate: cal.Slate{ Date: cal.Date{Year: 2024, Month: 5, DayOfWeek: []cal.Day{ cal.NewDay(cal.Wednesday, 0), }}, }, Title: "three", Task: cal.Task{ Priority: cal.Priority('A'), }, }, cal.Entry{ Slate: cal.Slate{ Date: cal.Date{Year: 2025, MonthOfYear: []cal.Month{cal.NewMonth(cal.January, 1)}}, }, Title: "four", Event: cal.Event{ StartsAt: cal.Time{Valid: true, Hour: 8}, EndsAt: cal.Time{Valid: true, Hour: 9}, }, }, ), }, } for _, tt := range tests { t.Run(tt.string[:15], func(t *testing.T) { is := is.New(t) var entries cal.Entries i, err := entries.Parse(tt.string) ttEntries := slices.Collect(tt.entries.Iter()) for i, entry := range enumerate(entries.Iter()) { compareEntry(t, entry, ttEntries[i]) } is.NoErr(err) is.Equal(i, len(tt.string)) }) } } //go:embed todo.txt var todotxt string func TestFileParse(t *testing.T) { is := is.New(t) var entries cal.Entries i, err := entries.Parse(todotxt) is.NoErr(err) is.Equal(i, len(todotxt)) _ = entries.String() } func enumerate[T any](it iter.Seq[T]) iter.Seq2[int, T] { return func(yield func(int, T) bool) { i := 0 for v := range it { if !yield(i, v) { return } i++ } } }