From 5eb4e2bb289a2bab815033eadb3336993fa9b35b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Roch=C3=A9?= Date: Wed, 25 Sep 2024 16:39:48 +0800 Subject: [PATCH] setup ppx_expect --- dune-project | 1 + ppx_deriving_jsonschema.opam | 1 + src/ppx_deriving_jsonschema.ml | 41 +- test/dune | 12 +- test/generate_schemas.ml | 40 ++ test/test.expected.ml | 829 +++++++++++++++++++++++++--- test/test.ml | 770 ++++++++++++++++++++++++-- test/test_schemas.expected.json | 949 ++++++++++++++++---------------- 8 files changed, 2040 insertions(+), 603 deletions(-) create mode 100644 test/generate_schemas.ml diff --git a/dune-project b/dune-project index db52a02..67be962 100644 --- a/dune-project +++ b/dune-project @@ -31,6 +31,7 @@ (ppxlib (>= "0.24.0")) (yojson :with-test) + (ppx_expect :with-test) (ocamlformat :with-dev-setup) (ocaml-lsp-server :with-dev-setup)) (tags diff --git a/ppx_deriving_jsonschema.opam b/ppx_deriving_jsonschema.opam index d97f855..a2c2ca8 100644 --- a/ppx_deriving_jsonschema.opam +++ b/ppx_deriving_jsonschema.opam @@ -19,6 +19,7 @@ depends: [ "dune" {>= "3.16"} "ppxlib" {>= "0.24.0"} "yojson" {with-test} + "ppx_expect" {with-test} "ocamlformat" {with-dev-setup} "ocaml-lsp-server" {with-dev-setup} "odoc" {with-doc} diff --git a/src/ppx_deriving_jsonschema.ml b/src/ppx_deriving_jsonschema.ml index c566307..fcb98c1 100644 --- a/src/ppx_deriving_jsonschema.ml +++ b/src/ppx_deriving_jsonschema.ml @@ -138,7 +138,8 @@ let is_optional_type core_type = | [%type: [%t? _] option] -> true | _ -> false -let rec type_of_core ~loc ~config core_type = +let rec type_of_core ~config core_type = + let loc = core_type.ptyp_loc in match core_type with | [%type: int] | [%type: int32] | [%type: int64] | [%type: nativeint] -> Schema.type_def ~loc "integer" | [%type: float] -> Schema.type_def ~loc "number" @@ -146,10 +147,10 @@ let rec type_of_core ~loc ~config core_type = | [%type: bool] -> Schema.type_def ~loc "boolean" | [%type: char] -> Schema.char ~loc | [%type: unit] -> Schema.null ~loc - | [%type: [%t? t] option] -> type_of_core ~loc ~config t - | [%type: [%t? t] ref] -> type_of_core ~loc ~config t + | [%type: [%t? t] option] -> type_of_core ~config t + | [%type: [%t? t] ref] -> type_of_core ~config t | [%type: [%t? t] list] | [%type: [%t? t] array] -> - let t = type_of_core ~loc ~config t in + let t = type_of_core ~config t in Schema.array_ ~loc t | _ -> match core_type.ptyp_desc with @@ -157,7 +158,7 @@ let rec type_of_core ~loc ~config core_type = (* todo: support using references with [type_ref ~loc type_name] instead of inlining everything *) type_constr_conv ~loc id ~f:(fun s -> s ^ "_jsonschema") [] | Ptyp_tuple types -> - let ts = List.map (type_of_core ~loc ~config) types in + let ts = List.map (type_of_core ~config) types in Schema.tuple ~loc ts | Ptyp_variant (row_fields, _, _) -> let constrs = @@ -170,10 +171,10 @@ let rec type_of_core ~loc ~config core_type = | Some name -> name | None -> name.txt in - let typs = List.map (type_of_core ~loc ~config) typs in + let typs = List.map (type_of_core ~config) typs in `Tag (name, typs) | { prf_desc = Rinherit core_type; _ } -> - let typ = type_of_core ~loc ~config core_type in + let typ = type_of_core ~config core_type in `Inherit typ) row_fields in @@ -185,34 +186,28 @@ let rec type_of_core ~loc ~config core_type = in v | _ -> - (* Format.printf "unsuported core type: %a\n------\n" Astlib.Pprintast.core_type core_type; *) - [%expr - (* todo: this type is unknown, placeholder to accept anything. Should create an error instead. *) - `Assoc - [ - "unsuported core type", `String [%e estring ~loc (Format.asprintf "%a" Astlib.Pprintast.core_type core_type)]; - ]] + let msg = Format.asprintf "ppx_deriving_jsonschema: unsupported type %a" Astlib.Pprintast.core_type core_type in + [%expr [%ocaml.error [%e estring ~loc msg]]] -(* todo: add option to inline types instead of using definitions references *) let object_ ~loc ~config fields = let fields, required = List.fold_left - (fun (fields, required) ({ pld_name = { txt = name; _ }; pld_type; _ } as field) -> + (fun (fields, required) ({ pld_name; pld_type; pld_loc = _loc; _ } as field) -> let name = match Attribute.get jsonschema_key field with | Some name -> name - | None -> name + | None -> pld_name.txt in let type_def = match Attribute.get jsonschema_ref field with | Some def -> Schema.type_ref ~loc def - | None -> type_of_core ~loc ~config pld_type + | None -> type_of_core ~config pld_type in ( [%expr [%e estring ~loc name], [%e type_def]] :: fields, - if is_optional_type pld_type then required else name :: required )) + if is_optional_type pld_type then required else { txt = name; loc } :: required )) ([], []) fields in - let required = List.map (fun name -> [%expr `String [%e estring ~loc name]]) required in + let required = List.map (fun { txt = name; loc } -> [%expr `String [%e estring ~loc name]]) required in [%expr `Assoc [ @@ -239,7 +234,7 @@ let derive_jsonschema ~ctxt ast flag_variant_as_array = let typs = [ object_ ~loc ~config label_declarations ] in `Tag (name, typs) | Pcstr_tuple typs -> - let types = List.map (type_of_core ~loc ~config) typs in + let types = List.map (type_of_core ~config) typs in `Tag (name, types)) variants in @@ -255,11 +250,11 @@ let derive_jsonschema ~ctxt ast flag_variant_as_array = let jsonschema_expr = create_value ~loc type_name (object_ ~loc ~config label_declarations) in [ jsonschema_expr ] | _, [ { ptype_name = { txt = type_name; _ }; ptype_kind = Ptype_abstract; ptype_manifest = Some core_type; _ } ] -> - let jsonschema_expr = create_value ~loc type_name (type_of_core ~loc ~config core_type) in + let jsonschema_expr = create_value ~loc type_name (type_of_core ~config core_type) in [ jsonschema_expr ] | _, _ast -> (* Format.printf "unsuported type: %a\n======\n" Format.(pp_print_list Astlib.Pprintast.type_declaration) ast; *) - [%str [%ocaml.error "Oops, jsonschema deriving does not support this type"]] + [%str [%ocaml.error "ppx_deriving_jsonschema: unsupported type"]] let generator () = Deriving.Generator.V2.make ~attributes (args ()) derive_jsonschema (* let generator () = Deriving.Generator.V2.make_noarg derive_jsonschema *) diff --git a/test/dune b/test/dune index 425cf28..0ecd744 100644 --- a/test/dune +++ b/test/dune @@ -16,19 +16,25 @@ (action (diff test.expected.ml test.actual.ml))) -(executable +(library (name test) (modules test) (libraries yojson) + (inline_tests) (preprocess - (pps ppx_deriving_jsonschema))) + (pps ppx_deriving_jsonschema ppx_expect))) + +(executable + (name generate_schemas) + (modules generate_schemas) + (libraries test)) (rule (targets test_schemas.actual.json) (action (with-stdout-to %{targets} - (run ./test.exe)))) + (run ./generate_schemas.exe)))) (rule (alias runtest) diff --git a/test/generate_schemas.ml b/test/generate_schemas.ml new file mode 100644 index 0000000..2efb615 --- /dev/null +++ b/test/generate_schemas.ml @@ -0,0 +1,40 @@ +open Test +open Ppx_deriving_jsonschema_runtime + +let schemas = + [ + json_schema with_modules_jsonschema; + json_schema kind_jsonschema; + json_schema kind_as_array_jsonschema; + json_schema poly_kind_jsonschema; + json_schema poly_kind_as_array_jsonschema; + json_schema poly_kind_with_payload_jsonschema; + json_schema poly_kind_with_payload_as_array_jsonschema; + json_schema poly_inherit_jsonschema; + json_schema poly_inherit_as_array_jsonschema; + json_schema event_jsonschema; + json_schema events_jsonschema; + json_schema eventss_jsonschema; + json_schema event_comment_jsonschema; + json_schema event_comments'_jsonschema; + json_schema event_n_jsonschema; + json_schema events_array_jsonschema; + json_schema numbers_jsonschema; + json_schema opt_jsonschema; + json_schema using_m_jsonschema; + json_schema poly2_jsonschema; + json_schema tuple_with_variant_jsonschema; + json_schema ~id:"https://ahrefs.com/schemas/player_scores" ~title:"Player scores" + ~description:"Object representing player scores" + ~definitions:[ "numbers", numbers_jsonschema ] + player_scores_jsonschema; + json_schema t_jsonschema; + json_schema ~definitions:[ "shared_address", address_jsonschema ] tt_jsonschema; + json_schema c_jsonschema; + json_schema variant_inline_record_jsonschema; + json_schema variant_with_payload_jsonschema; + ] + +let schema = `Assoc [ "$schema", `String "https://json-schema.org/draft/2020-12/schema"; "oneOf", `List schemas ] + +let () = print_endline (Yojson.Basic.pretty_to_string schema) diff --git a/test/test.expected.ml b/test/test.expected.ml index 329231e..5f6064e 100644 --- a/test/test.expected.ml +++ b/test/test.expected.ml @@ -18,6 +18,16 @@ module Mod1 = [`Assoc [("const", (`String "A"))]; `Assoc [("const", (`String "B"))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] + [%%expect_test + let "m_1" = + print_schema m_1_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "A" }, { "const": "B" } ] + } + |}]] module Mod2 = struct type m_2 = @@ -33,6 +43,16 @@ module Mod1 = `Assoc [("const", (`String "D"))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] + [%%expect_test + let "m_2" = + print_schema m_2_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "C" }, { "const": "D" } ] + } + |}]] end end type with_modules = { @@ -49,7 +69,20 @@ include ("required", (`List [`String "m2"; `String "m"]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema with_modules_jsonschema +[%%expect_test + let "with_modules" = + print_schema with_modules_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "m2": { "anyOf": [ { "const": "C" }, { "const": "D" } ] }, + "m": { "anyOf": [ { "const": "A" }, { "const": "B" } ] } + }, + "required": [ "m2", "m" ] + } |}]] type kind = | Success | Error @@ -64,7 +97,17 @@ include `Assoc [("const", (`String "Error"))]; `Assoc [("const", (`String "skipped"))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema kind_jsonschema +[%%expect_test + let "kind" = + print_schema kind_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { "const": "Success" }, { "const": "Error" }, { "const": "skipped" } + ] + } |}]] type kind_as_array = | Success | Error @@ -97,7 +140,37 @@ include ("minItems", (`Int 1)); ("maxItems", (`Int 1))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema kind_as_array_jsonschema +[%%expect_test + let "kind_as_array" = + print_schema kind_as_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "Success" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Error" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "skipped" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + } + ] + } |}]] type poly_kind = [ `Aaa | `Bbb | `Ccc [@name "ccc"]][@@deriving jsonschema] include struct @@ -109,7 +182,15 @@ include `Assoc [("const", (`String "Bbb"))]; `Assoc [("const", (`String "ccc"))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly_kind_jsonschema +[%%expect_test + let "poly_kind" = + print_schema poly_kind_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] + } |}]] type poly_kind_as_array = [ `Aaa | `Bbb | `Ccc [@name "ccc"]][@@deriving jsonschema ~variant_as_array] @@ -141,7 +222,37 @@ include ("minItems", (`Int 1)); ("maxItems", (`Int 1))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly_kind_as_array_jsonschema +[%%expect_test + let "poly_kind_as_array" = + print_schema poly_kind_as_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "Aaa" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Bbb" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "ccc" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + } + ] + } |}]] type poly_kind_with_payload = [ `Aaa of int | `Bbb | `Ccc of (string * bool) [@name "ccc"]][@@deriving jsonschema] @@ -155,7 +266,15 @@ include `Assoc [("const", (`String "Bbb"))]; `Assoc [("const", (`String "ccc"))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly_kind_with_payload_jsonschema +[%%expect_test + let "poly_kind_with_payload" = + print_schema poly_kind_with_payload_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] + } |}]] type poly_kind_with_payload_as_array = [ `Aaa of int | `Bbb | `Ccc of (string * bool) [@name "ccc"]][@@deriving jsonschema @@ -200,7 +319,46 @@ include ("minItems", (`Int 2)); ("maxItems", (`Int 2))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly_kind_with_payload_as_array_jsonschema +[%%expect_test + let "poly_kind_with_payload_as_array" = + print_schema poly_kind_with_payload_as_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "Aaa" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ { "const": "Bbb" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ + { "const": "ccc" }, + { + "type": "array", + "prefixItems": [ { "type": "string" }, { "type": "boolean" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ] + } |}]] type poly_inherit = [ `New_one | `Second_one of int | poly_kind][@@deriving jsonschema] include @@ -213,7 +371,21 @@ include `Assoc [("const", (`String "Second_one"))]; poly_kind_jsonschema]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly_inherit_jsonschema +[%%expect_test + let "poly_inherit" = + print_schema poly_inherit_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { "const": "New_one" }, + { "const": "Second_one" }, + { + "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] + } + ] + } |}]] type poly_inherit_as_array = [ `New_one | `Second_one of int | poly_kind_as_array][@@deriving jsonschema @@ -242,7 +414,55 @@ include ("maxItems", (`Int 2))]; poly_kind_as_array_jsonschema]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly_inherit_as_array_jsonschema +[%%expect_test + let "poly_inherit_as_array" = + print_schema poly_inherit_as_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "New_one" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Second_one" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "Aaa" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Bbb" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "ccc" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + } + ] + } + ] + } |}]] type event = { date: float ; @@ -306,7 +526,39 @@ include `String "kind_f"; `String "date"]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema event_jsonschema +[%%expect_test + let "event" = + print_schema event_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, { "const": "Error" }, { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", "a", + "comment", "kind_f", "date" + ] + } |}]] type events = event list[@@deriving jsonschema] include struct @@ -314,7 +566,46 @@ include `Assoc [("type", (`String "array")); ("items", event_jsonschema)] [@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema events_jsonschema +[%%expect_test + let "events" = + print_schema events_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", + "a", "comment", "kind_f", "date" + ] + } + } |}]] type eventss = event list list[@@deriving jsonschema] include struct @@ -325,7 +616,49 @@ include (`Assoc [("type", (`String "array")); ("items", event_jsonschema)]))] [@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema eventss_jsonschema +[%%expect_test + let "eventss" = + print_schema eventss_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", + "a", "comment", "kind_f", "date" + ] + } + } + } |}]] type event_comment = (event * string)[@@deriving jsonschema] include struct @@ -338,7 +671,52 @@ include ("minItems", (`Int 2)); ("maxItems", (`Int 2))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema event_comment_jsonschema +[%%expect_test + let "event_comment" = + print_schema event_comment_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", + "a", "comment", "kind_f", "date" + ] + }, + { "type": "string" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } |}]] type event_comments' = event_comment list[@@deriving jsonschema] include struct @@ -347,7 +725,55 @@ include [("type", (`String "array")); ("items", event_comment_jsonschema)] [@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema event_comments'_jsonschema +[%%expect_test + let "event_comments'" = + print_schema event_comments'_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" + ] + }, + { "type": "string" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + } |}]] type event_n = (event * int) list[@@deriving jsonschema] include struct @@ -364,7 +790,55 @@ include ("minItems", (`Int 2)); ("maxItems", (`Int 2))]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema event_n_jsonschema +[%%expect_test + let "event_n" = + print_schema event_n_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" + ] + }, + { "type": "integer" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + } |}]] type events_array = events array[@@deriving jsonschema] include struct @@ -372,7 +846,49 @@ include `Assoc [("type", (`String "array")); ("items", events_jsonschema)] [@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema events_array_jsonschema +[%%expect_test + let "events_array" = + print_schema events_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", + "a", "comment", "kind_f", "date" + ] + } + } + } |}]] type numbers = int list[@@deriving jsonschema] include struct @@ -382,14 +898,31 @@ include ("items", (`Assoc [("type", (`String "integer"))]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema numbers_jsonschema +[%%expect_test + let "numbers" = + print_schema numbers_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { "type": "integer" } + } |}]] type opt = int option[@@deriving jsonschema] include struct let opt_jsonschema = `Assoc [("type", (`String "integer"))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema opt_jsonschema +[%%expect_test + let "opt" = + print_schema opt_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer" + } |}]] type using_m = { m: Mod1.m_1 }[@@deriving jsonschema] include @@ -400,20 +933,17 @@ include ("properties", (`Assoc [("m", Mod1.m_1_jsonschema)])); ("required", (`List [`String "m"]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema using_m_jsonschema -type 'param poly = { - f: 'param }[@@deriving jsonschema] -include - struct - let poly_jsonschema = - `Assoc - [("type", (`String "object")); - ("properties", - (`Assoc - [("f", (`Assoc [("unsuported core type", (`String "'param"))]))])); - ("required", (`List [`String "f"]))][@@warning "-32-39"] - end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly_jsonschema +[%%expect_test + let "using_m" = + print_schema using_m_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { "m": { "anyOf": [ { "const": "A" }, { "const": "B" } ] } }, + "required": [ "m" ] + } |}]] type 'param2 poly2 = | C of 'param2 [@@deriving jsonschema] include @@ -422,26 +952,15 @@ include `Assoc [("anyOf", (`List [`Assoc [("const", (`String "C"))]]))] [@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly2_jsonschema -type 'param2 poly2_as_array = - | C of 'param2 [@@deriving jsonschema ~variant_as_array] -include - struct - let poly2_as_array_jsonschema = - `Assoc - [("anyOf", - (`List - [`Assoc - [("type", (`String "array")); - ("prefixItems", - (`List - [`Assoc [("const", (`String "C"))]; - `Assoc [("unsuported core type", (`String "'param2"))]])); - ("unevaluatedItems", (`Bool false)); - ("minItems", (`Int 2)); - ("maxItems", (`Int 2))]]))][@@warning "-32-39"] - end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema poly2_as_array_jsonschema +[%%expect_test + let "poly2" = + print_schema poly2_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "C" } ] + } |}]] type tuple_with_variant = (int * [ `A | `B [@name "second_cstr"]])[@@deriving jsonschema] include @@ -461,7 +980,22 @@ include ("minItems", (`Int 2)); ("maxItems", (`Int 2))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema tuple_with_variant_jsonschema +[%%expect_test + let "tuple_with_variant" = + print_schema tuple_with_variant_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "prefixItems": [ + { "type": "integer" }, + { "anyOf": [ { "const": "A" }, { "const": "second_cstr" } ] } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } |}]] type player_scores = { player: string ; @@ -479,10 +1013,26 @@ include ("required", (`List [`String "scores_ref"; `String "player"]))] [@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = - print_schema ~id:"https://ahrefs.com/schemas/player_scores" - ~title:"Player scores" ~description:"Object representing player scores" - ~definitions:[("numbers", numbers_jsonschema)] player_scores_jsonschema +[%%expect_test + let "player_scores" = + print_schema ~id:"https://ahrefs.com/schemas/player_scores" + ~title:"Player scores" ~description:"Object representing player scores" + ~definitions:[("numbers", numbers_jsonschema)] player_scores_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ahrefs.com/schemas/player_scores", + "title": "Player scores", + "description": "Object representing player scores", + "$defs": { "numbers": { "type": "array", "items": { "type": "integer" } } }, + "type": "object", + "properties": { + "scores_ref": { "$ref": "#/$defs/numbers" }, + "player": { "type": "string" } + }, + "required": [ "scores_ref", "player" ] + } |}]] type address = { street: string ; city: string ; @@ -521,7 +1071,30 @@ include (`List [`String "address"; `String "age"; `String "name"]))] [@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema t_jsonschema +[%%expect_test + let "t" = + print_schema t_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "address": { + "type": "object", + "properties": { + "zip": { "type": "string" }, + "city": { "type": "string" }, + "street": { "type": "string" } + }, + "required": [ "zip", "city", "street" ] + }, + "email": { "type": "string" }, + "age": { "type": "integer" }, + "name": { "type": "string" } + }, + "required": [ "address", "age", "name" ] + } |}]] type tt = { name: string ; @@ -554,9 +1127,38 @@ include `String "age"; `String "name"]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = - print_schema ~definitions:[("shared_address", address_jsonschema)] - tt_jsonschema +[%%expect_test + let "tt" = + print_schema ~definitions:[("shared_address", address_jsonschema)] + tt_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "shared_address": { + "type": "object", + "properties": { + "zip": { "type": "string" }, + "city": { "type": "string" }, + "street": { "type": "string" } + }, + "required": [ "zip", "city", "street" ] + } + }, + "type": "object", + "properties": { + "retreat_address": { "$ref": "#/$defs/shared_address" }, + "work_address": { "$ref": "#/$defs/shared_address" }, + "home_address": { "$ref": "#/$defs/shared_address" }, + "email": { "type": "string" }, + "age": { "type": "integer" }, + "name": { "type": "string" } + }, + "required": [ + "retreat_address", "work_address", "home_address", "age", "name" + ] + } |}]] type c = char[@@deriving jsonschema] include struct @@ -566,7 +1168,17 @@ include ("minLength", (`Int 1)); ("maxLength", (`Int 1))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema c_jsonschema +[%%expect_test + let "c" = + print_schema c_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "minLength": 1, + "maxLength": 1 + } |}]] type variant_inline_record = | A of { a: int } @@ -607,7 +1219,44 @@ include ("minItems", (`Int 2)); ("maxItems", (`Int 2))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema variant_inline_record_jsonschema +[%%expect_test + let "variant_inline_record" = + print_schema variant_inline_record_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ + { "const": "A" }, + { + "type": "object", + "properties": { "a": { "type": "integer" } }, + "required": [ "a" ] + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ + { "const": "B" }, + { + "type": "object", + "properties": { "b": { "type": "string" } }, + "required": [ "b" ] + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ] + } |}]] type variant_with_payload = | A of int | B @@ -663,4 +1312,56 @@ include ("minItems", (`Int 2)); ("maxItems", (`Int 2))]]))][@@warning "-32-39"] end[@@ocaml.doc "@inline"][@@merlin.hide ] -let () = print_schema variant_with_payload_jsonschema +[%%expect_test + let "variant_with_payload" = + print_schema variant_with_payload_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "A" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ { "const": "B" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ + { "const": "C" }, { "type": "integer" }, { "type": "string" } + ], + "unevaluatedItems": false, + "minItems": 3, + "maxItems": 3 + }, + { + "type": "array", + "prefixItems": [ + { "const": "D" }, + { + "type": "array", + "prefixItems": [ + { "type": "integer" }, + { "type": "string" }, + { "type": "boolean" } + ], + "unevaluatedItems": false, + "minItems": 3, + "maxItems": 3 + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ] + } |}]] diff --git a/test/test.ml b/test/test.ml index cd27f18..2708859 100644 --- a/test/test.ml +++ b/test/test.ml @@ -11,11 +11,31 @@ module Mod1 = struct | B [@@deriving jsonschema] + let%expect_test "m_1" = + print_schema m_1_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "A" }, { "const": "B" } ] + } + |}] + module Mod2 = struct type m_2 = | C | D [@@deriving jsonschema] + + let%expect_test "m_2" = + print_schema m_2_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "C" }, { "const": "D" } ] + } + |}] end end @@ -25,7 +45,19 @@ type with_modules = { } [@@deriving jsonschema] -let () = print_schema with_modules_jsonschema +let%expect_test "with_modules" = + print_schema with_modules_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "m2": { "anyOf": [ { "const": "C" }, { "const": "D" } ] }, + "m": { "anyOf": [ { "const": "A" }, { "const": "B" } ] } + }, + "required": [ "m2", "m" ] + } |}] type kind = | Success @@ -33,7 +65,16 @@ type kind = | Skipped [@name "skipped"] [@@deriving jsonschema] -let () = print_schema kind_jsonschema +let%expect_test "kind" = + print_schema kind_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { "const": "Success" }, { "const": "Error" }, { "const": "skipped" } + ] + } |}] type kind_as_array = | Success @@ -41,7 +82,36 @@ type kind_as_array = | Skipped [@name "skipped"] [@@deriving jsonschema ~variant_as_array] -let () = print_schema kind_as_array_jsonschema +let%expect_test "kind_as_array" = + print_schema kind_as_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "Success" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Error" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "skipped" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + } + ] + } |}] type poly_kind = [ `Aaa @@ -50,7 +120,14 @@ type poly_kind = ] [@@deriving jsonschema] -let () = print_schema poly_kind_jsonschema +let%expect_test "poly_kind" = + print_schema poly_kind_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] + } |}] type poly_kind_as_array = [ `Aaa @@ -59,7 +136,36 @@ type poly_kind_as_array = ] [@@deriving jsonschema ~variant_as_array] -let () = print_schema poly_kind_as_array_jsonschema +let%expect_test "poly_kind_as_array" = + print_schema poly_kind_as_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "Aaa" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Bbb" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "ccc" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + } + ] + } |}] type poly_kind_with_payload = [ `Aaa of int @@ -68,7 +174,14 @@ type poly_kind_with_payload = ] [@@deriving jsonschema] -let () = print_schema poly_kind_with_payload_jsonschema +let%expect_test "poly_kind_with_payload" = + print_schema poly_kind_with_payload_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] + } |}] type poly_kind_with_payload_as_array = [ `Aaa of int @@ -77,7 +190,45 @@ type poly_kind_with_payload_as_array = ] [@@deriving jsonschema ~variant_as_array] -let () = print_schema poly_kind_with_payload_as_array_jsonschema +let%expect_test "poly_kind_with_payload_as_array" = + print_schema poly_kind_with_payload_as_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "Aaa" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ { "const": "Bbb" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ + { "const": "ccc" }, + { + "type": "array", + "prefixItems": [ { "type": "string" }, { "type": "boolean" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ] + } |}] type poly_inherit = [ `New_one @@ -86,7 +237,20 @@ type poly_inherit = ] [@@deriving jsonschema] -let () = print_schema poly_inherit_jsonschema +let%expect_test "poly_inherit" = + print_schema poly_inherit_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { "const": "New_one" }, + { "const": "Second_one" }, + { + "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] + } + ] + } |}] type poly_inherit_as_array = [ `New_one @@ -95,7 +259,54 @@ type poly_inherit_as_array = ] [@@deriving jsonschema ~variant_as_array] -let () = print_schema poly_inherit_as_array_jsonschema +let%expect_test "poly_inherit_as_array" = + print_schema poly_inherit_as_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "New_one" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Second_one" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "Aaa" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Bbb" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "ccc" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + } + ] + } + ] + } |}] type event = { date : float; @@ -113,7 +324,38 @@ type event = { } [@@deriving jsonschema] -let () = print_schema event_jsonschema +let%expect_test "event" = + print_schema event_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, { "const": "Error" }, { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", "a", + "comment", "kind_f", "date" + ] + } |}] (* type recursive_record = { a : int; @@ -132,55 +374,349 @@ let () = print_schema event_jsonschema type events = event list [@@deriving jsonschema] -let () = print_schema events_jsonschema +let%expect_test "events" = + print_schema events_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", + "a", "comment", "kind_f", "date" + ] + } + } |}] type eventss = event list list [@@deriving jsonschema] -let () = print_schema eventss_jsonschema +let%expect_test "eventss" = + print_schema eventss_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", + "a", "comment", "kind_f", "date" + ] + } + } + } |}] type event_comment = event * string [@@deriving jsonschema] -let () = print_schema event_comment_jsonschema +let%expect_test "event_comment" = + print_schema event_comment_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", + "a", "comment", "kind_f", "date" + ] + }, + { "type": "string" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } |}] type event_comments' = event_comment list [@@deriving jsonschema] -let () = print_schema event_comments'_jsonschema +let%expect_test "event_comments'" = + print_schema event_comments'_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" + ] + }, + { "type": "string" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + } |}] type event_n = (event * int) list [@@deriving jsonschema] -let () = print_schema event_n_jsonschema +let%expect_test "event_n" = + print_schema event_n_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" + ] + }, + { "type": "integer" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + } |}] type events_array = events array [@@deriving jsonschema] -let () = print_schema events_array_jsonschema +let%expect_test "events_array" = + print_schema events_array_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", + "a", "comment", "kind_f", "date" + ] + } + } + } |}] type numbers = int list [@@deriving jsonschema] -let () = print_schema numbers_jsonschema +let%expect_test "numbers" = + print_schema numbers_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { "type": "integer" } + } |}] type opt = int option [@@deriving jsonschema] -let () = print_schema opt_jsonschema +let%expect_test "opt" = + print_schema opt_jsonschema; + [%expect {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer" + } |}] type using_m = { m : Mod1.m_1 } [@@deriving jsonschema] -let () = print_schema using_m_jsonschema - -type 'param poly = { f : 'param } [@@deriving jsonschema] - -let () = print_schema poly_jsonschema +let%expect_test "using_m" = + print_schema using_m_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { "m": { "anyOf": [ { "const": "A" }, { "const": "B" } ] } }, + "required": [ "m" ] + } |}] type 'param2 poly2 = C of 'param2 [@@deriving jsonschema] -let () = print_schema poly2_jsonschema - -type 'param2 poly2_as_array = C of 'param2 [@@deriving jsonschema ~variant_as_array] - -let () = print_schema poly2_as_array_jsonschema +let%expect_test "poly2" = + print_schema poly2_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "C" } ] + } |}] type tuple_with_variant = int * [ `A | `B [@name "second_cstr"] ] [@@deriving jsonschema] -let () = print_schema tuple_with_variant_jsonschema +let%expect_test "tuple_with_variant" = + print_schema tuple_with_variant_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "prefixItems": [ + { "type": "integer" }, + { "anyOf": [ { "const": "A" }, { "const": "second_cstr" } ] } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } |}] type player_scores = { player : string; @@ -188,11 +724,26 @@ type player_scores = { } [@@deriving jsonschema] -let () = +let%expect_test "player_scores" = print_schema ~id:"https://ahrefs.com/schemas/player_scores" ~title:"Player scores" ~description:"Object representing player scores" ~definitions:[ "numbers", numbers_jsonschema ] - player_scores_jsonschema + player_scores_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ahrefs.com/schemas/player_scores", + "title": "Player scores", + "description": "Object representing player scores", + "$defs": { "numbers": { "type": "array", "items": { "type": "integer" } } }, + "type": "object", + "properties": { + "scores_ref": { "$ref": "#/$defs/numbers" }, + "player": { "type": "string" } + }, + "required": [ "scores_ref", "player" ] + } |}] type address = { street : string; @@ -209,7 +760,29 @@ type t = { } [@@deriving jsonschema] -let () = print_schema t_jsonschema +let%expect_test "t" = + print_schema t_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "address": { + "type": "object", + "properties": { + "zip": { "type": "string" }, + "city": { "type": "string" }, + "street": { "type": "string" } + }, + "required": [ "zip", "city", "street" ] + }, + "email": { "type": "string" }, + "age": { "type": "integer" }, + "name": { "type": "string" } + }, + "required": [ "address", "age", "name" ] + } |}] type tt = { name : string; @@ -221,18 +794,92 @@ type tt = { } [@@deriving jsonschema] -let () = print_schema ~definitions:[ "shared_address", address_jsonschema ] tt_jsonschema +let%expect_test "tt" = + print_schema ~definitions:[ "shared_address", address_jsonschema ] tt_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "shared_address": { + "type": "object", + "properties": { + "zip": { "type": "string" }, + "city": { "type": "string" }, + "street": { "type": "string" } + }, + "required": [ "zip", "city", "street" ] + } + }, + "type": "object", + "properties": { + "retreat_address": { "$ref": "#/$defs/shared_address" }, + "work_address": { "$ref": "#/$defs/shared_address" }, + "home_address": { "$ref": "#/$defs/shared_address" }, + "email": { "type": "string" }, + "age": { "type": "integer" }, + "name": { "type": "string" } + }, + "required": [ + "retreat_address", "work_address", "home_address", "age", "name" + ] + } |}] type c = char [@@deriving jsonschema] -let () = print_schema c_jsonschema +let%expect_test "c" = + print_schema c_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "minLength": 1, + "maxLength": 1 + } |}] type variant_inline_record = | A of { a : int } | B of { b : string } [@@deriving jsonschema ~variant_as_array] -let () = print_schema variant_inline_record_jsonschema +let%expect_test "variant_inline_record" = + print_schema variant_inline_record_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ + { "const": "A" }, + { + "type": "object", + "properties": { "a": { "type": "integer" } }, + "required": [ "a" ] + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ + { "const": "B" }, + { + "type": "object", + "properties": { "b": { "type": "string" } }, + "required": [ "b" ] + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ] + } |}] type variant_with_payload = | A of int @@ -241,4 +888,55 @@ type variant_with_payload = | D of (int * string * bool) [@@deriving jsonschema ~variant_as_array] -let () = print_schema variant_with_payload_jsonschema +let%expect_test "variant_with_payload" = + print_schema variant_with_payload_jsonschema; + [%expect + {| + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "A" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ { "const": "B" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ + { "const": "C" }, { "type": "integer" }, { "type": "string" } + ], + "unevaluatedItems": false, + "minItems": 3, + "maxItems": 3 + }, + { + "type": "array", + "prefixItems": [ + { "const": "D" }, + { + "type": "array", + "prefixItems": [ + { "type": "integer" }, + { "type": "string" }, + { "type": "boolean" } + ], + "unevaluatedItems": false, + "minItems": 3, + "maxItems": 3 + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ] + } |}] diff --git a/test/test_schemas.expected.json b/test/test_schemas.expected.json index 0318777..2192592 100644 --- a/test/test_schemas.expected.json +++ b/test/test_schemas.expected.json @@ -1,141 +1,53 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "m2": { "anyOf": [ { "const": "C" }, { "const": "D" } ] }, - "m": { "anyOf": [ { "const": "A" }, { "const": "B" } ] } - }, - "required": [ "m2", "m" ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ - { "const": "Success" }, { "const": "Error" }, { "const": "skipped" } - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ - { - "type": "array", - "prefixItems": [ { "const": "Success" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 - }, - { - "type": "array", - "prefixItems": [ { "const": "Error" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 - }, - { - "type": "array", - "prefixItems": [ { "const": "skipped" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 - } - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ + "oneOf": [ { - "type": "array", - "prefixItems": [ { "const": "Aaa" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 - }, - { - "type": "array", - "prefixItems": [ { "const": "Bbb" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 - }, - { - "type": "array", - "prefixItems": [ { "const": "ccc" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 - } - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ - { - "type": "array", - "prefixItems": [ { "const": "Aaa" }, { "type": "integer" } ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "m2": { "anyOf": [ { "const": "C" }, { "const": "D" } ] }, + "m": { "anyOf": [ { "const": "A" }, { "const": "B" } ] } + }, + "required": [ "m2", "m" ] }, { - "type": "array", - "prefixItems": [ { "const": "Bbb" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { "const": "Success" }, { "const": "Error" }, { "const": "skipped" } + ] }, { - "type": "array", - "prefixItems": [ - { "const": "ccc" }, + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "type": "array", - "prefixItems": [ { "type": "string" }, { "type": "boolean" } ], + "prefixItems": [ { "const": "Success" } ], "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Error" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "skipped" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 } - ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 - } - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ - { "const": "New_one" }, - { "const": "Second_one" }, - { - "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] - } - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ - { - "type": "array", - "prefixItems": [ { "const": "New_one" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 + ] }, { - "type": "array", - "prefixItems": [ { "const": "Second_one" }, { "type": "integer" } ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] }, { + "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [ { "type": "array", @@ -159,115 +71,104 @@ "maxItems": 1 } ] - } - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "native_int": { "type": "integer" }, - "unit": { "type": "null" }, - "string_ref": { "type": "string" }, - "bunch_of_bytes": { "type": "string" }, - "c": { "type": "string", "minLength": 1, "maxLength": 1 }, - "t": { - "anyOf": [ { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } ] }, - "l": { "type": "array", "items": { "type": "string" } }, - "a": { "type": "array", "items": { "type": "number" } }, - "opt_int": { "type": "integer" }, - "comment": { "type": "string" }, - "kind_f": { + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [ - { "const": "Success" }, { "const": "Error" }, { "const": "skipped" } + { + "type": "array", + "prefixItems": [ { "const": "Aaa" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ { "const": "Bbb" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ + { "const": "ccc" }, + { + "type": "array", + "prefixItems": [ { "type": "string" }, { "type": "boolean" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } ] }, - "date": { "type": "number" } - }, - "required": [ - "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", "a", - "comment", "kind_f", "date" - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "array", - "items": { - "type": "object", - "properties": { - "native_int": { "type": "integer" }, - "unit": { "type": "null" }, - "string_ref": { "type": "string" }, - "bunch_of_bytes": { "type": "string" }, - "c": { "type": "string", "minLength": 1, "maxLength": 1 }, - "t": { - "anyOf": [ - { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } - ] - }, - "l": { "type": "array", "items": { "type": "string" } }, - "a": { "type": "array", "items": { "type": "number" } }, - "opt_int": { "type": "integer" }, - "comment": { "type": "string" }, - "kind_f": { - "anyOf": [ - { "const": "Success" }, - { "const": "Error" }, - { "const": "skipped" } - ] - }, - "date": { "type": "number" } - }, - "required": [ - "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", - "a", "comment", "kind_f", "date" - ] - } -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "array", - "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "native_int": { "type": "integer" }, - "unit": { "type": "null" }, - "string_ref": { "type": "string" }, - "bunch_of_bytes": { "type": "string" }, - "c": { "type": "string", "minLength": 1, "maxLength": 1 }, - "t": { + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { "const": "New_one" }, + { "const": "Second_one" }, + { "anyOf": [ - { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + { "const": "Aaa" }, { "const": "Bbb" }, { "const": "ccc" } ] + } + ] + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "New_one" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 }, - "l": { "type": "array", "items": { "type": "string" } }, - "a": { "type": "array", "items": { "type": "number" } }, - "opt_int": { "type": "integer" }, - "comment": { "type": "string" }, - "kind_f": { + { + "type": "array", + "prefixItems": [ { "const": "Second_one" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { "anyOf": [ - { "const": "Success" }, - { "const": "Error" }, - { "const": "skipped" } + { + "type": "array", + "prefixItems": [ { "const": "Aaa" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "Bbb" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, + { + "type": "array", + "prefixItems": [ { "const": "ccc" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + } ] - }, - "date": { "type": "number" } - }, - "required": [ - "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", - "a", "comment", "kind_f", "date" + } ] - } - } -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "array", - "prefixItems": [ + }, { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "native_int": { "type": "integer" }, @@ -298,19 +199,10 @@ "a", "comment", "kind_f", "date" ] }, - { "type": "string" } - ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "array", - "items": { - "type": "array", - "prefixItems": [ - { + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { "type": "object", "properties": { "native_int": { "type": "integer" }, @@ -340,288 +232,391 @@ "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", "a", "comment", "kind_f", "date" ] - }, - { "type": "string" } - ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 - } -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "array", - "items": { - "type": "array", - "prefixItems": [ - { - "type": "object", - "properties": { - "native_int": { "type": "integer" }, - "unit": { "type": "null" }, - "string_ref": { "type": "string" }, - "bunch_of_bytes": { "type": "string" }, - "c": { "type": "string", "minLength": 1, "maxLength": 1 }, - "t": { - "anyOf": [ - { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + } + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" + ] + } + } + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" + ] + }, + { "type": "string" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" ] }, - "l": { "type": "array", "items": { "type": "string" } }, - "a": { "type": "array", "items": { "type": "number" } }, - "opt_int": { "type": "integer" }, - "comment": { "type": "string" }, - "kind_f": { - "anyOf": [ - { "const": "Success" }, - { "const": "Error" }, - { "const": "skipped" } + { "type": "string" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "prefixItems": [ + { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" ] }, - "date": { "type": "number" } - }, - "required": [ - "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", - "l", "a", "comment", "kind_f", "date" - ] - }, - { "type": "integer" } - ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 - } -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "array", - "items": { - "type": "array", - "items": { + { "type": "integer" } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "native_int": { "type": "integer" }, + "unit": { "type": "null" }, + "string_ref": { "type": "string" }, + "bunch_of_bytes": { "type": "string" }, + "c": { "type": "string", "minLength": 1, "maxLength": 1 }, + "t": { + "anyOf": [ + { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } + ] + }, + "l": { "type": "array", "items": { "type": "string" } }, + "a": { "type": "array", "items": { "type": "number" } }, + "opt_int": { "type": "integer" }, + "comment": { "type": "string" }, + "kind_f": { + "anyOf": [ + { "const": "Success" }, + { "const": "Error" }, + { "const": "skipped" } + ] + }, + "date": { "type": "number" } + }, + "required": [ + "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", + "l", "a", "comment", "kind_f", "date" + ] + } + } + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { "type": "integer" } + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer" + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { - "native_int": { "type": "integer" }, - "unit": { "type": "null" }, - "string_ref": { "type": "string" }, - "bunch_of_bytes": { "type": "string" }, - "c": { "type": "string", "minLength": 1, "maxLength": 1 }, - "t": { - "anyOf": [ - { "const": "Foo" }, { "const": "Bar" }, { "const": "Baz" } - ] - }, - "l": { "type": "array", "items": { "type": "string" } }, - "a": { "type": "array", "items": { "type": "number" } }, - "opt_int": { "type": "integer" }, - "comment": { "type": "string" }, - "kind_f": { - "anyOf": [ - { "const": "Success" }, - { "const": "Error" }, - { "const": "skipped" } - ] - }, - "date": { "type": "number" } + "m": { "anyOf": [ { "const": "A" }, { "const": "B" } ] } }, - "required": [ - "native_int", "unit", "string_ref", "bunch_of_bytes", "c", "t", "l", - "a", "comment", "kind_f", "date" - ] - } - } -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "array", - "items": { "type": "integer" } -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "integer" -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { "m": { "anyOf": [ { "const": "A" }, { "const": "B" } ] } }, - "required": [ "m" ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { "f": { "unsuported core type": "'param" } }, - "required": [ "f" ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ { "const": "C" } ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ + "required": [ "m" ] + }, { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ { "const": "C" } ] + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "array", "prefixItems": [ - { "const": "C" }, { "unsuported core type": "'param2" } + { "type": "integer" }, + { "anyOf": [ { "const": "A" }, { "const": "second_cstr" } ] } ], "unevaluatedItems": false, "minItems": 2, "maxItems": 2 - } - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "array", - "prefixItems": [ - { "type": "integer" }, - { "anyOf": [ { "const": "A" }, { "const": "second_cstr" } ] } - ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ahrefs.com/schemas/player_scores", - "title": "Player scores", - "description": "Object representing player scores", - "$defs": { "numbers": { "type": "array", "items": { "type": "integer" } } }, - "type": "object", - "properties": { - "scores_ref": { "$ref": "#/$defs/numbers" }, - "player": { "type": "string" } - }, - "required": [ "scores_ref", "player" ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "address": { + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ahrefs.com/schemas/player_scores", + "title": "Player scores", + "description": "Object representing player scores", + "$defs": { + "numbers": { "type": "array", "items": { "type": "integer" } } + }, "type": "object", "properties": { - "zip": { "type": "string" }, - "city": { "type": "string" }, - "street": { "type": "string" } + "scores_ref": { "$ref": "#/$defs/numbers" }, + "player": { "type": "string" } }, - "required": [ "zip", "city", "street" ] + "required": [ "scores_ref", "player" ] }, - "email": { "type": "string" }, - "age": { "type": "integer" }, - "name": { "type": "string" } - }, - "required": [ "address", "age", "name" ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "shared_address": { + { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { - "zip": { "type": "string" }, - "city": { "type": "string" }, - "street": { "type": "string" } - }, - "required": [ "zip", "city", "street" ] - } - }, - "type": "object", - "properties": { - "retreat_address": { "$ref": "#/$defs/shared_address" }, - "work_address": { "$ref": "#/$defs/shared_address" }, - "home_address": { "$ref": "#/$defs/shared_address" }, - "email": { "type": "string" }, - "age": { "type": "integer" }, - "name": { "type": "string" } - }, - "required": [ - "retreat_address", "work_address", "home_address", "age", "name" - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "string", - "minLength": 1, - "maxLength": 1 -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ - { - "type": "array", - "prefixItems": [ - { "const": "A" }, - { + "address": { "type": "object", - "properties": { "a": { "type": "integer" } }, - "required": [ "a" ] - } - ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 + "properties": { + "zip": { "type": "string" }, + "city": { "type": "string" }, + "street": { "type": "string" } + }, + "required": [ "zip", "city", "street" ] + }, + "email": { "type": "string" }, + "age": { "type": "integer" }, + "name": { "type": "string" } + }, + "required": [ "address", "age", "name" ] }, { - "type": "array", - "prefixItems": [ - { "const": "B" }, - { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "shared_address": { "type": "object", - "properties": { "b": { "type": "string" } }, - "required": [ "b" ] + "properties": { + "zip": { "type": "string" }, + "city": { "type": "string" }, + "street": { "type": "string" } + }, + "required": [ "zip", "city", "street" ] } - ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 - } - ] -} -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ - { - "type": "array", - "prefixItems": [ { "const": "A" }, { "type": "integer" } ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 + }, + "type": "object", + "properties": { + "retreat_address": { "$ref": "#/$defs/shared_address" }, + "work_address": { "$ref": "#/$defs/shared_address" }, + "home_address": { "$ref": "#/$defs/shared_address" }, + "email": { "type": "string" }, + "age": { "type": "integer" }, + "name": { "type": "string" } + }, + "required": [ + "retreat_address", "work_address", "home_address", "age", "name" + ] }, { - "type": "array", - "prefixItems": [ { "const": "B" } ], - "unevaluatedItems": false, - "minItems": 1, - "maxItems": 1 + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "minLength": 1, + "maxLength": 1 }, { - "type": "array", - "prefixItems": [ - { "const": "C" }, { "type": "integer" }, { "type": "string" } - ], - "unevaluatedItems": false, - "minItems": 3, - "maxItems": 3 + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ + { "const": "A" }, + { + "type": "object", + "properties": { "a": { "type": "integer" } }, + "required": [ "a" ] + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ + { "const": "B" }, + { + "type": "object", + "properties": { "b": { "type": "string" } }, + "required": [ "b" ] + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + } + ] }, { - "type": "array", - "prefixItems": [ - { "const": "D" }, + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "array", + "prefixItems": [ { "const": "A" }, { "type": "integer" } ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "prefixItems": [ { "const": "B" } ], + "unevaluatedItems": false, + "minItems": 1, + "maxItems": 1 + }, { "type": "array", "prefixItems": [ - { "type": "integer" }, - { "type": "string" }, - { "type": "boolean" } + { "const": "C" }, { "type": "integer" }, { "type": "string" } ], "unevaluatedItems": false, "minItems": 3, "maxItems": 3 + }, + { + "type": "array", + "prefixItems": [ + { "const": "D" }, + { + "type": "array", + "prefixItems": [ + { "type": "integer" }, + { "type": "string" }, + { "type": "boolean" } + ], + "unevaluatedItems": false, + "minItems": 3, + "maxItems": 3 + } + ], + "unevaluatedItems": false, + "minItems": 2, + "maxItems": 2 } - ], - "unevaluatedItems": false, - "minItems": 2, - "maxItems": 2 + ] } ] }