package nextdue import "testing" func TestParseErrorError(t *testing.T) { var nilErr *ParseError if nilErr.Error() != "" { t.Fatal("nil ParseError should produce empty string") } if (&ParseError{Msg: "boom"}).Error() != "boom" { t.Fatal("fieldless error should be just the message") } if (&ParseError{Field: "due", Msg: "boom"}).Error() != "due: boom" { t.Fatal("field error should be 'field: msg'") } } func TestParseDefaultDateLayout(t *testing.T) { p := Parser{} // empty DateLayout -> falls back to default v, err := p.Parse("due", "2026-06-17") if err != nil || v.Kind != ValueKindDate { t.Fatalf("default layout should parse date, got kind=%q err=%v", v.Kind, err) } } func TestParse(t *testing.T) { p := NewParser() cases := []struct { raw string kind ValueKind ok bool }{ {"", ValueKindUnknown, true}, {"1200", ValueKindHours, true}, {"1200.5", ValueKindHours, true}, {"2026-06-17", ValueKindDate, true}, {"1200 FH", ValueKindUnknown, false}, } for _, tc := range cases { t.Run(tc.raw, func(t *testing.T) { v, err := p.Parse("due", tc.raw) if tc.ok && err != nil { t.Fatalf("Parse(%q) err = %v", tc.raw, err) } if !tc.ok && err == nil { t.Fatalf("Parse(%q) expected error", tc.raw) } if tc.ok && v.Kind != tc.kind { t.Fatalf("Parse(%q) kind = %q, want %q", tc.raw, v.Kind, tc.kind) } }) } } func TestIsUnset(t *testing.T) { p := NewParser() cases := []struct { raw string unset bool }{ {"", true}, {"0", true}, {"100", false}, {"2026-06-17", false}, } for _, tc := range cases { t.Run(tc.raw, func(t *testing.T) { v, err := p.Parse("due", tc.raw) if err != nil { t.Fatalf("Parse(%q) err = %v", tc.raw, err) } if IsUnset(v) != tc.unset { t.Fatalf("IsUnset(%q) = %v, want %v", tc.raw, IsUnset(v), tc.unset) } }) } }