RFC6901 JSON Pointer implementation in OCaml using jsont
1(* Test runner for json_pointer *)
2
3let read_file path =
4 let ic = open_in path in
5 let n = in_channel_length ic in
6 let s = really_input_string ic n in
7 close_in ic;
8 s
9
10let parse_json s =
11 match Jsont_bytesrw.decode_string Jsont.json s with
12 | Ok json -> json
13 | Error e -> failwith e
14
15let json_to_string json =
16 match Jsont_bytesrw.encode_string Jsont.json json with
17 | Ok s -> s
18 | Error e -> failwith e
19
20(* Helper to get indices from any pointer *)
21let indices_of_any (Json_pointer.Any p) = Json_pointer.indices p
22
23(* Helper to convert to string from any pointer *)
24let to_string_of_any (Json_pointer.Any p) = Json_pointer.to_string p
25
26(* Helper to check if pointer is append *)
27let is_append_any (Json_pointer.Any p : Json_pointer.any) =
28 not (Json_pointer.is_nav (Json_pointer.Any p))
29
30(* Test: parse pointer and print indices *)
31let test_parse pointer_str =
32 try
33 let result = Json_pointer.of_string pointer_str in
34 let indices = indices_of_any result in
35 let index_strs = List.map (fun idx ->
36 match idx with
37 | Jsont.Path.Mem (s, _) -> Printf.sprintf "Mem:%s" s
38 | Jsont.Path.Nth (n, _) -> Printf.sprintf "Nth:%d" n
39 ) indices in
40 let suffix = if is_append_any result then ", /-" else "" in
41 Printf.printf "OK: [%s%s]\n" (String.concat ", " index_strs) suffix
42 with Jsont.Error e ->
43 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
44
45(* Test: roundtrip pointer string *)
46let test_roundtrip pointer_str =
47 try
48 let result = Json_pointer.of_string pointer_str in
49 let s = to_string_of_any result in
50 if s = pointer_str then
51 Printf.printf "OK: %s\n" s
52 else
53 Printf.printf "MISMATCH: input=%s output=%s\n" pointer_str s
54 with Jsont.Error e ->
55 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
56
57(* Test: evaluate pointer against JSON *)
58let test_eval json_path pointer_str =
59 try
60 let json = parse_json (read_file json_path) in
61 let p = Json_pointer.of_string_nav pointer_str in
62 let result = Json_pointer.get p json in
63 Printf.printf "OK: %s\n" (json_to_string result)
64 with
65 | Jsont.Error e ->
66 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
67 | Failure e ->
68 Printf.printf "FAIL: %s\n" e
69
70(* Test: escape token *)
71let test_escape token =
72 let escaped = Json_pointer.Token.escape token in
73 Printf.printf "%s\n" escaped
74
75(* Test: unescape token *)
76let test_unescape token =
77 try
78 let unescaped = Json_pointer.Token.unescape token in
79 Printf.printf "OK: %s\n" unescaped
80 with Jsont.Error e ->
81 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
82
83(* Test: URI fragment roundtrip *)
84let test_uri_fragment pointer_str =
85 try
86 let result = Json_pointer.of_string pointer_str in
87 let (Json_pointer.Any p) = result in
88 let frag = Json_pointer.to_uri_fragment p in
89 let result2 = Json_pointer.of_uri_fragment frag in
90 let s2 = to_string_of_any result2 in
91 if s2 = pointer_str then
92 Printf.printf "OK: %s -> %s\n" pointer_str frag
93 else
94 Printf.printf "MISMATCH: %s -> %s -> %s\n" pointer_str frag s2
95 with Jsont.Error e ->
96 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
97
98(* Test: add operation *)
99let test_add json_str pointer_str value_str =
100 try
101 let json = parse_json json_str in
102 let value = parse_json value_str in
103 let p = Json_pointer.of_string pointer_str in
104 let result = Json_pointer.add p json ~value in
105 Printf.printf "%s\n" (json_to_string result)
106 with Jsont.Error e ->
107 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
108
109(* Test: remove operation *)
110let test_remove json_str pointer_str =
111 try
112 let json = parse_json json_str in
113 let p = Json_pointer.of_string_nav pointer_str in
114 let result = Json_pointer.remove p json in
115 Printf.printf "%s\n" (json_to_string result)
116 with Jsont.Error e ->
117 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
118
119(* Test: replace operation *)
120let test_replace json_str pointer_str value_str =
121 try
122 let json = parse_json json_str in
123 let p = Json_pointer.of_string_nav pointer_str in
124 let value = parse_json value_str in
125 let result = Json_pointer.replace p json ~value in
126 Printf.printf "%s\n" (json_to_string result)
127 with Jsont.Error e ->
128 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
129
130(* Test: move operation *)
131let test_move json_str from_str path_str =
132 try
133 let json = parse_json json_str in
134 let from = Json_pointer.of_string_nav from_str in
135 let path = Json_pointer.of_string path_str in
136 let result = Json_pointer.move ~from ~path json in
137 Printf.printf "%s\n" (json_to_string result)
138 with Jsont.Error e ->
139 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
140
141(* Test: copy operation *)
142let test_copy json_str from_str path_str =
143 try
144 let json = parse_json json_str in
145 let from = Json_pointer.of_string_nav from_str in
146 let path = Json_pointer.of_string path_str in
147 let result = Json_pointer.copy ~from ~path json in
148 Printf.printf "%s\n" (json_to_string result)
149 with Jsont.Error e ->
150 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
151
152(* Test: test operation *)
153let test_test json_str pointer_str expected_str =
154 try
155 let json = parse_json json_str in
156 let p = Json_pointer.of_string_nav pointer_str in
157 let expected = parse_json expected_str in
158 let result = Json_pointer.test p json ~expected in
159 Printf.printf "%b\n" result
160 with Jsont.Error e ->
161 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
162
163(* Test: has operation (checks if pointer exists) *)
164let test_has json_str pointer_str =
165 try
166 let json = parse_json json_str in
167 let p = Json_pointer.of_string_nav pointer_str in
168 let result = Json_pointer.find p json in
169 Printf.printf "%b\n" (Option.is_some result)
170 with Jsont.Error e ->
171 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
172
173let () =
174 match Array.to_list Sys.argv with
175 | _ :: "parse" :: pointer :: _ ->
176 test_parse pointer
177 | _ :: "roundtrip" :: pointer :: _ ->
178 test_roundtrip pointer
179 | _ :: "eval" :: json_path :: pointer :: _ ->
180 test_eval json_path pointer
181 | _ :: "escape" :: token :: _ ->
182 test_escape token
183 | _ :: "unescape" :: token :: _ ->
184 test_unescape token
185 | _ :: "uri-fragment" :: pointer :: _ ->
186 test_uri_fragment pointer
187 | _ :: "add" :: json :: pointer :: value :: _ ->
188 test_add json pointer value
189 | _ :: "remove" :: json :: pointer :: _ ->
190 test_remove json pointer
191 | _ :: "replace" :: json :: pointer :: value :: _ ->
192 test_replace json pointer value
193 | _ :: "move" :: json :: from :: path :: _ ->
194 test_move json from path
195 | _ :: "copy" :: json :: from :: path :: _ ->
196 test_copy json from path
197 | _ :: "test" :: json :: pointer :: expected :: _ ->
198 test_test json pointer expected
199 | _ :: "has" :: json :: pointer :: _ ->
200 test_has json pointer
201 | _ ->
202 Printf.printf "Usage:\n";
203 Printf.printf " test_pointer parse <pointer>\n";
204 Printf.printf " test_pointer roundtrip <pointer>\n";
205 Printf.printf " test_pointer eval <json-file> <pointer>\n";
206 Printf.printf " test_pointer escape <token>\n";
207 Printf.printf " test_pointer unescape <token>\n";
208 Printf.printf " test_pointer uri-fragment <pointer>\n";
209 Printf.printf " test_pointer add <json> <pointer> <value>\n";
210 Printf.printf " test_pointer remove <json> <pointer>\n";
211 Printf.printf " test_pointer replace <json> <pointer> <value>\n";
212 Printf.printf " test_pointer move <json> <from> <path>\n";
213 Printf.printf " test_pointer copy <json> <from> <path>\n";
214 Printf.printf " test_pointer test <json> <pointer> <expected>\n";
215 Printf.printf " test_pointer has <json> <pointer>\n";
216 exit 1