From 6192ef3ed5f92dc7679a90ea2dc0c745109d38d8 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Mon, 23 Feb 2026 23:39:04 -0800 Subject: [PATCH] fix: correct time.Time date-only fallback parsing in deepObject The date-only fallback in assignPathValues erroneously returned an error wrapping nil after a successful parse, preventing date-only strings from being unmarshalled into time.Time fields via deepObject. Co-Authored-By: Claude Opus 4.6 --- deepobject.go | 3 +-- deepobject_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/deepobject.go b/deepobject.go index 2742076..9140f80 100644 --- a/deepobject.go +++ b/deepobject.go @@ -258,11 +258,10 @@ func assignPathValues(dst interface{}, pathValues fieldOrValue) error { tm, err = time.Parse(time.RFC3339Nano, pathValues.value) if err != nil { // Fall back to parsing it as a date. - _, err = time.Parse(types.DateFormat, pathValues.value) // the time result is never used, so it doesn't need to be assigned + tm, err = time.Parse(types.DateFormat, pathValues.value) if err != nil { return fmt.Errorf("error parsing '%s' as RFC3339 or 2006-01-02 time: %w", pathValues.value, err) } - return fmt.Errorf("invalid date format: %w", err) } dst := iv if it != reflect.TypeOf(time.Time{}) { diff --git a/deepobject_test.go b/deepobject_test.go index 2646ad4..3298220 100644 --- a/deepobject_test.go +++ b/deepobject_test.go @@ -123,6 +123,42 @@ type Item struct { Value string `json:"value"` } +func TestDeepObject_TimeFields(t *testing.T) { + type TimeObject struct { + Created time.Time `json:"created"` + } + + t.Run("RFC3339 time parses correctly", func(t *testing.T) { + params := url.Values{} + params.Set("p[created]", "2024-01-15T10:30:00Z") + + var dst TimeObject + err := UnmarshalDeepObject(&dst, "p", params) + require.NoError(t, err) + assert.Equal(t, time.Date(2024, 1, 15, 10, 30, 0, 0, time.UTC), dst.Created) + }) + + t.Run("date-only string parses correctly as time.Time", func(t *testing.T) { + params := url.Values{} + params.Set("p[created]", "2024-01-15") + + var dst TimeObject + err := UnmarshalDeepObject(&dst, "p", params) + require.NoError(t, err) + assert.Equal(t, time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC), dst.Created) + }) + + t.Run("invalid time string returns error", func(t *testing.T) { + params := url.Values{} + params.Set("p[created]", "not-a-time") + + var dst TimeObject + err := UnmarshalDeepObject(&dst, "p", params) + require.Error(t, err) + assert.Contains(t, err.Error(), "error parsing") + }) +} + func TestDeepObject_ArrayOfObjects(t *testing.T) { // Test case for: // name: items