277 lines
5.1 KiB
Go

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++
}
}
}