RFC6901 JSON Pointer implementation in OCaml using jsont
at main 172 lines 5.2 kB view raw
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