package rfctime import ( "encoding/json" "testing" "time" "git.blackforestbytes.com/BlackForestBytes/goext/tst" ) func TestDateString(t *testing.T) { d := Date{Year: 2023, Month: 5, Day: 7} tst.AssertEqual(t, d.String(), "2023-05-07") tst.AssertEqual(t, d.Serialize(), "2023-05-07") tst.AssertEqual(t, d.GoString(), "rfctime.Date{Year: 2023, Month: 5, Day: 7}") tst.AssertEqual(t, d.FormatStr(), "2006-01-02") } func TestDateIsZero(t *testing.T) { tst.AssertEqual(t, Date{}.IsZero(), true) tst.AssertEqual(t, Date{Year: 1, Month: 1, Day: 1}.IsZero(), false) } func TestDateNew(t *testing.T) { tm := time.Date(2023, 5, 7, 12, 30, 0, 0, time.UTC) d := NewDate(tm) tst.AssertEqual(t, d.Year, 2023) tst.AssertEqual(t, d.Month, 5) tst.AssertEqual(t, d.Day, 7) } func TestDateTimeConversions(t *testing.T) { d := Date{Year: 2023, Month: 5, Day: 7} utc := d.TimeUTC() tst.AssertEqual(t, utc.Year(), 2023) tst.AssertEqual(t, utc.Month(), time.May) tst.AssertEqual(t, utc.Day(), 7) tst.AssertEqual(t, utc.Location(), time.UTC) loc := d.TimeLocal() tst.AssertEqual(t, loc.Location(), time.Local) custom := d.Time(time.UTC) tst.AssertEqual(t, custom.Hour(), 0) tst.AssertEqual(t, custom.Location(), time.UTC) } func TestDateJSON(t *testing.T) { type Wrap struct { D Date `json:"d"` } w1 := Wrap{D: Date{Year: 2023, Month: 5, Day: 7}} b, err := json.Marshal(w1) if err != nil { t.Fatal(err) } tst.AssertEqual(t, string(b), `{"d":"2023-05-07"}`) var w2 Wrap if err := json.Unmarshal(b, &w2); err != nil { t.Fatal(err) } tst.AssertEqual(t, w2.D, w1.D) } func TestDateJSONInvalid(t *testing.T) { var d Date if err := d.UnmarshalJSON([]byte(`"not-a-date"`)); err == nil { t.Errorf("expected parse error") } if err := d.UnmarshalJSON([]byte(`123`)); err == nil { t.Errorf("expected json error for number") } } func TestDateText(t *testing.T) { d := Date{Year: 2023, Month: 5, Day: 7} b, err := d.MarshalText() if err != nil { t.Fatal(err) } tst.AssertEqual(t, string(b), "2023-05-07") var d2 Date if err := d2.UnmarshalText(b); err != nil { t.Fatal(err) } tst.AssertEqual(t, d2, d) if err := d2.UnmarshalText([]byte("garbage")); err == nil { t.Errorf("expected error") } } func TestDateBinaryGob(t *testing.T) { d := Date{Year: 2023, Month: 5, Day: 7} bin, err := d.MarshalBinary() if err != nil { t.Fatal(err) } var d2 Date if err := d2.UnmarshalBinary(bin); err != nil { t.Fatal(err) } tst.AssertEqual(t, d2, d) gob, err := d.GobEncode() if err != nil { t.Fatal(err) } var d3 Date if err := d3.GobDecode(gob); err != nil { t.Fatal(err) } tst.AssertEqual(t, d3, d) } func TestDateAccessors(t *testing.T) { d := Date{Year: 2023, Month: 5, Day: 17} y, m, day := d.Date() tst.AssertEqual(t, y, 2023) tst.AssertEqual(t, m, time.May) tst.AssertEqual(t, day, 17) tst.AssertEqual(t, d.Weekday(), time.Wednesday) wy, ww := d.ISOWeek() ey, ew := d.TimeUTC().ISOWeek() tst.AssertEqual(t, wy, ey) tst.AssertEqual(t, ww, ew) tst.AssertEqual(t, d.YearDay(), d.TimeUTC().YearDay()) tst.AssertEqual(t, d.Unix(), d.TimeUTC().Unix()) tst.AssertEqual(t, d.UnixMilli(), d.TimeUTC().UnixMilli()) tst.AssertEqual(t, d.UnixMicro(), d.TimeUTC().UnixMicro()) tst.AssertEqual(t, d.UnixNano(), d.TimeUTC().UnixNano()) tst.AssertEqual(t, d.Format("2006/01/02"), "2023/05/17") } func TestDateAddDate(t *testing.T) { d := Date{Year: 2023, Month: 5, Day: 17} d2 := d.AddDate(1, 2, 3) tst.AssertEqual(t, d2.Year, 2024) tst.AssertEqual(t, d2.Month, 7) tst.AssertEqual(t, d2.Day, 20) } func TestDateParseString(t *testing.T) { tests := []struct { input string ok bool expected Date }{ {"2023-05-07", true, Date{2023, 5, 7}}, {"0001-01-01", true, Date{1, 1, 1}}, {"2023-13-01", false, Date{}}, // bad month {"2023-12-32", false, Date{}}, // bad day {"2023-00-15", false, Date{}}, // month 0 {"2023-05", false, Date{}}, // bad format {"2023-05-07-extra", false, Date{}}, {"abcd-ef-gh", false, Date{}}, {"-1-05-07", false, Date{}}, // negative year } for _, tc := range tests { var d Date err := d.ParseString(tc.input) if tc.ok { if err != nil { t.Errorf("ParseString(%q) failed: %v", tc.input, err) continue } tst.AssertEqual(t, d, tc.expected) } else if err == nil { t.Errorf("ParseString(%q) should have failed", tc.input) } } } func TestNowDate(t *testing.T) { now := time.Now().UTC() d := NowDate(time.UTC) tst.AssertEqual(t, d.Year, now.Year()) tst.AssertEqual(t, d.Month, int(now.Month())) tst.AssertEqual(t, d.Day, now.Day()) dl := NowDateLoc() if dl.Year < 1970 { t.Errorf("NowDateLoc returned implausible year: %d", dl.Year) } du := NowDateUTC() if du.Year < 1970 { t.Errorf("NowDateUTC returned implausible year: %d", du.Year) } }