638 lines
11 KiB
Go

package main_test
import (
"fmt"
"iter"
"strings"
"testing"
"time"
"github.com/matryer/is"
cal "go.sour.is/cal"
)
func TestDay(t *testing.T) {
tests := []struct {
name string
dayOfWeek cal.Day
weekOfMonth int
string string
}{
{
"test monday 0",
cal.Monday,
0,
"Mon",
},
{
"test monday 1",
cal.Monday,
1,
"1Mon",
},
{
"test monday 5",
cal.Monday,
5,
"5Mon",
},
{
"test monday -1",
cal.Monday,
-1,
"-1Mon",
},
{
"test monday -5",
cal.Monday,
-5,
"-5Mon",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
is := is.New(t)
day := cal.NewDay(tt.dayOfWeek, tt.weekOfMonth)
is.Equal(day.Day(), tt.dayOfWeek)
is.Equal(day.WeekOfMonth(), tt.weekOfMonth)
is.Equal(day.String(), tt.string)
})
}
}
func TestMonth(t *testing.T) {
tests := []struct {
month cal.Month
dayOfMonth int
string string
}{
{
cal.January,
0,
"Jan",
},
{
cal.February,
1,
"Feb1",
},
{
cal.March,
31,
"Mar31",
},
{month: cal.April, string: "Apr"},
{month: cal.May, string: "May"},
{month: cal.June, string: "Jun"},
{month: cal.July, string: "Jul"},
{month: cal.August, string: "Aug"},
{month: cal.September, string: "Sep"},
{month: cal.October, string: "Oct"},
{month: cal.November, string: "Nov"},
{month: cal.December, string: "Dec"},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("%d %s %d %s", i, tt.month, tt.dayOfMonth, tt.string), func(t *testing.T) {
is := is.New(t)
month := cal.NewMonth(tt.month, tt.dayOfMonth)
is.Equal(month.Month(), tt.month)
is.Equal(month.DayOfMonth(), tt.dayOfMonth)
is.Equal(month.String(), tt.string)
})
}
}
func TestWeek(t *testing.T) {
tests := []struct {
name string
week int
string string
}{
{
"test week 1",
1,
"w01",
},
{
"test week 52",
52,
"w52",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
is := is.New(t)
week := cal.NewWeek(tt.week)
is.Equal(week.WeekOfYear(), tt.week)
is.Equal(week.String(), tt.string)
})
}
}
func TestDate(t *testing.T) {
tests := []struct {
date cal.Date
string string
}{
{
cal.Date{
Year: 2022,
},
"2022",
},
{
cal.Date{
Year: 2022,
Month: 2,
},
"2022-02",
},
{
cal.Date{
Year: 2022,
Month: 1,
Day: 1,
},
"2022-01-01",
},
{
cal.Date{
Year: 2022,
WeekOfYear: []cal.Week{
cal.NewWeek(1),
},
},
"2022 w01",
},
{
cal.Date{
Year: 2022,
WeekOfYear: []cal.Week{
cal.NewWeek(1),
cal.NewWeek(4),
},
},
"2022 w01, w04",
},
{
cal.Date{
Year: 2022,
MonthOfYear: []cal.Month{
cal.NewMonth(cal.January, 17),
},
},
"2022 Jan17",
},
{
cal.Date{
Year: 2022,
MonthOfYear: []cal.Month{
cal.NewMonth(cal.January, 1),
cal.NewMonth(cal.December, -1),
},
},
"2022 Jan1, Dec-1",
},
{
cal.Date{
Year: 2022,
MonthOfYear: []cal.Month{
cal.January,
},
DayOfWeek: []cal.Day{
cal.NewDay(cal.Monday, 2),
},
},
"2022 Jan 2Mon",
},
{
cal.Date{
Year: 2022,
WeekOfYear: []cal.Week{
cal.NewWeek(6),
},
DayOfWeek: []cal.Day{
cal.Tuesday,
},
},
"2022 w06 Tue",
},
{
cal.Date{
Year: 2022,
Month: 8,
DayOfWeek: []cal.Day{
cal.Wednesday,
},
},
"2022-08 Wed",
},
{
cal.Date{
Year: 2022,
Month: 8,
DayOfWeek: []cal.Day{
cal.Thursday,
cal.Friday,
cal.Saturday,
cal.Sunday,
},
},
"2022-08 Thu, Fri, Sat, Sun",
},
{
cal.Date{},
"",
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("%d %s", i, tt.string), func(t *testing.T) {
_ = i
is := is.New(t)
s := tt.date.String()
is.Equal(s, tt.string)
})
}
}
func TestMonthParse(t *testing.T) {
tests := []struct {
month cal.Month
day int
string string
}{
{
cal.January,
1,
"Jan1",
},
{
cal.March,
2,
"March2",
},
{
cal.February,
3,
"feb3",
},
{
cal.April,
-3,
"april-3",
},
{
cal.May,
0,
"MAY",
},
{
cal.June,
-30,
"JUN-30",
},
{
cal.July,
4,
"jul4",
},
{
cal.August,
3,
"aug3",
},
{
cal.September,
21,
"sept21",
},
{
cal.October,
31,
"Oct31",
},
{
cal.November,
15,
"nov15",
},
{
cal.December,
25,
"december25",
},
}
for _, tt := range tests {
t.Run(tt.string, func(t *testing.T) {
is := is.New(t)
var m cal.Month
i, err := m.Parse(tt.string)
is.NoErr(err)
is.Equal(m.Month(), tt.month)
is.Equal(m.DayOfMonth(), tt.day)
is.Equal(i, len(tt.string))
})
}
}
func TestDayParse(t *testing.T) {
tests := []struct {
day cal.Day
week int
string string
}{
{
cal.Monday,
1,
"1monday",
},
{
cal.Tuesday,
2,
"2Tuesday",
},
{
cal.Wednesday,
3,
"3Wed",
},
{
cal.Thursday,
4,
"4Thur",
},
{
cal.Friday,
-5,
"-5Friday",
},
{
cal.Saturday,
-2,
"-2Saturday",
},
{
cal.Sunday,
-1,
"-1Sunday",
},
}
for _, tt := range tests {
t.Run(tt.string, func(t *testing.T) {
is := is.New(t)
var d cal.Day
i, err := d.Parse(tt.string)
is.NoErr(err)
is.Equal(d.Day(), tt.day)
is.Equal(d.WeekOfMonth(), tt.week)
is.Equal(i, len(tt.string))
})
}
}
func TestWeekParse(t *testing.T) {
tests := []struct {
week int
string string
}{
{
1,
"w01",
},
{
52,
"w52",
},
}
for _, tt := range tests {
t.Run(tt.string, func(t *testing.T) {
is := is.New(t)
var w cal.Week
i, err := w.Parse(tt.string)
is.NoErr(err)
is.Equal(w.WeekOfYear(), tt.week)
is.Equal(i, len(tt.string))
})
}
}
func TestDateParse(t *testing.T) {
tests := []struct {
date cal.Date
string string
extra string
}{
{
date: cal.Date{Year: 2024},
string: "2024",
},
{
date: cal.Date{Year: 2024},
string: "2024 ",
extra: "make food",
},
{
date: cal.Date{Year: 2024, WeekOfYear: []cal.Week{cal.NewWeek(5)}},
string: "2024 w05",
},
{
date: cal.Date{Year: 2024, DayOfWeek: []cal.Day{cal.NewDay(cal.Monday, 2)}},
string: "2024 2mon",
},
{
date: cal.Date{Year: 2024, WeekOfYear: []cal.Week{cal.NewWeek(5), cal.NewWeek(10)}},
string: "2024 w05, w10",
},
{
date: cal.Date{Year: 2024, WeekOfYear: []cal.Week{cal.NewWeek(5)}, DayOfWeek: []cal.Day{cal.NewDay(cal.Monday, 0)}},
string: "2024 w05 mon",
},
{
date: cal.Date{Year: 2024, WeekOfYear: []cal.Week{cal.NewWeek(5)}},
string: "2024 w05 ",
extra: "monitoring",
},
{
date: cal.Date{
Year: 2024,
WeekOfYear: []cal.Week{cal.NewWeek(5), cal.NewWeek(17)},
DayOfWeek: []cal.Day{cal.NewDay(cal.Monday, 0), cal.NewDay(cal.Friday, 0)},
},
string: "2024 w05 mon, w17 fri",
},
{
date: cal.Date{
Year: 2024,
MonthOfYear: []cal.Month{cal.NewMonth(cal.September, 0)},
DayOfWeek: []cal.Day{cal.NewDay(cal.Monday, 1)},
},
string: "2024 Sept 1mon",
},
{
date: cal.Date{
Year: 2024,
MonthOfYear: []cal.Month{cal.NewMonth(cal.September, 1)},
},
string: "2024 Sept1 ",
extra: "monitoring",
},
{
date: cal.Date{
Year: 2024,
MonthOfYear: []cal.Month{
cal.NewMonth(cal.September, 1),
cal.NewMonth(cal.October, -1),
},
},
string: "2024 Sept1, October-1 ",
extra: "monitoring",
},
{
date: cal.Date{
Year: 2024,
MonthOfYear: []cal.Month{cal.NewMonth(cal.September, 1)},
},
string: "2024 Sept1 ",
extra: "monitoring",
},
{
date: cal.Date{
Year: 2024,
MonthOfYear: []cal.Month{cal.NewMonth(cal.August, 0), cal.NewMonth(cal.October, 0)},
DayOfWeek: []cal.Day{cal.NewDay(cal.Monday, 2), cal.NewDay(cal.Friday, -1)},
},
string: "2024 Aug 2mon, Oct -1fri",
},
{
date: cal.Date{Year: 2024, Month: 5},
string: "2024-05",
},
{
date: cal.Date{Year: 2024, Month: 5, DayOfWeek: []cal.Day{cal.NewDay(cal.Monday, 2)}},
string: "2024-05 2mon",
},
{
date: cal.Date{Year: 2024, Month: 5, DayOfWeek: []cal.Day{
cal.NewDay(cal.Monday, 2),
cal.NewDay(cal.Thursday, 3),
}},
string: "2024-05 2mon, 3thur",
},
{
date: cal.Date{Year: 2024, Month: 5, DayOfWeek: []cal.Day{
cal.NewDay(cal.Monday, 2),
cal.NewDay(cal.Thursday, 3),
}},
string: "2024-05 2mon, 3thur ",
extra: "make food",
},
{
date: cal.Date{Year: 2024, Month: 5, Day: 14},
string: "2024-05-14",
},
{
date: cal.Date{Year: 2024, Month: 5, Day: 14},
string: "2024-05-14 ",
extra: "make food",
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("%d %s%s", i, tt.string, tt.extra), func(t *testing.T) {
is := is.New(t)
var d cal.Date
i, err := d.Parse(tt.string + tt.extra)
is.NoErr(err)
is.Equal(fmt.Sprintf("%#v", d), fmt.Sprintf("%#v", tt.date))
is.Equal(d, tt.date)
is.Equal(i, len(tt.string))
})
}
}
func TestDateProject(t *testing.T) {
type test struct {
date string
start string
out string
}
tests := []test{
{"2024-05-14", "2024-05-14", "2024-05-14"},
{"2024-05-14", "2024-06-24", "2024-06-24"},
{"2024-05", "2024-05-01", "2024-05-31"},
{"2024-05", "2025-02-01", "2025-02-28"},
{"2024-05 2mon", "2025-02-01", "2025-02-10"},
{"2024-05 2mon, 2fri", "2025-02-11", "2025-02-14"},
{"2024-05 -1mon, -2fri", "2025-02-01", "2025-02-24 2025-02-21"},
{"2024 feb -1mon, feb -2fri", "2025-02-01", "2025-02-24 2025-02-21"},
{"2024", "2025-02-01", "2025-12-31"},
{"2024 mar mon, mar 3mon", "2025-02-01", "2025-03-03 2025-03-17"},
{"2024 mar3, mar17", "2025-03-01", "2025-03-03 2025-03-17"},
{"2024 mar, nov", "2025-03-01", "2025-03-31 2025-11-30"},
{"2024 w03, w-2", "2025-01-01", "2025-01-18 2025-12-27"},
{"2024 w03 mon, w-1 wed, w-01 sat", "2025-01-01", "2025-01-13 2025-12-31 2026-01-03"},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("%03d %s %s", i, tt.date, tt.start), func(t *testing.T) {
is := is.New(t)
var date cal.Date
_, err := date.Parse(tt.date)
is.NoErr(err)
start, err := time.Parse("2006-01-02", tt.start)
is.NoErr(err)
out := collectN(len(tt.out)+1, date.Project(start))
fields := strings.Fields(tt.out)
is.Equal(len(out), len(fields))
for i, v := range fields {
is.Equal(out[i].Format("2006-01-02"), v)
}
})
}
}
func collectN[T any](n int, seq iter.Seq[T]) []T {
out := make([]T, 0, n)
i := 0
for v := range seq {
out = append(out, v)
i++
if i == n {
break
}
}
return out
}
func timeDate(year, month, day int) time.Time {
return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
}