Skip to content

Commit 9e45903

Browse files
committed
json wip
1 parent 0288ca9 commit 9e45903

File tree

7 files changed

+342
-177
lines changed

7 files changed

+342
-177
lines changed

assign.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package jsonpointer
22

33
import (
4-
"fmt"
54
"reflect"
65
)
76

@@ -26,22 +25,17 @@ func Assign(dst interface{}, ptr JSONPointer, value interface{}) error {
2625
typ: dv.Type(),
2726
}
2827
}
29-
3028
cpy := dv
3129
dv = dv.Elem()
32-
switch dv.Type().Kind() {
33-
case reflect.Ptr:
34-
if dv.IsNil() {
35-
dv = reflect.New(dv.Type().Elem())
36-
}
37-
case reflect.Slice:
38-
if dv.Type().AssignableTo(typeByteSlice) {
39-
fmt.Println("is byte slice")
40-
}
30+
if dv.Kind() == reflect.Ptr && dv.IsNil() {
31+
dv = reflect.New(dv.Type().Elem())
4132
}
4233
dp := reflect.New(dv.Type())
4334
dp.Elem().Set(dv)
4435
res, err := s.assign(dp, reflect.ValueOf(value))
36+
if err != nil {
37+
return err
38+
}
4539
cpy.Elem().Set(res.Elem())
46-
return err
40+
return nil
4741
}

assign_test.go

Lines changed: 81 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package jsonpointer_test
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"testing"
67

