RFC6901 JSON Pointer implementation in OCaml using jsont
at main 14 kB view raw
1JSON Pointer API Test Suite 2 3This tests all functions exposed in json_pointer.mli. 4 5================================================================================ 6Index Functions (mem, nth, pp_index, equal_index, compare_index) 7================================================================================ 8 9Creating indices with mem: 10 $ ./test_pointer.exe mem "foo" 11 mem(foo) = /foo 12 $ ./test_pointer.exe mem "" 13 mem() = / 14 $ ./test_pointer.exe mem "a/b" 15 mem(a/b) = /a~1b 16 $ ./test_pointer.exe mem "m~n" 17 mem(m~n) = /m~0n 18 19Creating indices with nth: 20 $ ./test_pointer.exe nth 0 21 nth(0) = /0 22 $ ./test_pointer.exe nth 5 23 nth(5) = /5 24 $ ./test_pointer.exe nth 123 25 nth(123) = /123 26 27Testing index equality: 28 $ ./test_pointer.exe equal-index "foo" "foo" 29 true 30 $ ./test_pointer.exe equal-index "foo" "bar" 31 false 32 $ ./test_pointer.exe equal-index "0" "0" 33 true 34 $ ./test_pointer.exe equal-index "0" "1" 35 false 36 $ ./test_pointer.exe equal-index "foo" "0" 37 false 38 39Testing index comparison: 40 $ ./test_pointer.exe compare-index "foo" "foo" 41 EQ 42 $ ./test_pointer.exe compare-index "aaa" "bbb" 43 LT 44 $ ./test_pointer.exe compare-index "bbb" "aaa" 45 GT 46 $ ./test_pointer.exe compare-index "0" "0" 47 EQ 48 $ ./test_pointer.exe compare-index "0" "5" 49 LT 50 $ ./test_pointer.exe compare-index "5" "0" 51 GT 52 $ ./test_pointer.exe compare-index "foo" "0" 53 LT 54 $ ./test_pointer.exe compare-index "0" "foo" 55 GT 56 57================================================================================ 58Pointer Constructors (root, is_root, make, /, append_index, at_end, concat, parent, last) 59================================================================================ 60 61Root pointer: 62 $ ./test_pointer.exe root 63 root = 64 is_root(root) = true 65 66Testing is_root: 67 $ ./test_pointer.exe is-root "" 68 true 69 $ ./test_pointer.exe is-root "/foo" 70 false 71 $ ./test_pointer.exe is-root "/foo/bar" 72 false 73 74Making pointers from indices: 75 $ ./test_pointer.exe make "foo" 76 /foo 77 $ ./test_pointer.exe make "foo,bar" 78 /foo/bar 79 $ ./test_pointer.exe make "foo,0,bar" 80 /foo/0/bar 81 $ ./test_pointer.exe make "0,1,2" 82 /0/1/2 83 84Appending index to pointer: 85 $ ./test_pointer.exe append-index "" "foo" 86 /foo 87 $ ./test_pointer.exe append-index "/foo" "bar" 88 /foo/bar 89 $ ./test_pointer.exe append-index "/foo" "0" 90 /foo/0 91 $ ./test_pointer.exe append-index "/foo/bar" "baz" 92 /foo/bar/baz 93 94Creating append pointers with at_end: 95 $ ./test_pointer.exe at-end "" 96 /- 97 $ ./test_pointer.exe at-end "/foo" 98 /foo/- 99 $ ./test_pointer.exe at-end "/foo/bar" 100 /foo/bar/- 101 102Concatenating pointers: 103 $ ./test_pointer.exe concat "" "" 104 105 106 $ ./test_pointer.exe concat "/foo" "" 107 /foo 108 $ ./test_pointer.exe concat "" "/bar" 109 /bar 110 $ ./test_pointer.exe concat "/foo" "/bar" 111 /foo/bar 112 $ ./test_pointer.exe concat "/a/b" "/c/d" 113 /a/b/c/d 114 115Getting parent pointer: 116 $ ./test_pointer.exe parent "" 117 None 118 $ ./test_pointer.exe parent "/foo" 119 Some() 120 $ ./test_pointer.exe parent "/foo/bar" 121 Some(/foo) 122 $ ./test_pointer.exe parent "/a/b/c" 123 Some(/a/b) 124 125Getting last index: 126 $ ./test_pointer.exe last "" 127 None 128 $ ./test_pointer.exe last "/foo" 129 Some(/foo) 130 $ ./test_pointer.exe last "/foo/bar" 131 Some(/bar) 132 $ ./test_pointer.exe last "/foo/0" 133 Some(/0) 134 135Getting all indices: 136 $ ./test_pointer.exe indices "" 137 [] 138 $ ./test_pointer.exe indices "/foo" 139 [Mem:foo] 140 $ ./test_pointer.exe indices "/foo/bar" 141 [Mem:foo, Mem:bar] 142 $ ./test_pointer.exe indices "/foo/0/bar" 143 [Mem:foo, Nth:0, Mem:bar] 144 $ ./test_pointer.exe indices "/foo/-" 145 [Mem:foo] 146 147================================================================================ 148Coercion Functions (any, is_nav, to_nav, to_nav_exn) 149================================================================================ 150 151Note: is_nav is tested indirectly via the parse tests. Testing to_nav: 152 153 $ ./test_pointer.exe to-nav "" 154 Some() 155 $ ./test_pointer.exe to-nav "/foo" 156 Some(/foo) 157 $ ./test_pointer.exe to-nav "/foo/bar" 158 Some(/foo/bar) 159 $ ./test_pointer.exe to-nav "/-" 160 None 161 $ ./test_pointer.exe to-nav "/foo/-" 162 None 163 164Testing to_nav_exn: 165 $ ./test_pointer.exe to-nav-exn "" 166 OK: 167 $ ./test_pointer.exe to-nav-exn "/foo" 168 OK: /foo 169 $ ./test_pointer.exe to-nav-exn "/-" 170 ERROR: JSON Pointer: cannot convert append pointer to nav pointer 171 $ ./test_pointer.exe to-nav-exn "/foo/-" 172 ERROR: JSON Pointer: cannot convert append pointer to nav pointer 173 174================================================================================ 175Parsing Functions (of_string_kind, of_string_result, of_uri_fragment_nav, of_uri_fragment_result) 176================================================================================ 177 178Testing of_string_kind: 179 $ ./test_pointer.exe of-string-kind "" 180 Nav() 181 $ ./test_pointer.exe of-string-kind "/foo" 182 Nav(/foo) 183 $ ./test_pointer.exe of-string-kind "/-" 184 Append(/-) 185 $ ./test_pointer.exe of-string-kind "/foo/-" 186 Append(/foo/-) 187 $ ./test_pointer.exe of-string-kind "/foo/bar" 188 Nav(/foo/bar) 189 190Testing of_string_result: 191 $ ./test_pointer.exe of-string-result "" 192 Ok() 193 $ ./test_pointer.exe of-string-result "/foo" 194 Ok(/foo) 195 $ ./test_pointer.exe of-string-result "/-" 196 Ok(/-) 197 $ ./test_pointer.exe of-string-result "invalid" 198 Error(Invalid JSON Pointer: must be empty or start with '/': invalid) 199 $ ./test_pointer.exe of-string-result "/~" 200 Error(Invalid JSON Pointer: incomplete escape sequence at end) 201 202Testing of_uri_fragment_nav: 203 $ ./test_pointer.exe of-uri-fragment-nav "" 204 OK: 205 $ ./test_pointer.exe of-uri-fragment-nav "/foo" 206 OK: /foo 207 $ ./test_pointer.exe of-uri-fragment-nav "/foo/bar" 208 OK: /foo/bar 209 $ ./test_pointer.exe of-uri-fragment-nav "/foo%2Fbar" 210 OK: /foo/bar 211 $ ./test_pointer.exe of-uri-fragment-nav "/-" 212 ERROR: Invalid JSON Pointer: '-' not allowed in navigation pointer 213 214Testing of_uri_fragment_result: 215 $ ./test_pointer.exe of-uri-fragment-result "" 216 Ok() 217 $ ./test_pointer.exe of-uri-fragment-result "/foo" 218 Ok(/foo) 219 $ ./test_pointer.exe of-uri-fragment-result "/-" 220 Ok(/-) 221 $ ./test_pointer.exe of-uri-fragment-result "invalid" 222 Error(Invalid JSON Pointer: must be empty or start with '/': invalid) 223 224================================================================================ 225Pretty Printing (pp, pp_verbose) 226================================================================================ 227 228Testing pp: 229 $ ./test_pointer.exe pp "" 230 231 232 $ ./test_pointer.exe pp "/foo" 233 /foo 234 $ ./test_pointer.exe pp "/foo/bar" 235 /foo/bar 236 $ ./test_pointer.exe pp "/-" 237 /- 238 $ ./test_pointer.exe pp "/foo/-" 239 /foo/- 240 241Testing pp_verbose: 242 $ ./test_pointer.exe pp-verbose "" 243 [] 244 $ ./test_pointer.exe pp-verbose "/foo" 245 [Mem "foo"] 246 $ ./test_pointer.exe pp-verbose "/foo/0" 247 [Mem "foo"; Nth 0] 248 $ ./test_pointer.exe pp-verbose "/foo/bar/baz" 249 [Mem "foo"; Mem "bar"; Mem "baz"] 250 $ ./test_pointer.exe pp-verbose "/-" 251 [] /- 252 $ ./test_pointer.exe pp-verbose "/foo/-" 253 [Mem "foo"] /- 254 255================================================================================ 256Comparison (equal, compare) 257================================================================================ 258 259Testing equal: 260 $ ./test_pointer.exe equal "" "" 261 true 262 $ ./test_pointer.exe equal "/foo" "/foo" 263 true 264 $ ./test_pointer.exe equal "/foo" "/bar" 265 false 266 $ ./test_pointer.exe equal "/foo/0" "/foo/0" 267 true 268 $ ./test_pointer.exe equal "/foo/0" "/foo/1" 269 false 270 $ ./test_pointer.exe equal "/-" "/-" 271 true 272 $ ./test_pointer.exe equal "/foo/-" "/foo/-" 273 true 274 $ ./test_pointer.exe equal "/foo" "/foo/-" 275 false 276 277Testing compare: 278 $ ./test_pointer.exe compare "" "" 279 EQ 280 $ ./test_pointer.exe compare "/foo" "/foo" 281 EQ 282 $ ./test_pointer.exe compare "/aaa" "/bbb" 283 LT 284 $ ./test_pointer.exe compare "/bbb" "/aaa" 285 GT 286 $ ./test_pointer.exe compare "/foo" "/foo/bar" 287 LT 288 $ ./test_pointer.exe compare "/foo/bar" "/foo" 289 GT 290 $ ./test_pointer.exe compare "/foo" "/foo/-" 291 LT 292 $ ./test_pointer.exe compare "/foo/-" "/foo" 293 GT 294 295================================================================================ 296Jsont.Path Conversion (of_path, to_path) 297================================================================================ 298 299Testing of_path (builds a path programmatically): 300 $ ./test_pointer.exe of-path 301 /0/foo/1 302 303Testing to_path: 304 $ ./test_pointer.exe to-path "" 305 [] 306 $ ./test_pointer.exe to-path "/foo" 307 [Mem:foo] 308 $ ./test_pointer.exe to-path "/foo/0" 309 [Mem:foo, Nth:0] 310 $ ./test_pointer.exe to-path "/a/b/c" 311 [Mem:a, Mem:b, Mem:c] 312 313================================================================================ 314Evaluation (get_result, set) 315================================================================================ 316 317Testing get_result: 318 $ ./test_pointer.exe get-result '{"foo":"bar"}' '/foo' 319 Ok("bar") 320 $ ./test_pointer.exe get-result '{"foo":{"bar":"baz"}}' '/foo/bar' 321 Ok("baz") 322 $ ./test_pointer.exe get-result '["a","b","c"]' '/1' 323 Ok("b") 324 $ ./test_pointer.exe get-result '{"foo":"bar"}' '/baz' 325 Error(JSON Pointer: member 'baz' not found 326 File "-":) 327 $ ./test_pointer.exe get-result '["a","b"]' '/5' 328 Error(JSON Pointer: index 5 out of bounds (array has 2 elements) 329 File "-":) 330 331Testing set (with nav pointer): 332 $ ./test_pointer.exe set '{"foo":"bar"}' '/foo' '"baz"' 333 {"foo":"baz"} 334 $ ./test_pointer.exe set '{"foo":{"bar":"old"}}' '/foo/bar' '"new"' 335 {"foo":{"bar":"new"}} 336 $ ./test_pointer.exe set '["a","b","c"]' '/1' '"x"' 337 ["a","x","c"] 338 339Testing set (with append pointer): 340 $ ./test_pointer.exe set '["a","b"]' '/-' '"c"' 341 ["a","b","c"] 342 $ ./test_pointer.exe set '{"arr":["x"]}' '/arr/-' '"y"' 343 {"arr":["x","y"]} 344 345================================================================================ 346Jsont Codecs (jsont, jsont_kind, jsont_nav, jsont_uri_fragment) 347================================================================================ 348 349Testing jsont codec roundtrip: 350 $ ./test_pointer.exe jsont-codec "" 351 "" 352 $ ./test_pointer.exe jsont-codec "/foo" 353 "/foo" 354 $ ./test_pointer.exe jsont-codec "/foo/bar" 355 "/foo/bar" 356 $ ./test_pointer.exe jsont-codec "/-" 357 "/-" 358 $ ./test_pointer.exe jsont-codec "/foo/-" 359 "/foo/-" 360 361Testing jsont_kind codec: 362 $ ./test_pointer.exe jsont-kind "" 363 Nav() 364 $ ./test_pointer.exe jsont-kind "/foo" 365 Nav(/foo) 366 $ ./test_pointer.exe jsont-kind "/-" 367 Append(/-) 368 $ ./test_pointer.exe jsont-kind "/foo/-" 369 Append(/foo/-) 370 371Testing jsont_nav codec: 372 $ ./test_pointer.exe jsont-nav "" 373 OK: 374 $ ./test_pointer.exe jsont-nav "/foo" 375 OK: /foo 376 $ ./test_pointer.exe jsont-nav "/-" 377 ERROR: Invalid JSON Pointer: '-' not allowed in navigation pointer 378 $ ./test_pointer.exe jsont-nav "/foo/-" 379 ERROR: Invalid JSON Pointer: '-' not allowed in navigation pointer 380 381Testing jsont_uri_fragment codec: 382 $ ./test_pointer.exe jsont-uri-fragment "" 383 "" 384 $ ./test_pointer.exe jsont-uri-fragment "/foo" 385 "/foo" 386 $ ./test_pointer.exe jsont-uri-fragment "/a~1b" 387 "/a~1b" 388 389================================================================================ 390Query Combinators (path, set_path, update_path, delete_path) 391================================================================================ 392 393Testing path combinator: 394 $ ./test_pointer.exe query-path '{"name":"alice"}' '/name' 395 OK: alice 396 $ ./test_pointer.exe query-path '{"user":{"name":"bob"}}' '/user/name' 397 OK: bob 398 399Testing path combinator with absent: 400 $ ./test_pointer.exe query-path-absent '{"name":"alice"}' '/name' 'default' 401 OK: alice 402 $ ./test_pointer.exe query-path-absent '{"other":"value"}' '/name' 'default' 403 OK: default 404 405Testing set_path combinator: 406 $ ./test_pointer.exe set-path '{"name":"alice"}' '/name' 'bob' 407 {"name":"bob"} 408 $ ./test_pointer.exe set-path '{"user":{"name":"old"}}' '/user/name' 'new' 409 {"user":{"name":"new"}} 410 411Testing update_path combinator: 412 $ ./test_pointer.exe update-path '{"name":"alice"}' '/name' 413 {"name":"alice"} 414 $ ./test_pointer.exe update-path '{"user":{"name":"bob"}}' '/user/name' 415 {"user":{"name":"bob"}} 416 417Testing delete_path combinator: 418 $ ./test_pointer.exe delete-path '{"foo":"bar","baz":"qux"}' '/foo' 419 {"baz":"qux"} 420 $ ./test_pointer.exe delete-path '{"user":{"name":"bob","age":30}}' '/user/name' 421 {"user":{"age":30}} 422 423Testing delete_path with allow_absent: 424 $ ./test_pointer.exe delete-path-absent '{"foo":"bar"}' '/baz' 425 {"foo":"bar"} 426 $ ./test_pointer.exe delete-path-absent '{"foo":"bar"}' '/foo' 427 {} 428 429================================================================================ 430JMAP Extended Pointers - Additional Tests 431================================================================================ 432 433Testing Jmap.of_string_result: 434 $ ./test_pointer.exe jmap-of-string-result "" 435 Ok() 436 $ ./test_pointer.exe jmap-of-string-result "/foo" 437 Ok(/foo) 438 $ ./test_pointer.exe jmap-of-string-result "/*" 439 Ok(/*) 440 $ ./test_pointer.exe jmap-of-string-result "/list/*/id" 441 Ok(/list/*/id) 442 $ ./test_pointer.exe jmap-of-string-result "invalid" 443 Error(Invalid JMAP Pointer: must be empty or start with '/': invalid) 444 $ ./test_pointer.exe jmap-of-string-result "/-" 445 Error(Invalid JMAP Pointer: '-' not supported in result reference paths) 446 447Testing Jmap.pp: 448 $ ./test_pointer.exe jmap-pp "" 449 450 451 $ ./test_pointer.exe jmap-pp "/foo" 452 /foo 453 $ ./test_pointer.exe jmap-pp "/*" 454 /* 455 $ ./test_pointer.exe jmap-pp "/list/*/id" 456 /list/*/id 457 458Testing Jmap.eval_result: 459 $ ./test_pointer.exe jmap-eval-result '{"foo":"bar"}' '/foo' 460 Ok("bar") 461 $ ./test_pointer.exe jmap-eval-result '{"list":[{"id":"a"},{"id":"b"}]}' '/list/*/id' 462 Ok(["a","b"]) 463 $ ./test_pointer.exe jmap-eval-result '{"foo":"bar"}' '/baz' 464 Error(JMAP Pointer: member 'baz' not found 465 File "-":) 466 467Testing Jmap.find: 468 $ ./test_pointer.exe jmap-find '{"foo":"bar"}' '/foo' 469 Some("bar") 470 $ ./test_pointer.exe jmap-find '{"list":[{"id":"a"},{"id":"b"}]}' '/list/*/id' 471 Some(["a","b"]) 472 $ ./test_pointer.exe jmap-find '{"foo":"bar"}' '/baz' 473 None 474 $ ./test_pointer.exe jmap-find '{"obj":{"a":1}}' '/obj/*' 475 None 476 477Testing Jmap.jsont codec: 478 $ ./test_pointer.exe jmap-jsont "" 479 "" 480 $ ./test_pointer.exe jmap-jsont "/foo" 481 "/foo" 482 $ ./test_pointer.exe jmap-jsont "/*" 483 "/*" 484 $ ./test_pointer.exe jmap-jsont "/list/*/id" 485 "/list/*/id"