RFC6901 JSON Pointer implementation in OCaml using jsont
1JSON Pointer Mutation Tests (RFC 6902 JSON Patch operations)
2
3Add to object:
4 $ ./test_pointer.exe add '{"foo":"bar"}' '/baz' '"qux"'
5 {"foo":"bar","baz":"qux"}
6
7Add to array (insert before):
8 $ ./test_pointer.exe add '{"foo":["bar","baz"]}' '/foo/1' '"qux"'
9 {"foo":["bar","qux","baz"]}
10
11Add to array at beginning:
12 $ ./test_pointer.exe add '{"foo":["bar","baz"]}' '/foo/0' '"qux"'
13 {"foo":["qux","bar","baz"]}
14
15Add to array at end using -:
16 $ ./test_pointer.exe add '{"foo":["bar"]}' '/foo/-' '"qux"'
17 {"foo":["bar","qux"]}
18
19Add replaces existing member:
20 $ ./test_pointer.exe add '{"foo":"bar"}' '/foo' '"baz"'
21 {"foo":"baz"}
22
23Remove from object:
24 $ ./test_pointer.exe remove '{"foo":"bar","baz":"qux"}' '/baz'
25 {"foo":"bar"}
26
27Remove from array:
28 $ ./test_pointer.exe remove '{"foo":["bar","qux","baz"]}' '/foo/1'
29 {"foo":["bar","baz"]}
30
31Remove first element:
32 $ ./test_pointer.exe remove '{"foo":["bar","baz"]}' '/foo/0'
33 {"foo":["baz"]}
34
35Replace in object:
36 $ ./test_pointer.exe replace '{"foo":"bar"}' '/foo' '"baz"'
37 {"foo":"baz"}
38
39Replace in array:
40 $ ./test_pointer.exe replace '{"foo":["bar","baz"]}' '/foo/0' '"qux"'
41 {"foo":["qux","baz"]}
42
43Move within object:
44 $ ./test_pointer.exe move '{"foo":{"bar":"baz"},"qux":{}}' '/foo/bar' '/qux/thud'
45 {"foo":{},"qux":{"thud":"baz"}}
46
47Move within array:
48 $ ./test_pointer.exe move '{"foo":["a","b","c","d"]}' '/foo/1' '/foo/3'
49 {"foo":["a","c","d","b"]}
50
51Copy within object:
52 $ ./test_pointer.exe copy '{"foo":{"bar":"baz"}}' '/foo/bar' '/foo/qux'
53 {"foo":{"bar":"baz","qux":"baz"}}
54
55Copy to new location:
56 $ ./test_pointer.exe copy '{"foo":"bar"}' '/foo' '/baz'
57 {"foo":"bar","baz":"bar"}
58
59Test equality (true):
60 $ ./test_pointer.exe test '{"foo":"bar"}' '/foo' '"bar"'
61 true
62
63Test equality (false):
64 $ ./test_pointer.exe test '{"foo":"bar"}' '/foo' '"baz"'
65 false
66
67Test array equality:
68 $ ./test_pointer.exe test '{"foo":["bar","baz"]}' '/foo' '["bar","baz"]'
69 true
70
71Test nonexistent path returns false:
72 $ ./test_pointer.exe test '{"foo":"bar"}' '/baz' '"qux"'
73 false
74
75Error: remove root:
76 $ ./test_pointer.exe remove '{"foo":"bar"}' ''
77 ERROR: JSON Pointer: cannot remove root document
78
79Error: remove nonexistent:
80 $ ./test_pointer.exe remove '{"foo":"bar"}' '/baz'
81 ERROR: JSON Pointer: member 'baz' not found for remove
82 File "-":
83
84Error: replace nonexistent:
85 $ ./test_pointer.exe replace '{"foo":"bar"}' '/baz' '"qux"'
86 ERROR: JSON Pointer: member 'baz' not found
87 File "-":
88
89Error: add to out of bounds index:
90 $ ./test_pointer.exe add '{"foo":["bar"]}' '/foo/5' '"qux"'
91 ERROR: JSON Pointer: index 5 out of bounds for add (array has 1 elements)
92 File "-":
93
94Add nested path (parent must exist):
95 $ ./test_pointer.exe add '{"foo":{}}' '/foo/bar' '"baz"'
96 {"foo":{"bar":"baz"}}
97
98Add to root-level array:
99 $ ./test_pointer.exe add '["a","b"]' '/1' '"x"'
100 ["a","x","b"]
101 $ ./test_pointer.exe add '["a","b"]' '/-' '"c"'
102 ["a","b","c"]
103 $ ./test_pointer.exe add '["a","b"]' '/0' '"x"'
104 ["x","a","b"]
105
106Replace root document:
107 $ ./test_pointer.exe replace '{"foo":"bar"}' '' '"new root"'
108 "new root"
109 $ ./test_pointer.exe replace '["a","b"]' '' '{"replaced":true}'
110 {"replaced":true}
111
112Move from array to object:
113 $ ./test_pointer.exe move '{"arr":["x","y"],"obj":{}}' '/arr/0' '/obj/item'
114 {"arr":["y"],"obj":{"item":"x"}}
115
116Copy array element:
117 $ ./test_pointer.exe copy '{"arr":["x","y"]}' '/arr/0' '/arr/-'
118 {"arr":["x","y","x"]}
119
120Test with numeric string member names (RFC 6901: context determines interpretation):
121 $ ./test_pointer.exe add '{"0":"zero","1":"one"}' '/2' '"two"'
122 {"0":"zero","1":"one","2":"two"}
123 $ ./test_pointer.exe eval data/numeric_keys.json "/0"
124 OK: "zero"
125
126Special characters in member names:
127 $ ./test_pointer.exe add '{}' '/a~1b' '"slash"'
128 {"a/b":"slash"}
129 $ ./test_pointer.exe add '{}' '/m~0n' '"tilde"'
130 {"m~n":"tilde"}
131 $ ./test_pointer.exe replace '{"a/b":"old"}' '/a~1b' '"new"'
132 {"a/b":"new"}
133
134Deep nested mutations:
135 $ ./test_pointer.exe add '{"a":{"b":{"c":{}}}}' '/a/b/c/d' '"deep"'
136 {"a":{"b":{"c":{"d":"deep"}}}}
137 $ ./test_pointer.exe remove '{"a":{"b":{"c":{"d":"deep"}}}}' '/a/b/c/d'
138 {"a":{"b":{"c":{}}}}
139
140Error: remove from nonexistent array index:
141 $ ./test_pointer.exe remove '{"foo":["bar"]}' '/foo/5'
142 ERROR: JSON Pointer: index 5 out of bounds for remove
143 File "-":
144
145Error: move to descendant of source (path doesn't exist after removal):
146 $ ./test_pointer.exe move '{"a":{"b":"c"}}' '/a' '/a/b'
147 ERROR: JSON Pointer: member 'a' not found
148 File "-":
149
150Copy to same location (no-op essentially):
151 $ ./test_pointer.exe copy '{"foo":"bar"}' '/foo' '/foo'
152 {"foo":"bar"}
153
154Test value equality with different types:
155 $ ./test_pointer.exe test '{"n":1}' '/n' '1'
156 true
157 $ ./test_pointer.exe test '{"n":1.0}' '/n' '1'
158 true
159 $ ./test_pointer.exe test '{"n":"1"}' '/n' '1'
160 false
161 $ ./test_pointer.exe test '{"b":true}' '/b' 'true'
162 true
163 $ ./test_pointer.exe test '{"b":false}' '/b' 'false'
164 true
165 $ ./test_pointer.exe test '{"n":null}' '/n' 'null'
166 true
167
168Test deep equality:
169 $ ./test_pointer.exe test '{"obj":{"a":1,"b":2}}' '/obj' '{"a":1,"b":2}'
170 true
171 $ ./test_pointer.exe test '{"arr":[1,2,3]}' '/arr' '[1,2,3]'
172 true