• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[
2    { "comment": "empty list, empty docs",
3      "doc": {},
4      "patch": [],
5      "expected": {} },
6
7    { "comment": "empty patch list",
8      "doc": {"foo": 1},
9      "patch": [],
10      "expected": {"foo": 1} },
11
12    { "comment": "rearrangements OK?",
13      "doc": {"foo": 1, "bar": 2},
14      "patch": [],
15      "expected": {"bar":2, "foo": 1} },
16
17    { "comment": "rearrangements OK?  How about one level down ... array",
18      "doc": [{"foo": 1, "bar": 2}],
19      "patch": [],
20      "expected": [{"bar":2, "foo": 1}] },
21
22    { "comment": "rearrangements OK?  How about one level down...",
23      "doc": {"foo":{"foo": 1, "bar": 2}},
24      "patch": [],
25      "expected": {"foo":{"bar":2, "foo": 1}} },
26
27    { "comment": "add replaces any existing field",
28      "doc": {"foo": null},
29      "patch": [{"op": "add", "path": "/foo", "value":1}],
30      "expected": {"foo": 1} },
31
32    { "comment": "toplevel array",
33      "doc": [],
34      "patch": [{"op": "add", "path": "/0", "value": "foo"}],
35      "expected": ["foo"] },
36
37    { "comment": "toplevel array, no change",
38      "doc": ["foo"],
39      "patch": [],
40      "expected": ["foo"] },
41
42    { "comment": "toplevel object, numeric string",
43      "doc": {},
44      "patch": [{"op": "add", "path": "/foo", "value": "1"}],
45      "expected": {"foo":"1"} },
46
47    { "comment": "toplevel object, integer",
48      "doc": {},
49      "patch": [{"op": "add", "path": "/foo", "value": 1}],
50      "expected": {"foo":1} },
51
52    { "comment": "Toplevel scalar values OK?",
53      "doc": "foo",
54      "patch": [{"op": "replace", "path": "", "value": "bar"}],
55      "expected": "bar",
56      "disabled": true },
57
58    { "comment": "replace object document with array document?",
59      "doc": {},
60      "patch": [{"op": "add", "path": "", "value": []}],
61      "expected": [] },
62
63    { "comment": "replace array document with object document?",
64      "doc": [],
65      "patch": [{"op": "add", "path": "", "value": {}}],
66      "expected": {} },
67
68    { "comment": "append to root array document?",
69      "doc": [],
70      "patch": [{"op": "add", "path": "/-", "value": "hi"}],
71      "expected": ["hi"] },
72
73    { "comment": "Add, / target",
74      "doc": {},
75      "patch": [ {"op": "add", "path": "/", "value":1 } ],
76      "expected": {"":1} },
77
78    { "comment": "Add, /foo/ deep target (trailing slash)",
79      "doc": {"foo": {}},
80      "patch": [ {"op": "add", "path": "/foo/", "value":1 } ],
81      "expected": {"foo":{"": 1}} },
82
83    { "comment": "Add composite value at top level",
84      "doc": {"foo": 1},
85      "patch": [{"op": "add", "path": "/bar", "value": [1, 2]}],
86      "expected": {"foo": 1, "bar": [1, 2]} },
87
88    { "comment": "Add into composite value",
89      "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
90      "patch": [{"op": "add", "path": "/baz/0/foo", "value": "world"}],
91      "expected": {"foo": 1, "baz": [{"qux": "hello", "foo": "world"}]} },
92
93    { "doc": {"bar": [1, 2]},
94      "patch": [{"op": "add", "path": "/bar/8", "value": "5"}],
95      "error": "Out of bounds (upper)" },
96
97    { "doc": {"bar": [1, 2]},
98      "patch": [{"op": "add", "path": "/bar/-1", "value": "5"}],
99      "error": "Out of bounds (lower)" },
100
101    { "doc": {"foo": 1},
102      "patch": [{"op": "add", "path": "/bar", "value": true}],
103      "expected": {"foo": 1, "bar": true} },
104
105    { "doc": {"foo": 1},
106      "patch": [{"op": "add", "path": "/bar", "value": false}],
107      "expected": {"foo": 1, "bar": false} },
108
109    { "doc": {"foo": 1},
110      "patch": [{"op": "add", "path": "/bar", "value": null}],
111      "expected": {"foo": 1, "bar": null} },
112
113    { "comment": "0 can be an array index or object element name",
114      "doc": {"foo": 1},
115      "patch": [{"op": "add", "path": "/0", "value": "bar"}],
116      "expected": {"foo": 1, "0": "bar" } },
117
118    { "doc": ["foo"],
119      "patch": [{"op": "add", "path": "/1", "value": "bar"}],
120      "expected": ["foo", "bar"] },
121
122    { "doc": ["foo", "sil"],
123      "patch": [{"op": "add", "path": "/1", "value": "bar"}],
124      "expected": ["foo", "bar", "sil"] },
125
126    { "doc": ["foo", "sil"],
127      "patch": [{"op": "add", "path": "/0", "value": "bar"}],
128      "expected": ["bar", "foo", "sil"] },
129
130    { "comment": "push item to array via last index + 1",
131      "doc": ["foo", "sil"],
132      "patch": [{"op":"add", "path": "/2", "value": "bar"}],
133      "expected": ["foo", "sil", "bar"] },
134
135    { "comment": "add item to array at index > length should fail",
136      "doc": ["foo", "sil"],
137      "patch": [{"op":"add", "path": "/3", "value": "bar"}],
138      "error": "index is greater than number of items in array" },
139
140    { "comment": "test against implementation-specific numeric parsing",
141      "doc": {"1e0": "foo"},
142      "patch": [{"op": "test", "path": "/1e0", "value": "foo"}],
143      "expected": {"1e0": "foo"} },
144
145    { "comment": "test with bad number should fail",
146      "doc": ["foo", "bar"],
147      "patch": [{"op": "test", "path": "/1e0", "value": "bar"}],
148      "error": "test op shouldn't get array element 1" },
149
150    { "doc": ["foo", "sil"],
151      "patch": [{"op": "add", "path": "/bar", "value": 42}],
152      "error": "Object operation on array target" },
153
154    { "doc": ["foo", "sil"],
155      "patch": [{"op": "add", "path": "/1", "value": ["bar", "baz"]}],
156      "expected": ["foo", ["bar", "baz"], "sil"],
157      "comment": "value in array add not flattened" },
158
159    { "doc": {"foo": 1, "bar": [1, 2, 3, 4]},
160      "patch": [{"op": "remove", "path": "/bar"}],
161      "expected": {"foo": 1} },
162
163    { "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
164      "patch": [{"op": "remove", "path": "/baz/0/qux"}],
165      "expected": {"foo": 1, "baz": [{}]} },
166
167    { "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
168      "patch": [{"op": "replace", "path": "/foo", "value": [1, 2, 3, 4]}],
169      "expected": {"foo": [1, 2, 3, 4], "baz": [{"qux": "hello"}]} },
170
171    { "doc": {"foo": [1, 2, 3, 4], "baz": [{"qux": "hello"}]},
172      "patch": [{"op": "replace", "path": "/baz/0/qux", "value": "world"}],
173      "expected": {"foo": [1, 2, 3, 4], "baz": [{"qux": "world"}]} },
174
175    { "doc": ["foo"],
176      "patch": [{"op": "replace", "path": "/0", "value": "bar"}],
177      "expected": ["bar"] },
178
179    { "doc": [""],
180      "patch": [{"op": "replace", "path": "/0", "value": 0}],
181      "expected": [0] },
182
183    { "doc": [""],
184      "patch": [{"op": "replace", "path": "/0", "value": true}],
185      "expected": [true] },
186
187    { "doc": [""],
188      "patch": [{"op": "replace", "path": "/0", "value": false}],
189      "expected": [false] },
190
191    { "doc": [""],
192      "patch": [{"op": "replace", "path": "/0", "value": null}],
193      "expected": [null] },
194
195    { "doc": ["foo", "sil"],
196      "patch": [{"op": "replace", "path": "/1", "value": ["bar", "baz"]}],
197      "expected": ["foo", ["bar", "baz"]],
198      "comment": "value in array replace not flattened" },
199
200    { "comment": "replace whole document",
201      "doc": {"foo": "bar"},
202      "patch": [{"op": "replace", "path": "", "value": {"baz": "qux"}}],
203      "expected": {"baz": "qux"} },
204
205    { "comment": "test replace with missing parent key should fail",
206      "doc": {"bar": "baz"},
207      "patch": [{"op": "replace", "path": "/foo/bar", "value": false}],
208      "error": "replace op should fail with missing parent key" },
209
210    { "comment": "spurious patch properties",
211      "doc": {"foo": 1},
212      "patch": [{"op": "test", "path": "/foo", "value": 1, "spurious": 1}],
213      "expected": {"foo": 1} },
214
215    { "doc": {"foo": null},
216      "patch": [{"op": "test", "path": "/foo", "value": null}],
217      "expected": {"foo": null},
218      "comment": "null value should be valid obj property" },
219
220    { "doc": {"foo": null},
221      "patch": [{"op": "replace", "path": "/foo", "value": "truthy"}],
222      "expected": {"foo": "truthy"},
223      "comment": "null value should be valid obj property to be replaced with something truthy" },
224
225    { "doc": {"foo": null},
226      "patch": [{"op": "move", "from": "/foo", "path": "/bar"}],
227      "expected": {"bar": null},
228      "comment": "null value should be valid obj property to be moved" },
229
230    { "doc": {"foo": null},
231      "patch": [{"op": "copy", "from": "/foo", "path": "/bar"}],
232      "expected": {"foo": null, "bar": null},
233      "comment": "null value should be valid obj property to be copied" },
234
235    { "doc": {"foo": null},
236      "patch": [{"op": "remove", "path": "/foo"}],
237      "expected": {},
238      "comment": "null value should be valid obj property to be removed" },
239
240    { "doc": {"foo": "bar"},
241      "patch": [{"op": "replace", "path": "/foo", "value": null}],
242      "expected": {"foo": null},
243      "comment": "null value should still be valid obj property replace other value" },
244
245    { "doc": {"foo": {"foo": 1, "bar": 2}},
246      "patch": [{"op": "test", "path": "/foo", "value": {"bar": 2, "foo": 1}}],
247      "expected": {"foo": {"foo": 1, "bar": 2}},
248      "comment": "test should pass despite rearrangement" },
249
250    { "doc": {"foo": [{"foo": 1, "bar": 2}]},
251      "patch": [{"op": "test", "path": "/foo", "value": [{"bar": 2, "foo": 1}]}],
252      "expected": {"foo": [{"foo": 1, "bar": 2}]},
253      "comment": "test should pass despite (nested) rearrangement" },
254
255    { "doc": {"foo": {"bar": [1, 2, 5, 4]}},
256      "patch": [{"op": "test", "path": "/foo", "value": {"bar": [1, 2, 5, 4]}}],
257      "expected": {"foo": {"bar": [1, 2, 5, 4]}},
258      "comment": "test should pass - no error" },
259
260    { "doc": {"foo": {"bar": [1, 2, 5, 4]}},
261      "patch": [{"op": "test", "path": "/foo", "value": [1, 2]}],
262      "error": "test op should fail" },
263
264    { "comment": "Whole document",
265      "doc": { "foo": 1 },
266      "patch": [{"op": "test", "path": "", "value": {"foo": 1}}],
267      "disabled": true },
268
269    { "comment": "Empty-string element",
270      "doc": { "": 1 },
271      "patch": [{"op": "test", "path": "/", "value": 1}],
272      "expected": { "": 1 } },
273
274    { "doc": {
275            "foo": ["bar", "baz"],
276            "": 0,
277            "a/b": 1,
278            "c%d": 2,
279            "e^f": 3,
280            "g|h": 4,
281            "i\\j": 5,
282            "k\"l": 6,
283            " ": 7,
284            "m~n": 8
285            },
286      "patch": [{"op": "test", "path": "/foo", "value": ["bar", "baz"]},
287                {"op": "test", "path": "/foo/0", "value": "bar"},
288                {"op": "test", "path": "/", "value": 0},
289                {"op": "test", "path": "/a~1b", "value": 1},
290                {"op": "test", "path": "/c%d", "value": 2},
291                {"op": "test", "path": "/e^f", "value": 3},
292                {"op": "test", "path": "/g|h", "value": 4},
293                {"op": "test", "path":  "/i\\j", "value": 5},
294                {"op": "test", "path": "/k\"l", "value": 6},
295                {"op": "test", "path": "/ ", "value": 7},
296                {"op": "test", "path": "/m~0n", "value": 8}],
297      "expected": {
298            "": 0,
299            " ": 7,
300            "a/b": 1,
301            "c%d": 2,
302            "e^f": 3,
303            "foo": [
304                "bar",
305                "baz"
306            ],
307            "g|h": 4,
308            "i\\j": 5,
309            "k\"l": 6,
310            "m~n": 8
311        }
312    },
313    { "comment": "Move to same location has no effect",
314      "doc": {"foo": 1},
315      "patch": [{"op": "move", "from": "/foo", "path": "/foo"}],
316      "expected": {"foo": 1} },
317
318    { "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
319      "patch": [{"op": "move", "from": "/foo", "path": "/bar"}],
320      "expected": {"baz": [{"qux": "hello"}], "bar": 1} },
321
322    { "doc": {"baz": [{"qux": "hello"}], "bar": 1},
323      "patch": [{"op": "move", "from": "/baz/0/qux", "path": "/baz/1"}],
324      "expected": {"baz": [{}, "hello"], "bar": 1} },
325
326    { "doc": {"baz": [{"qux": "hello"}], "bar": 1},
327      "patch": [{"op": "copy", "from": "/baz/0", "path": "/boo"}],
328      "expected": {"baz":[{"qux":"hello"}],"bar":1,"boo":{"qux":"hello"}} },
329
330    { "comment": "replacing the root of the document is possible with add",
331      "doc": {"foo": "bar"},
332      "patch": [{"op": "add", "path": "", "value": {"baz": "qux"}}],
333      "expected": {"baz":"qux"}},
334
335    { "comment": "Adding to \"/-\" adds to the end of the array",
336      "doc": [ 1, 2 ],
337      "patch": [ { "op": "add", "path": "/-", "value": { "foo": [ "bar", "baz" ] } } ],
338      "expected": [ 1, 2, { "foo": [ "bar", "baz" ] } ]},
339
340    { "comment": "Adding to \"/-\" adds to the end of the array, even n levels down",
341      "doc": [ 1, 2, [ 3, [ 4, 5 ] ] ],
342      "patch": [ { "op": "add", "path": "/2/1/-", "value": { "foo": [ "bar", "baz" ] } } ],
343      "expected": [ 1, 2, [ 3, [ 4, 5, { "foo": [ "bar", "baz" ] } ] ] ]},
344
345    { "comment": "test remove with bad number should fail",
346      "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
347      "patch": [{"op": "remove", "path": "/baz/1e0/qux"}],
348      "error": "remove op shouldn't remove from array with bad number" },
349
350    { "comment": "test remove on array",
351      "doc": [1, 2, 3, 4],
352      "patch": [{"op": "remove", "path": "/0"}],
353      "expected": [2, 3, 4] },
354
355    { "comment": "test repeated removes",
356      "doc": [1, 2, 3, 4],
357      "patch": [{ "op": "remove", "path": "/1" },
358                { "op": "remove", "path": "/2" }],
359      "expected": [1, 3] },
360
361    { "comment": "test remove with bad index should fail",
362      "doc": [1, 2, 3, 4],
363      "patch": [{"op": "remove", "path": "/1e0"}],
364      "error": "remove op shouldn't remove from array with bad number" },
365
366    { "comment": "test replace with bad number should fail",
367      "doc": [""],
368      "patch": [{"op": "replace", "path": "/1e0", "value": false}],
369      "error": "replace op shouldn't replace in array with bad number" },
370
371    { "comment": "test copy with bad number should fail",
372      "doc": {"baz": [1,2,3], "bar": 1},
373      "patch": [{"op": "copy", "from": "/baz/1e0", "path": "/boo"}],
374      "error": "copy op shouldn't work with bad number" },
375
376    { "comment": "test move with bad number should fail",
377      "doc": {"foo": 1, "baz": [1,2,3,4]},
378      "patch": [{"op": "move", "from": "/baz/1e0", "path": "/foo"}],
379      "error": "move op shouldn't work with bad number" },
380
381    { "comment": "test add with bad number should fail",
382      "doc": ["foo", "sil"],
383      "patch": [{"op": "add", "path": "/1e0", "value": "bar"}],
384      "error": "add op shouldn't add to array with bad number" },
385
386    { "comment": "missing 'value' parameter to add",
387      "doc": [ 1 ],
388      "patch": [ { "op": "add", "path": "/-" } ],
389      "error": "missing 'value' parameter" },
390
391    { "comment": "missing 'value' parameter to replace",
392      "doc": [ 1 ],
393      "patch": [ { "op": "replace", "path": "/0" } ],
394      "error": "missing 'value' parameter" },
395
396    { "comment": "missing 'value' parameter to test",
397      "doc": [ null ],
398      "patch": [ { "op": "test", "path": "/0" } ],
399      "error": "missing 'value' parameter" },
400
401    { "comment": "missing value parameter to test - where undef is falsy",
402      "doc": [ false ],
403      "patch": [ { "op": "test", "path": "/0" } ],
404      "error": "missing 'value' parameter" },
405
406    { "comment": "missing from parameter to copy",
407      "doc": [ 1 ],
408      "patch": [ { "op": "copy", "path": "/-" } ],
409      "error": "missing 'from' parameter" },
410
411    { "comment": "missing from location to copy",
412      "doc": { "foo": 1 },
413      "patch": [ { "op": "copy", "from": "/bar", "path": "/foo" } ],
414      "error": "missing 'from' location" },
415
416    { "comment": "missing from parameter to move",
417      "doc": { "foo": 1 },
418      "patch": [ { "op": "move", "path": "" } ],
419      "error": "missing 'from' parameter" },
420
421    { "comment": "missing from location to move",
422      "doc": { "foo": 1 },
423      "patch": [ { "op": "move", "from": "/bar", "path": "/foo" } ],
424      "error": "missing 'from' location" },
425
426    { "comment": "duplicate ops",
427      "doc": { "foo": "bar" },
428      "patch": [ { "op": "add", "path": "/baz", "value": "qux",
429                   "op": "move", "from":"/foo" } ],
430      "error": "patch has two 'op' members",
431      "disabled": true },
432
433    { "comment": "unrecognized op should fail",
434      "doc": {"foo": 1},
435      "patch": [{"op": "spam", "path": "/foo", "value": 1}],
436      "error": "Unrecognized op 'spam'" },
437
438    { "comment": "test with bad array number that has leading zeros",
439      "doc": ["foo", "bar"],
440      "patch": [{"op": "test", "path": "/00", "value": "foo"}],
441      "error": "test op should reject the array value, it has leading zeros" },
442
443    { "comment": "test with bad array number that has leading zeros",
444      "doc": ["foo", "bar"],
445      "patch": [{"op": "test", "path": "/01", "value": "bar"}],
446      "error": "test op should reject the array value, it has leading zeros" },
447
448    { "comment": "Removing nonexistent field",
449      "doc": {"foo" : "bar"},
450      "patch": [{"op": "remove", "path": "/baz"}],
451      "error": "removing a nonexistent field should fail" },
452
453    { "comment": "Removing nonexistent index",
454      "doc": ["foo", "bar"],
455      "patch": [{"op": "remove", "path": "/2"}],
456      "error": "removing a nonexistent index should fail" },
457
458    { "comment": "Patch with different capitalisation than doc",
459       "doc": {"foo":"bar"},
460       "patch": [{"op": "add", "path": "/FOO", "value": "BAR"}],
461       "expected": {"foo": "bar", "FOO": "BAR"}
462    }
463
464]
465