@@ -237,4 +237,94 @@ func TestSet(t *testing.T) {
237237 checkSet (t , `[0,1]` , `/-` , true , `[0,1,true]` )
238238 checkSet (t , `{}` , `/ok` , true , `{"ok":true}` )
239239 checkSet (t , `{"x":[]}` , `/x/-` , true , `{"x":[true]}` )
240+
241+ // json.RawMessage nested in the tree: it must be decoded and stored in
242+ // the tree before being modified
243+ checkSet (t , map [string ]interface {}{"a" : json .RawMessage (`{}` )}, `/a/b` , 1 , `{"a":{"b":1}}` )
244+ checkSet (t , map [string ]interface {}{"a" : json .RawMessage (`{"x":{"y":[]}}` )}, `/a/x/y/-` , true , `{"a":{"x":{"y":[true]}}}` )
245+ checkSet (t , map [string ]interface {}{"a" : json .RawMessage (`[]` )}, `/a/-` , true , `{"a":[true]}` )
246+ checkSet (t , []interface {}{json .RawMessage (`[1]` )}, `/0/-` , 2 , `[[1,2]]` )
247+ checkSet (t , []interface {}{json .RawMessage (`[1]` )}, `/0/0` , 2 , `[[2]]` )
248+ checkSet (t , map [string ]interface {}{"a" : json .RawMessage (`{"b":{"c":1}}` )}, `/a/b/c` , 2 , `{"a":{"b":{"c":2}}}` )
249+ // Replacing the RawMessage itself
250+ checkSet (t , map [string ]interface {}{"a" : json .RawMessage (`{}` )}, `/a` , 1 , `{"a":1}` )
251+ // Nested streamed decoder
252+ checkSet (t , map [string ]interface {}{"a" : json .NewDecoder (strings .NewReader (`{"x":[1]}` ))}, `/a/x/-` , 2 , `{"a":{"x":[1,2]}}` )
253+ // Nested in a RawMessage root
254+ checkSet (t , `{"a":{"b":[]}}` , `/a/b/0` , true , `{"a":{"b":[true]}}` )
255+
256+ // Invalid JSON in a nested RawMessage
257+ doc := interface {}(map [string ]interface {}{"a" : json .RawMessage (`{` )})
258+ err := jsonptr .Set (& doc , `/a/b` , 1 )
259+ var docErr * jsonptr.DocumentError
260+ if ! errors .As (err , & docErr ) {
261+ t .Errorf ("invalid nested JSON: got %T %v, want *DocumentError" , err , err )
262+ }
263+ }
264+
265+ func checkDelete (t * testing.T , data interface {}, ptr string , expectedValue interface {}, jsonOut string ) {
266+ t .Logf ("%#v - \" %v\" " , data , ptr )
267+ got , err := jsonptr .Delete (& data , ptr )
268+ if err != nil {
269+ t .Errorf (" unexpected error: %s" , err )
270+ return
271+ }
272+ if ! reflect .DeepEqual (got , expectedValue ) {
273+ t .Errorf (" deleted value: got %T %v, want %T %v" , got , got , expectedValue , expectedValue )
274+ }
275+ out , err := json .Marshal (data )
276+ if err != nil {
277+ t .Errorf (" can't marshal output: %s" , err )
278+ return
279+ }
280+ if string (out ) != jsonOut {
281+ t .Errorf (" got %s, want %s" , out , jsonOut )
282+ }
283+ }
284+
285+ func TestDelete (t * testing.T ) {
286+ checkDelete (t , map [string ]interface {}{"a" : 1 , "b" : 2 }, `/a` , 1 , `{"b":2}` )
287+ checkDelete (t , []interface {}{1 , 2 , 3 }, `/1` , 2 , `[1,3]` )
288+ checkDelete (t , []interface {}{1 , 2 , 3 }, `/2` , 3 , `[1,2]` )
289+ checkDelete (t , []interface {}{1 }, `/0` , 1 , `[]` )
290+ checkDelete (t , map [string ]interface {}{"a" : []interface {}{1 , 2 }}, `/a/0` , 1 , `{"a":[2]}` )
291+
292+ // json.RawMessage in the tree, at root or nested
293+ checkDelete (t , json .RawMessage (`{"a":1,"b":2}` ), `/a` , float64 (1 ), `{"b":2}` )
294+ checkDelete (t , json .RawMessage (`[1,2,3]` ), `/1` , float64 (2 ), `[1,3]` )
295+ checkDelete (t , map [string ]interface {}{"a" : json .RawMessage (`{"b":1,"c":2}` )}, `/a/b` , float64 (1 ), `{"a":{"c":2}}` )
296+ checkDelete (t , map [string ]interface {}{"a" : json .RawMessage (`[1,2,3]` )}, `/a/1` , float64 (2 ), `{"a":[1,3]}` )
297+ checkDelete (t , map [string ]interface {}{"a" : json .RawMessage (`{"b":{"c":[true]}}` )}, `/a/b/c/0` , true , `{"a":{"b":{"c":[]}}}` )
298+ checkDelete (t , map [string ]interface {}{"a" : json .NewDecoder (strings .NewReader (`{"b":1,"c":2}` ))}, `/a/b` , float64 (1 ), `{"a":{"c":2}}` )
299+
300+ // Errors
301+ for _ , test := range []struct {
302+ doc interface {}
303+ ptr string
304+ err error
305+ }{
306+ {map [string ]interface {}{}, `` , jsonptr .ErrDeleteRoot },
307+ {map [string ]interface {}{}, `a` , jsonptr .ErrSyntax },
308+ {map [string ]interface {}{}, `/a` , jsonptr .ErrProperty },
309+ {map [string ]interface {}{"a" : 1 }, `/a/b` , nil }, // DocumentError
310+ {[]interface {}{1 }, `/1` , jsonptr .ErrIndex },
311+ {[]interface {}{1 }, `/-` , jsonptr .ErrIndex },
312+ {[]interface {}{1 }, `/x` , jsonptr .ErrSyntax },
313+ {map [string ]interface {}{"a" : json .RawMessage (`{` )}, `/a/b` , nil }, // DocumentError
314+ } {
315+ doc := test .doc
316+ _ , err := jsonptr .Delete (& doc , test .ptr )
317+ if err == nil {
318+ t .Errorf ("%#v - %q: expected error" , test .doc , test .ptr )
319+ continue
320+ }
321+ if test .err == nil {
322+ var docErr * jsonptr.DocumentError
323+ if ! errors .As (err , & docErr ) {
324+ t .Errorf ("%#v - %q: got %T %v, want *DocumentError" , test .doc , test .ptr , err , err )
325+ }
326+ } else if ! errors .Is (err , test .err ) {
327+ t .Errorf ("%#v - %q: got %T %v, want %v" , test .doc , test .ptr , err , err , test .err )
328+ }
329+ }
240330}
0 commit comments