From 5b2fdce41df6b199683be034a69a7eb2a446a7d5 Mon Sep 17 00:00:00 2001 From: terminalchai <213856599+terminalchai@users.noreply.github.com> Date: Sat, 24 Oct 2026 02:01:41 +0530 Subject: [PATCH 1/2] fix(accessors): honor map slice defaults --- type_specific.go | 3 ++ type_specific_test.go | 76 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/type_specific.go b/type_specific.go index 0dbe062..dcfbc9a 100644 --- a/type_specific.go +++ b/type_specific.go @@ -224,6 +224,9 @@ func (v *Value) ObjxMapSlice(optionalDefault ...[]Map) []Map { case map[string]any: result[i] = New(s[i]) default: + if len(optionalDefault) == 1 { + return optionalDefault[0] + } return nil } } diff --git a/type_specific_test.go b/type_specific_test.go index b3ca0b5..9a4abdb 100644 --- a/type_specific_test.go +++ b/type_specific_test.go @@ -456,3 +456,79 @@ func TestCollectObjxMap2(t *testing.T) { assert.Equal(t, collectedArr[4], 4) } } + +func TestObjxMapSliceDefaultFromJSON(t *testing.T) { + m := objx.MustFromJSON(`{"rows":[{"id":1},false]}`) + fallback := []objx.Map{{"fallback": true}} + + assert.Equal(t, fallback, m.Get("rows").ObjxMapSlice(fallback)) + assert.Equal(t, []any{map[string]any{"id": float64(1)}, false}, m.Get("rows").Data()) + assert.Equal(t, []objx.Map{{"fallback": true}}, fallback) +} + +func TestObjxMapSliceInvalidElementDefaults(t *testing.T) { + invalid := []struct { + name string + value any + }{ + {"nil", nil}, + {"bool", false}, + {"string", "invalid"}, + {"number", 1}, + {"slice", []any{1}}, + {"other map", map[int]any{1: "invalid"}}, + } + for _, tt := range invalid { + for position := range 3 { + t.Run(fmt.Sprintf("%s/position%d", tt.name, position), func(t *testing.T) { + source := []any{objx.Map{"id": 1}, map[string]any{"id": 2}, objx.Map{"id": 3}} + source[position] = tt.value + before := []any{objx.Map{"id": 1}, map[string]any{"id": 2}, objx.Map{"id": 3}} + before[position] = tt.value + value := objx.Map{"rows": source}.Get("rows") + fallback := []objx.Map{{"fallback": true}} + empty := []objx.Map{} + + assert.Nil(t, value.ObjxMapSlice()) + assert.Nil(t, value.ObjxMapSlice(nil)) + assert.Equal(t, empty, value.ObjxMapSlice(empty)) + got := value.ObjxMapSlice(fallback) + assert.Equal(t, fallback, got) + if len(got) == 1 { + assert.True(t, &got[0] == &fallback[0], "default slice must be returned directly") + } + assert.Nil(t, value.ObjxMapSlice(fallback, empty)) + assert.Equal(t, before, source) + assert.Equal(t, []objx.Map{{"fallback": true}}, fallback) + }) + } + } +} + +func TestObjxMapSliceValidInputsWithDefault(t *testing.T) { + valid := []struct { + name string + value any + want []objx.Map + }{ + {"nil Map slice", []objx.Map(nil), nil}, + {"empty Map slice", []objx.Map{}, []objx.Map{}}, + {"Map slice", []objx.Map{{"id": 1}}, []objx.Map{{"id": 1}}}, + {"nil raw map slice", []map[string]any(nil), []objx.Map{}}, + {"empty raw map slice", []map[string]any{}, []objx.Map{}}, + {"raw map slice", []map[string]any{{"id": 1}}, []objx.Map{{"id": 1}}}, + {"nil any slice", []any(nil), []objx.Map{}}, + {"empty any slice", []any{}, []objx.Map{}}, + {"mixed maps", []any{objx.Map{"id": 1}, map[string]any{"id": 2}}, []objx.Map{{"id": 1}, {"id": 2}}}, + } + for _, tt := range valid { + t.Run(tt.name, func(t *testing.T) { + value := objx.Map{"rows": tt.value}.Get("rows") + fallback := []objx.Map{{"fallback": true}} + assert.Equal(t, tt.want, value.ObjxMapSlice()) + assert.Equal(t, tt.want, value.ObjxMapSlice(fallback)) + assert.Equal(t, tt.want, value.ObjxMapSlice(fallback, fallback)) + assert.Equal(t, []objx.Map{{"fallback": true}}, fallback) + }) + } +} From 4abb5324620ec3f4caaa0aaca8d021775a665730 Mon Sep 17 00:00:00 2001 From: terminalchai <213856599+terminalchai@users.noreply.github.com> Date: Sat, 24 Oct 2026 21:27:50 +0530 Subject: [PATCH 2/2] test(accessors): trim default regression coverage --- type_specific_test.go | 70 ++++--------------------------------------- 1 file changed, 5 insertions(+), 65 deletions(-) diff --git a/type_specific_test.go b/type_specific_test.go index 9a4abdb..f450fbe 100644 --- a/type_specific_test.go +++ b/type_specific_test.go @@ -462,73 +462,13 @@ func TestObjxMapSliceDefaultFromJSON(t *testing.T) { fallback := []objx.Map{{"fallback": true}} assert.Equal(t, fallback, m.Get("rows").ObjxMapSlice(fallback)) - assert.Equal(t, []any{map[string]any{"id": float64(1)}, false}, m.Get("rows").Data()) - assert.Equal(t, []objx.Map{{"fallback": true}}, fallback) } func TestObjxMapSliceInvalidElementDefaults(t *testing.T) { - invalid := []struct { - name string - value any - }{ - {"nil", nil}, - {"bool", false}, - {"string", "invalid"}, - {"number", 1}, - {"slice", []any{1}}, - {"other map", map[int]any{1: "invalid"}}, - } - for _, tt := range invalid { - for position := range 3 { - t.Run(fmt.Sprintf("%s/position%d", tt.name, position), func(t *testing.T) { - source := []any{objx.Map{"id": 1}, map[string]any{"id": 2}, objx.Map{"id": 3}} - source[position] = tt.value - before := []any{objx.Map{"id": 1}, map[string]any{"id": 2}, objx.Map{"id": 3}} - before[position] = tt.value - value := objx.Map{"rows": source}.Get("rows") - fallback := []objx.Map{{"fallback": true}} - empty := []objx.Map{} - - assert.Nil(t, value.ObjxMapSlice()) - assert.Nil(t, value.ObjxMapSlice(nil)) - assert.Equal(t, empty, value.ObjxMapSlice(empty)) - got := value.ObjxMapSlice(fallback) - assert.Equal(t, fallback, got) - if len(got) == 1 { - assert.True(t, &got[0] == &fallback[0], "default slice must be returned directly") - } - assert.Nil(t, value.ObjxMapSlice(fallback, empty)) - assert.Equal(t, before, source) - assert.Equal(t, []objx.Map{{"fallback": true}}, fallback) - }) - } - } -} - -func TestObjxMapSliceValidInputsWithDefault(t *testing.T) { - valid := []struct { - name string - value any - want []objx.Map - }{ - {"nil Map slice", []objx.Map(nil), nil}, - {"empty Map slice", []objx.Map{}, []objx.Map{}}, - {"Map slice", []objx.Map{{"id": 1}}, []objx.Map{{"id": 1}}}, - {"nil raw map slice", []map[string]any(nil), []objx.Map{}}, - {"empty raw map slice", []map[string]any{}, []objx.Map{}}, - {"raw map slice", []map[string]any{{"id": 1}}, []objx.Map{{"id": 1}}}, - {"nil any slice", []any(nil), []objx.Map{}}, - {"empty any slice", []any{}, []objx.Map{}}, - {"mixed maps", []any{objx.Map{"id": 1}, map[string]any{"id": 2}}, []objx.Map{{"id": 1}, {"id": 2}}}, - } - for _, tt := range valid { - t.Run(tt.name, func(t *testing.T) { - value := objx.Map{"rows": tt.value}.Get("rows") - fallback := []objx.Map{{"fallback": true}} - assert.Equal(t, tt.want, value.ObjxMapSlice()) - assert.Equal(t, tt.want, value.ObjxMapSlice(fallback)) - assert.Equal(t, tt.want, value.ObjxMapSlice(fallback, fallback)) - assert.Equal(t, []objx.Map{{"fallback": true}}, fallback) - }) + fallback := []objx.Map{{"fallback": true}} + for _, invalid := range []any{nil, "not a map"} { + value := objx.Map{"rows": []any{invalid}}.Get("rows") + assert.Equal(t, fallback, value.ObjxMapSlice(fallback)) + assert.Nil(t, value.ObjxMapSlice()) } }