@@ -17,66 +18,82 @@ func TestAssign(t *testing.T) {
1718
tests := []struct {
1819
ptr jsonpointer.JSONPointer
1920
value interface{}
20-
err error
21-
run func(v interface{})
21+
run func(v interface{}, err error)
2222
}{
23-
{"/nested/str", "strval", nil, func(val interface{}) {
24-
assert.Equal(val, r.Nested.String)
23+
{"/nested/str", "strval", func(val interface{}, err error) {
24+
assert.NoError(err)
25+
assert.Equal(val, r.Nested.Str)
2526
}},
26-
{"/nestedptr/str", "x", nil, func(val interface{}) {
27-
assert.Equal(val, r.NestedPtr.String)
27+
{"/nestedptr/str", "x", func(val interface{}, err error) {
28+
assert.NoError(err)
29+
assert.Equal(val, r.NestedPtr.Str)
2830
}},
29-
{"/nested/entrymap/keyval/name", "entry-name", nil, func(v interface{}) {
31+
{"/nested/entrymap/keyval/name", "entry-name", func(v interface{}, err error) {
32+
assert.NoError(err)
3033
assert.Contains(r.Nested.EntryMap, "keyval")
3134
assert.Equal("entry-name", r.Nested.EntryMap["keyval"].Name)
3235
}},
33-
{"/nested/strarray/1", "strval", nil, func(v interface{}) {
36+
{"/nested/strarray/1", "strval", func(v interface{}, err error) {
37+
assert.NoError(err)
3438
assert.Equal(v, r.Nested.StrArray[1])
3539
}},
36-
{"/nested/intarray/1", 1, nil, func(v interface{}) {
40+
{"/nested/intarray/1", 1, func(v interface{}, err error) {
41+
assert.NoError(err)
3742
assert.Equal(v, r.Nested.IntArray[1])
3843
}},
39-
{"/nested/intarray/2", 3, nil, func(v interface{}) {
44+
{"/nested/intarray/2", 3, func(v interface{}, err error) {
45+
assert.NoError(err)
4046
assert.Equal(v, r.Nested.IntArray[2])
4147
}},
42-
{"/nested/intarray/3", 3, jsonpointer.ErrOutOfRange, nil},
43-
{"/nested/anon/value", "val", nil, func(v interface{}) {
48+
{"/nested/intarray/3", 3, func(v interface{}, err error) {
49+
assert.Error(err)
50+
assert.ErrorIs(err, jsonpointer.ErrOutOfRange)
51+
ie, ok := jsonpointer.AsIndexError(err)
52+
assert.True(ok, "err is not an IndexError")
53+
assert.Equal(3, ie.Index())
54+
}},
55+
{"/nested/anon/value", "val", func(v interface{}, err error) {
56+
assert.NoError(err)
4457
assert.Equal(v, r.Nested.AnonStruct.Value)
4558
}},
46-
{"/nested/strslice/-", "val", nil, func(v interface{}) {
59+
{"/nested/strslice/-", "val", func(v interface{}, err error) {
60+
assert.NoError(err)
4761
assert.Len(r.Nested.StrSlice, 1)
4862
assert.Equal(v, r.Nested.StrSlice[0])
4963
}},
50-
{"/nested/strslice/-", "val2", nil, func(v interface{}) {
64+
{"/nested/strslice/-", "val2", func(v interface{}, err error) {
65+
assert.NoError(err)
5166
assert.Len(r.Nested.StrSlice, 2)
5267
assert.Equal(v, r.Nested.StrSlice[1])
5368
}},
54-
{"/nested/custommap/key", "val", nil, func(v interface{}) {
69+
{"/nested/custommap/key", "val", func(v interface{}, err error) {
70+
assert.NoError(err)
5571
assert.Len(r.Nested.CustomMap, 1)
5672
assert.Contains(r.Nested.CustomMap, Key{"key"})
5773
}},
58-
{"/nested/embedded/value", "embed-val", nil, func(v interface{}) {
74+
{"/nested/embedded/value", "embed-val", func(v interface{}, err error) {
75+
assert.NoError(err)
5976
assert.Equal(v, r.Nested.Embedded.Value)
6077
}},
61-
{"/nested/yield/value", "yielded value", nil, func(v interface{}) {
78+
{"/nested/yield/value", "yielded value", func(v interface{}, err error) {
79+
assert.NoError(err)
6280
assert.Equal(v, r.Nested.Yield.Value)
6381
}},
64-
{"/nested/interface/private/value", uint(3), nil, func(v interface{}) {
82+
{"/nested/interface/private/value", uint(3), func(v interface{}, err error) {
83+
assert.NoError(err)
6584
assert.Equal(v, r.Nested.InterContainer.Interface.Value())
6685
}},
6786
}
6887

6988
for i, test := range tests {
7089
fmt.Printf("=== RUN TestAssign #%d, pointer %s\n", i+1, test.ptr)
7190
err := jsonpointer.Assign(&r, test.ptr, test.value)
72-
if test.err != nil {
73-
assert.ErrorIs(err, test.err)
74-
} else {
75-
assert.NoError(err)
76-
test.run(test.value)
77-
}
78-
fmt.Printf("--- PASS TestAssign #%d, pointer %s\n", i, test.ptr)
91+
test.run(test.value, err)
92+
93+
fmt.Println("--- PASS")
7994
}
95+
b, _ := json.MarshalIndent(r, "", " ")
96+
fmt.Println(string(b))
8097
}
8198

8299
func TestAssignAny(t *testing.T) {
@@ -110,7 +127,6 @@ func TestAssignAny(t *testing.T) {
110127
assert.Contains(e, "value")
111128
assert.Equal(v, e["value"])
112129
}},
113-
114130
{"/nested/intarray/0", int(1), nil, func(v interface{}) {
115131
a := m["nested"].(map[string]interface{})["intarray"].([]interface{})
116132
assert.Len(a, 1)
@@ -137,7 +153,45 @@ func TestAssignAny(t *testing.T) {
137153
assert.NoError(err)
138154
test.run(test.value)
139155
}
140-
fmt.Printf("--- PASS TestAssign #%d, pointer %s\n", i, test.ptr)
156+
fmt.Println("--- PASS")
141157
}
142158
litter.Dump(m)
143159
}
160+
161+
func TestAssignJSON(t *testing.T) {
162+
assert := require.New(t)
163+
_ = assert
164+
165+
tests := []struct {
166+
ptr jsonpointer.JSONPointer
167+
json string
168+
value interface{}
169+
run func(v Root, err error)
170+
}{
171+
{
172+
"/nested/str",
173+
`{
174+
"nested": {
175+
"str": "old-value"
176+
}
177+
}`,
178+
"new-value",
179+
func(r Root, err error) {
180+
assert.NoError(err)
181+
assert.Equal("new-value", r.Nested.Str)
182+
},
183+
},
184+
}
185+
186+
for i, test := range tests {
187+
fmt.Printf("=== RUN TestAssignJSON #%d, pointer %s\n", i, test.ptr)
188+
b := []byte(test.json)
189+
err := jsonpointer.Assign(&b, test.ptr, test.value)
190+
var r Root
191+
if uerr := json.Unmarshal(b, &r); uerr != nil {
192+
assert.Failf("unmarshal failed: %v", uerr.Error())
193+
}
194+
test.run(r, err)
195+
fmt.Println("--- PASS")
196+
}
197+
}

errors.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ var (
6060
ErrNilInterface = errors.New("jsonpointer: can not assign due to nil interface")
6161

6262
// ErrMalformedIndex indicates a syntax error in the index or a slice or an array.
63-
ErrMalformedIndex = errors.New("jsonpointer: malformed slice/array index")
63+
ErrMalformedIndex = errors.New("jsonpointer: malformed slice or array index")
6464
)
6565

6666
// Error is a base error type returned from Resolve, Assign, and Delete.
@@ -301,7 +301,7 @@ func (e *indexError) Error() string {
301301
// AsIndexError is a convenience function which calls calls errors.As, returning
302302
// err as an IndexError and true or nil and false if err can not be assigned to
303303
// an IndexError
304-
func (e *indexError) AsIndexError(err error) (IndexError, bool) {
304+
func AsIndexError(err error) (IndexError, bool) {
305305
var ie IndexError
306306
return ie, errors.As(err, &ie)
307307
}

resolve.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package jsonpointer
22

3-
import "reflect"
3+
import (
4+
"encoding/json"
5+
"reflect"
6+
)
47

58
type Resolver interface {
69
ResolveJSONPointer(ptr *JSONPointer, op Operation) (interface{}, error)
@@ -24,5 +27,12 @@ func Resolve(src interface{}, ptr JSONPointer, dst interface{}) error {
2427
if err != nil {
2528
return err
2629
}
30+
if isByteSlice(dv.Elem()) {
31+
b, err := json.Marshal(v.Interface())
32+
if err != nil {
33+
return newError(err, *s, dv.Type())
34+
}
35+
v = reflect.ValueOf(b)
36+
}
2737
return s.setValue(dv, v)
2838
}

resolve_test.go

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package jsonpointer_test
22

33
import (
44
"fmt"
5+
"reflect"
56
"testing"
67

78
"github.com/chanced/jsonpointer"
@@ -21,11 +22,11 @@ func TestResolveField(t *testing.T) {
2122
}
2223
r := Root{
2324
Nested: Nested{
24-
String: "strval",
25+
Str: "strval",
2526
Float: 34.21,
2627
FloatPtr: fp,
2728
Inline: Inline{InlineStr: "inline value"},
28-
Nested: &Nested{String: "deeply nested value"},
29+
Nested: &Nested{Str: "deeply nested value"},
2930
Embedded: Embedded{Value: "embedded value"},
3031
IntSlice: []int{},
3132
Bool: true,
@@ -96,6 +97,7 @@ func TestResolveMapIndex(t *testing.T) {
9697
}
9798

9899
for i, test := range tests {
100+
fmt.Printf("=== RUN TestResolveMapIndex #%d, pointer %s\n", i, test.ptr)
99101
var val interface{}
100102
err := jsonpointer.Resolve(r, test.ptr, &val)
101103
if test.expectederr != nil {
@@ -104,6 +106,7 @@ func TestResolveMapIndex(t *testing.T) {
104106
assert.NoError(err, "test %d", i)
105107
}
106108
assert.Equal(test.expectedval, val, "test %d", i)
109+
fmt.Printf("--- PASS\n")
107110
}
108111
}
109112

@@ -152,11 +155,14 @@ func TestResolveArray(t *testing.T) {
152155
}
153156

154157
for i, test := range tests {
158+
fmt.Printf("=== RUN TestResolveArray #%d, pointer %s\n", i, test.ptr)
159+
155160
var val interface{}
156161
err := jsonpointer.Resolve(r, test.ptr, &val)
157162
assert.ErrorIs(err, test.expectederr, "test %d", i)
158163

159164
assert.Equal(test.expectedval, val, "test %d", i)
165+
fmt.Println("--- PASS")
160166
}
161167
}
162168

@@ -204,25 +210,40 @@ func TestResolveSlice(t *testing.T) {
204210
}
205211

206212
for i, test := range tests {
213+
fmt.Printf("=== RUN TestResolveArray #%d, pointer %s\n", i, test.ptr)
207214
var val interface{}
208215
err := jsonpointer.Resolve(r, test.ptr, &val)
209216
assert.ErrorIs(err, test.expectederr, "test %d", i)
210217
assert.Equal(test.expectedval, val, "test %d", i)
218+
fmt.Println("--- PASS")
211219
}
212220
}
213221

214-
func TestResolveJSONIntoValue(t *testing.T) {
215-
j := `{
216-
"nested": {
217-
218-
"bool": false,
219-
"entrymap": {
220-
"foo": {
221-
"name": "bar",
222-
"value": 34.34
223-
}
224-
}
225-
}`
226-
data := []byte(j)
227-
_ = data
222+
func TestResolveJSON(t *testing.T) {
223+
assert := require.New(t)
224+
225+
tests := []struct {
226+
ptr jsonpointer.JSONPointer
227+
json string
228+
val interface{}
229+
err error
230+
}{
231+
{"/nested/str", `{"nested":{"str":"foo"}}`, "foo", nil},
232+
{"/nested", `{"nested":{"str":"foo"}}`, []byte(`{"str":"foo"}`), nil},
233+
}
234+
235+
for i, test := range tests {
236+
fmt.Printf("=== RUN TestResolveJSON #%d, pointer %s\n", i, test.ptr)
237+
vt := reflect.TypeOf(test.val)
238+
rv := reflect.New(vt).Elem()
239+
v := rv.Interface()
240+
err := jsonpointer.Resolve([]byte(test.json), test.ptr, &v)
241+
if test.err != nil {
242+
assert.Error(err)
243+
} else {
244+
assert.NoError(err)
245+
assert.Equal(test.val, v)
246+
}
247+
fmt.Println("--- PASS")
248+
}
228249
}

0 commit comments

Comments
 (0)