Skip to content

Commit a43f9d0

Browse files
committed
fix JSON NestedMap + add tests
1 parent 1195999 commit a43f9d0

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

lib/chcol/json.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,15 @@ func (o *JSON) ValueAtPath(path string) (any, bool) {
5151

5252
// NestedMap converts the flattened JSON data into a nested structure
5353
func (o *JSON) NestedMap() map[string]any {
54-
nested := make(map[string]any)
54+
result := make(map[string]any)
5555

5656
for key, value := range o.valuesByPath {
57+
if vt, ok := value.(Variant); ok && vt.Nil() {
58+
continue
59+
}
60+
5761
parts := strings.Split(key, ".")
58-
current := nested
62+
current := result
5963

6064
for i := 0; i < len(parts)-1; i++ {
6165
part := parts[i]
@@ -64,13 +68,14 @@ func (o *JSON) NestedMap() map[string]any {
6468
current[part] = make(map[string]any)
6569
}
6670

67-
current = current[part].(map[string]any)
71+
if next, ok := current[part].(map[string]any); ok {
72+
current = next
73+
}
6874
}
69-
7075
current[parts[len(parts)-1]] = value
7176
}
7277

73-
return nested
78+
return result
7479
}
7580

7681
// MarshalJSON implements the json.Marshaler interface

lib/chcol/json_test.go

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package chcol
2+
3+
import (
4+
"github.com/stretchr/testify/require"
5+
"testing"
6+
)
7+
8+
func TestNestedMap(t *testing.T) {
9+
cases := []struct {
10+
name string
11+
input *JSON
12+
expected map[string]any
13+
}{
14+
{
15+
name: "nested object with values present",
16+
input: &JSON{
17+
valuesByPath: map[string]any{
18+
"x": NewVariant(nil),
19+
"x.a": NewVariant(42),
20+
"x.b": NewVariant(64),
21+
"x.b.c.d": NewVariant(96),
22+
"a.b.c": NewVariant(128),
23+
},
24+
},
25+
expected: map[string]any{
26+
"x": map[string]any{
27+
"a": NewVariant(42),
28+
"b": NewVariant(64),
29+
"c": map[string]any{
30+
"d": NewVariant(96),
31+
},
32+
},
33+
"a": map[string]any{
34+
"b": map[string]any{
35+
"c": NewVariant(128),
36+
},
37+
},
38+
},
39+
},
40+
{
41+
name: "nested object with only top level key present",
42+
input: &JSON{
43+
valuesByPath: map[string]any{
44+
"x": NewVariant(42),
45+
"x.a": NewVariant(nil),
46+
"x.b": NewVariant(nil),
47+
"x.b.c.d": NewVariant(nil),
48+
"a.b.c": NewVariant(nil),
49+
},
50+
},
51+
expected: map[string]any{
52+
"x": NewVariant(42),
53+
},
54+
},
55+
{
56+
name: "nested object with typed paths",
57+
input: &JSON{
58+
valuesByPath: map[string]any{
59+
"x": 42,
60+
"a.b": "test value",
61+
},
62+
},
63+
expected: map[string]any{
64+
"x": 42,
65+
"a": map[string]any{
66+
"b": "test value",
67+
},
68+
},
69+
},
70+
{
71+
name: "empty object",
72+
input: NewJSON(),
73+
expected: map[string]any{},
74+
},
75+
}
76+
77+
for _, c := range cases {
78+
t.Run(c.name, func(t *testing.T) {
79+
actual := c.input.NestedMap()
80+
require.Equal(t, c.expected, actual)
81+
})
82+
}
83+
}

0 commit comments

Comments
 (0)