Yaml encoder/decoder for OCaml jsont codecs

Update precommit and clean up yamlt test files

-4685
-67
tests/bin/dune
··· 1 - (executable 2 - (name test_scalars) 3 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 4 - 5 - (executable 6 - (name test_objects) 7 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 8 - 9 - (executable 10 - (name test_arrays) 11 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 12 - 13 - (executable 14 - (name test_formats) 15 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 16 - 17 - (executable 18 - (name test_roundtrip) 19 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 20 - 21 - (executable 22 - (name test_complex) 23 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 24 - 25 - (executable 26 - (name test_edge) 27 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 28 - 29 - (executable 30 - (name test_null_fix) 31 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 32 - 33 - (executable 34 - (name test_null_complete) 35 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 36 - 37 - (executable 38 - (name test_null_collections) 39 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 40 - 41 - (executable 42 - (name test_opt_array) 43 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 44 - 45 - (executable 46 - (name test_array_variants) 47 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 48 - 49 - (executable 50 - (name test_some_vs_option) 51 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 52 - 53 - (executable 54 - (name test_comprehensive) 55 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 56 - 57 - (executable 58 - (name test_flow_newline) 59 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 60 - 61 - (executable 62 - (name test_locations) 63 - (libraries yamlt jsont jsont.bytesrw bytesrw)) 64 - 65 - (executable 66 - (name test_multidoc) 67 - (libraries yamlt jsont jsont.bytesrw bytesrw))
-32
tests/bin/test_array_variants.ml
··· 1 - open Bytesrw 2 - 3 - let () = 4 - let codec1 = 5 - Jsont.Object.map ~kind:"Test" (fun arr -> arr) 6 - |> Jsont.Object.mem "values" (Jsont.array Jsont.string) ~enc:(fun arr -> 7 - arr) 8 - |> Jsont.Object.finish 9 - in 10 - 11 - let yaml1 = "values: [a, b, c]" in 12 - 13 - Printf.printf "Test 1: Non-optional array:\n"; 14 - (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml1) with 15 - | Ok arr -> Printf.printf "Result: [%d items]\n" (Array.length arr) 16 - | Error e -> Printf.printf "Error: %s\n" e); 17 - 18 - let codec2 = 19 - Jsont.Object.map ~kind:"Test" (fun arr -> arr) 20 - |> Jsont.Object.mem "values" 21 - (Jsont.option (Jsont.array Jsont.string)) 22 - ~enc:(fun arr -> arr) 23 - |> Jsont.Object.finish 24 - in 25 - 26 - Printf.printf "\nTest 2: Jsont.option (Jsont.array):\n"; 27 - match Yamlt.decode codec2 (Bytes.Reader.of_string yaml1) with 28 - | Ok arr -> ( 29 - match arr with 30 - | None -> Printf.printf "Result: None\n" 31 - | Some a -> Printf.printf "Result: Some([%d items])\n" (Array.length a)) 32 - | Error e -> Printf.printf "Error: %s\n" e
-334
tests/bin/test_arrays.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test array codec functionality with Yamlt *) 7 - 8 - open Bytesrw 9 - 10 - (* Helper to read file *) 11 - let read_file path = 12 - let ic = open_in path in 13 - let len = in_channel_length ic in 14 - let s = really_input_string ic len in 15 - close_in ic; 16 - s 17 - 18 - (* Helper to show results *) 19 - let show_result label = function 20 - | Ok v -> Printf.printf "%s: %s\n" label v 21 - | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 - 23 - let show_result_both label json_result yaml_result = 24 - Printf.printf "JSON: "; 25 - show_result label json_result; 26 - Printf.printf "YAML: "; 27 - show_result label yaml_result 28 - 29 - (* Test: Simple int array *) 30 - let test_int_array file = 31 - let module M = struct 32 - type numbers = { values : int array } 33 - 34 - let numbers_codec = 35 - Jsont.Object.map ~kind:"Numbers" (fun values -> { values }) 36 - |> Jsont.Object.mem "values" (Jsont.array Jsont.int) ~enc:(fun n -> 37 - n.values) 38 - |> Jsont.Object.finish 39 - 40 - let show n = 41 - Printf.sprintf "[%s]" 42 - (String.concat "; " (Array.to_list (Array.map string_of_int n.values))) 43 - end in 44 - let yaml = read_file file in 45 - let json = read_file (file ^ ".json") in 46 - let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in 47 - let yaml_result = 48 - Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) 49 - in 50 - 51 - show_result_both "int_array" 52 - (Result.map M.show json_result) 53 - (Result.map M.show yaml_result) 54 - 55 - (* Test: String array *) 56 - let test_string_array file = 57 - let module M = struct 58 - type tags = { items : string array } 59 - 60 - let tags_codec = 61 - Jsont.Object.map ~kind:"Tags" (fun items -> { items }) 62 - |> Jsont.Object.mem "items" (Jsont.array Jsont.string) ~enc:(fun t -> 63 - t.items) 64 - |> Jsont.Object.finish 65 - 66 - let show t = 67 - Printf.sprintf "[%s]" 68 - (String.concat "; " 69 - (Array.to_list (Array.map (Printf.sprintf "%S") t.items))) 70 - end in 71 - let yaml = read_file file in 72 - let json = read_file (file ^ ".json") in 73 - let json_result = Jsont_bytesrw.decode_string M.tags_codec json in 74 - let yaml_result = Yamlt.decode M.tags_codec (Bytes.Reader.of_string yaml) in 75 - 76 - show_result_both "string_array" 77 - (Result.map M.show json_result) 78 - (Result.map M.show yaml_result) 79 - 80 - (* Test: Float/number array *) 81 - let test_float_array file = 82 - let module M = struct 83 - type measurements = { values : float array } 84 - 85 - let measurements_codec = 86 - Jsont.Object.map ~kind:"Measurements" (fun values -> { values }) 87 - |> Jsont.Object.mem "values" (Jsont.array Jsont.number) ~enc:(fun m -> 88 - m.values) 89 - |> Jsont.Object.finish 90 - 91 - let show m = 92 - Printf.sprintf "[%s]" 93 - (String.concat "; " 94 - (Array.to_list (Array.map (Printf.sprintf "%.2f") m.values))) 95 - end in 96 - let yaml = read_file file in 97 - let json = read_file (file ^ ".json") in 98 - let json_result = Jsont_bytesrw.decode_string M.measurements_codec json in 99 - let yaml_result = 100 - Yamlt.decode M.measurements_codec (Bytes.Reader.of_string yaml) 101 - in 102 - 103 - show_result_both "float_array" 104 - (Result.map M.show json_result) 105 - (Result.map M.show yaml_result) 106 - 107 - (* Test: Empty array *) 108 - let test_empty_array file = 109 - let module M = struct 110 - type empty = { items : int array } 111 - 112 - let empty_codec = 113 - Jsont.Object.map ~kind:"Empty" (fun items -> { items }) 114 - |> Jsont.Object.mem "items" (Jsont.array Jsont.int) ~enc:(fun e -> 115 - e.items) 116 - |> Jsont.Object.finish 117 - 118 - let show e = Printf.sprintf "length=%d" (Stdlib.Array.length e.items) 119 - end in 120 - let yaml = read_file file in 121 - let json = read_file (file ^ ".json") in 122 - let json_result = Jsont_bytesrw.decode_string M.empty_codec json in 123 - let yaml_result = Yamlt.decode M.empty_codec (Bytes.Reader.of_string yaml) in 124 - 125 - show_result_both "empty_array" 126 - (Result.map M.show json_result) 127 - (Result.map M.show yaml_result) 128 - 129 - (* Test: Array of objects *) 130 - let test_object_array file = 131 - let module M = struct 132 - type person = { name : string; age : int } 133 - type people = { persons : person array } 134 - 135 - let person_codec = 136 - Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 137 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 138 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 139 - |> Jsont.Object.finish 140 - 141 - let people_codec = 142 - Jsont.Object.map ~kind:"People" (fun persons -> { persons }) 143 - |> Jsont.Object.mem "persons" (Jsont.array person_codec) ~enc:(fun p -> 144 - p.persons) 145 - |> Jsont.Object.finish 146 - 147 - let show_person p = Printf.sprintf "{%s,%d}" p.name p.age 148 - 149 - let show ps = 150 - Printf.sprintf "[%s]" 151 - (String.concat "; " (Array.to_list (Array.map show_person ps.persons))) 152 - end in 153 - let yaml = read_file file in 154 - let json = read_file (file ^ ".json") in 155 - let json_result = Jsont_bytesrw.decode_string M.people_codec json in 156 - let yaml_result = Yamlt.decode M.people_codec (Bytes.Reader.of_string yaml) in 157 - 158 - show_result_both "object_array" 159 - (Result.map M.show json_result) 160 - (Result.map M.show yaml_result) 161 - 162 - (* Test: Nested arrays *) 163 - let test_nested_arrays file = 164 - let module M = struct 165 - type matrix = { data : int array array } 166 - 167 - let matrix_codec = 168 - Jsont.Object.map ~kind:"Matrix" (fun data -> { data }) 169 - |> Jsont.Object.mem "data" 170 - (Jsont.array (Jsont.array Jsont.int)) 171 - ~enc:(fun m -> m.data) 172 - |> Jsont.Object.finish 173 - 174 - let show_row row = 175 - Printf.sprintf "[%s]" 176 - (String.concat "; " (Array.to_list (Array.map string_of_int row))) 177 - 178 - let show m = 179 - Printf.sprintf "[%s]" 180 - (String.concat "; " (Array.to_list (Array.map show_row m.data))) 181 - end in 182 - let yaml = read_file file in 183 - let json = read_file (file ^ ".json") in 184 - let json_result = Jsont_bytesrw.decode_string M.matrix_codec json in 185 - let yaml_result = Yamlt.decode M.matrix_codec (Bytes.Reader.of_string yaml) in 186 - 187 - show_result_both "nested_arrays" 188 - (Result.map M.show json_result) 189 - (Result.map M.show yaml_result) 190 - 191 - (* Test: Mixed types in array (should fail with homogeneous codec) *) 192 - let test_type_mismatch file = 193 - let module M = struct 194 - type numbers = { values : int array } 195 - 196 - let numbers_codec = 197 - Jsont.Object.map ~kind:"Numbers" (fun values -> { values }) 198 - |> Jsont.Object.mem "values" (Jsont.array Jsont.int) ~enc:(fun n -> 199 - n.values) 200 - |> Jsont.Object.finish 201 - end in 202 - let yaml = read_file file in 203 - let result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in 204 - match result with 205 - | Ok _ -> Printf.printf "Unexpected success\n" 206 - | Error e -> Printf.printf "Expected error: %s\n" e 207 - 208 - (* Test: Bool array *) 209 - let test_bool_array file = 210 - let module M = struct 211 - type flags = { values : bool array } 212 - 213 - let flags_codec = 214 - Jsont.Object.map ~kind:"Flags" (fun values -> { values }) 215 - |> Jsont.Object.mem "values" (Jsont.array Jsont.bool) ~enc:(fun f -> 216 - f.values) 217 - |> Jsont.Object.finish 218 - 219 - let show f = 220 - Printf.sprintf "[%s]" 221 - (String.concat "; " (Array.to_list (Array.map string_of_bool f.values))) 222 - end in 223 - let yaml = read_file file in 224 - let json = read_file (file ^ ".json") in 225 - let json_result = Jsont_bytesrw.decode_string M.flags_codec json in 226 - let yaml_result = Yamlt.decode M.flags_codec (Bytes.Reader.of_string yaml) in 227 - 228 - show_result_both "bool_array" 229 - (Result.map M.show json_result) 230 - (Result.map M.show yaml_result) 231 - 232 - (* Test: Array with nulls *) 233 - let test_nullable_array file = 234 - let module M = struct 235 - type nullable = { values : string option array } 236 - 237 - let nullable_codec = 238 - Jsont.Object.map ~kind:"Nullable" (fun values -> { values }) 239 - |> Jsont.Object.mem "values" 240 - (Jsont.array (Jsont.some Jsont.string)) 241 - ~enc:(fun n -> n.values) 242 - |> Jsont.Object.finish 243 - 244 - let show_opt = function None -> "null" | Some s -> Printf.sprintf "%S" s 245 - 246 - let show n = 247 - Printf.sprintf "[%s]" 248 - (String.concat "; " (Array.to_list (Array.map show_opt n.values))) 249 - end in 250 - let yaml = read_file file in 251 - let json = read_file (file ^ ".json") in 252 - let json_result = Jsont_bytesrw.decode_string M.nullable_codec json in 253 - let yaml_result = 254 - Yamlt.decode M.nullable_codec (Bytes.Reader.of_string yaml) 255 - in 256 - 257 - show_result_both "nullable_array" 258 - (Result.map M.show json_result) 259 - (Result.map M.show yaml_result) 260 - 261 - (* Test: Encoding arrays to different formats *) 262 - let test_encode_arrays () = 263 - let module M = struct 264 - type data = { numbers : int array; strings : string array } 265 - 266 - let data_codec = 267 - Jsont.Object.map ~kind:"Data" (fun numbers strings -> 268 - { numbers; strings }) 269 - |> Jsont.Object.mem "numbers" (Jsont.array Jsont.int) ~enc:(fun d -> 270 - d.numbers) 271 - |> Jsont.Object.mem "strings" (Jsont.array Jsont.string) ~enc:(fun d -> 272 - d.strings) 273 - |> Jsont.Object.finish 274 - end in 275 - let data = 276 - { M.numbers = [| 1; 2; 3; 4; 5 |]; strings = [| "hello"; "world" |] } 277 - in 278 - 279 - (* Encode to JSON *) 280 - (match Jsont_bytesrw.encode_string M.data_codec data with 281 - | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 282 - | Error e -> Printf.printf "JSON ERROR: %s\n" e); 283 - 284 - (* Encode to YAML Block *) 285 - (let b = Buffer.create 256 in 286 - let writer = Bytes.Writer.of_buffer b in 287 - match 288 - Yamlt.encode ~format:Yamlt.Block M.data_codec data ~eod:true writer 289 - with 290 - | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 291 - | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 292 - 293 - (* Encode to YAML Flow *) 294 - let b = Buffer.create 256 in 295 - let writer = Bytes.Writer.of_buffer b in 296 - match Yamlt.encode ~format:Yamlt.Flow M.data_codec data ~eod:true writer with 297 - | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 298 - | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e 299 - 300 - let () = 301 - let usage = "Usage: test_arrays <command> [args...]" in 302 - 303 - if Array.length Sys.argv < 2 then begin 304 - prerr_endline usage; 305 - exit 1 306 - end; 307 - 308 - match Sys.argv.(1) with 309 - | "int" when Array.length Sys.argv = 3 -> test_int_array Sys.argv.(2) 310 - | "string" when Array.length Sys.argv = 3 -> test_string_array Sys.argv.(2) 311 - | "float" when Array.length Sys.argv = 3 -> test_float_array Sys.argv.(2) 312 - | "empty" when Array.length Sys.argv = 3 -> test_empty_array Sys.argv.(2) 313 - | "objects" when Array.length Sys.argv = 3 -> test_object_array Sys.argv.(2) 314 - | "nested" when Array.length Sys.argv = 3 -> test_nested_arrays Sys.argv.(2) 315 - | "type-mismatch" when Array.length Sys.argv = 3 -> 316 - test_type_mismatch Sys.argv.(2) 317 - | "bool" when Array.length Sys.argv = 3 -> test_bool_array Sys.argv.(2) 318 - | "nullable" when Array.length Sys.argv = 3 -> 319 - test_nullable_array Sys.argv.(2) 320 - | "encode" when Array.length Sys.argv = 2 -> test_encode_arrays () 321 - | _ -> 322 - prerr_endline usage; 323 - prerr_endline "Commands:"; 324 - prerr_endline " int <file> - Test int array"; 325 - prerr_endline " string <file> - Test string array"; 326 - prerr_endline " float <file> - Test float array"; 327 - prerr_endline " empty <file> - Test empty array"; 328 - prerr_endline " objects <file> - Test array of objects"; 329 - prerr_endline " nested <file> - Test nested arrays"; 330 - prerr_endline " type-mismatch <file> - Test type mismatch error"; 331 - prerr_endline " bool <file> - Test bool array"; 332 - prerr_endline " nullable <file> - Test array with nulls"; 333 - prerr_endline " encode - Test encoding arrays"; 334 - exit 1
-208
tests/bin/test_complex.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test complex nested types with Yamlt *) 7 - 8 - open Bytesrw 9 - 10 - (* Helper to read file *) 11 - let read_file path = 12 - let ic = open_in path in 13 - let len = in_channel_length ic in 14 - let s = really_input_string ic len in 15 - close_in ic; 16 - s 17 - 18 - (* Helper to show results *) 19 - let show_result label = function 20 - | Ok v -> Printf.printf "%s: %s\n" label v 21 - | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 - 23 - let show_result_both label json_result yaml_result = 24 - Printf.printf "JSON: "; 25 - show_result label json_result; 26 - Printf.printf "YAML: "; 27 - show_result label yaml_result 28 - 29 - (* Test: Deeply nested objects *) 30 - let test_deep_nesting file = 31 - let module M = struct 32 - type level3 = { value : int } 33 - type level2 = { data : level3 } 34 - type level1 = { nested : level2 } 35 - type root = { top : level1 } 36 - 37 - let level3_codec = 38 - Jsont.Object.map ~kind:"Level3" (fun value -> { value }) 39 - |> Jsont.Object.mem "value" Jsont.int ~enc:(fun l -> l.value) 40 - |> Jsont.Object.finish 41 - 42 - let level2_codec = 43 - Jsont.Object.map ~kind:"Level2" (fun data -> { data }) 44 - |> Jsont.Object.mem "data" level3_codec ~enc:(fun l -> l.data) 45 - |> Jsont.Object.finish 46 - 47 - let level1_codec = 48 - Jsont.Object.map ~kind:"Level1" (fun nested -> { nested }) 49 - |> Jsont.Object.mem "nested" level2_codec ~enc:(fun l -> l.nested) 50 - |> Jsont.Object.finish 51 - 52 - let root_codec = 53 - Jsont.Object.map ~kind:"Root" (fun top -> { top }) 54 - |> Jsont.Object.mem "top" level1_codec ~enc:(fun r -> r.top) 55 - |> Jsont.Object.finish 56 - 57 - let show r = Printf.sprintf "depth=4, value=%d" r.top.nested.data.value 58 - end in 59 - let yaml = read_file file in 60 - let json = read_file (file ^ ".json") in 61 - let json_result = Jsont_bytesrw.decode_string M.root_codec json in 62 - let yaml_result = Yamlt.decode M.root_codec (Bytes.Reader.of_string yaml) in 63 - 64 - show_result_both "deep_nesting" 65 - (Result.map M.show json_result) 66 - (Result.map M.show yaml_result) 67 - 68 - (* Test: Array of objects with nested arrays *) 69 - let test_mixed_structure file = 70 - let module M = struct 71 - type item = { id : int; tags : string array } 72 - type collection = { name : string; items : item array } 73 - 74 - let item_codec = 75 - Jsont.Object.map ~kind:"Item" (fun id tags -> { id; tags }) 76 - |> Jsont.Object.mem "id" Jsont.int ~enc:(fun i -> i.id) 77 - |> Jsont.Object.mem "tags" (Jsont.array Jsont.string) ~enc:(fun i -> 78 - i.tags) 79 - |> Jsont.Object.finish 80 - 81 - let collection_codec = 82 - Jsont.Object.map ~kind:"Collection" (fun name items -> { name; items }) 83 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun c -> c.name) 84 - |> Jsont.Object.mem "items" (Jsont.array item_codec) ~enc:(fun c -> 85 - c.items) 86 - |> Jsont.Object.finish 87 - 88 - let show c = 89 - let total_tags = 90 - Stdlib.Array.fold_left 91 - (fun acc item -> acc + Stdlib.Array.length item.tags) 92 - 0 c.items 93 - in 94 - Printf.sprintf "name=%S, items=%d, total_tags=%d" c.name 95 - (Stdlib.Array.length c.items) 96 - total_tags 97 - end in 98 - let yaml = read_file file in 99 - let json = read_file (file ^ ".json") in 100 - let json_result = Jsont_bytesrw.decode_string M.collection_codec json in 101 - let yaml_result = 102 - Yamlt.decode M.collection_codec (Bytes.Reader.of_string yaml) 103 - in 104 - 105 - show_result_both "mixed_structure" 106 - (Result.map M.show json_result) 107 - (Result.map M.show yaml_result) 108 - 109 - (* Test: Complex optional and nullable combinations *) 110 - let test_complex_optional file = 111 - let module M = struct 112 - type config = { 113 - host : string; 114 - port : int option; 115 - ssl : bool option; 116 - cert_path : string option; 117 - fallback_hosts : string array option; 118 - } 119 - 120 - let config_codec = 121 - Jsont.Object.map ~kind:"Config" 122 - (fun host port ssl cert_path fallback_hosts -> 123 - { host; port; ssl; cert_path; fallback_hosts }) 124 - |> Jsont.Object.mem "host" Jsont.string ~enc:(fun c -> c.host) 125 - |> Jsont.Object.opt_mem "port" Jsont.int ~enc:(fun c -> c.port) 126 - |> Jsont.Object.opt_mem "ssl" Jsont.bool ~enc:(fun c -> c.ssl) 127 - |> Jsont.Object.opt_mem "cert_path" Jsont.string ~enc:(fun c -> 128 - c.cert_path) 129 - |> Jsont.Object.opt_mem "fallback_hosts" (Jsont.array Jsont.string) 130 - ~enc:(fun c -> c.fallback_hosts) 131 - |> Jsont.Object.finish 132 - 133 - let show c = 134 - let port_str = 135 - match c.port with None -> "None" | Some p -> string_of_int p 136 - in 137 - let ssl_str = 138 - match c.ssl with None -> "None" | Some b -> string_of_bool b 139 - in 140 - let fallbacks = 141 - match c.fallback_hosts with 142 - | None -> 0 143 - | Some arr -> Stdlib.Array.length arr 144 - in 145 - Printf.sprintf "host=%S, port=%s, ssl=%s, fallbacks=%d" c.host port_str 146 - ssl_str fallbacks 147 - end in 148 - let yaml = read_file file in 149 - let json = read_file (file ^ ".json") in 150 - let json_result = Jsont_bytesrw.decode_string M.config_codec json in 151 - let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in 152 - 153 - show_result_both "complex_optional" 154 - (Result.map M.show json_result) 155 - (Result.map M.show yaml_result) 156 - 157 - (* Test: Heterogeneous data via any type *) 158 - let test_heterogeneous file = 159 - let module M = struct 160 - type data = { mixed : Jsont.json array } 161 - 162 - let data_codec = 163 - Jsont.Object.map ~kind:"Data" (fun mixed -> { mixed }) 164 - |> Jsont.Object.mem "mixed" 165 - (Jsont.array (Jsont.any ())) 166 - ~enc:(fun d -> d.mixed) 167 - |> Jsont.Object.finish 168 - 169 - let show d = Printf.sprintf "items=%d" (Stdlib.Array.length d.mixed) 170 - end in 171 - let yaml = read_file file in 172 - let json = read_file (file ^ ".json") in 173 - let json_result = Jsont_bytesrw.decode_string M.data_codec json in 174 - let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in 175 - 176 - show_result_both "heterogeneous" 177 - (Result.map M.show json_result) 178 - (Result.map M.show yaml_result) 179 - 180 - let () = 181 - let usage = "Usage: test_complex <command> [args...]" in 182 - 183 - if Stdlib.Array.length Sys.argv < 2 then begin 184 - prerr_endline usage; 185 - exit 1 186 - end; 187 - 188 - match Sys.argv.(1) with 189 - | "deep-nesting" when Stdlib.Array.length Sys.argv = 3 -> 190 - test_deep_nesting Sys.argv.(2) 191 - | "mixed-structure" when Stdlib.Array.length Sys.argv = 3 -> 192 - test_mixed_structure Sys.argv.(2) 193 - | "complex-optional" when Stdlib.Array.length Sys.argv = 3 -> 194 - test_complex_optional Sys.argv.(2) 195 - | "heterogeneous" when Stdlib.Array.length Sys.argv = 3 -> 196 - test_heterogeneous Sys.argv.(2) 197 - | _ -> 198 - prerr_endline usage; 199 - prerr_endline "Commands:"; 200 - prerr_endline " deep-nesting <file> - Test deeply nested objects"; 201 - prerr_endline 202 - " mixed-structure <file> - Test arrays of objects with nested arrays"; 203 - prerr_endline 204 - " complex-optional <file> - Test complex optional/nullable \ 205 - combinations"; 206 - prerr_endline 207 - " heterogeneous <file> - Test heterogeneous data via any type"; 208 - exit 1
-103
tests/bin/test_comprehensive.ml
··· 1 - open Bytesrw 2 - 3 - let () = 4 - (* Test 1: Null handling with option types *) 5 - Printf.printf "=== NULL HANDLING ===\n"; 6 - let opt_codec = 7 - Jsont.Object.map ~kind:"Test" (fun v -> v) 8 - |> Jsont.Object.mem "value" (Jsont.option Jsont.string) ~enc:(fun v -> v) 9 - |> Jsont.Object.finish 10 - in 11 - 12 - (match Yamlt.decode opt_codec (Bytes.Reader.of_string "value: null") with 13 - | Ok None -> Printf.printf "✓ Plain 'null' with option codec: None\n" 14 - | _ -> Printf.printf "✗ FAIL\n"); 15 - 16 - (match Yamlt.decode opt_codec (Bytes.Reader.of_string "value: hello") with 17 - | Ok (Some "hello") -> 18 - Printf.printf "✓ Plain 'hello' with option codec: Some(hello)\n" 19 - | _ -> Printf.printf "✗ FAIL\n"); 20 - 21 - let string_codec = 22 - Jsont.Object.map ~kind:"Test" (fun v -> v) 23 - |> Jsont.Object.mem "value" Jsont.string ~enc:(fun v -> v) 24 - |> Jsont.Object.finish 25 - in 26 - 27 - (match Yamlt.decode string_codec (Bytes.Reader.of_string "value: null") with 28 - | Error _ -> 29 - Printf.printf "✓ Plain 'null' with string codec: ERROR (expected)\n" 30 - | _ -> Printf.printf "✗ FAIL\n"); 31 - 32 - (match Yamlt.decode string_codec (Bytes.Reader.of_string "value: \"\"") with 33 - | Ok "" -> Printf.printf "✓ Quoted empty string: \"\"\n" 34 - | _ -> Printf.printf "✗ FAIL\n"); 35 - 36 - (match 37 - Yamlt.decode string_codec (Bytes.Reader.of_string "value: \"null\"") 38 - with 39 - | Ok "null" -> Printf.printf "✓ Quoted 'null': \"null\"\n" 40 - | _ -> Printf.printf "✗ FAIL\n"); 41 - 42 - (* Test 2: Number formats *) 43 - Printf.printf "\n=== NUMBER FORMATS ===\n"; 44 - let num_codec = 45 - Jsont.Object.map ~kind:"Test" (fun v -> v) 46 - |> Jsont.Object.mem "value" Jsont.number ~enc:(fun v -> v) 47 - |> Jsont.Object.finish 48 - in 49 - 50 - (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0xFF") with 51 - | Ok 255. -> Printf.printf "✓ Hex 0xFF: 255\n" 52 - | _ -> Printf.printf "✗ FAIL\n"); 53 - 54 - (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0o77") with 55 - | Ok 63. -> Printf.printf "✓ Octal 0o77: 63\n" 56 - | _ -> Printf.printf "✗ FAIL\n"); 57 - 58 - (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0b1010") with 59 - | Ok 10. -> Printf.printf "✓ Binary 0b1010: 10\n" 60 - | _ -> Printf.printf "✗ FAIL\n"); 61 - 62 - (* Test 3: Optional arrays *) 63 - Printf.printf "\n=== OPTIONAL ARRAYS ===\n"; 64 - let opt_array_codec = 65 - Jsont.Object.map ~kind:"Test" (fun v -> v) 66 - |> Jsont.Object.opt_mem "values" (Jsont.array Jsont.string) ~enc:(fun v -> 67 - v) 68 - |> Jsont.Object.finish 69 - in 70 - 71 - (match 72 - Yamlt.decode opt_array_codec (Bytes.Reader.of_string "values: [a, b, c]") 73 - with 74 - | Ok (Some arr) when Array.length arr = 3 -> 75 - Printf.printf "✓ Optional array [a, b, c]: Some([3 items])\n" 76 - | _ -> Printf.printf "✗ FAIL\n"); 77 - 78 - (match Yamlt.decode opt_array_codec (Bytes.Reader.of_string "{}") with 79 - | Ok None -> Printf.printf "✓ Missing optional array: None\n" 80 - | _ -> Printf.printf "✗ FAIL\n"); 81 - 82 - (* Test 4: Flow encoding *) 83 - Printf.printf "\n=== FLOW ENCODING ===\n"; 84 - let encode_codec = 85 - Jsont.Object.map ~kind:"Test" (fun name values -> (name, values)) 86 - |> Jsont.Object.mem "name" Jsont.string ~enc:fst 87 - |> Jsont.Object.mem "values" (Jsont.array Jsont.number) ~enc:snd 88 - |> Jsont.Object.finish 89 - in 90 - 91 - let b = Buffer.create 256 in 92 - let writer = Bytes.Writer.of_buffer b in 93 - match 94 - Yamlt.encode ~format:Flow encode_codec 95 - ("test", [| 1.; 2.; 3. |]) 96 - ~eod:true writer 97 - with 98 - | Ok () 99 - when String.equal (Buffer.contents b) 100 - "{name: test, values: [1.0, 2.0, 3.0]}\n" -> 101 - Printf.printf "✓ Flow encoding with comma separator\n" 102 - | Ok () -> Printf.printf "✗ FAIL: %S\n" (Buffer.contents b) 103 - | Error e -> Printf.printf "✗ ERROR: %s\n" e
-216
tests/bin/test_edge.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test edge cases with Yamlt *) 7 - 8 - open Bytesrw 9 - 10 - (* Helper to read file *) 11 - let read_file path = 12 - let ic = open_in path in 13 - let len = in_channel_length ic in 14 - let s = really_input_string ic len in 15 - close_in ic; 16 - s 17 - 18 - (* Helper to show results *) 19 - let show_result label = function 20 - | Ok v -> Printf.printf "%s: %s\n" label v 21 - | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 - 23 - let show_result_both label json_result yaml_result = 24 - Printf.printf "JSON: "; 25 - show_result label json_result; 26 - Printf.printf "YAML: "; 27 - show_result label yaml_result 28 - 29 - (* Test: Very large numbers *) 30 - let test_large_numbers file = 31 - let module M = struct 32 - type numbers = { 33 - large_int : float; 34 - large_float : float; 35 - small_float : float; 36 - } 37 - 38 - let numbers_codec = 39 - Jsont.Object.map ~kind:"Numbers" (fun large_int large_float small_float -> 40 - { large_int; large_float; small_float }) 41 - |> Jsont.Object.mem "large_int" Jsont.number ~enc:(fun n -> n.large_int) 42 - |> Jsont.Object.mem "large_float" Jsont.number ~enc:(fun n -> 43 - n.large_float) 44 - |> Jsont.Object.mem "small_float" Jsont.number ~enc:(fun n -> 45 - n.small_float) 46 - |> Jsont.Object.finish 47 - 48 - let show n = 49 - Printf.sprintf "large_int=%.0f, large_float=%e, small_float=%e" 50 - n.large_int n.large_float n.small_float 51 - end in 52 - let yaml = read_file file in 53 - let json = read_file (file ^ ".json") in 54 - let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in 55 - let yaml_result = 56 - Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) 57 - in 58 - 59 - show_result_both "large_numbers" 60 - (Result.map M.show json_result) 61 - (Result.map M.show yaml_result) 62 - 63 - (* Test: Special characters in strings *) 64 - let test_special_chars file = 65 - let module M = struct 66 - type text = { content : string } 67 - 68 - let text_codec = 69 - Jsont.Object.map ~kind:"Text" (fun content -> { content }) 70 - |> Jsont.Object.mem "content" Jsont.string ~enc:(fun t -> t.content) 71 - |> Jsont.Object.finish 72 - 73 - let show t = 74 - Printf.sprintf "length=%d, contains_newline=%b, contains_tab=%b" 75 - (String.length t.content) 76 - (String.contains t.content '\n') 77 - (String.contains t.content '\t') 78 - end in 79 - let yaml = read_file file in 80 - let json = read_file (file ^ ".json") in 81 - let json_result = Jsont_bytesrw.decode_string M.text_codec json in 82 - let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in 83 - 84 - show_result_both "special_chars" 85 - (Result.map M.show json_result) 86 - (Result.map M.show yaml_result) 87 - 88 - (* Test: Unicode strings *) 89 - let test_unicode file = 90 - let module M = struct 91 - type text = { emoji : string; chinese : string; rtl : string } 92 - 93 - let text_codec = 94 - Jsont.Object.map ~kind:"Text" (fun emoji chinese rtl -> 95 - { emoji; chinese; rtl }) 96 - |> Jsont.Object.mem "emoji" Jsont.string ~enc:(fun t -> t.emoji) 97 - |> Jsont.Object.mem "chinese" Jsont.string ~enc:(fun t -> t.chinese) 98 - |> Jsont.Object.mem "rtl" Jsont.string ~enc:(fun t -> t.rtl) 99 - |> Jsont.Object.finish 100 - 101 - let show t = 102 - Printf.sprintf "emoji=%S, chinese=%S, rtl=%S" t.emoji t.chinese t.rtl 103 - end in 104 - let yaml = read_file file in 105 - let json = read_file (file ^ ".json") in 106 - let json_result = Jsont_bytesrw.decode_string M.text_codec json in 107 - let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in 108 - 109 - show_result_both "unicode" 110 - (Result.map M.show json_result) 111 - (Result.map M.show yaml_result) 112 - 113 - (* Test: Empty collections *) 114 - let test_empty_collections file = 115 - let module M = struct 116 - type data = { empty_array : int array; empty_object_array : unit array } 117 - 118 - let data_codec = 119 - Jsont.Object.map ~kind:"Data" (fun empty_array empty_object_array -> 120 - { empty_array; empty_object_array }) 121 - |> Jsont.Object.mem "empty_array" (Jsont.array Jsont.int) ~enc:(fun d -> 122 - d.empty_array) 123 - |> Jsont.Object.mem "empty_object_array" 124 - (Jsont.array (Jsont.null ())) 125 - ~enc:(fun d -> d.empty_object_array) 126 - |> Jsont.Object.finish 127 - 128 - let show d = 129 - Printf.sprintf "empty_array_len=%d, empty_object_array_len=%d" 130 - (Stdlib.Array.length d.empty_array) 131 - (Stdlib.Array.length d.empty_object_array) 132 - end in 133 - let yaml = read_file file in 134 - let json = read_file (file ^ ".json") in 135 - let json_result = Jsont_bytesrw.decode_string M.data_codec json in 136 - let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in 137 - 138 - show_result_both "empty_collections" 139 - (Result.map M.show json_result) 140 - (Result.map M.show yaml_result) 141 - 142 - (* Test: Key names with special characters *) 143 - let test_special_keys file = 144 - let module M = struct 145 - let show j = 146 - match Jsont.Json.decode (Jsont.any ()) j with 147 - | Ok (Jsont.Object _) -> "valid_object" 148 - | Ok _ -> "not_object" 149 - | Error _ -> "decode_error" 150 - end in 151 - let yaml = read_file file in 152 - let json = read_file (file ^ ".json") in 153 - let json_result = Jsont_bytesrw.decode_string (Jsont.any ()) json in 154 - let yaml_result = Yamlt.decode (Jsont.any ()) (Bytes.Reader.of_string yaml) in 155 - 156 - show_result_both "special_keys" 157 - (Result.map M.show json_result) 158 - (Result.map M.show yaml_result) 159 - 160 - (* Test: Single-element arrays *) 161 - let test_single_element file = 162 - let module M = struct 163 - type data = { single : int array } 164 - 165 - let data_codec = 166 - Jsont.Object.map ~kind:"Data" (fun single -> { single }) 167 - |> Jsont.Object.mem "single" (Jsont.array Jsont.int) ~enc:(fun d -> 168 - d.single) 169 - |> Jsont.Object.finish 170 - 171 - let show d = 172 - Printf.sprintf "length=%d, value=%d" 173 - (Stdlib.Array.length d.single) 174 - (if Stdlib.Array.length d.single > 0 then d.single.(0) else 0) 175 - end in 176 - let yaml = read_file file in 177 - let json = read_file (file ^ ".json") in 178 - let json_result = Jsont_bytesrw.decode_string M.data_codec json in 179 - let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in 180 - 181 - show_result_both "single_element" 182 - (Result.map M.show json_result) 183 - (Result.map M.show yaml_result) 184 - 185 - let () = 186 - let usage = "Usage: test_edge <command> [args...]" in 187 - 188 - if Stdlib.Array.length Sys.argv < 2 then begin 189 - prerr_endline usage; 190 - exit 1 191 - end; 192 - 193 - match Sys.argv.(1) with 194 - | "large-numbers" when Stdlib.Array.length Sys.argv = 3 -> 195 - test_large_numbers Sys.argv.(2) 196 - | "special-chars" when Stdlib.Array.length Sys.argv = 3 -> 197 - test_special_chars Sys.argv.(2) 198 - | "unicode" when Stdlib.Array.length Sys.argv = 3 -> test_unicode Sys.argv.(2) 199 - | "empty-collections" when Stdlib.Array.length Sys.argv = 3 -> 200 - test_empty_collections Sys.argv.(2) 201 - | "special-keys" when Stdlib.Array.length Sys.argv = 3 -> 202 - test_special_keys Sys.argv.(2) 203 - | "single-element" when Stdlib.Array.length Sys.argv = 3 -> 204 - test_single_element Sys.argv.(2) 205 - | _ -> 206 - prerr_endline usage; 207 - prerr_endline "Commands:"; 208 - prerr_endline " large-numbers <file> - Test very large numbers"; 209 - prerr_endline 210 - " special-chars <file> - Test special characters in strings"; 211 - prerr_endline " unicode <file> - Test Unicode strings"; 212 - prerr_endline " empty-collections <file> - Test empty collections"; 213 - prerr_endline 214 - " special-keys <file> - Test special characters in keys"; 215 - prerr_endline " single-element <file> - Test single-element arrays"; 216 - exit 1
-23
tests/bin/test_flow_newline.ml
··· 1 - open Bytesrw 2 - 3 - let () = 4 - let encode_codec = 5 - Jsont.Object.map ~kind:"Test" (fun name values -> (name, values)) 6 - |> Jsont.Object.mem "name" Jsont.string ~enc:fst 7 - |> Jsont.Object.mem "values" (Jsont.array Jsont.number) ~enc:snd 8 - |> Jsont.Object.finish 9 - in 10 - 11 - let b = Buffer.create 256 in 12 - let writer = Bytes.Writer.of_buffer b in 13 - match 14 - Yamlt.encode ~format:Flow encode_codec 15 - ("test", [| 1.; 2.; 3. |]) 16 - ~eod:true writer 17 - with 18 - | Ok () -> 19 - let yaml_flow = Buffer.contents b in 20 - Printf.printf "Length: %d\n" (String.length yaml_flow); 21 - Printf.printf "Repr: %S\n" yaml_flow; 22 - Printf.printf "Output:\n%s" yaml_flow 23 - | Error e -> Printf.printf "Error: %s\n" e
-254
tests/bin/test_formats.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test format-specific features with Yamlt *) 7 - 8 - open Bytesrw 9 - 10 - (* Helper to read file *) 11 - let read_file path = 12 - let ic = open_in path in 13 - let len = in_channel_length ic in 14 - let s = really_input_string ic len in 15 - close_in ic; 16 - s 17 - 18 - (* Helper to show results *) 19 - let show_result label = function 20 - | Ok v -> Printf.printf "%s: %s\n" label v 21 - | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 - 23 - let show_result_both label json_result yaml_result = 24 - Printf.printf "JSON: "; 25 - show_result label json_result; 26 - Printf.printf "YAML: "; 27 - show_result label yaml_result 28 - 29 - (* Test: Multi-line strings - literal style *) 30 - let test_literal_string file = 31 - let module M = struct 32 - type text = { content : string } 33 - 34 - let text_codec = 35 - Jsont.Object.map ~kind:"Text" (fun content -> { content }) 36 - |> Jsont.Object.mem "content" Jsont.string ~enc:(fun t -> t.content) 37 - |> Jsont.Object.finish 38 - 39 - let show t = 40 - Printf.sprintf "lines=%d, length=%d" 41 - (List.length (String.split_on_char '\n' t.content)) 42 - (String.length t.content) 43 - end in 44 - let yaml = read_file file in 45 - let json = read_file (file ^ ".json") in 46 - let json_result = Jsont_bytesrw.decode_string M.text_codec json in 47 - let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in 48 - 49 - show_result_both "literal_string" 50 - (Result.map M.show json_result) 51 - (Result.map M.show yaml_result) 52 - 53 - (* Test: Multi-line strings - folded style *) 54 - let test_folded_string file = 55 - let module M = struct 56 - type text = { content : string } 57 - 58 - let text_codec = 59 - Jsont.Object.map ~kind:"Text" (fun content -> { content }) 60 - |> Jsont.Object.mem "content" Jsont.string ~enc:(fun t -> t.content) 61 - |> Jsont.Object.finish 62 - 63 - let show t = 64 - Printf.sprintf "length=%d, newlines=%d" (String.length t.content) 65 - (List.length 66 - (List.filter 67 - (fun c -> c = '\n') 68 - (List.init (String.length t.content) (String.get t.content)))) 69 - end in 70 - let yaml = read_file file in 71 - let json = read_file (file ^ ".json") in 72 - let json_result = Jsont_bytesrw.decode_string M.text_codec json in 73 - let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in 74 - 75 - show_result_both "folded_string" 76 - (Result.map M.show json_result) 77 - (Result.map M.show yaml_result) 78 - 79 - (* Test: Number formats - hex, octal, binary *) 80 - let test_number_formats file = 81 - let module M = struct 82 - type numbers = { hex : float; octal : float; binary : float } 83 - 84 - let numbers_codec = 85 - Jsont.Object.map ~kind:"Numbers" (fun hex octal binary -> 86 - { hex; octal; binary }) 87 - |> Jsont.Object.mem "hex" Jsont.number ~enc:(fun n -> n.hex) 88 - |> Jsont.Object.mem "octal" Jsont.number ~enc:(fun n -> n.octal) 89 - |> Jsont.Object.mem "binary" Jsont.number ~enc:(fun n -> n.binary) 90 - |> Jsont.Object.finish 91 - 92 - let show n = 93 - Printf.sprintf "hex=%.0f, octal=%.0f, binary=%.0f" n.hex n.octal n.binary 94 - end in 95 - let yaml = read_file file in 96 - let json = read_file (file ^ ".json") in 97 - let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in 98 - let yaml_result = 99 - Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) 100 - in 101 - 102 - show_result_both "number_formats" 103 - (Result.map M.show json_result) 104 - (Result.map M.show yaml_result) 105 - 106 - (* Test: Block vs Flow style encoding *) 107 - let test_encode_styles () = 108 - let module M = struct 109 - type data = { name : string; values : int array; nested : nested_data } 110 - and nested_data = { enabled : bool; count : int } 111 - 112 - let nested_codec = 113 - Jsont.Object.map ~kind:"Nested" (fun enabled count -> { enabled; count }) 114 - |> Jsont.Object.mem "enabled" Jsont.bool ~enc:(fun n -> n.enabled) 115 - |> Jsont.Object.mem "count" Jsont.int ~enc:(fun n -> n.count) 116 - |> Jsont.Object.finish 117 - 118 - let data_codec = 119 - Jsont.Object.map ~kind:"Data" (fun name values nested -> 120 - { name; values; nested }) 121 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun d -> d.name) 122 - |> Jsont.Object.mem "values" (Jsont.array Jsont.int) ~enc:(fun d -> 123 - d.values) 124 - |> Jsont.Object.mem "nested" nested_codec ~enc:(fun d -> d.nested) 125 - |> Jsont.Object.finish 126 - end in 127 - let data = 128 - { 129 - M.name = "test"; 130 - values = [| 1; 2; 3 |]; 131 - nested = { enabled = true; count = 5 }; 132 - } 133 - in 134 - 135 - (* Encode to YAML Block style *) 136 - (let b = Buffer.create 256 in 137 - let writer = Bytes.Writer.of_buffer b in 138 - match 139 - Yamlt.encode ~format:Yamlt.Block M.data_codec data ~eod:true writer 140 - with 141 - | Ok () -> Printf.printf "YAML Block:\n%s\n" (Buffer.contents b) 142 - | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 143 - 144 - (* Encode to YAML Flow style *) 145 - let b = Buffer.create 256 in 146 - let writer = Bytes.Writer.of_buffer b in 147 - match Yamlt.encode ~format:Yamlt.Flow M.data_codec data ~eod:true writer with 148 - | Ok () -> Printf.printf "YAML Flow:\n%s\n" (Buffer.contents b) 149 - | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e 150 - 151 - (* Test: Comments in YAML (should be ignored) *) 152 - let test_comments file = 153 - let module M = struct 154 - type config = { host : string; port : int; debug : bool } 155 - 156 - let config_codec = 157 - Jsont.Object.map ~kind:"Config" (fun host port debug -> 158 - { host; port; debug }) 159 - |> Jsont.Object.mem "host" Jsont.string ~enc:(fun c -> c.host) 160 - |> Jsont.Object.mem "port" Jsont.int ~enc:(fun c -> c.port) 161 - |> Jsont.Object.mem "debug" Jsont.bool ~enc:(fun c -> c.debug) 162 - |> Jsont.Object.finish 163 - 164 - let show c = 165 - Printf.sprintf "host=%S, port=%d, debug=%b" c.host c.port c.debug 166 - end in 167 - let yaml = read_file file in 168 - let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in 169 - 170 - match yaml_result with 171 - | Ok v -> Printf.printf "YAML (with comments): %s\n" (M.show v) 172 - | Error e -> Printf.printf "YAML ERROR: %s\n" e 173 - 174 - (* Test: Empty documents and null documents *) 175 - let test_empty_document file = 176 - let module M = struct 177 - type wrapper = { value : string option } 178 - 179 - let wrapper_codec = 180 - Jsont.Object.map ~kind:"Wrapper" (fun value -> { value }) 181 - |> Jsont.Object.mem "value" (Jsont.some Jsont.string) ~enc:(fun w -> 182 - w.value) 183 - |> Jsont.Object.finish 184 - 185 - let show w = 186 - match w.value with 187 - | None -> "value=None" 188 - | Some s -> Printf.sprintf "value=Some(%S)" s 189 - end in 190 - let yaml = read_file file in 191 - let json = read_file (file ^ ".json") in 192 - let json_result = Jsont_bytesrw.decode_string M.wrapper_codec json in 193 - let yaml_result = 194 - Yamlt.decode M.wrapper_codec (Bytes.Reader.of_string yaml) 195 - in 196 - 197 - show_result_both "empty_document" 198 - (Result.map M.show json_result) 199 - (Result.map M.show yaml_result) 200 - 201 - (* Test: Explicit typing with tags (if supported) *) 202 - let test_explicit_tags file = 203 - let module M = struct 204 - type value_holder = { data : string } 205 - 206 - let value_codec = 207 - Jsont.Object.map ~kind:"ValueHolder" (fun data -> { data }) 208 - |> Jsont.Object.mem "data" Jsont.string ~enc:(fun v -> v.data) 209 - |> Jsont.Object.finish 210 - 211 - let show v = Printf.sprintf "data=%S" v.data 212 - end in 213 - let yaml = read_file file in 214 - let yaml_result = Yamlt.decode M.value_codec (Bytes.Reader.of_string yaml) in 215 - 216 - match yaml_result with 217 - | Ok v -> Printf.printf "YAML (with tags): %s\n" (M.show v) 218 - | Error e -> Printf.printf "YAML ERROR: %s\n" e 219 - 220 - let () = 221 - let usage = "Usage: test_formats <command> [args...]" in 222 - 223 - if Stdlib.Array.length Sys.argv < 2 then begin 224 - prerr_endline usage; 225 - exit 1 226 - end; 227 - 228 - match Sys.argv.(1) with 229 - | "literal" when Stdlib.Array.length Sys.argv = 3 -> 230 - test_literal_string Sys.argv.(2) 231 - | "folded" when Stdlib.Array.length Sys.argv = 3 -> 232 - test_folded_string Sys.argv.(2) 233 - | "number-formats" when Stdlib.Array.length Sys.argv = 3 -> 234 - test_number_formats Sys.argv.(2) 235 - | "encode-styles" when Stdlib.Array.length Sys.argv = 2 -> 236 - test_encode_styles () 237 - | "comments" when Stdlib.Array.length Sys.argv = 3 -> 238 - test_comments Sys.argv.(2) 239 - | "empty-doc" when Stdlib.Array.length Sys.argv = 3 -> 240 - test_empty_document Sys.argv.(2) 241 - | "explicit-tags" when Stdlib.Array.length Sys.argv = 3 -> 242 - test_explicit_tags Sys.argv.(2) 243 - | _ -> 244 - prerr_endline usage; 245 - prerr_endline "Commands:"; 246 - prerr_endline " literal <file> - Test literal multi-line strings"; 247 - prerr_endline " folded <file> - Test folded multi-line strings"; 248 - prerr_endline 249 - " number-formats <file> - Test hex/octal/binary number formats"; 250 - prerr_endline " encode-styles - Test block vs flow encoding"; 251 - prerr_endline " comments <file> - Test YAML with comments"; 252 - prerr_endline " empty-doc <file> - Test empty documents"; 253 - prerr_endline " explicit-tags <file> - Test explicit type tags"; 254 - exit 1
-296
tests/bin/test_locations.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test location and layout preservation options with Yamlt codec *) 7 - 8 - (* Helper to read file *) 9 - open Bytesrw 10 - 11 - let read_file path = 12 - let ic = open_in path in 13 - let len = in_channel_length ic in 14 - let s = really_input_string ic len in 15 - close_in ic; 16 - s 17 - 18 - (* Helper to show results *) 19 - let show_result label = function 20 - | Ok _ -> Printf.printf "%s: OK\n" label 21 - | Error e -> Printf.printf "%s:\n%s\n" label e 22 - 23 - (* Test: Compare error messages with and without locs *) 24 - let test_error_precision file = 25 - let yaml = read_file file in 26 - 27 - (* Define a codec that will fail on type mismatch *) 28 - let codec = 29 - Jsont.Object.map ~kind:"Person" (fun name age -> (name, age)) 30 - |> Jsont.Object.mem "name" Jsont.string ~enc:fst 31 - |> Jsont.Object.mem "age" Jsont.int ~enc:snd 32 - |> Jsont.Object.finish 33 - in 34 - 35 - Printf.printf "=== Without locs (default) ===\n"; 36 - let result_no_locs = 37 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false 38 - in 39 - show_result "Error message" result_no_locs; 40 - 41 - Printf.printf "\n=== With locs=true ===\n"; 42 - let result_with_locs = 43 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true 44 - in 45 - show_result "Error message" result_with_locs 46 - 47 - (* Test: Show error locations for nested structures *) 48 - let test_nested_error file = 49 - let yaml = read_file file in 50 - 51 - (* Nested object codec *) 52 - let address_codec = 53 - Jsont.Object.map ~kind:"Address" (fun street city zip -> 54 - (street, city, zip)) 55 - |> Jsont.Object.mem "street" Jsont.string ~enc:(fun (s, _, _) -> s) 56 - |> Jsont.Object.mem "city" Jsont.string ~enc:(fun (_, c, _) -> c) 57 - |> Jsont.Object.mem "zip" Jsont.int ~enc:(fun (_, _, z) -> z) 58 - |> Jsont.Object.finish 59 - in 60 - 61 - let codec = 62 - Jsont.Object.map ~kind:"Employee" (fun name address -> (name, address)) 63 - |> Jsont.Object.mem "name" Jsont.string ~enc:fst 64 - |> Jsont.Object.mem "address" address_codec ~enc:snd 65 - |> Jsont.Object.finish 66 - in 67 - 68 - Printf.printf "=== Without locs (default) ===\n"; 69 - let result_no_locs = 70 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false 71 - in 72 - show_result "Nested error" result_no_locs; 73 - 74 - Printf.printf "\n=== With locs=true ===\n"; 75 - let result_with_locs = 76 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true 77 - in 78 - show_result "Nested error" result_with_locs 79 - 80 - (* Test: Array element error locations *) 81 - let test_array_error file = 82 - let yaml = read_file file in 83 - 84 - (* Array codec *) 85 - let codec = 86 - Jsont.Object.map ~kind:"Numbers" (fun nums -> nums) 87 - |> Jsont.Object.mem "values" (Jsont.array Jsont.int) ~enc:(fun n -> n) 88 - |> Jsont.Object.finish 89 - in 90 - 91 - Printf.printf "=== Without locs (default) ===\n"; 92 - let result_no_locs = 93 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false 94 - in 95 - show_result "Array error" result_no_locs; 96 - 97 - Printf.printf "\n=== With locs=true ===\n"; 98 - let result_with_locs = 99 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true 100 - in 101 - show_result "Array error" result_with_locs 102 - 103 - (* Test: Layout preservation - check if we can decode with layout info *) 104 - let test_layout_preservation file = 105 - let yaml = read_file file in 106 - 107 - let codec = 108 - Jsont.Object.map ~kind:"Config" (fun host port -> (host, port)) 109 - |> Jsont.Object.mem "host" Jsont.string ~enc:fst 110 - |> Jsont.Object.mem "port" Jsont.int ~enc:snd 111 - |> Jsont.Object.finish 112 - in 113 - 114 - Printf.printf "=== Without layout (default) ===\n"; 115 - (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:false with 116 - | Ok (host, port) -> 117 - Printf.printf "Decoded: host=%s, port=%d\n" host port; 118 - Printf.printf "Meta preserved: no\n" 119 - | Error e -> Printf.printf "Error: %s\n" e); 120 - 121 - Printf.printf "\n=== With layout=true ===\n"; 122 - match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:true with 123 - | Ok (host, port) -> 124 - Printf.printf "Decoded: host=%s, port=%d\n" host port; 125 - Printf.printf 126 - "Meta preserved: yes (style info available for round-tripping)\n" 127 - | Error e -> Printf.printf "Error: %s\n" e 128 - 129 - (* Test: Round-trip with layout preservation *) 130 - let test_roundtrip_layout file = 131 - let yaml = read_file file in 132 - 133 - let codec = 134 - Jsont.Object.map ~kind:"Data" (fun items -> items) 135 - |> Jsont.Object.mem "items" (Jsont.array Jsont.string) ~enc:(fun x -> x) 136 - |> Jsont.Object.finish 137 - in 138 - 139 - Printf.printf "=== Original YAML ===\n"; 140 - Printf.printf "%s\n" (String.trim yaml); 141 - 142 - Printf.printf "\n=== Decode without layout, re-encode ===\n"; 143 - (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:false with 144 - | Ok items -> ( 145 - let b = Buffer.create 256 in 146 - let writer = Bytes.Writer.of_buffer b in 147 - match Yamlt.encode ~format:Yamlt.Block codec items ~eod:true writer with 148 - | Ok () -> Printf.printf "%s" (Buffer.contents b) 149 - | Error e -> Printf.printf "Encode error: %s\n" e) 150 - | Error e -> Printf.printf "Decode error: %s\n" e); 151 - 152 - Printf.printf 153 - "\n=== Decode with layout=true, re-encode with Layout format ===\n"; 154 - match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:true with 155 - | Ok items -> ( 156 - let b = Buffer.create 256 in 157 - let writer = Bytes.Writer.of_buffer b in 158 - match Yamlt.encode ~format:Yamlt.Layout codec items ~eod:true writer with 159 - | Ok () -> Printf.printf "%s" (Buffer.contents b) 160 - | Error e -> Printf.printf "Encode error: %s\n" e) 161 - | Error e -> Printf.printf "Decode error: %s\n" e 162 - 163 - (* Test: File path in error messages *) 164 - let test_file_path () = 165 - let yaml = "name: Alice\nage: not-a-number\n" in 166 - 167 - let codec = 168 - Jsont.Object.map ~kind:"Person" (fun name age -> (name, age)) 169 - |> Jsont.Object.mem "name" Jsont.string ~enc:fst 170 - |> Jsont.Object.mem "age" Jsont.int ~enc:snd 171 - |> Jsont.Object.finish 172 - in 173 - 174 - Printf.printf "=== Without file path ===\n"; 175 - let result1 = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in 176 - show_result "Error" result1; 177 - 178 - Printf.printf "\n=== With file path ===\n"; 179 - let result2 = 180 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~file:"test.yml" 181 - in 182 - show_result "Error" result2 183 - 184 - (* Test: Missing field error with locs *) 185 - let test_missing_field file = 186 - let yaml = read_file file in 187 - 188 - let codec = 189 - Jsont.Object.map ~kind:"Complete" (fun a b c -> (a, b, c)) 190 - |> Jsont.Object.mem "field_a" Jsont.string ~enc:(fun (a, _, _) -> a) 191 - |> Jsont.Object.mem "field_b" Jsont.int ~enc:(fun (_, b, _) -> b) 192 - |> Jsont.Object.mem "field_c" Jsont.bool ~enc:(fun (_, _, c) -> c) 193 - |> Jsont.Object.finish 194 - in 195 - 196 - Printf.printf "=== Without locs ===\n"; 197 - let result_no_locs = 198 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false 199 - in 200 - show_result "Missing field" result_no_locs; 201 - 202 - Printf.printf "\n=== With locs=true ===\n"; 203 - let result_with_locs = 204 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true 205 - in 206 - show_result "Missing field" result_with_locs 207 - 208 - (* Test: Both locs and layout together *) 209 - let test_combined_options file = 210 - let yaml = read_file file in 211 - 212 - let codec = 213 - Jsont.Object.map ~kind:"Settings" (fun timeout retries -> 214 - (timeout, retries)) 215 - |> Jsont.Object.mem "timeout" Jsont.int ~enc:fst 216 - |> Jsont.Object.mem "retries" Jsont.int ~enc:snd 217 - |> Jsont.Object.finish 218 - in 219 - 220 - Printf.printf "=== locs=false, layout=false (defaults) ===\n"; 221 - (match 222 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false ~layout:false 223 - with 224 - | Ok (timeout, retries) -> 225 - Printf.printf "OK: timeout=%d, retries=%d\n" timeout retries 226 - | Error e -> Printf.printf "Error: %s\n" e); 227 - 228 - Printf.printf "\n=== locs=true, layout=false ===\n"; 229 - (match 230 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~layout:false 231 - with 232 - | Ok (timeout, retries) -> 233 - Printf.printf "OK: timeout=%d, retries=%d (with precise locations)\n" 234 - timeout retries 235 - | Error e -> Printf.printf "Error: %s\n" e); 236 - 237 - Printf.printf "\n=== locs=false, layout=true ===\n"; 238 - (match 239 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false ~layout:true 240 - with 241 - | Ok (timeout, retries) -> 242 - Printf.printf "OK: timeout=%d, retries=%d (with layout metadata)\n" 243 - timeout retries 244 - | Error e -> Printf.printf "Error: %s\n" e); 245 - 246 - Printf.printf "\n=== locs=true, layout=true (both enabled) ===\n"; 247 - match 248 - Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~layout:true 249 - with 250 - | Ok (timeout, retries) -> 251 - Printf.printf "OK: timeout=%d, retries=%d (with locations and layout)\n" 252 - timeout retries 253 - | Error e -> Printf.printf "Error: %s\n" e 254 - 255 - let () = 256 - let usage = "Usage: test_locations <command> [args...]" in 257 - 258 - if Stdlib.Array.length Sys.argv < 2 then begin 259 - prerr_endline usage; 260 - exit 1 261 - end; 262 - 263 - match Sys.argv.(1) with 264 - | "error-precision" when Array.length Sys.argv = 3 -> 265 - test_error_precision Sys.argv.(2) 266 - | "nested-error" when Array.length Sys.argv = 3 -> 267 - test_nested_error Sys.argv.(2) 268 - | "array-error" when Array.length Sys.argv = 3 -> 269 - test_array_error Sys.argv.(2) 270 - | "layout" when Array.length Sys.argv = 3 -> 271 - test_layout_preservation Sys.argv.(2) 272 - | "roundtrip" when Array.length Sys.argv = 3 -> 273 - test_roundtrip_layout Sys.argv.(2) 274 - | "file-path" -> test_file_path () 275 - | "missing-field" when Array.length Sys.argv = 3 -> 276 - test_missing_field Sys.argv.(2) 277 - | "combined" when Array.length Sys.argv = 3 -> 278 - test_combined_options Sys.argv.(2) 279 - | _ -> 280 - prerr_endline usage; 281 - prerr_endline "Commands:"; 282 - prerr_endline 283 - " error-precision <file> - Compare error messages with/without locs"; 284 - prerr_endline 285 - " nested-error <file> - Test error locations in nested objects"; 286 - prerr_endline 287 - " array-error <file> - Test error locations in arrays"; 288 - prerr_endline " layout <file> - Test layout preservation"; 289 - prerr_endline 290 - " roundtrip <file> - Test round-tripping with layout"; 291 - prerr_endline 292 - " file-path - Test file path in error messages"; 293 - prerr_endline 294 - " missing-field <file> - Test missing field errors with locs"; 295 - prerr_endline " combined <file> - Test locs and layout together"; 296 - exit 1
-241
tests/bin/test_multidoc.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test multi-document YAML streams with decode_all *) 7 - 8 - open Bytesrw 9 - 10 - (* Helper to read file *) 11 - let read_file path = 12 - let ic = open_in path in 13 - let len = in_channel_length ic in 14 - let s = really_input_string ic len in 15 - close_in ic; 16 - s 17 - 18 - (* Helper to show results *) 19 - let show_result label = function 20 - | Ok v -> Printf.printf "%s: %s\n" label v 21 - | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 - 23 - (* Test: Simple multi-document stream *) 24 - let test_simple file = 25 - let module M = struct 26 - type person = { name : string; age : int } 27 - 28 - let person_codec = 29 - Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 30 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 31 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 32 - |> Jsont.Object.finish 33 - 34 - let show p = Printf.sprintf "%s (age %d)" p.name p.age 35 - end in 36 - let yaml = read_file file in 37 - let reader = Bytes.Reader.of_string yaml in 38 - let seq = Yamlt.decode_all M.person_codec reader in 39 - Printf.printf "Documents:\n"; 40 - seq 41 - |> Seq.iteri (fun i result -> 42 - Printf.printf " [%d] " i; 43 - show_result "" (Result.map M.show result)) 44 - 45 - (* Test: Count documents *) 46 - let test_count file = 47 - let yaml = read_file file in 48 - let reader = Bytes.Reader.of_string yaml in 49 - let seq = Yamlt.decode_all Jsont.json reader in 50 - let count = Seq.fold_left (fun acc _ -> acc + 1) 0 seq in 51 - Printf.printf "Document count: %d\n" count 52 - 53 - (* Test: Error tracking - show which documents succeed and which fail *) 54 - let test_errors file = 55 - let module M = struct 56 - type person = { name : string; age : int } 57 - 58 - let person_codec = 59 - Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 60 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 61 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 62 - |> Jsont.Object.finish 63 - 64 - let show p = Printf.sprintf "%s (age %d)" p.name p.age 65 - end in 66 - let yaml = read_file file in 67 - let reader = Bytes.Reader.of_string yaml in 68 - let seq = Yamlt.decode_all M.person_codec reader in 69 - Printf.printf "Document results:\n"; 70 - seq 71 - |> Seq.iteri (fun i result -> 72 - match result with 73 - | Ok p -> Printf.printf " [%d] OK: %s\n" i (M.show p) 74 - | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e)) 75 - 76 - (* Test: Location tracking with locs=true *) 77 - let test_locations file = 78 - let module M = struct 79 - type person = { name : string; age : int } 80 - 81 - let person_codec = 82 - Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 83 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 84 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 85 - |> Jsont.Object.finish 86 - end in 87 - let yaml = read_file file in 88 - 89 - Printf.printf "=== Without locs (default) ===\n"; 90 - let reader = Bytes.Reader.of_string yaml in 91 - let seq = Yamlt.decode_all ~locs:false M.person_codec reader in 92 - seq 93 - |> Seq.iteri (fun i result -> 94 - match result with 95 - | Ok _ -> Printf.printf " [%d] OK\n" i 96 - | Error e -> Printf.printf " [%d] ERROR:\n%s\n" i (String.trim e)); 97 - 98 - Printf.printf "\n=== With locs=true ===\n"; 99 - let reader = Bytes.Reader.of_string yaml in 100 - let seq = 101 - Yamlt.decode_all ~locs:true ~file:"test.yml" M.person_codec reader 102 - in 103 - seq 104 - |> Seq.iteri (fun i result -> 105 - match result with 106 - | Ok _ -> Printf.printf " [%d] OK\n" i 107 - | Error e -> Printf.printf " [%d] ERROR:\n%s\n" i (String.trim e)) 108 - 109 - (* Test: Roundtrip to JSON - decode YAML multidoc, encode each to JSON *) 110 - let test_json_roundtrip file = 111 - let yaml = read_file file in 112 - let reader = Bytes.Reader.of_string yaml in 113 - let seq = Yamlt.decode_all Jsont.json reader in 114 - Printf.printf "JSON outputs:\n"; 115 - seq 116 - |> Seq.iteri (fun i result -> 117 - match result with 118 - | Ok json_val -> ( 119 - match Jsont_bytesrw.encode_string Jsont.json json_val with 120 - | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str) 121 - | Error e -> Printf.printf " [%d] ENCODE ERROR: %s\n" i e) 122 - | Error e -> Printf.printf " [%d] DECODE ERROR: %s\n" i (String.trim e)) 123 - 124 - (* Test: Nested objects in multidoc *) 125 - let test_nested file = 126 - let module M = struct 127 - type address = { street : string; city : string } 128 - type person = { name : string; age : int; address : address } 129 - 130 - let address_codec = 131 - Jsont.Object.map ~kind:"Address" (fun street city -> { street; city }) 132 - |> Jsont.Object.mem "street" Jsont.string ~enc:(fun a -> a.street) 133 - |> Jsont.Object.mem "city" Jsont.string ~enc:(fun a -> a.city) 134 - |> Jsont.Object.finish 135 - 136 - let person_codec = 137 - Jsont.Object.map ~kind:"Person" (fun name age address -> 138 - { name; age; address }) 139 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 140 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 141 - |> Jsont.Object.mem "address" address_codec ~enc:(fun p -> p.address) 142 - |> Jsont.Object.finish 143 - 144 - let show p = 145 - Printf.sprintf "%s (age %d) from %s, %s" p.name p.age p.address.street 146 - p.address.city 147 - end in 148 - let yaml = read_file file in 149 - let reader = Bytes.Reader.of_string yaml in 150 - let seq = Yamlt.decode_all M.person_codec reader in 151 - Printf.printf "Nested documents:\n"; 152 - seq 153 - |> Seq.iteri (fun i result -> 154 - Printf.printf " [%d] " i; 155 - show_result "" (Result.map M.show result)) 156 - 157 - (* Test: Arrays in multidoc *) 158 - let test_arrays file = 159 - let yaml = read_file file in 160 - let reader = Bytes.Reader.of_string yaml in 161 - let seq = Yamlt.decode_all Jsont.json reader in 162 - Printf.printf "Array documents:\n"; 163 - seq 164 - |> Seq.iteri (fun i result -> 165 - match result with 166 - | Ok json_val -> ( 167 - match Jsont_bytesrw.encode_string Jsont.json json_val with 168 - | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str) 169 - | Error e -> Printf.printf " [%d] ERROR: %s\n" i e) 170 - | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e)) 171 - 172 - (* Test: Scalars in multidoc *) 173 - let test_scalars file = 174 - let yaml = read_file file in 175 - let reader = Bytes.Reader.of_string yaml in 176 - let seq = Yamlt.decode_all Jsont.json reader in 177 - Printf.printf "Scalar documents:\n"; 178 - seq 179 - |> Seq.iteri (fun i result -> 180 - match result with 181 - | Ok json_val -> ( 182 - match Jsont_bytesrw.encode_string Jsont.json json_val with 183 - | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str) 184 - | Error e -> Printf.printf " [%d] ERROR: %s\n" i e) 185 - | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e)) 186 - 187 - (* Test: Summary stats - count successes vs failures *) 188 - let test_summary file = 189 - let module M = struct 190 - type person = { name : string; age : int } 191 - 192 - let person_codec = 193 - Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 194 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 195 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 196 - |> Jsont.Object.finish 197 - end in 198 - let yaml = read_file file in 199 - let reader = Bytes.Reader.of_string yaml in 200 - let seq = Yamlt.decode_all M.person_codec reader in 201 - let success = ref 0 in 202 - let failure = ref 0 in 203 - seq 204 - |> Seq.iter (fun result -> 205 - match result with Ok _ -> incr success | Error _ -> incr failure); 206 - Printf.printf "Summary: %d documents (%d ok, %d error)\n" 207 - (!success + !failure) !success !failure 208 - 209 - let () = 210 - let usage = "Usage: test_multidoc <command> <file>" in 211 - if Array.length Sys.argv < 3 then begin 212 - prerr_endline usage; 213 - exit 1 214 - end; 215 - 216 - let test = Sys.argv.(1) in 217 - let file = Sys.argv.(2) in 218 - match test with 219 - | "simple" -> test_simple file 220 - | "count" -> test_count file 221 - | "errors" -> test_errors file 222 - | "locations" -> test_locations file 223 - | "json" -> test_json_roundtrip file 224 - | "nested" -> test_nested file 225 - | "arrays" -> test_arrays file 226 - | "scalars" -> test_scalars file 227 - | "summary" -> test_summary file 228 - | _ -> 229 - prerr_endline usage; 230 - prerr_endline "Commands:"; 231 - prerr_endline " simple <file> - Decode person documents"; 232 - prerr_endline " count <file> - Count documents"; 233 - prerr_endline " errors <file> - Show success/error for each document"; 234 - prerr_endline 235 - " locations <file> - Test location tracking with locs=true"; 236 - prerr_endline " json <file> - Roundtrip to JSON"; 237 - prerr_endline " nested <file> - Decode nested objects"; 238 - prerr_endline " arrays <file> - Decode arrays"; 239 - prerr_endline " scalars <file> - Decode scalars"; 240 - prerr_endline " summary <file> - Show success/failure summary"; 241 - exit 1
-89
tests/bin/test_null_collections.ml
··· 1 - open Bytesrw 2 - 3 - let () = 4 - Printf.printf "=== Test 1: Explicit null as empty array ===\n"; 5 - let yaml1 = "values: null" in 6 - let codec1 = 7 - let open Jsont in 8 - Object.map ~kind:"Test" (fun v -> v) 9 - |> Object.mem "values" (list int) ~dec_absent:[] ~enc:(fun v -> v) 10 - |> Object.finish 11 - in 12 - (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml1) with 13 - | Ok v -> 14 - Printf.printf "Result: [%s]\n" 15 - (String.concat "; " (List.map string_of_int v)) 16 - | Error e -> Printf.printf "Error: %s\n" e); 17 - 18 - Printf.printf "\n=== Test 2: Tilde as empty array ===\n"; 19 - let yaml2 = "values: ~" in 20 - (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml2) with 21 - | Ok v -> 22 - Printf.printf "Result: [%s]\n" 23 - (String.concat "; " (List.map string_of_int v)) 24 - | Error e -> Printf.printf "Error: %s\n" e); 25 - 26 - Printf.printf "\n=== Test 3: Empty array syntax ===\n"; 27 - let yaml3 = "values: []" in 28 - (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml3) with 29 - | Ok v -> 30 - Printf.printf "Result: [%s]\n" 31 - (String.concat "; " (List.map string_of_int v)) 32 - | Error e -> Printf.printf "Error: %s\n" e); 33 - 34 - Printf.printf "\n=== Test 4: Array with values ===\n"; 35 - let yaml4 = "values: [1, 2, 3]" in 36 - (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml4) with 37 - | Ok v -> 38 - Printf.printf "Result: [%s]\n" 39 - (String.concat "; " (List.map string_of_int v)) 40 - | Error e -> Printf.printf "Error: %s\n" e); 41 - 42 - Printf.printf "\n=== Test 5: Explicit null as empty object ===\n"; 43 - let yaml5 = "config: null" in 44 - let codec2 = 45 - let open Jsont in 46 - let config_codec = 47 - Object.map ~kind:"Config" (fun timeout retries -> (timeout, retries)) 48 - |> Object.mem "timeout" int ~dec_absent:30 ~enc:fst 49 - |> Object.mem "retries" int ~dec_absent:3 ~enc:snd 50 - |> Object.finish 51 - in 52 - Object.map ~kind:"Test" (fun c -> c) 53 - |> Object.mem "config" config_codec ~dec_absent:(30, 3) ~enc:(fun c -> c) 54 - |> Object.finish 55 - in 56 - (match Yamlt.decode codec2 (Bytes.Reader.of_string yaml5) with 57 - | Ok (timeout, retries) -> 58 - Printf.printf "Result: {timeout=%d; retries=%d}\n" timeout retries 59 - | Error e -> Printf.printf "Error: %s\n" e); 60 - 61 - Printf.printf "\n=== Test 6: Empty object syntax ===\n"; 62 - let yaml6 = "config: {}" in 63 - (match Yamlt.decode codec2 (Bytes.Reader.of_string yaml6) with 64 - | Ok (timeout, retries) -> 65 - Printf.printf "Result: {timeout=%d; retries=%d}\n" timeout retries 66 - | Error e -> Printf.printf "Error: %s\n" e); 67 - 68 - Printf.printf "\n=== Test 7: Object with values ===\n"; 69 - let yaml7 = "config:\n timeout: 60\n retries: 5" in 70 - (match Yamlt.decode codec2 (Bytes.Reader.of_string yaml7) with 71 - | Ok (timeout, retries) -> 72 - Printf.printf "Result: {timeout=%d; retries=%d}\n" timeout retries 73 - | Error e -> Printf.printf "Error: %s\n" e); 74 - 75 - Printf.printf "\n=== Test 8: Nested null arrays ===\n"; 76 - let yaml8 = "name: test\nitems: null\ntags: ~" in 77 - let codec3 = 78 - let open Jsont in 79 - Object.map ~kind:"Nested" (fun name items tags -> (name, items, tags)) 80 - |> Object.mem "name" string ~enc:(fun (n, _, _) -> n) 81 - |> Object.mem "items" (list int) ~dec_absent:[] ~enc:(fun (_, i, _) -> i) 82 - |> Object.mem "tags" (list string) ~dec_absent:[] ~enc:(fun (_, _, t) -> t) 83 - |> Object.finish 84 - in 85 - match Yamlt.decode codec3 (Bytes.Reader.of_string yaml8) with 86 - | Ok (name, items, tags) -> 87 - Printf.printf "Result: {name=%s; items_count=%d; tags_count=%d}\n" name 88 - (List.length items) (List.length tags) 89 - | Error e -> Printf.printf "Error: %s\n" e
-39
tests/bin/test_null_complete.ml
··· 1 - open Bytesrw 2 - 3 - let () = 4 - Printf.printf "=== Test 1: Jsont.option with YAML null ===\n"; 5 - let yaml1 = "value: null" in 6 - let codec1 = 7 - let open Jsont in 8 - Object.map ~kind:"Test" (fun v -> v) 9 - |> Object.mem "value" (option string) ~enc:(fun v -> v) 10 - |> Object.finish 11 - in 12 - (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml1) with 13 - | Ok v -> 14 - Printf.printf "Result: %s\n" 15 - (match v with None -> "None" | Some s -> "Some(" ^ s ^ ")") 16 - | Error e -> Printf.printf "Error: %s\n" e); 17 - 18 - Printf.printf "\n=== Test 2: Jsont.option with YAML string ===\n"; 19 - (match Yamlt.decode codec1 (Bytes.Reader.of_string "value: hello") with 20 - | Ok v -> 21 - Printf.printf "Result: %s\n" 22 - (match v with None -> "None" | Some s -> "Some(" ^ s ^ ")") 23 - | Error e -> Printf.printf "Error: %s\n" e); 24 - 25 - Printf.printf "\n=== Test 3: Jsont.string with YAML null (should error) ===\n"; 26 - let codec2 = 27 - let open Jsont in 28 - Object.map ~kind:"Test" (fun v -> v) 29 - |> Object.mem "value" string ~enc:(fun v -> v) 30 - |> Object.finish 31 - in 32 - (match Yamlt.decode codec2 (Bytes.Reader.of_string "value: null") with 33 - | Ok v -> Printf.printf "Result: %s\n" v 34 - | Error e -> Printf.printf "Error (expected): %s\n" e); 35 - 36 - Printf.printf "\n=== Test 4: Jsont.string with YAML string ===\n"; 37 - match Yamlt.decode codec2 (Bytes.Reader.of_string "value: hello") with 38 - | Ok v -> Printf.printf "Result: %s\n" v 39 - | Error e -> Printf.printf "Error: %s\n" e
-31
tests/bin/test_null_fix.ml
··· 1 - open Bytesrw 2 - 3 - let () = 4 - let module M = struct 5 - type data = { value : string option } 6 - 7 - let data_codec = 8 - Jsont.Object.map ~kind:"Data" (fun value -> { value }) 9 - |> Jsont.Object.mem "value" (Jsont.option Jsont.string) ~enc:(fun d -> 10 - d.value) 11 - |> Jsont.Object.finish 12 - end in 13 - let yaml_null = "value: null" in 14 - 15 - Printf.printf "Testing YAML null handling with Jsont.option Jsont.string:\n\n"; 16 - 17 - match Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml_null) with 18 - | Ok data -> ( 19 - match data.M.value with 20 - | None -> Printf.printf "YAML: value=None (CORRECT)\n" 21 - | Some s -> Printf.printf "YAML: value=Some(%S) (BUG!)\n" s) 22 - | Error e -> ( 23 - Printf.printf "YAML ERROR: %s\n" e; 24 - 25 - let json_null = "{\"value\": null}" in 26 - match Jsont_bytesrw.decode_string M.data_codec json_null with 27 - | Ok data -> ( 28 - match data.M.value with 29 - | None -> Printf.printf "JSON: value=None (CORRECT)\n" 30 - | Some s -> Printf.printf "JSON: value=Some(%S) (BUG!)\n" s) 31 - | Error e -> Printf.printf "JSON ERROR: %s\n" e)
-356
tests/bin/test_objects.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test object codec functionality with Yamlt *) 7 - 8 - open Bytesrw 9 - 10 - (* Helper to read file *) 11 - let read_file path = 12 - let ic = open_in path in 13 - let len = in_channel_length ic in 14 - let s = really_input_string ic len in 15 - close_in ic; 16 - s 17 - 18 - (* Helper to show results *) 19 - let show_result label = function 20 - | Ok v -> Printf.printf "%s: %s\n" label v 21 - | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 - 23 - let show_result_both label json_result yaml_result = 24 - Printf.printf "JSON: "; 25 - show_result label json_result; 26 - Printf.printf "YAML: "; 27 - show_result label yaml_result 28 - 29 - (* Test: Simple object with required fields *) 30 - let test_simple_object file = 31 - let module M = struct 32 - type person = { name : string; age : int } 33 - 34 - let person_codec = 35 - Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 36 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 37 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 38 - |> Jsont.Object.finish 39 - 40 - let show p = Printf.sprintf "{name=%S; age=%d}" p.name p.age 41 - end in 42 - let yaml = read_file file in 43 - let json = read_file (file ^ ".json") in 44 - let json_result = Jsont_bytesrw.decode_string M.person_codec json in 45 - let yaml_result = Yamlt.decode M.person_codec (Bytes.Reader.of_string yaml) in 46 - 47 - show_result_both "person" 48 - (Result.map M.show json_result) 49 - (Result.map M.show yaml_result) 50 - 51 - (* Test: Object with optional fields *) 52 - let test_optional_fields file = 53 - let module M = struct 54 - type config = { host : string; port : int option; debug : bool option } 55 - 56 - let config_codec = 57 - Jsont.Object.map ~kind:"Config" (fun host port debug -> 58 - { host; port; debug }) 59 - |> Jsont.Object.mem "host" Jsont.string ~enc:(fun c -> c.host) 60 - |> Jsont.Object.opt_mem "port" Jsont.int ~enc:(fun c -> c.port) 61 - |> Jsont.Object.opt_mem "debug" Jsont.bool ~enc:(fun c -> c.debug) 62 - |> Jsont.Object.finish 63 - 64 - let show c = 65 - Printf.sprintf "{host=%S; port=%s; debug=%s}" c.host 66 - (match c.port with 67 - | None -> "None" 68 - | Some p -> Printf.sprintf "Some %d" p) 69 - (match c.debug with 70 - | None -> "None" 71 - | Some b -> Printf.sprintf "Some %b" b) 72 - end in 73 - let yaml = read_file file in 74 - let json = read_file (file ^ ".json") in 75 - let json_result = Jsont_bytesrw.decode_string M.config_codec json in 76 - let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in 77 - 78 - show_result_both "config" 79 - (Result.map M.show json_result) 80 - (Result.map M.show yaml_result) 81 - 82 - (* Test: Object with default values *) 83 - let test_default_values file = 84 - let module M = struct 85 - type settings = { timeout : int; retries : int; verbose : bool } 86 - 87 - let settings_codec = 88 - Jsont.Object.map ~kind:"Settings" (fun timeout retries verbose -> 89 - { timeout; retries; verbose }) 90 - |> Jsont.Object.mem "timeout" Jsont.int 91 - ~enc:(fun s -> s.timeout) 92 - ~dec_absent:30 93 - |> Jsont.Object.mem "retries" Jsont.int 94 - ~enc:(fun s -> s.retries) 95 - ~dec_absent:3 96 - |> Jsont.Object.mem "verbose" Jsont.bool 97 - ~enc:(fun s -> s.verbose) 98 - ~dec_absent:false 99 - |> Jsont.Object.finish 100 - 101 - let show s = 102 - Printf.sprintf "{timeout=%d; retries=%d; verbose=%b}" s.timeout s.retries 103 - s.verbose 104 - end in 105 - let yaml = read_file file in 106 - let json = read_file (file ^ ".json") in 107 - let json_result = Jsont_bytesrw.decode_string M.settings_codec json in 108 - let yaml_result = 109 - Yamlt.decode M.settings_codec (Bytes.Reader.of_string yaml) 110 - in 111 - 112 - show_result_both "settings" 113 - (Result.map M.show json_result) 114 - (Result.map M.show yaml_result) 115 - 116 - (* Test: Nested objects *) 117 - let test_nested_objects file = 118 - let module M = struct 119 - type address = { street : string; city : string; zip : string } 120 - type employee = { name : string; address : address } 121 - 122 - let address_codec = 123 - Jsont.Object.map ~kind:"Address" (fun street city zip -> 124 - { street; city; zip }) 125 - |> Jsont.Object.mem "street" Jsont.string ~enc:(fun a -> a.street) 126 - |> Jsont.Object.mem "city" Jsont.string ~enc:(fun a -> a.city) 127 - |> Jsont.Object.mem "zip" Jsont.string ~enc:(fun a -> a.zip) 128 - |> Jsont.Object.finish 129 - 130 - let employee_codec = 131 - Jsont.Object.map ~kind:"Employee" (fun name address -> { name; address }) 132 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun e -> e.name) 133 - |> Jsont.Object.mem "address" address_codec ~enc:(fun e -> e.address) 134 - |> Jsont.Object.finish 135 - 136 - let show e = 137 - Printf.sprintf "{name=%S; address={street=%S; city=%S; zip=%S}}" e.name 138 - e.address.street e.address.city e.address.zip 139 - end in 140 - let yaml = read_file file in 141 - let json = read_file (file ^ ".json") in 142 - let json_result = Jsont_bytesrw.decode_string M.employee_codec json in 143 - let yaml_result = 144 - Yamlt.decode M.employee_codec (Bytes.Reader.of_string yaml) 145 - in 146 - 147 - show_result_both "employee" 148 - (Result.map M.show json_result) 149 - (Result.map M.show yaml_result) 150 - 151 - (* Test: Unknown member handling - error *) 152 - let test_unknown_members_error file = 153 - let module M = struct 154 - type strict = { name : string } 155 - 156 - let strict_codec = 157 - Jsont.Object.map ~kind:"Strict" (fun name -> { name }) 158 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun s -> s.name) 159 - |> Jsont.Object.finish 160 - end in 161 - let yaml = read_file file in 162 - let result = Yamlt.decode M.strict_codec (Bytes.Reader.of_string yaml) in 163 - match result with 164 - | Ok _ -> Printf.printf "Unexpected success\n" 165 - | Error e -> Printf.printf "Expected error: %s\n" e 166 - 167 - (* Test: Unknown member handling - keep *) 168 - let test_unknown_members_keep file = 169 - let module M = struct 170 - type flexible = { name : string; extra : Jsont.json } 171 - 172 - let flexible_codec = 173 - Jsont.Object.map ~kind:"Flexible" (fun name extra -> { name; extra }) 174 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun f -> f.name) 175 - |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun f -> f.extra) 176 - |> Jsont.Object.finish 177 - 178 - let show f = Printf.sprintf "{name=%S; has_extra=true}" f.name 179 - end in 180 - let yaml = read_file file in 181 - let json = read_file (file ^ ".json") in 182 - let json_result = Jsont_bytesrw.decode_string M.flexible_codec json in 183 - let yaml_result = 184 - Yamlt.decode M.flexible_codec (Bytes.Reader.of_string yaml) 185 - in 186 - 187 - show_result_both "flexible" 188 - (Result.map M.show json_result) 189 - (Result.map M.show yaml_result) 190 - 191 - (* Test: Object cases (discriminated unions) - simplified version *) 192 - let test_object_cases file = 193 - let module M = struct 194 - type circle = { type_ : string; radius : float } 195 - 196 - let circle_codec = 197 - Jsont.Object.map ~kind:"Circle" (fun type_ radius -> { type_; radius }) 198 - |> Jsont.Object.mem "type" Jsont.string ~enc:(fun c -> c.type_) 199 - |> Jsont.Object.mem "radius" Jsont.number ~enc:(fun c -> c.radius) 200 - |> Jsont.Object.finish 201 - 202 - let show c = Printf.sprintf "Circle{radius=%.2f}" c.radius 203 - end in 204 - let yaml = read_file file in 205 - let json = read_file (file ^ ".json") in 206 - let json_result = Jsont_bytesrw.decode_string M.circle_codec json in 207 - let yaml_result = Yamlt.decode M.circle_codec (Bytes.Reader.of_string yaml) in 208 - 209 - show_result_both "shape" 210 - (Result.map M.show json_result) 211 - (Result.map M.show yaml_result) 212 - 213 - (* Test: Missing required field error *) 214 - let test_missing_required file = 215 - let module M = struct 216 - type required = { name : string; age : int } 217 - 218 - let required_codec = 219 - Jsont.Object.map ~kind:"Required" (fun name age -> { name; age }) 220 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun r -> r.name) 221 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun r -> r.age) 222 - |> Jsont.Object.finish 223 - end in 224 - let yaml = read_file file in 225 - let result = Yamlt.decode M.required_codec (Bytes.Reader.of_string yaml) in 226 - match result with 227 - | Ok _ -> Printf.printf "Unexpected success\n" 228 - | Error e -> Printf.printf "Expected error: %s\n" e 229 - 230 - (* Test: Encoding objects to different formats *) 231 - let test_encode_object () = 232 - let module M = struct 233 - type person = { name : string; age : int; active : bool } 234 - 235 - let person_codec = 236 - Jsont.Object.map ~kind:"Person" (fun name age active -> 237 - { name; age; active }) 238 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 239 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 240 - |> Jsont.Object.mem "active" Jsont.bool ~enc:(fun p -> p.active) 241 - |> Jsont.Object.finish 242 - end in 243 - let person = M.{ name = "Alice"; age = 30; active = true } in 244 - 245 - (* Encode to JSON *) 246 - (match Jsont_bytesrw.encode_string M.person_codec person with 247 - | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 248 - | Error e -> Printf.printf "JSON ERROR: %s\n" e); 249 - 250 - (* Encode to YAML Block *) 251 - (let b = Buffer.create 256 in 252 - let writer = Bytes.Writer.of_buffer b in 253 - match 254 - Yamlt.encode ~format:Yamlt.Block M.person_codec person ~eod:true writer 255 - with 256 - | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 257 - | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 258 - 259 - (* Encode to YAML Flow *) 260 - let b = Buffer.create 256 in 261 - let writer = Bytes.Writer.of_buffer b in 262 - match 263 - Yamlt.encode ~format:Yamlt.Flow M.person_codec person ~eod:true writer 264 - with 265 - | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 266 - | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e 267 - 268 - (* Test: Roundtrip encoding of objects with unknown members *) 269 - let test_unknown_keep_roundtrip file = 270 - let module M = struct 271 - type flexible = { name : string; extra : Jsont.json } 272 - 273 - let flexible_codec = 274 - Jsont.Object.map ~kind:"Flexible" (fun name extra -> { name; extra }) 275 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun f -> f.name) 276 - |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun f -> f.extra) 277 - |> Jsont.Object.finish 278 - 279 - let show_json json = 280 - match Jsont_bytesrw.encode_string Jsont.json json with 281 - | Ok s -> String.trim s 282 - | Error e -> Printf.sprintf "ERROR: %s" e 283 - end in 284 - let yaml = read_file file in 285 - 286 - (* Decode from YAML *) 287 - match Yamlt.decode M.flexible_codec (Bytes.Reader.of_string yaml) with 288 - | Error e -> Printf.printf "Decode error: %s\n" e 289 - | Ok v -> ( 290 - Printf.printf "Decoded: name=%S, extra=%s\n" v.M.name 291 - (M.show_json v.M.extra); 292 - 293 - (* Encode to YAML Block *) 294 - let b = Buffer.create 256 in 295 - let writer = Bytes.Writer.of_buffer b in 296 - (match 297 - Yamlt.encode ~format:Yamlt.Block M.flexible_codec v ~eod:true writer 298 - with 299 - | Ok () -> Printf.printf "Encoded Block:\n%s" (Buffer.contents b) 300 - | Error e -> Printf.printf "Encode Block ERROR: %s\n" e); 301 - 302 - (* Re-decode the encoded YAML to verify roundtrip *) 303 - let encoded = Buffer.contents b in 304 - match Yamlt.decode M.flexible_codec (Bytes.Reader.of_string encoded) with 305 - | Error e -> Printf.printf "Re-decode error: %s\n" e 306 - | Ok v2 -> 307 - Printf.printf "Re-decoded: name=%S, extra=%s\n" v2.M.name 308 - (M.show_json v2.M.extra); 309 - if M.show_json v.M.extra = M.show_json v2.M.extra then 310 - Printf.printf "Roundtrip: OK (extra members preserved)\n" 311 - else Printf.printf "Roundtrip: FAILED (extra members lost)\n") 312 - 313 - let () = 314 - let usage = "Usage: test_objects <command> [args...]" in 315 - 316 - if Stdlib.Array.length Sys.argv < 2 then begin 317 - prerr_endline usage; 318 - exit 1 319 - end; 320 - 321 - match Sys.argv.(1) with 322 - | "simple" when Stdlib.Array.length Sys.argv = 3 -> 323 - test_simple_object Sys.argv.(2) 324 - | "optional" when Stdlib.Array.length Sys.argv = 3 -> 325 - test_optional_fields Sys.argv.(2) 326 - | "defaults" when Stdlib.Array.length Sys.argv = 3 -> 327 - test_default_values Sys.argv.(2) 328 - | "nested" when Stdlib.Array.length Sys.argv = 3 -> 329 - test_nested_objects Sys.argv.(2) 330 - | "unknown-error" when Stdlib.Array.length Sys.argv = 3 -> 331 - test_unknown_members_error Sys.argv.(2) 332 - | "unknown-keep" when Stdlib.Array.length Sys.argv = 3 -> 333 - test_unknown_members_keep Sys.argv.(2) 334 - | "unknown-keep-roundtrip" when Stdlib.Array.length Sys.argv = 3 -> 335 - test_unknown_keep_roundtrip Sys.argv.(2) 336 - | "cases" when Stdlib.Array.length Sys.argv = 3 -> 337 - test_object_cases Sys.argv.(2) 338 - | "missing-required" when Stdlib.Array.length Sys.argv = 3 -> 339 - test_missing_required Sys.argv.(2) 340 - | "encode" when Stdlib.Array.length Sys.argv = 2 -> test_encode_object () 341 - | _ -> 342 - prerr_endline usage; 343 - prerr_endline "Commands:"; 344 - prerr_endline " simple <file> - Test simple object"; 345 - prerr_endline " optional <file> - Test optional fields"; 346 - prerr_endline " defaults <file> - Test default values"; 347 - prerr_endline " nested <file> - Test nested objects"; 348 - prerr_endline " unknown-error <file> - Test unknown member error"; 349 - prerr_endline " unknown-keep <file> - Test keeping unknown members"; 350 - prerr_endline 351 - " unknown-keep-roundtrip <file> - Test roundtrip of unknown members"; 352 - prerr_endline " cases <file> - Test object cases (unions)"; 353 - prerr_endline 354 - " missing-required <file> - Test missing required field error"; 355 - prerr_endline " encode - Test encoding objects"; 356 - exit 1
-19
tests/bin/test_opt_array.ml
··· 1 - open Bytesrw 2 - 3 - let () = 4 - let codec = 5 - Jsont.Object.map ~kind:"Test" (fun arr -> arr) 6 - |> Jsont.Object.opt_mem "values" (Jsont.array Jsont.string) ~enc:(fun arr -> 7 - arr) 8 - |> Jsont.Object.finish 9 - in 10 - 11 - let yaml = "values: [a, b, c]" in 12 - 13 - Printf.printf "Testing optional array field:\n"; 14 - match Yamlt.decode codec (Bytes.Reader.of_string yaml) with 15 - | Ok arr -> ( 16 - match arr with 17 - | None -> Printf.printf "Result: None\n" 18 - | Some a -> Printf.printf "Result: Some([%d items])\n" (Array.length a)) 19 - | Error e -> Printf.printf "Error: %s\n" e
-271
tests/bin/test_roundtrip.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test roundtrip encoding/decoding with Yamlt *) 7 - 8 - open Bytesrw 9 - 10 - (* Test: Roundtrip scalars *) 11 - let test_scalar_roundtrip () = 12 - let module M = struct 13 - type data = { s : string; n : float; b : bool; nul : unit } 14 - 15 - let data_codec = 16 - Jsont.Object.map ~kind:"Data" (fun s n b nul -> { s; n; b; nul }) 17 - |> Jsont.Object.mem "s" Jsont.string ~enc:(fun d -> d.s) 18 - |> Jsont.Object.mem "n" Jsont.number ~enc:(fun d -> d.n) 19 - |> Jsont.Object.mem "b" Jsont.bool ~enc:(fun d -> d.b) 20 - |> Jsont.Object.mem "nul" (Jsont.null ()) ~enc:(fun d -> d.nul) 21 - |> Jsont.Object.finish 22 - 23 - let equal d1 d2 = 24 - d1.s = d2.s && d1.n = d2.n && d1.b = d2.b && d1.nul = d2.nul 25 - end in 26 - let original = { M.s = "hello"; n = 42.5; b = true; nul = () } in 27 - 28 - (* JSON roundtrip *) 29 - let json_encoded = Jsont_bytesrw.encode_string M.data_codec original in 30 - let json_decoded = 31 - Result.bind json_encoded (Jsont_bytesrw.decode_string M.data_codec) 32 - in 33 - (match json_decoded with 34 - | Ok decoded when M.equal original decoded -> 35 - Printf.printf "JSON roundtrip: PASS\n" 36 - | Ok _ -> Printf.printf "JSON roundtrip: FAIL (data mismatch)\n" 37 - | Error e -> Printf.printf "JSON roundtrip: FAIL (%s)\n" e); 38 - 39 - (* YAML Block roundtrip *) 40 - let yaml_block_encoded = 41 - let b = Buffer.create 256 in 42 - let writer = Bytes.Writer.of_buffer b in 43 - match 44 - Yamlt.encode ~format:Yamlt.Block M.data_codec original ~eod:true writer 45 - with 46 - | Ok () -> Ok (Buffer.contents b) 47 - | Error e -> Error e 48 - in 49 - let yaml_block_decoded = 50 - Result.bind yaml_block_encoded (fun yaml -> 51 - Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml)) 52 - in 53 - (match yaml_block_decoded with 54 - | Ok decoded when M.equal original decoded -> 55 - Printf.printf "YAML Block roundtrip: PASS\n" 56 - | Ok _ -> Printf.printf "YAML Block roundtrip: FAIL (data mismatch)\n" 57 - | Error e -> Printf.printf "YAML Block roundtrip: FAIL (%s)\n" e); 58 - 59 - (* YAML Flow roundtrip *) 60 - let yaml_flow_encoded = 61 - let b = Buffer.create 256 in 62 - let writer = Bytes.Writer.of_buffer b in 63 - match 64 - Yamlt.encode ~format:Yamlt.Flow M.data_codec original ~eod:true writer 65 - with 66 - | Ok () -> Ok (Buffer.contents b) 67 - | Error e -> Error e 68 - in 69 - let yaml_flow_decoded = 70 - Result.bind yaml_flow_encoded (fun yaml -> 71 - Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml)) 72 - in 73 - match yaml_flow_decoded with 74 - | Ok decoded when M.equal original decoded -> 75 - Printf.printf "YAML Flow roundtrip: PASS\n" 76 - | Ok _ -> Printf.printf "YAML Flow roundtrip: FAIL (data mismatch)\n" 77 - | Error e -> Printf.printf "YAML Flow roundtrip: FAIL (%s)\n" e 78 - 79 - (* Test: Roundtrip arrays *) 80 - let test_array_roundtrip () = 81 - let module M = struct 82 - type data = { items : int array; nested : float array array } 83 - 84 - let data_codec = 85 - Jsont.Object.map ~kind:"Data" (fun items nested -> { items; nested }) 86 - |> Jsont.Object.mem "items" (Jsont.array Jsont.int) ~enc:(fun d -> 87 - d.items) 88 - |> Jsont.Object.mem "nested" 89 - (Jsont.array (Jsont.array Jsont.number)) 90 - ~enc:(fun d -> d.nested) 91 - |> Jsont.Object.finish 92 - 93 - let equal d1 d2 = d1.items = d2.items && d1.nested = d2.nested 94 - end in 95 - let original = 96 - { 97 - M.items = [| 1; 2; 3; 4; 5 |]; 98 - nested = [| [| 1.0; 2.0 |]; [| 3.0; 4.0 |] |]; 99 - } 100 - in 101 - 102 - (* JSON roundtrip *) 103 - let json_result = 104 - Result.bind 105 - (Jsont_bytesrw.encode_string M.data_codec original) 106 - (Jsont_bytesrw.decode_string M.data_codec) 107 - in 108 - (match json_result with 109 - | Ok decoded when M.equal original decoded -> 110 - Printf.printf "JSON array roundtrip: PASS\n" 111 - | Ok _ -> Printf.printf "JSON array roundtrip: FAIL (data mismatch)\n" 112 - | Error e -> Printf.printf "JSON array roundtrip: FAIL (%s)\n" e); 113 - 114 - (* YAML roundtrip *) 115 - let yaml_result = 116 - let b = Buffer.create 256 in 117 - let writer = Bytes.Writer.of_buffer b in 118 - match Yamlt.encode M.data_codec original ~eod:true writer with 119 - | Ok () -> 120 - let yaml = Buffer.contents b in 121 - Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) 122 - | Error e -> Error e 123 - in 124 - match yaml_result with 125 - | Ok decoded when M.equal original decoded -> 126 - Printf.printf "YAML array roundtrip: PASS\n" 127 - | Ok _ -> Printf.printf "YAML array roundtrip: FAIL (data mismatch)\n" 128 - | Error e -> Printf.printf "YAML array roundtrip: FAIL (%s)\n" e 129 - 130 - (* Test: Roundtrip objects *) 131 - let test_object_roundtrip () = 132 - let module M = struct 133 - type person = { p_name : string; age : int; active : bool } 134 - type company = { c_name : string; employees : person array } 135 - 136 - let person_codec = 137 - Jsont.Object.map ~kind:"Person" (fun p_name age active -> 138 - { p_name; age; active }) 139 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.p_name) 140 - |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 141 - |> Jsont.Object.mem "active" Jsont.bool ~enc:(fun p -> p.active) 142 - |> Jsont.Object.finish 143 - 144 - let company_codec = 145 - Jsont.Object.map ~kind:"Company" (fun c_name employees -> 146 - { c_name; employees }) 147 - |> Jsont.Object.mem "name" Jsont.string ~enc:(fun c -> c.c_name) 148 - |> Jsont.Object.mem "employees" (Jsont.array person_codec) ~enc:(fun c -> 149 - c.employees) 150 - |> Jsont.Object.finish 151 - 152 - let person_equal p1 p2 = 153 - p1.p_name = p2.p_name && p1.age = p2.age && p1.active = p2.active 154 - 155 - let equal c1 c2 = 156 - c1.c_name = c2.c_name 157 - && Stdlib.Array.length c1.employees = Stdlib.Array.length c2.employees 158 - && Stdlib.Array.for_all2 person_equal c1.employees c2.employees 159 - end in 160 - let original = 161 - { 162 - M.c_name = "Acme Corp"; 163 - employees = 164 - [| 165 - { p_name = "Alice"; age = 30; active = true }; 166 - { p_name = "Bob"; age = 25; active = false }; 167 - |]; 168 - } 169 - in 170 - 171 - (* JSON roundtrip *) 172 - let json_result = 173 - Result.bind 174 - (Jsont_bytesrw.encode_string M.company_codec original) 175 - (Jsont_bytesrw.decode_string M.company_codec) 176 - in 177 - (match json_result with 178 - | Ok decoded when M.equal original decoded -> 179 - Printf.printf "JSON object roundtrip: PASS\n" 180 - | Ok _ -> Printf.printf "JSON object roundtrip: FAIL (data mismatch)\n" 181 - | Error e -> Printf.printf "JSON object roundtrip: FAIL (%s)\n" e); 182 - 183 - (* YAML roundtrip *) 184 - let yaml_result = 185 - let b = Buffer.create 256 in 186 - let writer = Bytes.Writer.of_buffer b in 187 - match Yamlt.encode M.company_codec original ~eod:true writer with 188 - | Ok () -> 189 - let yaml = Buffer.contents b in 190 - Yamlt.decode M.company_codec (Bytes.Reader.of_string yaml) 191 - | Error e -> Error e 192 - in 193 - match yaml_result with 194 - | Ok decoded when M.equal original decoded -> 195 - Printf.printf "YAML object roundtrip: PASS\n" 196 - | Ok _ -> Printf.printf "YAML object roundtrip: FAIL (data mismatch)\n" 197 - | Error e -> Printf.printf "YAML object roundtrip: FAIL (%s)\n" e 198 - 199 - (* Test: Roundtrip with optionals *) 200 - let test_optional_roundtrip () = 201 - let module M = struct 202 - type data = { 203 - required : string; 204 - optional : int option; 205 - nullable : string option; 206 - } 207 - 208 - let data_codec = 209 - Jsont.Object.map ~kind:"Data" (fun required optional nullable -> 210 - { required; optional; nullable }) 211 - |> Jsont.Object.mem "required" Jsont.string ~enc:(fun d -> d.required) 212 - |> Jsont.Object.opt_mem "optional" Jsont.int ~enc:(fun d -> d.optional) 213 - |> Jsont.Object.mem "nullable" (Jsont.some Jsont.string) ~enc:(fun d -> 214 - d.nullable) 215 - |> Jsont.Object.finish 216 - 217 - let equal d1 d2 = 218 - d1.required = d2.required && d1.optional = d2.optional 219 - && d1.nullable = d2.nullable 220 - end in 221 - let original = { M.required = "test"; optional = Some 42; nullable = None } in 222 - 223 - (* JSON roundtrip *) 224 - let json_result = 225 - Result.bind 226 - (Jsont_bytesrw.encode_string M.data_codec original) 227 - (Jsont_bytesrw.decode_string M.data_codec) 228 - in 229 - (match json_result with 230 - | Ok decoded when M.equal original decoded -> 231 - Printf.printf "JSON optional roundtrip: PASS\n" 232 - | Ok _ -> Printf.printf "JSON optional roundtrip: FAIL (data mismatch)\n" 233 - | Error e -> Printf.printf "JSON optional roundtrip: FAIL (%s)\n" e); 234 - 235 - (* YAML roundtrip *) 236 - let yaml_result = 237 - let b = Buffer.create 256 in 238 - let writer = Bytes.Writer.of_buffer b in 239 - match Yamlt.encode M.data_codec original ~eod:true writer with 240 - | Ok () -> 241 - let yaml = Buffer.contents b in 242 - Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) 243 - | Error e -> Error e 244 - in 245 - match yaml_result with 246 - | Ok decoded when M.equal original decoded -> 247 - Printf.printf "YAML optional roundtrip: PASS\n" 248 - | Ok _ -> Printf.printf "YAML optional roundtrip: FAIL (data mismatch)\n" 249 - | Error e -> Printf.printf "YAML optional roundtrip: FAIL (%s)\n" e 250 - 251 - let () = 252 - let usage = "Usage: test_roundtrip <command>" in 253 - 254 - if Stdlib.Array.length Sys.argv < 2 then begin 255 - prerr_endline usage; 256 - exit 1 257 - end; 258 - 259 - match Sys.argv.(1) with 260 - | "scalar" -> test_scalar_roundtrip () 261 - | "array" -> test_array_roundtrip () 262 - | "object" -> test_object_roundtrip () 263 - | "optional" -> test_optional_roundtrip () 264 - | _ -> 265 - prerr_endline usage; 266 - prerr_endline "Commands:"; 267 - prerr_endline " scalar - Test scalar roundtrip"; 268 - prerr_endline " array - Test array roundtrip"; 269 - prerr_endline " object - Test object roundtrip"; 270 - prerr_endline " optional - Test optional fields roundtrip"; 271 - exit 1
-309
tests/bin/test_scalars.ml
··· 1 - (*--------------------------------------------------------------------------- 2 - Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 - SPDX-License-Identifier: ISC 4 - ---------------------------------------------------------------------------*) 5 - 6 - (** Test scalar type resolution with Yamlt codec *) 7 - 8 - open Bytesrw 9 - 10 - (* Helper to read file *) 11 - let read_file path = 12 - let ic = open_in path in 13 - let len = in_channel_length ic in 14 - let s = really_input_string ic len in 15 - close_in ic; 16 - s 17 - 18 - (* Helper to show results *) 19 - let show_result label = function 20 - | Ok v -> Printf.printf "%s: %s\n" label v 21 - | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 - 23 - let show_result_json label json_result yaml_result = 24 - Printf.printf "JSON %s\n" label; 25 - show_result " decode" json_result; 26 - Printf.printf "YAML %s\n" label; 27 - show_result " decode" yaml_result 28 - 29 - (* Test: Decode null values with different type expectations *) 30 - let test_null_resolution file = 31 - let yaml = read_file file in 32 - 33 - (* Define a simple object codec with nullable field *) 34 - let null_codec = 35 - Jsont.Object.map ~kind:"NullTest" (fun n -> n) 36 - |> Jsont.Object.mem "value" (Jsont.null ()) ~enc:(fun n -> n) 37 - |> Jsont.Object.finish 38 - in 39 - 40 - (* Try decoding as null *) 41 - let result = Yamlt.decode null_codec (Bytes.Reader.of_string yaml) in 42 - show_result "null_codec" (Result.map (fun () -> "null") result) 43 - 44 - (* Test: Boolean type-directed resolution *) 45 - let test_bool_resolution file = 46 - let yaml = read_file file in 47 - let json = read_file (file ^ ".json") in 48 - 49 - (* Codec expecting bool *) 50 - let bool_codec = 51 - Jsont.Object.map ~kind:"BoolTest" (fun b -> b) 52 - |> Jsont.Object.mem "value" Jsont.bool ~enc:(fun b -> b) 53 - |> Jsont.Object.finish 54 - in 55 - 56 - (* Codec expecting string *) 57 - let string_codec = 58 - Jsont.Object.map ~kind:"StringTest" (fun s -> s) 59 - |> Jsont.Object.mem "value" Jsont.string ~enc:(fun s -> s) 60 - |> Jsont.Object.finish 61 - in 62 - 63 - Printf.printf "=== Bool Codec ===\n"; 64 - let json_result = Jsont_bytesrw.decode_string bool_codec json in 65 - let yaml_result = Yamlt.decode bool_codec (Bytes.Reader.of_string yaml) in 66 - show_result_json "bool_codec" 67 - (Result.map (Printf.sprintf "%b") json_result) 68 - (Result.map (Printf.sprintf "%b") yaml_result); 69 - 70 - Printf.printf "\n=== String Codec ===\n"; 71 - let json_result = Jsont_bytesrw.decode_string string_codec json in 72 - let yaml_result = Yamlt.decode string_codec (Bytes.Reader.of_string yaml) in 73 - show_result_json "string_codec" 74 - (Result.map (Printf.sprintf "%S") json_result) 75 - (Result.map (Printf.sprintf "%S") yaml_result) 76 - 77 - (* Test: Number resolution *) 78 - let test_number_resolution file = 79 - let yaml = read_file file in 80 - let json = read_file (file ^ ".json") in 81 - 82 - let number_codec = 83 - Jsont.Object.map ~kind:"NumberTest" (fun n -> n) 84 - |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n) 85 - |> Jsont.Object.finish 86 - in 87 - 88 - let json_result = Jsont_bytesrw.decode_string number_codec json in 89 - let yaml_result = Yamlt.decode number_codec (Bytes.Reader.of_string yaml) in 90 - 91 - show_result_json "number_codec" 92 - (Result.map (Printf.sprintf "%.17g") json_result) 93 - (Result.map (Printf.sprintf "%.17g") yaml_result) 94 - 95 - (* Test: String resolution preserves everything *) 96 - let test_string_resolution file = 97 - let yaml = read_file file in 98 - let json = read_file (file ^ ".json") in 99 - 100 - let string_codec = 101 - Jsont.Object.map ~kind:"StringTest" (fun s -> s) 102 - |> Jsont.Object.mem "value" Jsont.string ~enc:(fun s -> s) 103 - |> Jsont.Object.finish 104 - in 105 - 106 - let json_result = Jsont_bytesrw.decode_string string_codec json in 107 - let yaml_result = Yamlt.decode string_codec (Bytes.Reader.of_string yaml) in 108 - 109 - show_result_json "string_codec" 110 - (Result.map (Printf.sprintf "%S") json_result) 111 - (Result.map (Printf.sprintf "%S") yaml_result) 112 - 113 - (* Test: Special float values *) 114 - let test_special_floats file = 115 - let yaml = read_file file in 116 - 117 - let number_codec = 118 - Jsont.Object.map ~kind:"SpecialFloat" (fun n -> n) 119 - |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n) 120 - |> Jsont.Object.finish 121 - in 122 - 123 - let result = Yamlt.decode number_codec (Bytes.Reader.of_string yaml) in 124 - match result with 125 - | Ok f -> 126 - if Float.is_nan f then Printf.printf "value: NaN\n" 127 - else if f = Float.infinity then Printf.printf "value: +Infinity\n" 128 - else if f = Float.neg_infinity then Printf.printf "value: -Infinity\n" 129 - else Printf.printf "value: %.17g\n" f 130 - | Error e -> Printf.printf "ERROR: %s\n" e 131 - 132 - (* Test: Type mismatch errors *) 133 - let test_type_mismatch file expected_type = 134 - let yaml = read_file file in 135 - 136 - match expected_type with 137 - | "bool" -> ( 138 - let codec = 139 - Jsont.Object.map ~kind:"BoolTest" (fun b -> b) 140 - |> Jsont.Object.mem "value" Jsont.bool ~enc:(fun b -> b) 141 - |> Jsont.Object.finish 142 - in 143 - let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in 144 - match result with 145 - | Ok _ -> Printf.printf "Unexpected success\n" 146 - | Error e -> Printf.printf "Expected error: %s\n" e) 147 - | "number" -> ( 148 - let codec = 149 - Jsont.Object.map ~kind:"NumberTest" (fun n -> n) 150 - |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n) 151 - |> Jsont.Object.finish 152 - in 153 - let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in 154 - match result with 155 - | Ok _ -> Printf.printf "Unexpected success\n" 156 - | Error e -> Printf.printf "Expected error: %s\n" e) 157 - | "null" -> ( 158 - let codec = 159 - Jsont.Object.map ~kind:"NullTest" (fun n -> n) 160 - |> Jsont.Object.mem "value" (Jsont.null ()) ~enc:(fun n -> n) 161 - |> Jsont.Object.finish 162 - in 163 - let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in 164 - match result with 165 - | Ok _ -> Printf.printf "Unexpected success\n" 166 - | Error e -> Printf.printf "Expected error: %s\n" e) 167 - | _ -> failwith "unknown type" 168 - 169 - (* Test: Decode with Jsont.json to see auto-resolution *) 170 - let test_any_resolution file = 171 - let yaml = read_file file in 172 - let json = read_file (file ^ ".json") in 173 - 174 - let any_codec = 175 - Jsont.Object.map ~kind:"AnyTest" (fun v -> v) 176 - |> Jsont.Object.mem "value" Jsont.json ~enc:(fun v -> v) 177 - |> Jsont.Object.finish 178 - in 179 - 180 - let json_result = Jsont_bytesrw.decode_string any_codec json in 181 - let yaml_result = Yamlt.decode any_codec (Bytes.Reader.of_string yaml) in 182 - 183 - (* Just show that it decoded successfully *) 184 - show_result_json "any_codec" 185 - (Result.map (fun _ -> "decoded") json_result) 186 - (Result.map (fun _ -> "decoded") yaml_result) 187 - 188 - (* Test: Encoding to different formats *) 189 - let test_encode_formats value_type value = 190 - match value_type with 191 - | "bool" -> ( 192 - let codec = 193 - Jsont.Object.map ~kind:"BoolTest" (fun b -> b) 194 - |> Jsont.Object.mem "value" Jsont.bool ~enc:(fun b -> b) 195 - |> Jsont.Object.finish 196 - in 197 - let v = bool_of_string value in 198 - (match Jsont_bytesrw.encode_string codec v with 199 - | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 200 - | Error e -> Printf.printf "JSON ERROR: %s\n" e); 201 - (let b = Buffer.create 256 in 202 - let writer = Bytes.Writer.of_buffer b in 203 - match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with 204 - | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 205 - | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 206 - let b = Buffer.create 256 in 207 - let writer = Bytes.Writer.of_buffer b in 208 - match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with 209 - | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 210 - | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e) 211 - | "number" -> ( 212 - let codec = 213 - Jsont.Object.map ~kind:"NumberTest" (fun n -> n) 214 - |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n) 215 - |> Jsont.Object.finish 216 - in 217 - let v = float_of_string value in 218 - (match Jsont_bytesrw.encode_string codec v with 219 - | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 220 - | Error e -> Printf.printf "JSON ERROR: %s\n" e); 221 - (let b = Buffer.create 256 in 222 - let writer = Bytes.Writer.of_buffer b in 223 - match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with 224 - | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 225 - | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 226 - let b = Buffer.create 256 in 227 - let writer = Bytes.Writer.of_buffer b in 228 - match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with 229 - | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 230 - | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e) 231 - | "string" -> ( 232 - let codec = 233 - Jsont.Object.map ~kind:"StringTest" (fun s -> s) 234 - |> Jsont.Object.mem "value" Jsont.string ~enc:(fun s -> s) 235 - |> Jsont.Object.finish 236 - in 237 - let v = value in 238 - (match Jsont_bytesrw.encode_string codec v with 239 - | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 240 - | Error e -> Printf.printf "JSON ERROR: %s\n" e); 241 - (let b = Buffer.create 256 in 242 - let writer = Bytes.Writer.of_buffer b in 243 - match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with 244 - | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 245 - | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 246 - let b = Buffer.create 256 in 247 - let writer = Bytes.Writer.of_buffer b in 248 - match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with 249 - | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 250 - | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e) 251 - | "null" -> ( 252 - let codec = 253 - Jsont.Object.map ~kind:"NullTest" (fun n -> n) 254 - |> Jsont.Object.mem "value" (Jsont.null ()) ~enc:(fun n -> n) 255 - |> Jsont.Object.finish 256 - in 257 - let v = () in 258 - (match Jsont_bytesrw.encode_string codec v with 259 - | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 260 - | Error e -> Printf.printf "JSON ERROR: %s\n" e); 261 - (let b = Buffer.create 256 in 262 - let writer = Bytes.Writer.of_buffer b in 263 - match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with 264 - | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 265 - | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 266 - let b = Buffer.create 256 in 267 - let writer = Bytes.Writer.of_buffer b in 268 - match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with 269 - | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 270 - | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e) 271 - | _ -> failwith "unknown type" 272 - 273 - let () = 274 - let usage = "Usage: test_scalars <command> [args...]" in 275 - 276 - if Stdlib.Array.length Sys.argv < 2 then begin 277 - prerr_endline usage; 278 - exit 1 279 - end; 280 - 281 - match Sys.argv.(1) with 282 - | "null" when Array.length Sys.argv = 3 -> test_null_resolution Sys.argv.(2) 283 - | "bool" when Array.length Sys.argv = 3 -> test_bool_resolution Sys.argv.(2) 284 - | "number" when Array.length Sys.argv = 3 -> 285 - test_number_resolution Sys.argv.(2) 286 - | "string" when Array.length Sys.argv = 3 -> 287 - test_string_resolution Sys.argv.(2) 288 - | "special-float" when Array.length Sys.argv = 3 -> 289 - test_special_floats Sys.argv.(2) 290 - | "type-mismatch" when Array.length Sys.argv = 4 -> 291 - test_type_mismatch Sys.argv.(2) Sys.argv.(3) 292 - | "any" when Array.length Sys.argv = 3 -> test_any_resolution Sys.argv.(2) 293 - | "encode" when Array.length Sys.argv = 4 -> 294 - test_encode_formats Sys.argv.(2) Sys.argv.(3) 295 - | _ -> 296 - prerr_endline usage; 297 - prerr_endline "Commands:"; 298 - prerr_endline " null <file> - Test null resolution"; 299 - prerr_endline 300 - " bool <file> - Test bool vs string resolution"; 301 - prerr_endline " number <file> - Test number resolution"; 302 - prerr_endline " string <file> - Test string resolution"; 303 - prerr_endline " special-float <file> - Test .inf, .nan, etc."; 304 - prerr_endline 305 - " type-mismatch <file> <type> - Test error on type mismatch"; 306 - prerr_endline 307 - " any <file> - Test Jsont.any auto-resolution"; 308 - prerr_endline " encode <type> <value> - Test encoding to JSON/YAML"; 309 - exit 1
-38
tests/bin/test_some_vs_option.ml
··· 1 - open Bytesrw 2 - 3 - let () = 4 - (* Using Jsont.some like opt_mem does *) 5 - let codec1 = 6 - Jsont.Object.map ~kind:"Test" (fun arr -> arr) 7 - |> Jsont.Object.mem "values" 8 - (Jsont.some (Jsont.array Jsont.string)) 9 - ~enc:(fun arr -> arr) 10 - |> Jsont.Object.finish 11 - in 12 - 13 - let yaml = "values: [a, b, c]" in 14 - 15 - Printf.printf "Test 1: Jsont.some (Jsont.array) - like opt_mem:\n"; 16 - (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml) with 17 - | Ok arr -> ( 18 - match arr with 19 - | None -> Printf.printf "Result: None\n" 20 - | Some a -> Printf.printf "Result: Some([%d items])\n" (Array.length a)) 21 - | Error e -> Printf.printf "Error: %s\n" e); 22 - 23 - (* Using Jsont.option *) 24 - let codec2 = 25 - Jsont.Object.map ~kind:"Test" (fun arr -> arr) 26 - |> Jsont.Object.mem "values" 27 - (Jsont.option (Jsont.array Jsont.string)) 28 - ~enc:(fun arr -> arr) 29 - |> Jsont.Object.finish 30 - in 31 - 32 - Printf.printf "\nTest 2: Jsont.option (Jsont.array):\n"; 33 - match Yamlt.decode codec2 (Bytes.Reader.of_string yaml) with 34 - | Ok arr -> ( 35 - match arr with 36 - | None -> Printf.printf "Result: None\n" 37 - | Some a -> Printf.printf "Result: Some([%d items])\n" (Array.length a)) 38 - | Error e -> Printf.printf "Error: %s\n" e
-148
tests/cram/arrays_codec.t
··· 1 - Array Codec Tests with Yamlt 2 - =============================== 3 - 4 - This test suite validates array encoding/decoding with Jsont codecs in YAML, 5 - including homogeneous type checking and nested structures. 6 - 7 - Setup 8 - ----- 9 - 10 - ================================================================================ 11 - HOMOGENEOUS ARRAYS 12 - ================================================================================ 13 - 14 - Integer arrays 15 - 16 - $ test_arrays int ../data/arrays/int_array.yml 17 - JSON: int_array: [1; 2; 3; 4; 5] 18 - YAML: int_array: [1; 2; 3; 4; 5] 19 - 20 - String arrays 21 - 22 - $ test_arrays string ../data/arrays/string_array.yml 23 - JSON: string_array: ["apple"; "banana"; "cherry"] 24 - YAML: string_array: ["apple"; "banana"; "cherry"] 25 - 26 - Float/Number arrays 27 - 28 - $ test_arrays float ../data/arrays/float_array.yml 29 - JSON: float_array: [1.50; 2.70; 3.14; 0.50] 30 - YAML: float_array: [1.50; 2.70; 3.14; 0.50] 31 - 32 - Boolean arrays 33 - 34 - $ test_arrays bool ../data/arrays/bool_array.yml 35 - JSON: bool_array: [true; false; true; true; false] 36 - YAML: bool_array: [true; false; true; true; false] 37 - 38 - ================================================================================ 39 - EMPTY ARRAYS 40 - ================================================================================ 41 - 42 - Empty arrays work correctly 43 - 44 - $ test_arrays empty ../data/arrays/empty_array.yml 45 - JSON: empty_array: length=0 46 - YAML: empty_array: length=0 47 - 48 - ================================================================================ 49 - ARRAYS OF OBJECTS 50 - ================================================================================ 51 - 52 - Arrays containing objects 53 - 54 - $ test_arrays objects ../data/arrays/object_array.yml 55 - JSON: object_array: [{Alice,30}; {Bob,25}; {Charlie,35}] 56 - YAML: object_array: [{Alice,30}; {Bob,25}; {Charlie,35}] 57 - 58 - ================================================================================ 59 - NESTED ARRAYS 60 - ================================================================================ 61 - 62 - Arrays containing arrays (matrices) 63 - 64 - $ test_arrays nested ../data/arrays/nested_array.yml 65 - JSON: nested_arrays: [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]] 66 - YAML: nested_arrays: [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]] 67 - 68 - ================================================================================ 69 - NULLABLE ARRAYS 70 - ================================================================================ 71 - 72 - Arrays with null elements 73 - 74 - $ test_arrays nullable ../data/arrays/nullable_array.yml 75 - JSON: nullable_array: ERROR: Expected string but found null 76 - File "-", line 1, characters 21-22: 77 - File "-", line 1, characters 21-22: at index 1 of 78 - File "-", line 1, characters 11-22: array<string> 79 - File "-": in member values of 80 - File "-", line 1, characters 0-22: Nullable object 81 - YAML: nullable_array: ERROR: Expected string but found null 82 - File "-": 83 - at index 1 of 84 - File "-": array<string> 85 - File "-": in member values of 86 - File "-": Nullable object 87 - 88 - ================================================================================ 89 - ERROR HANDLING 90 - ================================================================================ 91 - 92 - Type mismatch in array element 93 - 94 - $ test_arrays type-mismatch ../data/arrays/type_mismatch.yml 95 - Expected error: String "not-a-number" does not parse to OCaml int value 96 - File "-": 97 - at index 2 of 98 - File "-": array<OCaml int> 99 - File "-": in member values of 100 - File "-": Numbers object 101 - 102 - ================================================================================ 103 - ENCODING ARRAYS 104 - ================================================================================ 105 - 106 - Encode arrays to JSON and YAML formats 107 - 108 - $ test_arrays encode 109 - JSON: {"numbers":[1,2,3,4,5],"strings":["hello","world"]} 110 - YAML Block: 111 - numbers: 112 - - 1 113 - - 2 114 - - 3 115 - - 4 116 - - 5 117 - strings: 118 - - hello 119 - - world 120 - YAML Flow: {numbers: [1, 2, 3, 4, 5], strings: [hello, world]} 121 - 122 - ================================================================================ 123 - NEGATIVE TESTS - Wrong File Types 124 - ================================================================================ 125 - 126 - Attempting to decode an object file with an array codec should fail 127 - 128 - $ test_arrays int ../data/objects/simple.yml 129 - JSON: int_array: ERROR: Missing member values in Numbers object 130 - File "-", line 1, characters 0-28: 131 - YAML: int_array: ERROR: Missing member values in Numbers object 132 - File "-": 133 - 134 - Attempting to decode a scalar file with an array codec should fail 135 - 136 - $ test_arrays string ../data/scalars/string_plain.yml 137 - JSON: string_array: ERROR: Missing member items in Tags object 138 - File "-", line 1, characters 0-24: 139 - YAML: string_array: ERROR: Missing member items in Tags object 140 - File "-": 141 - 142 - Attempting to decode int array with string array codec should fail 143 - 144 - $ test_arrays string ../data/arrays/int_array.yml 145 - JSON: string_array: ERROR: Missing member items in Tags object 146 - File "-", line 1, characters 0-27: 147 - YAML: string_array: ERROR: Missing member items in Tags object 148 - File "-":
-71
tests/cram/complex_codec.t
··· 1 - Complex Nested Types Tests with Yamlt 2 - ====================================== 3 - 4 - This test suite validates complex nested structures combining objects, arrays, 5 - and various levels of nesting. 6 - 7 - ================================================================================ 8 - DEEPLY NESTED OBJECTS 9 - ================================================================================ 10 - 11 - Handle deeply nested object structures 12 - 13 - $ test_complex deep-nesting ../data/complex/deep_nesting.yml 14 - JSON: deep_nesting: depth=4, value=42 15 - YAML: deep_nesting: depth=4, value=42 16 - 17 - ================================================================================ 18 - MIXED STRUCTURES 19 - ================================================================================ 20 - 21 - Arrays of objects containing arrays 22 - 23 - $ test_complex mixed-structure ../data/complex/mixed_structure.yml 24 - JSON: mixed_structure: name="products", items=3, total_tags=6 25 - YAML: mixed_structure: name="products", items=3, total_tags=6 26 - 27 - ================================================================================ 28 - COMPLEX OPTIONAL COMBINATIONS 29 - ================================================================================ 30 - 31 - Multiple optional fields with different combinations 32 - 33 - $ test_complex complex-optional ../data/complex/complex_optional.yml 34 - JSON: complex_optional: host="example.com", port=443, ssl=true, fallbacks=2 35 - YAML: complex_optional: host="example.com", port=443, ssl=true, fallbacks=2 36 - 37 - ================================================================================ 38 - HETEROGENEOUS DATA 39 - ================================================================================ 40 - 41 - Mixed types in arrays using any type 42 - 43 - $ test_complex heterogeneous ../data/complex/heterogeneous.yml 44 - JSON: heterogeneous: ERROR: Expected one of but found number 45 - File "-", line 1, characters 11-12: 46 - File "-", line 1, characters 11-12: at index 0 of 47 - File "-", line 1, characters 10-12: array<one of > 48 - File "-": in member mixed of 49 - File "-", line 1, characters 0-12: Data object 50 - YAML: heterogeneous: ERROR: Expected one of but found number 51 - File "-": 52 - at index 0 of 53 - File "-": array<one of > 54 - File "-": in member mixed of 55 - File "-": Data object 56 - 57 - ================================================================================ 58 - NEGATIVE TESTS - Structure Mismatch 59 - ================================================================================ 60 - 61 - Using deeply nested data with flat codec should fail 62 - 63 - $ test_complex mixed-structure ../data/complex/deep_nesting.yml 64 - JSON: mixed_structure: ERROR: Missing members in Collection object: 65 - items 66 - name 67 - File "-", line 1, characters 0-44: 68 - YAML: mixed_structure: ERROR: Missing members in Collection object: 69 - items 70 - name 71 - File "-":
-17
tests/cram/dune
··· 1 - (cram 2 - (deps 3 - (package yamlt) 4 - (glob_files ../data/scalars/*.yml) 5 - (glob_files ../data/scalars/*.json) 6 - (glob_files ../data/objects/*.yml) 7 - (glob_files ../data/objects/*.json) 8 - (glob_files ../data/arrays/*.yml) 9 - (glob_files ../data/arrays/*.json) 10 - (glob_files ../data/formats/*.yml) 11 - (glob_files ../data/formats/*.json) 12 - (glob_files ../data/complex/*.yml) 13 - (glob_files ../data/complex/*.json) 14 - (glob_files ../data/edge/*.yml) 15 - (glob_files ../data/edge/*.json) 16 - (glob_files ../data/multidoc/*.yml) 17 - (glob_files ../data/locations/*.yml)))
-85
tests/cram/edge_codec.t
··· 1 - Edge Cases Tests with Yamlt 2 - ============================ 3 - 4 - This test suite validates edge cases including large numbers, special characters, 5 - unicode, and boundary conditions. 6 - 7 - ================================================================================ 8 - LARGE NUMBERS 9 - ================================================================================ 10 - 11 - Very large and very small floating point numbers 12 - 13 - $ test_edge large-numbers ../data/edge/large_numbers.yml 14 - JSON: large_numbers: large_int=9007199254740991, large_float=1.797693e+308, small_float=2.225074e-308 15 - YAML: large_numbers: large_int=9007199254740991, large_float=1.797693e+308, small_float=2.225074e-308 16 - 17 - ================================================================================ 18 - SPECIAL CHARACTERS 19 - ================================================================================ 20 - 21 - Strings containing newlines, tabs, and other special characters 22 - 23 - $ test_edge special-chars ../data/edge/special_chars.yml 24 - JSON: special_chars: length=34, contains_newline=true, contains_tab=true 25 - YAML: special_chars: length=34, contains_newline=true, contains_tab=true 26 - 27 - ================================================================================ 28 - UNICODE STRINGS 29 - ================================================================================ 30 - 31 - Emoji, Chinese, and RTL text 32 - 33 - $ test_edge unicode ../data/edge/unicode.yml 34 - JSON: unicode: emoji="\240\159\142\137\240\159\154\128\226\156\168", chinese="\228\189\160\229\165\189\228\184\150\231\149\140", rtl="\217\133\216\177\216\173\216\168\216\167" 35 - YAML: unicode: emoji="\240\159\142\137\240\159\154\128\226\156\168", chinese="\228\189\160\229\165\189\228\184\150\231\149\140", rtl="\217\133\216\177\216\173\216\168\216\167" 36 - 37 - ================================================================================ 38 - EMPTY COLLECTIONS 39 - ================================================================================ 40 - 41 - Empty arrays and objects 42 - 43 - $ test_edge empty-collections ../data/edge/empty_collections.yml 44 - JSON: empty_collections: empty_array_len=0, empty_object_array_len=0 45 - YAML: empty_collections: empty_array_len=0, empty_object_array_len=0 46 - 47 - ================================================================================ 48 - SPECIAL KEY NAMES 49 - ================================================================================ 50 - 51 - Keys with dots, dashes, colons 52 - 53 - $ test_edge special-keys ../data/edge/special_keys.yml 54 - JSON: special_keys: ERROR: Expected one of but found object 55 - File "-", line 1, characters 0-1: 56 - YAML: special_keys: ERROR: Expected one of but found object 57 - File "-": 58 - 59 - ================================================================================ 60 - SINGLE-ELEMENT ARRAYS 61 - ================================================================================ 62 - 63 - Arrays with exactly one element 64 - 65 - $ test_edge single-element ../data/edge/single_element.yml 66 - JSON: single_element: length=1, value=42 67 - YAML: single_element: length=1, value=42 68 - 69 - ================================================================================ 70 - NEGATIVE TESTS - Boundary Violations 71 - ================================================================================ 72 - 73 - Using unicode data with number codec should fail 74 - 75 - $ test_edge large-numbers ../data/edge/unicode.yml 76 - JSON: large_numbers: ERROR: Missing members in Numbers object: 77 - large_float 78 - large_int 79 - small_float 80 - File "-", line 1, characters 0-72: 81 - YAML: large_numbers: ERROR: Missing members in Numbers object: 82 - large_float 83 - large_int 84 - small_float 85 - File "-":
-107
tests/cram/formats_codec.t
··· 1 - Format-Specific Features Tests with Yamlt 2 - ========================================== 3 - 4 - This test suite validates YAML-specific format features and compares with JSON behavior. 5 - 6 - ================================================================================ 7 - MULTI-LINE STRINGS - LITERAL STYLE 8 - ================================================================================ 9 - 10 - Literal style (|) preserves newlines 11 - 12 - $ test_formats literal ../data/formats/literal_string.yml 13 - JSON: literal_string: lines=5, length=81 14 - YAML: literal_string: lines=5, length=81 15 - 16 - ================================================================================ 17 - MULTI-LINE STRINGS - FOLDED STYLE 18 - ================================================================================ 19 - 20 - Folded style (>) folds lines into single line 21 - 22 - $ test_formats folded ../data/formats/folded_string.yml 23 - JSON: folded_string: length=114, newlines=1 24 - YAML: folded_string: length=114, newlines=1 25 - 26 - ================================================================================ 27 - NUMBER FORMATS 28 - ================================================================================ 29 - 30 - YAML supports hex, octal, and binary number formats 31 - 32 - $ test_formats number-formats ../data/formats/number_formats.yml 33 - JSON: number_formats: hex=255, octal=63, binary=10 34 - YAML: number_formats: hex=255, octal=63, binary=10 35 - 36 - ================================================================================ 37 - COMMENTS 38 - ================================================================================ 39 - 40 - YAML comments are ignored during parsing 41 - 42 - $ test_formats comments ../data/formats/comments.yml 43 - YAML (with comments): host="localhost", port=8080, debug=true 44 - 45 - ================================================================================ 46 - EMPTY DOCUMENTS 47 - ================================================================================ 48 - 49 - Empty or null documents handled correctly 50 - 51 - $ test_formats empty-doc ../data/formats/empty_doc.yml 52 - JSON: empty_document: ERROR: Expected string but found null 53 - File "-", line 1, characters 10-11: 54 - File "-": in member value of 55 - File "-", line 1, characters 0-11: Wrapper object 56 - YAML: empty_document: ERROR: Expected string but found null 57 - File "-": 58 - File "-": in member value of 59 - File "-": Wrapper object 60 - 61 - ================================================================================ 62 - EXPLICIT TYPE TAGS 63 - ================================================================================ 64 - 65 - Explicit YAML type tags (!!str, !!int, etc.) 66 - 67 - $ test_formats explicit-tags ../data/formats/explicit_tags.yml 68 - YAML (with tags): data="123" 69 - 70 - ================================================================================ 71 - ENCODING STYLES 72 - ================================================================================ 73 - 74 - Compare Block vs Flow encoding styles 75 - 76 - $ test_formats encode-styles 77 - YAML Block: 78 - name: test 79 - values: 80 - - 1 81 - - 2 82 - - 3 83 - nested: 84 - enabled: true 85 - count: 5 86 - 87 - YAML Flow: 88 - {name: test, values: [1, 2, 3], nested: {enabled: true, count: 5}} 89 - 90 - 91 - ================================================================================ 92 - NEGATIVE TESTS - Format Compatibility 93 - ================================================================================ 94 - 95 - Using literal string test with number codec should fail 96 - 97 - $ test_formats number-formats ../data/formats/literal_string.yml 98 - JSON: number_formats: ERROR: Missing members in Numbers object: 99 - binary 100 - hex 101 - octal 102 - File "-", line 1, characters 0-100: 103 - YAML: number_formats: ERROR: Missing members in Numbers object: 104 - binary 105 - hex 106 - octal 107 - File "-":
-217
tests/cram/locations.t
··· 1 - Location and Layout Preservation Tests with Yamlt 2 - ================================================== 3 - 4 - This test suite validates the `locs` and `layout` options in the Yamlt decoder, 5 - demonstrating how they affect error messages and metadata preservation. 6 - 7 - ================================================================================ 8 - ERROR MESSAGE PRECISION - locs option 9 - ================================================================================ 10 - 11 - The `locs` option controls whether source locations are preserved in error messages. 12 - When `locs=false` (default), errors show basic location info. 13 - When `locs=true`, errors show precise character positions. 14 - 15 - Basic type error with and without locs 16 - 17 - $ test_locations error-precision ../data/locations/type_error.yml 18 - === Without locs (default) === 19 - Error message: 20 - String "not-a-number" does not parse to OCaml int value 21 - File "-": 22 - File "-": in member age of 23 - File "-": Person object 24 - 25 - === With locs=true === 26 - Error message: 27 - String "not-a-number" does not parse to OCaml int value 28 - File "-", line 2, characters 5-18: 29 - File "-", line 2, characters 0-3: in member age of 30 - File "-", line 1, characters 0-1: Person object 31 - 32 - ================================================================================ 33 - NESTED ERROR LOCATIONS 34 - ================================================================================ 35 - 36 - The `locs` option is especially useful for nested structures, 37 - showing exactly where deep errors occur. 38 - 39 - Error in nested object field 40 - 41 - $ test_locations nested-error ../data/locations/nested_error.yml 42 - === Without locs (default) === 43 - Nested error: 44 - String "invalid-zip" does not parse to OCaml int value 45 - File "-": 46 - File "-": in member zip of 47 - File "-": Address object 48 - File "-": in member address of 49 - File "-": Employee object 50 - 51 - === With locs=true === 52 - Nested error: 53 - String "invalid-zip" does not parse to OCaml int value 54 - File "-", line 5, characters 7-19: 55 - File "-", line 5, characters 2-5: in member zip of 56 - File "-", line 3, characters 2-3: Address object 57 - File "-", line 2, characters 0-7: in member address of 58 - File "-", line 1, characters 0-1: Employee object 59 - 60 - ================================================================================ 61 - ARRAY ELEMENT ERROR LOCATIONS 62 - ================================================================================ 63 - 64 - The `locs` option pinpoints which array element caused an error. 65 - 66 - Error at specific array index 67 - 68 - $ test_locations array-error ../data/locations/array_error.yml 69 - === Without locs (default) === 70 - Array error: 71 - String "not-a-number" does not parse to OCaml int value 72 - File "-": 73 - at index 2 of 74 - File "-": array<OCaml int> 75 - File "-": in member values of 76 - File "-": Numbers object 77 - 78 - === With locs=true === 79 - Array error: 80 - String "not-a-number" does not parse to OCaml int value 81 - File "-", lines 4-5, characters 4-2: 82 - at index 2 of 83 - File "-", line 2, characters 2-3: array<OCaml int> 84 - File "-", line 1, characters 0-6: in member values of 85 - File "-", line 1, characters 0-1: Numbers object 86 - 87 - ================================================================================ 88 - FILE PATH IN ERROR MESSAGES 89 - ================================================================================ 90 - 91 - The `file` parameter sets the file path shown in error messages. 92 - 93 - $ test_locations file-path 94 - === Without file path === 95 - Error: 96 - String "not-a-number" does not parse to OCaml int value 97 - File "-", line 2, characters 5-18: 98 - File "-", line 2, characters 0-3: in member age of 99 - File "-", line 1, characters 0-1: Person object 100 - 101 - === With file path === 102 - Error: 103 - String "not-a-number" does not parse to OCaml int value 104 - File "test.yml", line 2, characters 5-18: 105 - File "test.yml", line 2, characters 0-3: in member age of 106 - File "test.yml", line 1, characters 0-1: Person object 107 - 108 - ================================================================================ 109 - MISSING FIELD ERROR LOCATIONS 110 - ================================================================================ 111 - 112 - The `locs` option helps identify where fields are missing. 113 - 114 - $ test_locations missing-field ../data/locations/missing_field.yml 115 - === Without locs === 116 - Missing field: 117 - Missing member field_c in Complete object 118 - File "-": 119 - 120 - === With locs=true === 121 - Missing field: 122 - Missing member field_c in Complete object 123 - File "-", line 1, characters 0-1: 124 - 125 - ================================================================================ 126 - LAYOUT PRESERVATION - layout option 127 - ================================================================================ 128 - 129 - The `layout` option controls whether style information (block vs flow) 130 - is preserved in metadata for potential round-tripping. 131 - 132 - Basic layout preservation 133 - 134 - $ test_locations layout ../data/locations/simple.yml 135 - === Without layout (default) === 136 - Decoded: host=localhost, port=8080 137 - Meta preserved: no 138 - 139 - === With layout=true === 140 - Decoded: host=localhost, port=8080 141 - Meta preserved: yes (style info available for round-tripping) 142 - 143 - ================================================================================ 144 - ROUND-TRIPPING WITH LAYOUT 145 - ================================================================================ 146 - 147 - With `layout=true` during decode and `format:Layout` during encode, 148 - the original YAML style can be preserved. 149 - 150 - Flow style preservation 151 - 152 - $ test_locations roundtrip ../data/locations/flow_style.yml 153 - === Original YAML === 154 - items: [apple, banana, cherry] 155 - 156 - === Decode without layout, re-encode === 157 - items: 158 - - apple 159 - - banana 160 - - cherry 161 - 162 - === Decode with layout=true, re-encode with Layout format === 163 - items: 164 - - apple 165 - - banana 166 - - cherry 167 - 168 - Block style preservation 169 - 170 - $ test_locations roundtrip ../data/locations/block_style.yml 171 - === Original YAML === 172 - items: 173 - - apple 174 - - banana 175 - - cherry 176 - 177 - === Decode without layout, re-encode === 178 - items: 179 - - apple 180 - - banana 181 - - cherry 182 - 183 - === Decode with layout=true, re-encode with Layout format === 184 - items: 185 - - apple 186 - - banana 187 - - cherry 188 - 189 - ================================================================================ 190 - COMBINED OPTIONS - locs and layout together 191 - ================================================================================ 192 - 193 - Both options can be used simultaneously for maximum information. 194 - 195 - $ test_locations combined ../data/locations/valid_settings.yml 196 - === locs=false, layout=false (defaults) === 197 - OK: timeout=30, retries=3 198 - 199 - === locs=true, layout=false === 200 - OK: timeout=30, retries=3 (with precise locations) 201 - 202 - === locs=false, layout=true === 203 - OK: timeout=30, retries=3 (with layout metadata) 204 - 205 - === locs=true, layout=true (both enabled) === 206 - OK: timeout=30, retries=3 (with locations and layout) 207 - 208 - ================================================================================ 209 - SUMMARY OF OPTIONS 210 - ================================================================================ 211 - 212 - locs option: 213 - 214 - layout option: 215 - 216 - Both options add metadata overhead, so only enable when needed. 217 - For production parsing where you only need the data, use defaults (both false).
-220
tests/cram/multidoc.t
··· 1 - Multi-Document YAML Streams with Yamlt 2 - ======================================== 3 - 4 - This test suite validates multi-document YAML stream decoding using decode_all, 5 - including error handling, location tracking, and JSON roundtripping. 6 - 7 - ================================================================================ 8 - BASIC MULTIDOC DECODING 9 - ================================================================================ 10 - 11 - Simple multi-document stream with person objects 12 - 13 - $ test_multidoc simple ../data/multidoc/simple.yml 14 - Documents: 15 - [0] : Alice (age 30) 16 - [1] : Bob (age 25) 17 - [2] : Charlie (age 35) 18 - 19 - Count documents in a stream 20 - 21 - $ test_multidoc count ../data/multidoc/simple.yml 22 - Document count: 3 23 - 24 - ================================================================================ 25 - ERROR HANDLING - MIXED VALID AND INVALID DOCUMENTS 26 - ================================================================================ 27 - 28 - When some documents succeed and others fail, decode_all continues processing 29 - and returns results for each document individually. 30 - 31 - Stream with one error in the middle 32 - 33 - $ test_multidoc errors ../data/multidoc/mixed_errors.yml 34 - Document results: 35 - [0] OK: Alice (age 30) 36 - [1] ERROR: String "not-a-number" does not parse to OCaml int value 37 - File "-": 38 - File "-": in member age of 39 - File "-": Person object 40 - [2] OK: Charlie (age 35) 41 - 42 - Summary statistics for mixed documents 43 - 44 - $ test_multidoc summary ../data/multidoc/mixed_errors.yml 45 - Summary: 3 documents (2 ok, 1 error) 46 - 47 - Stream where all documents fail 48 - 49 - $ test_multidoc errors ../data/multidoc/all_errors.yml 50 - Document results: 51 - [0] ERROR: String "invalid1" does not parse to OCaml int value 52 - File "-": 53 - File "-": in member age of 54 - File "-": Person object 55 - [1] ERROR: String "invalid2" does not parse to OCaml int value 56 - File "-": 57 - File "-": in member age of 58 - File "-": Person object 59 - [2] ERROR: String "invalid3" does not parse to OCaml int value 60 - File "-": 61 - File "-": in member age of 62 - File "-": Person object 63 - 64 - Summary for all-error stream 65 - 66 - $ test_multidoc summary ../data/multidoc/all_errors.yml 67 - Summary: 3 documents (0 ok, 3 error) 68 - 69 - ================================================================================ 70 - LOCATION TRACKING WITH locs=true 71 - ================================================================================ 72 - 73 - Location tracking helps identify exactly where errors occur in each document 74 - of a multi-document stream. 75 - 76 - Without locs (default) - basic error information 77 - 78 - $ test_multidoc locations ../data/multidoc/mixed_errors.yml 79 - === Without locs (default) === 80 - [0] OK 81 - [1] ERROR: 82 - String "not-a-number" does not parse to OCaml int value 83 - File "-": 84 - File "-": in member age of 85 - File "-": Person object 86 - [2] OK 87 - 88 - === With locs=true === 89 - [0] OK 90 - [1] ERROR: 91 - String "not-a-number" does not parse to OCaml int value 92 - File "test.yml", line 6, characters 5-18: 93 - File "test.yml", line 6, characters 0-3: in member age of 94 - File "test.yml", line 5, characters 0-1: Person object 95 - [2] OK 96 - 97 - ================================================================================ 98 - MISSING FIELDS IN MULTIDOC 99 - ================================================================================ 100 - 101 - Documents with missing required fields generate errors but don't stop 102 - processing of subsequent documents. 103 - 104 - $ test_multidoc errors ../data/multidoc/missing_fields.yml 105 - Document results: 106 - [0] OK: Alice (age 30) 107 - [1] ERROR: Missing member age in Person object 108 - File "-": 109 - [2] OK: Charlie (age 35) 110 - 111 - Summary of missing fields test 112 - 113 - $ test_multidoc summary ../data/multidoc/missing_fields.yml 114 - Summary: 3 documents (2 ok, 1 error) 115 - 116 - ================================================================================ 117 - JSON ROUNDTRIPPING 118 - ================================================================================ 119 - 120 - Decode YAML multi-document streams and encode each document as JSON. 121 - This validates that the data model conversion is correct. 122 - 123 - Simple documents to JSON 124 - 125 - $ test_multidoc json ../data/multidoc/simple.yml 126 - JSON outputs: 127 - [0] {"name":"Alice","age":30} 128 - [1] {"name":"Bob","age":25} 129 - [2] {"name":"Charlie","age":35} 130 - 131 - Nested objects to JSON 132 - 133 - $ test_multidoc json ../data/multidoc/nested.yml 134 - JSON outputs: 135 - [0] {"name":"Alice","age":30,"address":{"street":"123 Main St","city":"Boston"}} 136 - [1] {"name":"Bob","age":25,"address":{"street":"456 Oak Ave","city":"Seattle"}} 137 - [2] {"name":"Charlie","age":35,"address":{"street":"789 Pine Rd","city":"Portland"}} 138 - 139 - Arrays to JSON 140 - 141 - $ test_multidoc json ../data/multidoc/arrays.yml 142 - JSON outputs: 143 - [0] [1,2,3] 144 - [1] ["apple","banana","cherry"] 145 - [2] [true,false,true] 146 - 147 - Scalar values to JSON 148 - 149 - $ test_multidoc json ../data/multidoc/scalars.yml 150 - JSON outputs: 151 - [0] "hello world" 152 - [1] 42 153 - [2] true 154 - [3] null 155 - 156 - ================================================================================ 157 - NESTED OBJECTS IN MULTIDOC 158 - ================================================================================ 159 - 160 - Test decoding complex nested structures across multiple documents. 161 - 162 - $ test_multidoc nested ../data/multidoc/nested.yml 163 - Nested documents: 164 - [0] : Alice (age 30) from 123 Main St, Boston 165 - [1] : Bob (age 25) from 456 Oak Ave, Seattle 166 - [2] : Charlie (age 35) from 789 Pine Rd, Portland 167 - 168 - ================================================================================ 169 - ARRAYS IN MULTIDOC 170 - ================================================================================ 171 - 172 - Test decoding different array types across documents. 173 - 174 - $ test_multidoc arrays ../data/multidoc/arrays.yml 175 - Array documents: 176 - [0] [1,2,3] 177 - [1] ["apple","banana","cherry"] 178 - [2] [true,false,true] 179 - 180 - ================================================================================ 181 - SCALARS IN MULTIDOC 182 - ================================================================================ 183 - 184 - Test decoding bare scalar values as documents. 185 - 186 - $ test_multidoc scalars ../data/multidoc/scalars.yml 187 - Scalar documents: 188 - [0] "hello world" 189 - [1] 42 190 - [2] true 191 - [3] null 192 - 193 - ================================================================================ 194 - EMPTY DOCUMENTS 195 - ================================================================================ 196 - 197 - Empty or null documents in a stream are handled correctly. 198 - 199 - $ test_multidoc json ../data/multidoc/empty_docs.yml 200 - JSON outputs: 201 - [0] {"name":"Alice","age":30} 202 - [1] null 203 - [2] {"name":"Charlie","age":35} 204 - 205 - Count including empty documents 206 - 207 - $ test_multidoc count ../data/multidoc/empty_docs.yml 208 - Document count: 3 209 - 210 - ================================================================================ 211 - SUMMARY 212 - ================================================================================ 213 - 214 - The decode_all function: 215 - - Processes all documents in a stream, not stopping on errors 216 - - Returns a sequence of Result values (Ok/Error for each document) 217 - - Supports all decode options: locs, layout, file, max_depth, max_nodes 218 - - Correctly handles document boundaries even when errors occur 219 - - Works with any Jsont codec (objects, arrays, scalars, etc.) 220 - - Can be used for JSON roundtripping and format conversion
-37
tests/cram/null_collections.t
··· 1 - Null to Empty Collection Tests 2 - ================================ 3 - 4 - This test suite validates that yamlt treats null values as empty collections 5 - when decoding into Array or Object types, providing a more user-friendly 6 - YAML experience. 7 - 8 - ================================================================================ 9 - NULL AS EMPTY COLLECTION 10 - ================================================================================ 11 - 12 - Test various forms of null decoding as empty arrays and objects 13 - 14 - $ test_null_collections 15 - === Test 1: Explicit null as empty array === 16 - Result: [] 17 - 18 - === Test 2: Tilde as empty array === 19 - Result: [] 20 - 21 - === Test 3: Empty array syntax === 22 - Result: [] 23 - 24 - === Test 4: Array with values === 25 - Result: [1; 2; 3] 26 - 27 - === Test 5: Explicit null as empty object === 28 - Result: {timeout=30; retries=3} 29 - 30 - === Test 6: Empty object syntax === 31 - Result: {timeout=30; retries=3} 32 - 33 - === Test 7: Object with values === 34 - Result: {timeout=60; retries=5} 35 - 36 - === Test 8: Nested null arrays === 37 - Result: {name=test; items_count=0; tags_count=0}
-171
tests/cram/objects_codec.t
··· 1 - Object Codec Tests with Yamlt 2 - ================================ 3 - 4 - This test suite validates object encoding/decoding with Jsont codecs in YAML, 5 - and compares behavior with JSON. 6 - 7 - Setup 8 - ----- 9 - 10 - 11 - ================================================================================ 12 - SIMPLE OBJECTS 13 - ================================================================================ 14 - 15 - Decode simple object with required fields 16 - 17 - $ test_objects simple ../data/objects/simple.yml 18 - JSON: person: {name="Alice"; age=30} 19 - YAML: person: {name="Alice"; age=30} 20 - 21 - ================================================================================ 22 - OPTIONAL FIELDS 23 - ================================================================================ 24 - 25 - Object with all optional fields present 26 - 27 - $ test_objects optional ../data/objects/optional_all.yml 28 - JSON: config: {host="localhost"; port=Some 8080; debug=Some true} 29 - YAML: config: {host="localhost"; port=Some 8080; debug=Some true} 30 - 31 - Object with some optional fields missing 32 - 33 - $ test_objects optional ../data/objects/optional_partial.yml 34 - JSON: config: {host="example.com"; port=Some 3000; debug=None} 35 - YAML: config: {host="example.com"; port=Some 3000; debug=None} 36 - 37 - Object with only required field 38 - 39 - $ test_objects optional ../data/objects/optional_minimal.yml 40 - JSON: config: {host="minimal.com"; port=None; debug=None} 41 - YAML: config: {host="minimal.com"; port=None; debug=None} 42 - 43 - ================================================================================ 44 - DEFAULT VALUES 45 - ================================================================================ 46 - 47 - Empty object uses all defaults 48 - 49 - $ test_objects defaults ../data/objects/defaults_empty.yml 50 - JSON: settings: {timeout=30; retries=3; verbose=false} 51 - YAML: settings: {timeout=30; retries=3; verbose=false} 52 - 53 - Object with partial fields uses defaults for missing ones 54 - 55 - $ test_objects defaults ../data/objects/defaults_partial.yml 56 - JSON: settings: {timeout=60; retries=3; verbose=false} 57 - YAML: settings: {timeout=60; retries=3; verbose=false} 58 - 59 - ================================================================================ 60 - NESTED OBJECTS 61 - ================================================================================ 62 - 63 - Objects containing other objects 64 - 65 - $ test_objects nested ../data/objects/nested.yml 66 - JSON: employee: {name="Bob"; address={street="123 Main St"; city="Springfield"; zip="12345"}} 67 - YAML: employee: {name="Bob"; address={street="123 Main St"; city="Springfield"; zip="12345"}} 68 - 69 - ================================================================================ 70 - UNKNOWN MEMBER HANDLING 71 - ================================================================================ 72 - 73 - Unknown members cause error by default 74 - 75 - $ test_objects unknown-error ../data/objects/unknown_members.yml 76 - Unexpected success 77 - 78 - Unknown members can be kept 79 - 80 - $ test_objects unknown-keep ../data/objects/unknown_keep.yml 81 - JSON: flexible: {name="Charlie"; has_extra=true} 82 - YAML: flexible: {name="Charlie"; has_extra=true} 83 - 84 - Unknown members are preserved during encoding roundtrip 85 - 86 - $ test_objects unknown-keep-roundtrip ../data/objects/unknown_keep.yml 87 - Decoded: name="Charlie", extra={"extra1":"value1","extra2":"value2"} 88 - Encoded Block: 89 - name: Charlie 90 - extra1: value1 91 - extra2: value2 92 - Re-decoded: name="Charlie", extra={"extra1":"value1","extra2":"value2"} 93 - Roundtrip: OK (extra members preserved) 94 - 95 - ================================================================================ 96 - OBJECT CASES (DISCRIMINATED UNIONS) 97 - ================================================================================ 98 - 99 - Decode circle variant 100 - 101 - $ test_objects cases ../data/objects/case_circle.yml 102 - JSON: shape: Circle{radius=5.50} 103 - YAML: shape: Circle{radius=5.50} 104 - 105 - Decode rectangle variant 106 - 107 - $ test_objects cases ../data/objects/case_rectangle.yml 108 - JSON: shape: ERROR: Missing member radius in Circle object 109 - File "-", line 1, characters 0-52: 110 - YAML: shape: ERROR: Missing member radius in Circle object 111 - File "-": 112 - 113 - ================================================================================ 114 - ERROR HANDLING 115 - ================================================================================ 116 - 117 - Missing required field produces error 118 - 119 - $ test_objects missing-required ../data/objects/missing_required.yml 120 - Expected error: Missing member age in Required object 121 - File "-": 122 - 123 - ================================================================================ 124 - ENCODING OBJECTS 125 - ================================================================================ 126 - 127 - Encode objects to JSON and YAML formats 128 - 129 - $ test_objects encode 130 - JSON: {"name":"Alice","age":30,"active":true} 131 - YAML Block: 132 - name: Alice 133 - age: 30 134 - active: true 135 - YAML Flow: {name: Alice, age: 30, active: true} 136 - 137 - ================================================================================ 138 - NEGATIVE TESTS - Wrong File Types 139 - ================================================================================ 140 - 141 - Attempting to decode an array file with an object codec should fail 142 - 143 - $ test_objects simple ../data/arrays/int_array.yml 144 - JSON: person: ERROR: Missing members in Person object: 145 - age 146 - name 147 - File "-", line 1, characters 0-27: 148 - YAML: person: ERROR: Missing members in Person object: 149 - age 150 - name 151 - File "-": 152 - 153 - Attempting to decode a scalar file with an object codec should fail 154 - 155 - $ test_objects simple ../data/scalars/string_plain.yml 156 - JSON: person: ERROR: Missing members in Person object: 157 - age 158 - name 159 - File "-", line 1, characters 0-24: 160 - YAML: person: ERROR: Missing members in Person object: 161 - age 162 - name 163 - File "-": 164 - 165 - Attempting to decode wrong object type (nested when expecting simple) should fail 166 - 167 - $ test_objects simple ../data/objects/nested.yml 168 - JSON: person: ERROR: Missing member age in Person object 169 - File "-", line 1, characters 0-92: 170 - YAML: person: ERROR: Missing member age in Person object 171 - File "-":
-46
tests/cram/roundtrip_codec.t
··· 1 - Roundtrip Encoding/Decoding Tests with Yamlt 2 - ============================================= 3 - 4 - This test suite validates that data can be encoded and then decoded back 5 - to the original value, ensuring no data loss in the roundtrip process. 6 - 7 - ================================================================================ 8 - SCALAR ROUNDTRIP 9 - ================================================================================ 10 - 11 - Encode and decode scalar types 12 - 13 - $ test_roundtrip scalar 14 - JSON roundtrip: PASS 15 - YAML Block roundtrip: PASS 16 - YAML Flow roundtrip: PASS 17 - 18 - ================================================================================ 19 - ARRAY ROUNDTRIP 20 - ================================================================================ 21 - 22 - Encode and decode arrays including nested arrays 23 - 24 - $ test_roundtrip array 25 - JSON array roundtrip: PASS 26 - YAML array roundtrip: PASS 27 - 28 - ================================================================================ 29 - OBJECT ROUNDTRIP 30 - ================================================================================ 31 - 32 - Encode and decode complex objects with nested structures 33 - 34 - $ test_roundtrip object 35 - JSON object roundtrip: PASS 36 - YAML object roundtrip: PASS 37 - 38 - ================================================================================ 39 - OPTIONAL FIELDS ROUNDTRIP 40 - ================================================================================ 41 - 42 - Encode and decode optional and nullable fields 43 - 44 - $ test_roundtrip optional 45 - Fatal error: exception Invalid_argument("option is None") 46 - [2]
-339
tests/cram/scalars_codec.t
··· 1 - Scalar Type Resolution Tests with Yamlt Codec 2 - ================================================== 3 - 4 - This test suite validates how YAML scalars are resolved based on the expected 5 - Jsont type codec, and compares behavior with JSON decoding. 6 - 7 - ================================================================================ 8 - NULL RESOLUTION 9 - ================================================================================ 10 - 11 - Explicit null value 12 - 13 - $ test_scalars null ../data/scalars/null_explicit.yml 14 - null_codec: null 15 - 16 - Tilde as null 17 - 18 - $ test_scalars null ../data/scalars/null_tilde.yml 19 - null_codec: null 20 - 21 - Empty value as null 22 - 23 - $ test_scalars null ../data/scalars/null_empty.yml 24 - null_codec: null 25 - 26 - ================================================================================ 27 - BOOLEAN TYPE-DIRECTED RESOLUTION 28 - ================================================================================ 29 - 30 - Plain "true" resolves to bool(true) with bool codec, but string "true" with string codec 31 - 32 - $ test_scalars bool ../data/scalars/bool_true_plain.yml 33 - === Bool Codec === 34 - JSON bool_codec 35 - decode: true 36 - YAML bool_codec 37 - decode: true 38 - 39 - === String Codec === 40 - JSON string_codec 41 - decode: ERROR: Expected string but found bool 42 - File "-", line 1, characters 10-11: 43 - File "-": in member value of 44 - File "-", line 1, characters 0-11: StringTest object 45 - YAML string_codec 46 - decode: "true" 47 - 48 - Quoted "true" always resolves to string, even with bool codec 49 - 50 - $ test_scalars bool ../data/scalars/bool_true_quoted.yml 51 - === Bool Codec === 52 - JSON bool_codec 53 - decode: ERROR: Expected bool but found string 54 - File "-", line 1, characters 10-11: 55 - File "-": in member value of 56 - File "-", line 1, characters 0-11: BoolTest object 57 - YAML bool_codec 58 - decode: true 59 - 60 - === String Codec === 61 - JSON string_codec 62 - decode: "true" 63 - YAML string_codec 64 - decode: "true" 65 - 66 - YAML-specific bool: "yes" resolves to bool(true) 67 - 68 - $ test_scalars bool ../data/scalars/bool_yes.yml 69 - === Bool Codec === 70 - JSON bool_codec 71 - decode: true 72 - YAML bool_codec 73 - decode: true 74 - 75 - === String Codec === 76 - JSON string_codec 77 - decode: ERROR: Expected string but found bool 78 - File "-", line 1, characters 10-11: 79 - File "-": in member value of 80 - File "-", line 1, characters 0-11: StringTest object 81 - YAML string_codec 82 - decode: "yes" 83 - 84 - Plain "false" and "no" work similarly 85 - 86 - $ test_scalars bool ../data/scalars/bool_false.yml 87 - === Bool Codec === 88 - JSON bool_codec 89 - decode: false 90 - YAML bool_codec 91 - decode: false 92 - 93 - === String Codec === 94 - JSON string_codec 95 - decode: ERROR: Expected string but found bool 96 - File "-", line 1, characters 10-11: 97 - File "-": in member value of 98 - File "-", line 1, characters 0-11: StringTest object 99 - YAML string_codec 100 - decode: "false" 101 - 102 - $ test_scalars bool ../data/scalars/bool_no.yml 103 - === Bool Codec === 104 - JSON bool_codec 105 - decode: false 106 - YAML bool_codec 107 - decode: false 108 - 109 - === String Codec === 110 - JSON string_codec 111 - decode: ERROR: Expected string but found bool 112 - File "-", line 1, characters 10-11: 113 - File "-": in member value of 114 - File "-", line 1, characters 0-11: StringTest object 115 - YAML string_codec 116 - decode: "no" 117 - 118 - ================================================================================ 119 - NUMBER RESOLUTION 120 - ================================================================================ 121 - 122 - Integer values 123 - 124 - $ test_scalars number ../data/scalars/number_int.yml 125 - JSON number_codec 126 - decode: 42 127 - YAML number_codec 128 - decode: 42 129 - 130 - Float values 131 - 132 - $ test_scalars number ../data/scalars/number_float.yml 133 - JSON number_codec 134 - decode: 3.1415899999999999 135 - YAML number_codec 136 - decode: 3.1415899999999999 137 - 138 - Hexadecimal notation (YAML-specific) 139 - 140 - $ test_scalars number ../data/scalars/number_hex.yml 141 - JSON number_codec 142 - decode: 42 143 - YAML number_codec 144 - decode: 42 145 - 146 - Octal notation (YAML-specific) 147 - 148 - $ test_scalars number ../data/scalars/number_octal.yml 149 - JSON number_codec 150 - decode: 42 151 - YAML number_codec 152 - decode: 42 153 - 154 - Negative numbers 155 - 156 - $ test_scalars number ../data/scalars/number_negative.yml 157 - JSON number_codec 158 - decode: -273.14999999999998 159 - YAML number_codec 160 - decode: -273.14999999999998 161 - 162 - ================================================================================ 163 - SPECIAL FLOAT VALUES (YAML-specific) 164 - ================================================================================ 165 - 166 - Positive infinity 167 - 168 - $ test_scalars special-float ../data/scalars/special_inf.yml 169 - value: +Infinity 170 - 171 - Negative infinity 172 - 173 - $ test_scalars special-float ../data/scalars/special_neg_inf.yml 174 - value: -Infinity 175 - 176 - Not-a-Number (NaN) 177 - 178 - $ test_scalars special-float ../data/scalars/special_nan.yml 179 - value: NaN 180 - 181 - ================================================================================ 182 - STRING RESOLUTION 183 - ================================================================================ 184 - 185 - Plain strings 186 - 187 - $ test_scalars string ../data/scalars/string_plain.yml 188 - JSON string_codec 189 - decode: "hello world" 190 - YAML string_codec 191 - decode: "hello world" 192 - 193 - Quoted numeric strings stay as strings 194 - 195 - $ test_scalars string ../data/scalars/string_quoted.yml 196 - JSON string_codec 197 - decode: "42" 198 - YAML string_codec 199 - decode: "42" 200 - 201 - Empty strings 202 - 203 - $ test_scalars string ../data/scalars/string_empty.yml 204 - JSON string_codec 205 - decode: "" 206 - YAML string_codec 207 - decode: "" 208 - 209 - ================================================================================ 210 - TYPE MISMATCH ERRORS 211 - ================================================================================ 212 - 213 - String when bool expected 214 - 215 - $ test_scalars type-mismatch ../data/scalars/mismatch_string_as_bool.yml bool 216 - Expected error: Expected bool but found scalar hello 217 - File "-": 218 - File "-": in member value of 219 - File "-": BoolTest object 220 - 221 - String when number expected 222 - 223 - $ test_scalars type-mismatch ../data/scalars/mismatch_string_as_number.yml number 224 - Expected error: Expected number but found scalar not-a-number 225 - File "-": 226 - File "-": in member value of 227 - File "-": NumberTest object 228 - 229 - Number when null expected 230 - 231 - $ test_scalars type-mismatch ../data/scalars/mismatch_number_as_null.yml null 232 - Expected error: Expected null but found scalar 42 233 - File "-": 234 - File "-": in member value of 235 - File "-": NullTest object 236 - 237 - ================================================================================ 238 - JSONT.ANY AUTO-RESOLUTION 239 - ================================================================================ 240 - 241 - With Jsont.any, scalars are auto-resolved based on their content 242 - 243 - Null auto-resolves to null 244 - 245 - $ test_scalars any ../data/scalars/any_null.yml 246 - JSON any_codec 247 - decode: decoded 248 - YAML any_codec 249 - decode: decoded 250 - 251 - Plain bool auto-resolves to bool 252 - 253 - $ test_scalars any ../data/scalars/any_bool.yml 254 - JSON any_codec 255 - decode: decoded 256 - YAML any_codec 257 - decode: decoded 258 - 259 - Number auto-resolves to number 260 - 261 - $ test_scalars any ../data/scalars/any_number.yml 262 - JSON any_codec 263 - decode: decoded 264 - YAML any_codec 265 - decode: decoded 266 - 267 - Plain string auto-resolves to string 268 - 269 - $ test_scalars any ../data/scalars/any_string.yml 270 - JSON any_codec 271 - decode: decoded 272 - YAML any_codec 273 - decode: decoded 274 - 275 - ================================================================================ 276 - ENCODING SCALARS 277 - ================================================================================ 278 - 279 - Encoding bool values 280 - 281 - $ test_scalars encode bool true 282 - JSON: {"value":true} 283 - YAML Block: 284 - value: true 285 - YAML Flow: {value: true} 286 - 287 - $ test_scalars encode bool false 288 - JSON: {"value":false} 289 - YAML Block: 290 - value: false 291 - YAML Flow: {value: false} 292 - 293 - Encoding numbers 294 - 295 - $ test_scalars encode number 42.5 296 - JSON: {"value":42.5} 297 - YAML Block: 298 - value: 42.5 299 - YAML Flow: {value: 42.5} 300 - 301 - Encoding strings 302 - 303 - $ test_scalars encode string "hello world" 304 - JSON: {"value":"hello world"} 305 - YAML Block: 306 - value: hello world 307 - YAML Flow: {value: hello world} 308 - 309 - Encoding null 310 - 311 - $ test_scalars encode null "" 312 - JSON: {"value":null} 313 - YAML Block: 314 - value: null 315 - YAML Flow: {value: null} 316 - 317 - ================================================================================ 318 - NEGATIVE TESTS - Wrong File Types 319 - ================================================================================ 320 - 321 - Attempting to decode an object file with a scalar codec should fail 322 - 323 - $ test_scalars string ../data/objects/simple.yml 324 - JSON string_codec 325 - decode: ERROR: Missing member value in StringTest object 326 - File "-", line 1, characters 0-28: 327 - YAML string_codec 328 - decode: ERROR: Missing member value in StringTest object 329 - File "-": 330 - 331 - Attempting to decode an array file with a scalar codec should fail 332 - 333 - $ test_scalars number ../data/arrays/int_array.yml 334 - JSON number_codec 335 - decode: ERROR: Missing member value in NumberTest object 336 - File "-", line 1, characters 0-27: 337 - YAML number_codec 338 - decode: ERROR: Missing member value in NumberTest object 339 - File "-":
-6
tests/data/arrays/bool_array.yml
··· 1 - values: 2 - - true 3 - - false 4 - - true 5 - - true 6 - - false
-1
tests/data/arrays/bool_array.yml.json
··· 1 - {"values": [true, false, true, true, false]}
-1
tests/data/arrays/empty_array.yml
··· 1 - items: []
-1
tests/data/arrays/empty_array.yml.json
··· 1 - {"items": []}
-5
tests/data/arrays/float_array.yml
··· 1 - values: 2 - - 1.5 3 - - 2.7 4 - - 3.14 5 - - 0.5
-1
tests/data/arrays/float_array.yml.json
··· 1 - {"values": [1.5, 2.7, 3.14, 0.5]}
-6
tests/data/arrays/int_array.yml
··· 1 - values: 2 - - 1 3 - - 2 4 - - 3 5 - - 4 6 - - 5
-1
tests/data/arrays/int_array.yml.json
··· 1 - {"values": [1, 2, 3, 4, 5]}
-4
tests/data/arrays/nested_array.yml
··· 1 - data: 2 - - [1, 2, 3] 3 - - [4, 5, 6] 4 - - [7, 8, 9]
-1
tests/data/arrays/nested_array.yml.json
··· 1 - {"data": [[1, 2, 3], [4, 5, 6], [7, 8, 9]]}
-6
tests/data/arrays/nullable_array.yml
··· 1 - values: 2 - - hello 3 - - null 4 - - world 5 - - null 6 - - test
-1
tests/data/arrays/nullable_array.yml.json
··· 1 - {"values": ["hello", null, "world", null, "test"]}
-7
tests/data/arrays/object_array.yml
··· 1 - persons: 2 - - name: Alice 3 - age: 30 4 - - name: Bob 5 - age: 25 6 - - name: Charlie 7 - age: 35
-1
tests/data/arrays/object_array.yml.json
··· 1 - {"persons": [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}, {"name": "Charlie", "age": 35}]}
-4
tests/data/arrays/string_array.yml
··· 1 - items: 2 - - apple 3 - - banana 4 - - cherry
-1
tests/data/arrays/string_array.yml.json
··· 1 - {"items": ["apple", "banana", "cherry"]}
-5
tests/data/arrays/type_mismatch.yml
··· 1 - values: 2 - - 1 3 - - 2 4 - - not-a-number 5 - - 4
-4
tests/data/complex/complex_optional.yml
··· 1 - host: example.com 2 - port: 443 3 - ssl: true 4 - fallback_hosts: [backup1.example.com, backup2.example.com]
-1
tests/data/complex/complex_optional.yml.json
··· 1 - {"host": "example.com", "port": 443, "ssl": true, "fallback_hosts": ["backup1.example.com", "backup2.example.com"]}
-4
tests/data/complex/deep_nesting.yml
··· 1 - top: 2 - nested: 3 - data: 4 - value: 42
-1
tests/data/complex/deep_nesting.yml.json
··· 1 - {"top": {"nested": {"data": {"value": 42}}}}
-1
tests/data/complex/heterogeneous.yml
··· 1 - mixed: [42, "hello", true, null, 3.14]
-1
tests/data/complex/heterogeneous.yml.json
··· 1 - {"mixed": [42, "hello", true, null, 3.14]}
-8
tests/data/complex/mixed_structure.yml
··· 1 - name: products 2 - items: 3 - - id: 1 4 - tags: [new, sale, featured] 5 - - id: 2 6 - tags: [clearance] 7 - - id: 3 8 - tags: [premium, exclusive]
-1
tests/data/complex/mixed_structure.yml.json
··· 1 - {"name": "products", "items": [{"id": 1, "tags": ["new", "sale", "featured"]}, {"id": 2, "tags": ["clearance"]}, {"id": 3, "tags": ["premium", "exclusive"]}]}
-2
tests/data/edge/empty_collections.yml
··· 1 - empty_array: [] 2 - empty_object_array: []
-1
tests/data/edge/empty_collections.yml.json
··· 1 - {"empty_array": [], "empty_object_array": []}
-3
tests/data/edge/large_numbers.yml
··· 1 - large_int: 9007199254740991 2 - large_float: 1.7976931348623157e+308 3 - small_float: 2.2250738585072014e-308
-1
tests/data/edge/large_numbers.yml.json
··· 1 - {"large_int": 9007199254740991, "large_float": 1.7976931348623157e+308, "small_float": 2.2250738585072014e-308}
-1
tests/data/edge/single_element.yml
··· 1 - single: [42]
-1
tests/data/edge/single_element.yml.json
··· 1 - {"single": [42]}
-1
tests/data/edge/special_chars.yml
··· 1 - content: "Line 1\nLine 2\tTabbed\r\nWindows line"
-1
tests/data/edge/special_chars.yml.json
··· 1 - {"content": "Line 1\nLine 2\tTabbed\r\nWindows line"}
-3
tests/data/edge/special_keys.yml
··· 1 - "key.with.dots": value1 2 - "key-with-dashes": value2 3 - "key:with:colons": value3
-1
tests/data/edge/special_keys.yml.json
··· 1 - {"key.with.dots": "value1", "key-with-dashes": "value2", "key:with:colons": "value3"}
-3
tests/data/edge/unicode.yml
··· 1 - emoji: "🎉🚀✨" 2 - chinese: "你好世界" 3 - rtl: "مرحبا"
-1
tests/data/edge/unicode.yml.json
··· 1 - {"emoji": "🎉🚀✨", "chinese": "你好世界", "rtl": "مرحبا"}
-5
tests/data/formats/comments.yml
··· 1 - # Configuration file with comments 2 - host: localhost # The server host 3 - port: 8080 # The server port 4 - # Enable debug mode for development 5 - debug: true
-1
tests/data/formats/empty_doc.yml
··· 1 - value: null
-1
tests/data/formats/empty_doc.yml.json
··· 1 - {"value": null}
-1
tests/data/formats/explicit_tags.yml
··· 1 - data: !!str 123
-5
tests/data/formats/folded_string.yml
··· 1 - content: > 2 - This is a folded string that 3 - spans multiple lines but will 4 - be folded into a single line 5 - with spaces between words
-1
tests/data/formats/folded_string.yml.json
··· 1 - {"content": "This is a folded string that spans multiple lines but will be folded into a single line with spaces between words\n"}
-5
tests/data/formats/literal_string.yml
··· 1 - content: | 2 - This is a literal string 3 - with multiple lines 4 - preserving newlines 5 - and indentation
-1
tests/data/formats/literal_string.yml.json
··· 1 - {"content": "This is a literal string\nwith multiple lines\npreserving newlines\nand indentation\n"}
-3
tests/data/formats/number_formats.yml
··· 1 - hex: 0xFF 2 - octal: 0o77 3 - binary: 0b1010
-1
tests/data/formats/number_formats.yml.json
··· 1 - {"hex": 255, "octal": 63, "binary": 10}
-6
tests/data/locations/array_error.yml
··· 1 - values: 2 - - 1 3 - - 2 4 - - not-a-number 5 - - 4 6 - - 5
-4
tests/data/locations/block_style.yml
··· 1 - items: 2 - - apple 3 - - banana 4 - - cherry
-1
tests/data/locations/flow_style.yml
··· 1 - items: [apple, banana, cherry]
-2
tests/data/locations/missing_field.yml
··· 1 - field_a: hello 2 - field_b: 42
-5
tests/data/locations/nested_error.yml
··· 1 - name: Bob 2 - address: 3 - street: 123 Main St 4 - city: Springfield 5 - zip: invalid-zip
-2
tests/data/locations/simple.yml
··· 1 - host: localhost 2 - port: 8080
-2
tests/data/locations/type_error.yml
··· 1 - name: Alice 2 - age: not-a-number
-2
tests/data/locations/valid_settings.yml
··· 1 - timeout: 30 2 - retries: 3
-9
tests/data/multidoc/all_errors.yml
··· 1 - --- 2 - name: Alice 3 - age: invalid1 4 - --- 5 - name: Bob 6 - age: invalid2 7 - --- 8 - name: Charlie 9 - age: invalid3
-12
tests/data/multidoc/arrays.yml
··· 1 - --- 2 - - 1 3 - - 2 4 - - 3 5 - --- 6 - - apple 7 - - banana 8 - - cherry 9 - --- 10 - - true 11 - - false 12 - - true
-7
tests/data/multidoc/empty_docs.yml
··· 1 - --- 2 - name: Alice 3 - age: 30 4 - --- 5 - --- 6 - name: Charlie 7 - age: 35
-9
tests/data/multidoc/missing_fields.yml
··· 1 - --- 2 - name: Alice 3 - age: 30 4 - --- 5 - name: Bob 6 - --- 7 - name: Charlie 8 - age: 35 9 - city: Springfield
-9
tests/data/multidoc/mixed_errors.yml
··· 1 - --- 2 - name: Alice 3 - age: 30 4 - --- 5 - name: Bob 6 - age: not-a-number 7 - --- 8 - name: Charlie 9 - age: 35
-18
tests/data/multidoc/nested.yml
··· 1 - --- 2 - name: Alice 3 - age: 30 4 - address: 5 - street: 123 Main St 6 - city: Boston 7 - --- 8 - name: Bob 9 - age: 25 10 - address: 11 - street: 456 Oak Ave 12 - city: Seattle 13 - --- 14 - name: Charlie 15 - age: 35 16 - address: 17 - street: 789 Pine Rd 18 - city: Portland
-8
tests/data/multidoc/scalars.yml
··· 1 - --- 2 - hello world 3 - --- 4 - 42 5 - --- 6 - true 7 - --- 8 - null
-9
tests/data/multidoc/simple.yml
··· 1 - --- 2 - name: Alice 3 - age: 30 4 - --- 5 - name: Bob 6 - age: 25 7 - --- 8 - name: Charlie 9 - age: 35
-2
tests/data/objects/case_circle.yml
··· 1 - type: circle 2 - radius: 5.5
-1
tests/data/objects/case_circle.yml.json
··· 1 - {"type": "circle", "radius": 5.5}
-3
tests/data/objects/case_rectangle.yml
··· 1 - type: rectangle 2 - width: 10.0 3 - height: 20.0
-1
tests/data/objects/case_rectangle.yml.json
··· 1 - {"type": "rectangle", "width": 10.0, "height": 20.0}
-1
tests/data/objects/defaults_empty.yml
··· 1 - {}
-1
tests/data/objects/defaults_empty.yml.json
··· 1 - {}
-1
tests/data/objects/defaults_partial.yml
··· 1 - timeout: 60
-1
tests/data/objects/defaults_partial.yml.json
··· 1 - {"timeout": 60}
-1
tests/data/objects/missing_required.yml
··· 1 - name: Incomplete
-5
tests/data/objects/nested.yml
··· 1 - name: Bob 2 - address: 3 - street: 123 Main St 4 - city: Springfield 5 - zip: "12345"
-1
tests/data/objects/nested.yml.json
··· 1 - {"name": "Bob", "address": {"street": "123 Main St", "city": "Springfield", "zip": "12345"}}
-3
tests/data/objects/optional_all.yml
··· 1 - host: localhost 2 - port: 8080 3 - debug: true
-1
tests/data/objects/optional_all.yml.json
··· 1 - {"host": "localhost", "port": 8080, "debug": true}
-1
tests/data/objects/optional_minimal.yml
··· 1 - host: minimal.com
-1
tests/data/objects/optional_minimal.yml.json
··· 1 - {"host": "minimal.com"}
-2
tests/data/objects/optional_partial.yml
··· 1 - host: example.com 2 - port: 3000
-1
tests/data/objects/optional_partial.yml.json
··· 1 - {"host": "example.com", "port": 3000}
-2
tests/data/objects/simple.yml
··· 1 - name: Alice 2 - age: 30
-1
tests/data/objects/simple.yml.json
··· 1 - {"name": "Alice", "age": 30}
-3
tests/data/objects/unknown_keep.yml
··· 1 - name: Charlie 2 - extra1: value1 3 - extra2: value2
-1
tests/data/objects/unknown_keep.yml.json
··· 1 - {"name": "Charlie", "extra1": "value1", "extra2": "value2"}
-3
tests/data/objects/unknown_members.yml
··· 1 - name: Alice 2 - age: 30 3 - extra: not_expected
-1
tests/data/scalars/any_bool.yml
··· 1 - value: true
-1
tests/data/scalars/any_bool.yml.json
··· 1 - {"value": true}
-1
tests/data/scalars/any_null.yml
··· 1 - value: null
-1
tests/data/scalars/any_null.yml.json
··· 1 - {"value": null}
-1
tests/data/scalars/any_number.yml
··· 1 - value: 123.45
-1
tests/data/scalars/any_number.yml.json
··· 1 - {"value": 123.45}
-1
tests/data/scalars/any_string.yml
··· 1 - value: hello
-1
tests/data/scalars/any_string.yml.json
··· 1 - {"value": "hello"}
-1
tests/data/scalars/bool_false.yml
··· 1 - value: false
-1
tests/data/scalars/bool_false.yml.json
··· 1 - {"value": false}
-1
tests/data/scalars/bool_no.yml
··· 1 - value: no
-1
tests/data/scalars/bool_no.yml.json
··· 1 - {"value": false}
-1
tests/data/scalars/bool_true_plain.yml
··· 1 - value: true
-1
tests/data/scalars/bool_true_plain.yml.json
··· 1 - {"value": true}
-1
tests/data/scalars/bool_true_quoted.yml
··· 1 - value: "true"
-1
tests/data/scalars/bool_true_quoted.yml.json
··· 1 - {"value": "true"}
-1
tests/data/scalars/bool_yes.yml
··· 1 - value: yes
-1
tests/data/scalars/bool_yes.yml.json
··· 1 - {"value": true}
-1
tests/data/scalars/mismatch_number_as_null.yml
··· 1 - value: 42
-1
tests/data/scalars/mismatch_string_as_bool.yml
··· 1 - value: hello
-1
tests/data/scalars/mismatch_string_as_number.yml
··· 1 - value: not-a-number
-1
tests/data/scalars/null_empty.yml
··· 1 - value:
-1
tests/data/scalars/null_explicit.yml
··· 1 - value: null
-1
tests/data/scalars/null_tilde.yml
··· 1 - value: ~
-1
tests/data/scalars/number_float.yml
··· 1 - value: 3.14159
-1
tests/data/scalars/number_float.yml.json
··· 1 - {"value": 3.14159}
-1
tests/data/scalars/number_hex.yml
··· 1 - value: 0x2A
-1
tests/data/scalars/number_hex.yml.json
··· 1 - {"value": 42}
-1
tests/data/scalars/number_int.yml
··· 1 - value: 42
-1
tests/data/scalars/number_int.yml.json
··· 1 - {"value": 42}
-1
tests/data/scalars/number_negative.yml
··· 1 - value: -273.15
-1
tests/data/scalars/number_negative.yml.json
··· 1 - {"value": -273.15}
-1
tests/data/scalars/number_octal.yml
··· 1 - value: 0o52
-1
tests/data/scalars/number_octal.yml.json
··· 1 - {"value": 42}
-1
tests/data/scalars/special_inf.yml
··· 1 - value: .inf
-1
tests/data/scalars/special_nan.yml
··· 1 - value: .nan
-1
tests/data/scalars/special_neg_inf.yml
··· 1 - value: -.inf
-1
tests/data/scalars/string_empty.yml
··· 1 - value: ""
-1
tests/data/scalars/string_empty.yml.json
··· 1 - {"value": ""}
-1
tests/data/scalars/string_plain.yml
··· 1 - value: hello world
-1
tests/data/scalars/string_plain.yml.json
··· 1 - {"value": "hello world"}
-1
tests/data/scalars/string_quoted.yml
··· 1 - value: "42"
-1
tests/data/scalars/string_quoted.yml.json
··· 1 - {"value": "42"}