|
| 1 | +let ( >:: ), ( >::: ) = OUnit.(( >:: ), ( >::: )) |
| 2 | +type t = Ext_json_noloc.t |
| 3 | +let rec equal (x : t) (y : t) = |
| 4 | + match x with |
| 5 | + | Null -> ( |
| 6 | + (* [%p? Null _ ] *) |
| 7 | + match y with |
| 8 | + | Null -> true |
| 9 | + | _ -> false) |
| 10 | + | Str str -> ( |
| 11 | + match y with |
| 12 | + | Str str2 -> str = str2 |
| 13 | + | _ -> false) |
| 14 | + | Flo flo -> ( |
| 15 | + match y with |
| 16 | + | Flo flo2 -> flo = flo2 |
| 17 | + | _ -> false) |
| 18 | + | True -> ( |
| 19 | + match y with |
| 20 | + | True -> true |
| 21 | + | _ -> false) |
| 22 | + | False -> ( |
| 23 | + match y with |
| 24 | + | False -> true |
| 25 | + | _ -> false) |
| 26 | + | Arr content -> ( |
| 27 | + match y with |
| 28 | + | Arr content2 -> Ext_array.for_all2_no_exn content content2 equal |
| 29 | + | _ -> false) |
| 30 | + | Obj map -> ( |
| 31 | + match y with |
| 32 | + | Obj map2 -> |
| 33 | + let xs = |
| 34 | + Map_string.bindings map |> List.sort (fun (a, _) (b, _) -> compare a b) |
| 35 | + in |
| 36 | + let ys = |
| 37 | + Map_string.bindings map2 |> List.sort (fun (a, _) (b, _) -> compare a b) |
| 38 | + in |
| 39 | + Ext_list.for_all2_no_exn xs ys (fun (k0, v0) (k1, v1) -> |
| 40 | + k0 = k1 && equal v0 v1) |
| 41 | + | _ -> false) |
| 42 | + |
| 43 | +open Ext_json_parse |
| 44 | +let ( |? ) m (key, cb) = m |> Ext_json.test key cb |
| 45 | + |
| 46 | +let rec strip (x : Ext_json_types.t) : Ext_json_noloc.t = |
| 47 | + let open Ext_json_noloc in |
| 48 | + match x with |
| 49 | + | True _ -> true_ |
| 50 | + | False _ -> false_ |
| 51 | + | Null _ -> null |
| 52 | + | Flo {flo = s} -> flo s |
| 53 | + | Str {str = s} -> str s |
| 54 | + | Arr {content} -> arr (Array.map strip content) |
| 55 | + | Obj {map} -> obj (Map_string.map map strip) |
| 56 | + |
| 57 | +let id_parsing_serializing x = |
| 58 | + let normal_s = |
| 59 | + Ext_json_noloc.to_string @@ strip @@ Ext_json_parse.parse_json_from_string x |
| 60 | + in |
| 61 | + let normal_ss = |
| 62 | + Ext_json_noloc.to_string @@ strip |
| 63 | + @@ Ext_json_parse.parse_json_from_string normal_s |
| 64 | + in |
| 65 | + if normal_s <> normal_ss then ( |
| 66 | + prerr_endline "ERROR"; |
| 67 | + prerr_endline normal_s; |
| 68 | + prerr_endline normal_ss); |
| 69 | + OUnit.assert_equal ~cmp:(fun (x : string) y -> x = y) normal_s normal_ss |
| 70 | + |
| 71 | +let id_parsing_x2 x = |
| 72 | + let stru = Ext_json_parse.parse_json_from_string x |> strip in |
| 73 | + let normal_s = Ext_json_noloc.to_string stru in |
| 74 | + let normal_ss = strip (Ext_json_parse.parse_json_from_string normal_s) in |
| 75 | + if equal stru normal_ss then true |
| 76 | + else ( |
| 77 | + prerr_endline "ERROR"; |
| 78 | + prerr_endline normal_s; |
| 79 | + Format.fprintf Format.err_formatter "%a@.%a@." Ext_obj.pp_any stru |
| 80 | + Ext_obj.pp_any normal_ss; |
| 81 | + |
| 82 | + prerr_endline (Ext_json_noloc.to_string normal_ss); |
| 83 | + false) |
| 84 | + |
| 85 | +let test_data = |
| 86 | + [ |
| 87 | + {| |
| 88 | + {} |
| 89 | + |}; |
| 90 | + {| [] |}; |
| 91 | + {| [1,2,3]|}; |
| 92 | + {| ["x", "y", 1,2,3 ]|}; |
| 93 | + {| { "x" : 3, "y" : "x", "z" : [1,2,3, "x"] }|}; |
| 94 | + {| {"x " : true , "y" : false , "z\"" : 1} |}; |
| 95 | + ] |
| 96 | +exception Parse_error |
| 97 | +let suites = |
| 98 | + __FILE__ |
| 99 | + >::: [ |
| 100 | + (__LOC__ >:: fun _ -> List.iter id_parsing_serializing test_data); |
| 101 | + ( __LOC__ >:: fun _ -> |
| 102 | + List.iteri |
| 103 | + (fun i x -> |
| 104 | + OUnit.assert_bool (__LOC__ ^ string_of_int i) (id_parsing_x2 x)) |
| 105 | + test_data ); |
| 106 | + ( "empty_json" >:: fun _ -> |
| 107 | + let v = parse_json_from_string "{}" in |
| 108 | + match v with |
| 109 | + | Obj {map = v} -> OUnit.assert_equal (Map_string.is_empty v) true |
| 110 | + | _ -> OUnit.assert_failure "should be empty" ); |
| 111 | + ( "empty_arr" >:: fun _ -> |
| 112 | + let v = parse_json_from_string "[]" in |
| 113 | + match v with |
| 114 | + | Arr {content = [||]} -> () |
| 115 | + | _ -> OUnit.assert_failure "should be empty" ); |
| 116 | + ( "empty trails" >:: fun _ -> |
| 117 | + ( OUnit.assert_raises Parse_error @@ fun _ -> |
| 118 | + try parse_json_from_string {| [,]|} with _ -> raise Parse_error ); |
| 119 | + OUnit.assert_raises Parse_error @@ fun _ -> |
| 120 | + try parse_json_from_string {| {,}|} with _ -> raise Parse_error ); |
| 121 | + ( "two trails" >:: fun _ -> |
| 122 | + ( OUnit.assert_raises Parse_error @@ fun _ -> |
| 123 | + try parse_json_from_string {| [1,2,,]|} |
| 124 | + with _ -> raise Parse_error ); |
| 125 | + OUnit.assert_raises Parse_error @@ fun _ -> |
| 126 | + try parse_json_from_string {| { "x": 3, ,}|} |
| 127 | + with _ -> raise Parse_error ); |
| 128 | + ( "two trails fail" >:: fun _ -> |
| 129 | + OUnit.assert_raises Parse_error @@ fun _ -> |
| 130 | + try parse_json_from_string {| { "x": 3, 2 ,}|} |
| 131 | + with _ -> raise Parse_error ); |
| 132 | + ( "trail comma obj" >:: fun _ -> |
| 133 | + let v = parse_json_from_string {| { "x" : 3 , }|} in |
| 134 | + let v1 = parse_json_from_string {| { "x" : 3 , }|} in |
| 135 | + let test (v : Ext_json_types.t) = |
| 136 | + match v with |
| 137 | + | Obj {map = v} -> |
| 138 | + v |? ("x", `Flo (fun x -> OUnit.assert_equal x "3")) |> ignore |
| 139 | + | _ -> OUnit.assert_failure "trail comma" |
| 140 | + in |
| 141 | + test v; |
| 142 | + test v1 ); |
| 143 | + ( "trail comma arr" >:: fun _ -> |
| 144 | + let v = parse_json_from_string {| [ 1, 3, ]|} in |
| 145 | + let v1 = parse_json_from_string {| [ 1, 3 ]|} in |
| 146 | + let test (v : Ext_json_types.t) = |
| 147 | + match v with |
| 148 | + | Arr {content = [|Flo {flo = "1"}; Flo {flo = "3"}|]} -> () |
| 149 | + | _ -> OUnit.assert_failure "trailing comma array" |
| 150 | + in |
| 151 | + test v; |
| 152 | + test v1 ); |
| 153 | + ] |
0 commit comments