mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-14 21:04:04 +01:00
refactor(docgen): remove HTML output, focus exclusively on MDX generation
BREAKING CHANGE: HTML output format has been removed. The tool now generates MDX documentation for Astro Starlight exclusively. This commit removes the HTML generator and all associated code, simplifying the codebase to focus on MDX output only. Removed - `src/generator.rs` - HTML documentation generator (1827 lines) - `src/identifiers.rs` - CSS/HTML identifiers (371 lines) - `src/templates/base.html` - HTML base template - `src/templates/macros.html` - HTML macro templates - `src/templates/style.css` - CSS styles (1216 lines) - `src/templates/test_index.html` - Test HTML template - `build.rs` - CSS minification build script - `tests/json_schema_test_suite.rs` - JSON Schema test suite (501 lines) - `tests/fixtures/json-schema-test-suite/` - All draft2020-12 test fixtures Removed Dependencies - lightningcss (CSS minification) - rayon (parallel processing) - struct_iterable (struct iteration) - regex, chrono (dev dependencies) Added - `ENUMS.md` - Comprehensive documentation of all 11 Rust enum patterns and their JSONSchema representations - 12 unit tests covering all enum patterns to prevent Value duplication Changed CLI (src/main.rs) - Remove `--format` flag (was html/mdx, now mdx only) - Remove `Format` enum - Simplify to always output MDX Library (src/lib.rs) - Remove `Options` struct and `generate_html()` function - Remove `Generator`, `CSS`, `IDS`, `TYPE_CLASSES` exports - Update module docs to reflect MDX-only output - Update tests to use `generate_mdx()` Templates (src/templates/mdx_macros.md) - Add section headers organizing macros by function - Add comprehensive comments documenting all enum patterns - Fix duplicate Value rendering for const variants - Add Pattern 7 detection for externally tagged enums - Change `<details>` to `<details open>` for better visibility - Render required properties before optional ones - Move `$ref` handling after `type` in render_type_badge (Pattern 6 fix) Preparation (src/prepare.rs) - Minor formatting improvements
This commit is contained in:
1 parent
f48586033d
commit
91463ff033
97 files changed
+1918
-22456
No files matched your search
Generated
+12
-661
@@ -2,30 +2,6 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
|
||||
dependencies = [
|
||||
"getrandom 0.2.16",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom 0.3.4",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
@@ -100,33 +76,12 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64-simd"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5"
|
||||
dependencies = [
|
||||
"simd-abstraction",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
@@ -152,34 +107,6 @@ version = "3.19.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
|
||||
|
||||
[[package]]
|
||||
name = "bytecheck"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2"
|
||||
dependencies = [
|
||||
"bytecheck_derive",
|
||||
"ptr_meta",
|
||||
"simdutf8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytecheck_derive"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.51"
|
||||
@@ -203,9 +130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
@@ -262,7 +187,7 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -277,35 +202,6 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "const-str"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21077772762a1002bb421c3af42ac1725fa56066bfc53d9a55bb79905df2aaf3"
|
||||
dependencies = [
|
||||
"const-str-proc-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-str-proc-macro"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e1e0fdd2e5d3041e530e1b21158aeeef8b5d0e306bc5c1e3d6cf0930d10e25a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
@@ -356,66 +252,6 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cssparser"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be934d936a0fbed5bcdc01042b770de1398bf79d0e192f49fa7faea0e99281e"
|
||||
dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa",
|
||||
"phf",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cssparser-color"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556c099a61d85989d7af52b692e35a8d68a57e7df8c6d07563dc0778b3960c9f"
|
||||
dependencies = [
|
||||
"cssparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cssparser-macros"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown 0.14.5",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
|
||||
|
||||
[[package]]
|
||||
name = "data-url"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193"
|
||||
dependencies = [
|
||||
"matches",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deunicode"
|
||||
version = "1.6.2"
|
||||
@@ -432,60 +268,18 @@ dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa-short"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87"
|
||||
dependencies = [
|
||||
"dtoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "erased-serde"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
@@ -516,18 +310,6 @@ dependencies = [
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.18"
|
||||
@@ -552,27 +334,6 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
dependencies = [
|
||||
"ahash 0.7.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
@@ -628,33 +389,12 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.16.1",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.16"
|
||||
@@ -689,67 +429,12 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
||||
|
||||
[[package]]
|
||||
name = "lightningcss"
|
||||
version = "1.0.0-alpha.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b407ca668368d1d5a86cea58ac82d9f9f9ca4bac1e9dce6f16f875f0f081a911"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"bitflags",
|
||||
"const-str",
|
||||
"cssparser",
|
||||
"cssparser-color",
|
||||
"dashmap",
|
||||
"data-encoding",
|
||||
"getrandom 0.3.4",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"lightningcss-derive",
|
||||
"parcel_selectors",
|
||||
"parcel_sourcemap",
|
||||
"pastey",
|
||||
"pathdiff",
|
||||
"rayon",
|
||||
"serde",
|
||||
"serde-content",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lightningcss-derive"
|
||||
version = "1.0.0-alpha.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84c12744d1279367caed41739ef094c325d53fb0ffcd4f9b84a368796f870252"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
@@ -777,55 +462,6 @@ version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||
|
||||
[[package]]
|
||||
name = "outref"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4"
|
||||
|
||||
[[package]]
|
||||
name = "parcel_selectors"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54fd03f1ad26cb6b3ec1b7414fa78a3bd639e7dbb421b1a60513c96ce886a196"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cssparser",
|
||||
"log",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
"precomputed-hash",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parcel_sourcemap"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "485b74d7218068b2b7c0e3ff12fbc61ae11d57cb5d8224f525bd304c6be05bbb"
|
||||
dependencies = [
|
||||
"base64-simd",
|
||||
"data-url",
|
||||
"rkyv",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"vlq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parse-zoneinfo"
|
||||
version = "0.3.1"
|
||||
@@ -835,18 +471,6 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pastey"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec"
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.2"
|
||||
@@ -883,7 +507,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -902,7 +526,6 @@ version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
@@ -926,19 +549,6 @@ dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.3"
|
||||
@@ -957,12 +567,6 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "precomputed-hash"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.103"
|
||||
@@ -972,26 +576,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ptr_meta"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1"
|
||||
dependencies = [
|
||||
"ptr_meta_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ptr_meta_derive"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.13.0"
|
||||
@@ -1020,18 +604,6 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@@ -1059,36 +631,7 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1108,7 +651,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1140,50 +683,6 @@ version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
||||
|
||||
[[package]]
|
||||
name = "rend"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c"
|
||||
dependencies = [
|
||||
"bytecheck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rkyv"
|
||||
version = "0.7.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"bytecheck",
|
||||
"bytes",
|
||||
"hashbrown 0.12.3",
|
||||
"ptr_meta",
|
||||
"rend",
|
||||
"rkyv_derive",
|
||||
"seahash",
|
||||
"tinyvec",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rkyv_derive"
|
||||
version = "0.7.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
@@ -1216,16 +715,11 @@ dependencies = [
|
||||
name = "schemars-docgen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"lightningcss",
|
||||
"pulldown-cmark",
|
||||
"rayon",
|
||||
"regex",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"struct_iterable",
|
||||
"tera",
|
||||
"thiserror",
|
||||
]
|
||||
@@ -1239,21 +733,9 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "seahash"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
@@ -1264,15 +746,6 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-content"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3753ca04f350fa92d00b6146a3555e63c55388c9ef2e11e09bce2ff1c0b509c6"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
@@ -1290,7 +763,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1301,7 +774,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1334,21 +807,6 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "simd-abstraction"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987"
|
||||
dependencies = [
|
||||
"outref",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.1"
|
||||
@@ -1365,58 +823,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "struct_iterable"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "849a064c6470a650b72e41fa6c057879b68f804d113af92900f27574828e7712"
|
||||
dependencies = [
|
||||
"struct_iterable_derive",
|
||||
"struct_iterable_internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "struct_iterable_derive"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bb939ce88a43ea4e9d012f2f6b4cc789deb2db9d47bad697952a85d6978662c"
|
||||
dependencies = [
|
||||
"erased-serde",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"struct_iterable_internal",
|
||||
"syn 2.0.111",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "struct_iterable_internal"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9426b2a0c03e6cc2ea8dbc0168dbbf943f88755e409fb91bcb8f6a268305f4a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.111"
|
||||
@@ -1428,12 +840,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tera"
|
||||
version = "1.20.1"
|
||||
@@ -1473,24 +879,9 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
@@ -1533,28 +924,12 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "vlq"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
@@ -1571,15 +946,6 @@ version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.1+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.106"
|
||||
@@ -1612,7 +978,7 @@ dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -1655,7 +1021,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1666,7 +1032,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1702,21 +1068,6 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||
dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.31"
|
||||
@@ -1734,7 +1085,7 @@ checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
-11
@@ -20,14 +20,3 @@ tera = "1"
|
||||
pulldown-cmark = "0.13"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
thiserror = "2"
|
||||
struct_iterable = "0.1"
|
||||
|
||||
[build-dependencies]
|
||||
lightningcss = "1.0.0-alpha.68"
|
||||
struct_iterable = "0.1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
regex = "1"
|
||||
rayon = "1"
|
||||
chrono = "0.4"
|
||||
@@ -0,0 +1,826 @@
|
||||
# Comprehensive Analysis: Rust Enum Representations in JSONSchema
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides an exhaustive analysis of all the different ways Rust enums in the `komorebi-for-mac` project are represented in the generated schema files (`schema.json` and `schema.bar.json`). The project uses `schemars` with the `JsonSchema` derive macro for schema generation.
|
||||
|
||||
---
|
||||
|
||||
## Pattern 1: Simple Unit Enums (String Constants)
|
||||
|
||||
**Rust Pattern:** Enums where all variants have no associated data.
|
||||
|
||||
**Serde Attributes:** None (default) or `#[serde(rename_all = "...")]`
|
||||
|
||||
**JSONSchema Representation:** Uses `oneOf` with each variant as `{ "type": "string", "const": "VariantName" }`
|
||||
|
||||
**Source Example:** `ApplicationIdentifier` in `komorebi/src/core/mod.rs`
|
||||
```rust
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum ApplicationIdentifier {
|
||||
/// Executable name
|
||||
Exe,
|
||||
/// Title
|
||||
Title,
|
||||
/// Path
|
||||
Path,
|
||||
/// App Bundle name
|
||||
Name,
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Application identifier",
|
||||
"oneOf": [
|
||||
{ "description": "Executable name", "type": "string", "const": "Exe" },
|
||||
{ "description": "Title", "type": "string", "const": "Title" },
|
||||
{ "description": "Path", "type": "string", "const": "Path" },
|
||||
{ "description": "App Bundle name", "type": "string", "const": "Name" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Field | JSON Path | Description |
|
||||
|-------|-----------|-------------|
|
||||
| Variant Name | `oneOf[n].const` | The variant name as a string constant |
|
||||
| Variant Description | `oneOf[n].description` | Doc comment from the variant |
|
||||
| Enum Description | `description` | Doc comment from the enum |
|
||||
|
||||
**Examples in schema.json:**
|
||||
| Definition | Lines |
|
||||
|------------|-------|
|
||||
| `ApplicationIdentifier` | L570-594 |
|
||||
| `Axis` | L622-641 |
|
||||
| `CrossBoundaryBehaviour` | L2410-2424 |
|
||||
| `FloatingLayerBehaviour` | L2476-2490 |
|
||||
| `MatchingStrategy` | L2898-2952 |
|
||||
| `MoveBehaviour` | L3050-3069 |
|
||||
| `OperationBehaviour` | L3070-3084 |
|
||||
| `Placement` | L3141-3160 |
|
||||
| `PredefinedAspectRatio` | L3161-3180 |
|
||||
| `ThemeVariant` | L3366-3380 |
|
||||
| `WindowContainerBehaviour` | L3413-3427 |
|
||||
| `WindowHidingPosition` | L3428-3442 |
|
||||
| `Catppuccin` | L2237-2261 |
|
||||
| `CatppuccinValue` | L2262-2396 |
|
||||
| `Base16Value` | L2080-2164 |
|
||||
| `Base16` | L642-1991 (270 theme variants) |
|
||||
|
||||
**Examples in schema.bar.json:**
|
||||
| Definition | Lines |
|
||||
|------------|-------|
|
||||
| `ApplicationsDisplayFormat` | L268-287 |
|
||||
| `DisplayFormat` | L2241-2270 |
|
||||
| `GroupingStyle` | L2441-2480 |
|
||||
| `LabelPrefix` | L2958-2982 |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 2: Unit Enum with Default Value
|
||||
|
||||
**Rust Pattern:** Unit enum with `#[schemars(extend("default" = Self::Variant))]`
|
||||
|
||||
**JSONSchema Representation:** Same as Pattern 1, but with an additional `"default"` field at the enum level.
|
||||
|
||||
**Source Example:** `DefaultLayout` in `komorebi/src/core/default_layout.rs`
|
||||
```rust
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[cfg_attr(feature = "schemars", schemars(extend("default" = Self::BSP)))]
|
||||
pub enum DefaultLayout {
|
||||
/// BSP Layout
|
||||
BSP,
|
||||
/// Columns Layout
|
||||
Columns,
|
||||
// ... more variants
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "A predefined komorebi layout",
|
||||
"default": "BSP",
|
||||
"oneOf": [
|
||||
{ "description": "BSP Layout", "type": "string", "const": "BSP" },
|
||||
{ "description": "Columns Layout", "type": "string", "const": "Columns" },
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Field | JSON Path | Description |
|
||||
|-------|-----------|-------------|
|
||||
| Variant Name | `oneOf[n].const` | The variant name as a string constant |
|
||||
| Default Value | `default` | The default variant name (at enum root level) |
|
||||
| Variant Description | `oneOf[n].description` | Doc comment from the variant |
|
||||
|
||||
**Examples:**
|
||||
| Schema | Definition | Lines |
|
||||
|--------|------------|-------|
|
||||
| schema.json | `DefaultLayout` | L2425-2475 |
|
||||
| schema.bar.json | `DefaultLayout` | L2190-2240 |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 3: Mixed Enum (Unit Variants + Newtype Variants)
|
||||
|
||||
**Rust Pattern:** Enum with mostly unit variants plus one or more tuple/newtype variants containing data. Uses default external tagging.
|
||||
|
||||
**JSONSchema Representation:** Uses `oneOf` where:
|
||||
- Unit variants become `{ "type": "string", "const": "Name" }`
|
||||
- Newtype variants become objects with the variant name as a property key
|
||||
|
||||
**Source Example:** `DateFormat` in `komorebi-bar/src/widgets/date.rs`
|
||||
```rust
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum DateFormat {
|
||||
/// Month/Date/Year format (09/08/24)
|
||||
MonthDateYear,
|
||||
/// Year-Month-Date format (2024-09-08)
|
||||
YearMonthDate,
|
||||
/// Custom format
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Custom"))]
|
||||
Custom(String),
|
||||
/// Custom format with modifiers
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "CustomModifiers"))]
|
||||
CustomModifiers(CustomModifiers),
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Date widget format",
|
||||
"oneOf": [
|
||||
{ "description": "Month/Date/Year format", "type": "string", "const": "MonthDateYear" },
|
||||
{ "description": "Year-Month-Date format", "type": "string", "const": "YearMonthDate" },
|
||||
{
|
||||
"title": "Custom",
|
||||
"description": "Custom format",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Custom": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["Custom"]
|
||||
},
|
||||
{
|
||||
"title": "CustomModifiers",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"CustomModifiers": { "$ref": "#/$defs/CustomModifiers" }
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["CustomModifiers"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Variant Type | Field | JSON Path | Description |
|
||||
|--------------|-------|-----------|-------------|
|
||||
| Unit | Variant Name | `oneOf[n].const` | The variant name as a string constant |
|
||||
| Unit | Description | `oneOf[n].description` | Doc comment from the variant |
|
||||
| Newtype | Title | `oneOf[n].title` | Variant name (from `#[schemars(title = "...")]`) |
|
||||
| Newtype | Property Key | `oneOf[n].properties.<VariantName>` | Variant name as object property key |
|
||||
| Newtype | Required | `oneOf[n].required[0]` | Variant name in required array |
|
||||
|
||||
**Examples in schema.bar.json:**
|
||||
| Definition | Lines |
|
||||
|------------|-------|
|
||||
| `DateFormat` | L2137-2189 |
|
||||
| `TimeFormat` | L3442-3490 |
|
||||
| `KomorebiLayout` | L2794-2832 |
|
||||
|
||||
**Examples in schema.json:**
|
||||
| Definition | Lines | Notes |
|
||||
|------------|-------|-------|
|
||||
| `AnimationStyle` | L312-505 | 31 unit variants + `CubicBezier(f64,f64,f64,f64)` - **Note: Has custom Serialize/Deserialize that serializes CubicBezier as bare array, but schema shows wrapped object** |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 4: Untagged Enum (anyOf)
|
||||
|
||||
**Rust Pattern:** Enum with `#[serde(untagged)]` attribute.
|
||||
|
||||
**JSONSchema Representation:** Uses `anyOf` (not `oneOf`) with each variant's type directly, without wrapper objects or discriminator fields.
|
||||
|
||||
### Subpattern 4a: Untagged with Primitives
|
||||
|
||||
**Source Example:** `MonitorConfigOrIndex` in `komorebi-bar/src/config.rs`
|
||||
```rust
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
pub enum MonitorConfigOrIndex {
|
||||
/// The monitor index
|
||||
Index(usize),
|
||||
/// The full monitor config
|
||||
MonitorConfig(MonitorConfig),
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Monitor configuration or monitor index",
|
||||
"anyOf": [
|
||||
{ "description": "The monitor index", "type": "integer", "format": "uint", "minimum": 0 },
|
||||
{ "description": "The full monitor config", "$ref": "#/$defs/MonitorConfig" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Subpattern 4b: Untagged with Multiple Struct Refs
|
||||
|
||||
**Source Example:** `SpacingKind` in `komorebi-bar/src/config.rs`
|
||||
```rust
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
// WARNING: Order matters! Grouped must come last
|
||||
pub enum SpacingKind {
|
||||
/// Spacing applied to all sides
|
||||
All(f32),
|
||||
/// Individual spacing
|
||||
Individual(IndividualSpacingConfig),
|
||||
/// Grouped spacing
|
||||
Grouped(GroupedSpacingConfig),
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Spacing kind",
|
||||
"anyOf": [
|
||||
{ "description": "Spacing applied to all sides", "type": "number", "format": "float" },
|
||||
{ "description": "Individual spacing", "$ref": "#/$defs/IndividualSpacingConfig" },
|
||||
{ "description": "Grouped spacing", "$ref": "#/$defs/GroupedSpacingConfig" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Subpattern 4c: Untagged with Two $refs
|
||||
|
||||
**Source Example:** `Colour` in `komorebi/src/core/colour.rs`
|
||||
```rust
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
pub enum Colour {
|
||||
/// RGB representation
|
||||
Rgb(Rgb),
|
||||
/// Hex representation
|
||||
Hex(Hex),
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Colour representation",
|
||||
"anyOf": [
|
||||
{ "description": "Colour represented as RGB", "$ref": "#/$defs/Rgb" },
|
||||
{ "description": "Colour represented as Hex", "$ref": "#/$defs/Hex" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Subpattern 4d: Untagged with Single vs Array
|
||||
|
||||
**Source Example:** `MatchingRule` in `komorebi/src/core/config_generation.rs`
|
||||
```rust
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
pub enum MatchingRule {
|
||||
/// Simple matching rule
|
||||
Simple(IdWithIdentifier),
|
||||
/// Composite matching rule
|
||||
Composite(Vec<IdWithIdentifier>),
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Rule for matching applications",
|
||||
"anyOf": [
|
||||
{ "description": "Simple matching rule", "$ref": "#/$defs/IdWithIdentifier" },
|
||||
{ "description": "Composite matching rule", "type": "array", "items": { "$ref": "#/$defs/IdWithIdentifier" } }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Subpattern 4e: Untagged with Tuple
|
||||
|
||||
**Source Example:** `GroupedSpacingOptions` in `komorebi-bar/src/config.rs`
|
||||
```rust
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
pub enum GroupedSpacingOptions {
|
||||
/// Symmetrical spacing
|
||||
Symmetrical(f32),
|
||||
/// Split spacing (top/left, bottom/right)
|
||||
Split(f32, f32),
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Grouped spacing options",
|
||||
"anyOf": [
|
||||
{ "description": "Symmetrical spacing", "type": "number", "format": "float" },
|
||||
{
|
||||
"description": "Split spacing",
|
||||
"type": "array",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"prefixItems": [
|
||||
{ "type": "number", "format": "float" },
|
||||
{ "type": "number", "format": "float" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Field | JSON Path | Description |
|
||||
|-------|-----------|-------------|
|
||||
| Variant Description | `anyOf[n].description` | Doc comment from the variant |
|
||||
| Variant Title (optional) | `anyOf[n].title` | Title if `#[schemars(title = "...")]` is used |
|
||||
| **No discriminant** | N/A | Untagged enums have no discriminant field - they rely on type matching |
|
||||
|
||||
**Note:** Untagged enums use `anyOf` (not `oneOf`) and do not have explicit discriminant values. The JSON parser tries each variant in order until one matches the input structure.
|
||||
|
||||
**All Untagged Enum Examples:**
|
||||
| Schema | Definition | Lines | Subpattern |
|
||||
|--------|------------|-------|------------|
|
||||
| schema.json | `Colour` | L2397-2409 | 4c |
|
||||
| schema.json | `MatchingRule` | L2882-2897 | 4d |
|
||||
| schema.json | `AspectRatio` | L595-621 | 4a (ref + tuple) |
|
||||
| schema.json | `AppSpecificConfigurationPath` | L554-569 | 4d (ref + array) |
|
||||
| schema.bar.json | `MonitorConfigOrIndex` | L3053-3067 | 4a |
|
||||
| schema.bar.json | `SpacingKind` | L3310-3327 | 4b |
|
||||
| schema.bar.json | `GroupedSpacingOptions` | L2312-2337 | 4e |
|
||||
| schema.bar.json | `RoundingConfig` | L3290-3309 | 4e |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 5: Internally Tagged Enum (Struct Variants with Discriminator)
|
||||
|
||||
**Rust Pattern:** Enum with `#[serde(tag = "field_name")]` where variants have named fields (struct variants).
|
||||
|
||||
**JSONSchema Representation:** Uses `oneOf` where each variant is an object with:
|
||||
- A discriminator field with `{ "type": "string", "const": "VariantName" }`
|
||||
- All other fields from the struct variant
|
||||
- The discriminator field in `required` array
|
||||
|
||||
**Source Example:** `KomorebiTheme` in `komorebi/src/static_config.rs`
|
||||
```rust
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(tag = "palette")]
|
||||
pub enum KomorebiTheme {
|
||||
/// A theme from catppuccin-egui
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Catppuccin"))]
|
||||
Catppuccin {
|
||||
name: komorebi_themes::Catppuccin,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
single_border: Option<komorebi_themes::CatppuccinValue>,
|
||||
// ... more fields
|
||||
},
|
||||
/// A theme from base16-egui-themes
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Base16"))]
|
||||
Base16 {
|
||||
name: komorebi_themes::Base16,
|
||||
// ... fields
|
||||
},
|
||||
/// A custom Base16 theme
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Custom"))]
|
||||
Custom {
|
||||
colours: Base16ColourPalette,
|
||||
// ... fields
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Komorebi theme",
|
||||
"oneOf": [
|
||||
{
|
||||
"title": "Catppuccin",
|
||||
"description": "A theme from catppuccin-egui",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"palette": { "type": "string", "const": "Catppuccin" },
|
||||
"name": { "$ref": "#/$defs/Catppuccin" },
|
||||
"single_border": { "anyOf": [{ "$ref": "#/$defs/CatppuccinValue" }, { "type": "null" }], "default": "Blue" }
|
||||
},
|
||||
"required": ["palette", "name"]
|
||||
},
|
||||
{
|
||||
"title": "Base16",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"palette": { "type": "string", "const": "Base16" },
|
||||
"name": { "$ref": "#/$defs/Base16" }
|
||||
},
|
||||
"required": ["palette", "name"]
|
||||
},
|
||||
{
|
||||
"title": "Custom",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"palette": { "type": "string", "const": "Custom" },
|
||||
"colours": { "$ref": "#/$defs/Base16ColourPalette" }
|
||||
},
|
||||
"required": ["palette", "colours"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Field | JSON Path | Description |
|
||||
|-------|-----------|-------------|
|
||||
| Variant Title | `oneOf[n].title` | Variant name (from `#[schemars(title = "...")]`) |
|
||||
| **Discriminant Field** | `oneOf[n].properties.<tag_name>` | The tag field (e.g., `palette`) as a property |
|
||||
| **Discriminant Value** | `oneOf[n].properties.<tag_name>.const` | The variant name as const value |
|
||||
| Required Fields | `oneOf[n].required` | Contains the tag field name |
|
||||
|
||||
**Note:** The discriminant field name comes from `#[serde(tag = "...")]`. In this case, `palette` is the tag field, and each variant has `properties.palette.const` set to its variant name.
|
||||
|
||||
**Examples:**
|
||||
| Schema | Definition | Discriminator | Lines |
|
||||
|--------|------------|---------------|-------|
|
||||
| schema.json | `KomorebiTheme` | `palette` | L2540-2853 |
|
||||
| schema.bar.json | `KomobarTheme` | `palette` | L2518-2669 |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 6: Internally Tagged Enum with Flattened Newtype Variants
|
||||
|
||||
**Rust Pattern:** Enum with `#[serde(tag = "kind")]` where some variants wrap a struct (newtype pattern). The wrapped struct's fields get flattened.
|
||||
|
||||
**JSONSchema Representation:** Uses `oneOf` where:
|
||||
- Each variant has a discriminator field (`kind`)
|
||||
- Variants that wrap structs include `$ref` at the same level to merge properties
|
||||
|
||||
**Source Example:** `Grouping` in `komorebi-bar/src/render.rs`
|
||||
```rust
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(tag = "kind")]
|
||||
pub enum Grouping {
|
||||
/// No grouping
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "None"))]
|
||||
None,
|
||||
/// Grouped as a whole
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Bar"))]
|
||||
Bar(GroupingConfig),
|
||||
/// Grouped by alignment
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Alignment"))]
|
||||
Alignment(GroupingConfig),
|
||||
/// Grouped individually
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Widget"))]
|
||||
Widget(GroupingConfig),
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Grouping",
|
||||
"oneOf": [
|
||||
{
|
||||
"title": "None",
|
||||
"description": "No grouping is applied",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": { "type": "string", "const": "None" }
|
||||
},
|
||||
"required": ["kind"]
|
||||
},
|
||||
{
|
||||
"title": "Bar",
|
||||
"description": "Widgets are grouped as a whole",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": { "type": "string", "const": "Bar" }
|
||||
},
|
||||
"$ref": "#/$defs/GroupingConfig",
|
||||
"required": ["kind"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Field | JSON Path | Description |
|
||||
|-------|-----------|-------------|
|
||||
| Variant Title | `oneOf[n].title` | Variant name (from `#[schemars(title = "...")]`) |
|
||||
| **Discriminant Field** | `oneOf[n].properties.<tag_name>` | The tag field (e.g., `kind`) as a property |
|
||||
| **Discriminant Value** | `oneOf[n].properties.<tag_name>.const` | The variant name as const value |
|
||||
| Flattened Properties | `oneOf[n].$ref` | Reference to merged struct (only for newtype variants) |
|
||||
| Required Fields | `oneOf[n].required` | Contains the tag field name |
|
||||
|
||||
**Note:** Similar to Pattern 5, but newtype variants include a `$ref` at the variant level that merges in additional properties from the wrapped struct. The `$ref` appears alongside `properties` and `required`.
|
||||
|
||||
**Examples:**
|
||||
| Schema | Definition | Discriminator | Lines |
|
||||
|--------|------------|---------------|-------|
|
||||
| schema.bar.json | `Grouping` | `kind` | L2338-2401 |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 7: Externally Tagged Enum (Newtype Variants Only)
|
||||
|
||||
**Rust Pattern:** Enum with only newtype variants (no unit variants), using default external tagging.
|
||||
|
||||
**JSONSchema Representation:** Uses `oneOf` where each variant is an object with:
|
||||
- The variant name as a property key
|
||||
- The wrapped type as the property value (usually a `$ref`)
|
||||
- `additionalProperties: false`
|
||||
- The variant name in `required` array
|
||||
|
||||
**Source Example:** `WidgetConfig` in `komorebi-bar/src/widgets/widget.rs`
|
||||
```rust
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum WidgetConfig {
|
||||
/// Applications widget
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Applications"))]
|
||||
Applications(ApplicationsConfig),
|
||||
/// Battery widget
|
||||
#[cfg_attr(feature = "schemars", schemars(title = "Battery"))]
|
||||
Battery(BatteryConfig),
|
||||
// ... 8 more variants
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Widget configuration",
|
||||
"oneOf": [
|
||||
{
|
||||
"title": "Applications",
|
||||
"description": "Applications widget configuration",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Applications": { "$ref": "#/$defs/ApplicationsConfig" }
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["Applications"]
|
||||
},
|
||||
{
|
||||
"title": "Battery",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Battery": { "$ref": "#/$defs/BatteryConfig" }
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["Battery"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Field | JSON Path | Description |
|
||||
|-------|-----------|-------------|
|
||||
| Variant Title | `oneOf[n].title` | Variant name (from `#[schemars(title = "...")]`) |
|
||||
| **Discriminant (Property Key)** | `oneOf[n].properties.<VariantName>` | Variant name is the property key itself |
|
||||
| **Discriminant (Required)** | `oneOf[n].required[0]` | Variant name in required array |
|
||||
| Wrapped Type | `oneOf[n].properties.<VariantName>.$ref` | Reference to the wrapped struct |
|
||||
|
||||
**Note:** In externally tagged enums, the variant name serves as both the property key and the discriminant. There is no separate `const` field - the presence of the property key identifies the variant.
|
||||
|
||||
**Examples:**
|
||||
| Schema | Definition | Lines |
|
||||
|--------|------------|-------|
|
||||
| schema.bar.json | `WidgetConfig` | L3525-3669 |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 8: Adjacently Tagged Enum
|
||||
|
||||
**Rust Pattern:** Enum with `#[serde(tag = "type", content = "content")]` - tag and content in separate fields.
|
||||
|
||||
**JSONSchema Representation:** This pattern is used for internal message types but may not appear in the public config schemas.
|
||||
|
||||
**Source Example:** `SocketMessage` in `komorebi/src/core/mod.rs`
|
||||
```rust
|
||||
#[serde_with::serde_as]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Display)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(tag = "type", content = "content")]
|
||||
pub enum SocketMessage {
|
||||
FocusWindow(OperationDirection),
|
||||
MoveWindow(OperationDirection),
|
||||
CancelPreselect,
|
||||
// ... many more variants
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Field | JSON Path | Description |
|
||||
|-------|-----------|-------------|
|
||||
| **Tag Field** | `oneOf[n].properties.<tag_name>` | The tag field (e.g., `type`) |
|
||||
| **Tag Value** | `oneOf[n].properties.<tag_name>.const` | The variant name as const value |
|
||||
| **Content Field** | `oneOf[n].properties.<content_name>` | The content field (e.g., `content`) |
|
||||
| Content Value | `oneOf[n].properties.<content_name>.*` | The variant's data |
|
||||
|
||||
**Note:** `SocketMessage`, `WindowManagerEvent`, and `SystemNotification` use this pattern but are primarily for IPC, not user configuration. They may not appear in the public schema files.
|
||||
|
||||
---
|
||||
|
||||
## Pattern 9: Untagged Hybrid Enum (Unit Variants + $ref Fallback)
|
||||
|
||||
**Rust Pattern:** Macro-generated enum using `extend_enum!` with `#[serde(untagged)]` on the fallback variant.
|
||||
|
||||
**Source Example:** `WorkspacesDisplayFormat` in `komorebi-bar/src/config.rs`
|
||||
```rust
|
||||
extend_enum!(
|
||||
DisplayFormat, WorkspacesDisplayFormat, {
|
||||
/// Show all icons only
|
||||
AllIcons,
|
||||
/// Show both all icons and text
|
||||
AllIconsAndText,
|
||||
/// Show all icons and text for the selected element
|
||||
AllIconsAndTextOnSelected,
|
||||
});
|
||||
```
|
||||
|
||||
Which expands to include an `#[serde(untagged)] Existing(DisplayFormat)` variant.
|
||||
|
||||
**Schema Output:**
|
||||
```json
|
||||
{
|
||||
"description": "Workspaces display format",
|
||||
"anyOf": [
|
||||
{ "description": "Show all icons only", "type": "string", "const": "AllIcons" },
|
||||
{ "description": "Show both all icons and text", "type": "string", "const": "AllIconsAndText" },
|
||||
{ "description": "Show all icons and text for the selected element", "type": "string", "const": "AllIconsAndTextOnSelected" },
|
||||
{ "$ref": "#/$defs/DisplayFormat" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Variant Type | Field | JSON Path | Description |
|
||||
|--------------|-------|-----------|-------------|
|
||||
| Unit | Variant Name | `anyOf[n].const` | The variant name as a string constant |
|
||||
| Unit | Description | `anyOf[n].description` | Doc comment from the variant |
|
||||
| Fallback | Reference | `anyOf[n].$ref` | Reference to the base enum for additional variants |
|
||||
|
||||
**Note:** This hybrid pattern combines explicit unit variants with a `$ref` fallback to another enum. The `$ref` variant has no `const` - it delegates to the referenced enum's schema.
|
||||
|
||||
**Examples:**
|
||||
| Schema | Definition | Lines |
|
||||
|--------|------------|-------|
|
||||
| schema.bar.json | `WorkspacesDisplayFormat` | L3670-3692 |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 10: Generic Enum Instantiations
|
||||
|
||||
**Rust Pattern:** Generic enum like `PerAnimationPrefixConfig<T>` with `#[serde(untagged)]` instantiated with different type parameters.
|
||||
|
||||
**JSONSchema Representation:** Creates separate definitions for each instantiation, with numbered suffixes.
|
||||
|
||||
**Source Example:** (likely in `komorebi/src/animation/mod.rs`)
|
||||
```rust
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
pub enum PerAnimationPrefixConfig<T> {
|
||||
/// Prefixed config
|
||||
Prefix(HashMap<String, T>),
|
||||
/// Global config
|
||||
Global(T),
|
||||
}
|
||||
```
|
||||
|
||||
**Schema Output (for bool):**
|
||||
```json
|
||||
{
|
||||
"description": "Animation configuration",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Prefixed config",
|
||||
"type": "object",
|
||||
"additionalProperties": { "type": "boolean" }
|
||||
},
|
||||
{
|
||||
"description": "Global config",
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Title/Discriminant Location:**
|
||||
| Field | JSON Path | Description |
|
||||
|-------|-----------|-------------|
|
||||
| Variant Description | `anyOf[n].description` | Doc comment from the variant |
|
||||
| **No discriminant** | N/A | Untagged - relies on type matching |
|
||||
| Definition Name | `$defs/<Name>` or `$defs/<Name><N>` | Numbered suffix for each instantiation |
|
||||
|
||||
**Note:** Each generic instantiation creates a separate definition. The first uses the base name, subsequent ones get numeric suffixes (e.g., `PerAnimationPrefixConfig2`, `PerAnimationPrefixConfig3`).
|
||||
|
||||
**Examples in schema.json:**
|
||||
| Definition | Type Parameter | Lines |
|
||||
|------------|---------------|-------|
|
||||
| `PerAnimationPrefixConfig` | `bool` | L3089-3104 |
|
||||
| `PerAnimationPrefixConfig2` | `u64` | L3105-3124 |
|
||||
| `PerAnimationPrefixConfig3` | `AnimationStyle` | L3125-3140 |
|
||||
|
||||
---
|
||||
|
||||
## Summary Table
|
||||
|
||||
| Pattern | Serde Attribute | JSONSchema Keyword | Discriminant Location |
|
||||
|---------|-----------------|-------------------|----------------------|
|
||||
| 1. Simple Unit | (none) | `oneOf` | `oneOf[n].const` |
|
||||
| 2. Unit + Default | `#[schemars(extend)]` | `oneOf` + `default` | `oneOf[n].const` + root `default` |
|
||||
| 3. Mixed (Unit + Newtype) | (none) | `oneOf` | Units: `oneOf[n].const`; Newtypes: `oneOf[n].properties.<Name>` + `oneOf[n].required[0]` |
|
||||
| 4. Untagged | `#[serde(untagged)]` | `anyOf` | None (type-based matching) |
|
||||
| 5. Internally Tagged | `#[serde(tag = "...")]` | `oneOf` | `oneOf[n].properties.<tag>.const` |
|
||||
| 6. Internally Tagged + Newtype | `#[serde(tag = "...")]` | `oneOf` with `$ref` | `oneOf[n].properties.<tag>.const` + `oneOf[n].$ref` |
|
||||
| 7. Externally Tagged (Newtype) | (none/default) | `oneOf` | `oneOf[n].properties.<VariantName>` + `oneOf[n].required[0]` |
|
||||
| 8. Adjacently Tagged | `#[serde(tag, content)]` | `oneOf` | `oneOf[n].properties.<tag>.const` + `oneOf[n].properties.<content>` |
|
||||
| 9. Untagged Hybrid | `#[serde(untagged)]` on fallback | `anyOf` | Units: `anyOf[n].const`; Fallback: `anyOf[n].$ref` |
|
||||
| 10. Generic | `#[serde(untagged)]` | `anyOf` | None; Definition name has numeric suffix |
|
||||
|
||||
### Title Location by Pattern
|
||||
|
||||
| Pattern | Title Location | Notes |
|
||||
|---------|---------------|-------|
|
||||
| 1. Simple Unit | No `title` field | Variant name is in `const` |
|
||||
| 2. Unit + Default | No `title` field | Variant name is in `const` |
|
||||
| 3. Mixed | `oneOf[n].title` (newtypes only) | From `#[schemars(title = "...")]` |
|
||||
| 4. Untagged | `anyOf[n].title` (optional) | Rarely used |
|
||||
| 5. Internally Tagged | `oneOf[n].title` | From `#[schemars(title = "...")]` |
|
||||
| 6. Internally Tagged + Newtype | `oneOf[n].title` | From `#[schemars(title = "...")]` |
|
||||
| 7. Externally Tagged | `oneOf[n].title` | From `#[schemars(title = "...")]` |
|
||||
| 8. Adjacently Tagged | `oneOf[n].title` | From `#[schemars(title = "...")]` |
|
||||
| 9. Untagged Hybrid | No `title` for units | Unit names in `const`, fallback is `$ref` |
|
||||
| 10. Generic | No `title` | Definition name identifies the instantiation |
|
||||
|
||||
---
|
||||
|
||||
## Key Observations
|
||||
|
||||
1. **`oneOf` vs `anyOf`**: Tagged enums use `oneOf` (exactly one must match); untagged enums use `anyOf` (first match wins).
|
||||
|
||||
2. **Unit variants**: Always represented as `{ "type": "string", "const": "VariantName" }`.
|
||||
|
||||
3. **Newtype variants with default tagging**: Become objects where the variant name is a property key containing the data.
|
||||
|
||||
4. **Struct variants with internal tagging**: The tag field appears as a regular property with a `const` value.
|
||||
|
||||
5. **Generic type monomorphization**: Each instantiation gets a separate schema definition with numeric suffixes.
|
||||
|
||||
6. **Descriptions preserved**: Both enum-level and variant-level doc comments appear in the schema.
|
||||
|
||||
7. **`#[schemars(title = "...")]`**: Used to control the `title` field in schema output for variants.
|
||||
|
||||
8. **Custom Serialize/Deserialize**: When enums have custom implementations (like `AnimationStyle`), the schema may not match the actual serialization format exactly.
|
||||
|
||||
9. **Variant ordering in untagged enums**: Order matters! See `SpacingKind` warning comment.
|
||||
|
||||
10. **Optional fields in struct variants**: Use `anyOf: [{ $ref }, { type: null }]` pattern with `default` values.
|
||||
|
||||
---
|
||||
|
||||
## Source Files Reference
|
||||
|
||||
| File | Key Enums |
|
||||
|------|-----------|
|
||||
| `komorebi/src/core/mod.rs` | `ApplicationIdentifier`, `SocketMessage`, `OperationBehaviour`, `WindowContainerBehaviour`, `FloatingLayerBehaviour`, `Placement`, `MoveBehaviour`, `CrossBoundaryBehaviour` |
|
||||
| `komorebi/src/core/config_generation.rs` | `MatchingRule`, `MatchingStrategy`, `ApplicationOptions` |
|
||||
| `komorebi/src/core/default_layout.rs` | `DefaultLayout` |
|
||||
| `komorebi/src/core/animation.rs` | `AnimationStyle` |
|
||||
| `komorebi/src/static_config.rs` | `KomorebiTheme` |
|
||||
| `komorebi/src/animation/mod.rs` | `PerAnimationPrefixConfig<T>` |
|
||||
| `komorebi-bar/src/config.rs` | `MonitorConfigOrIndex`, `SpacingKind`, `GroupedSpacingOptions`, `KomobarTheme`, `WorkspacesDisplayFormat` |
|
||||
| `komorebi-bar/src/render.rs` | `Grouping`, `GroupingStyle`, `RoundingConfig` |
|
||||
| `komorebi-bar/src/widgets/widget.rs` | `WidgetConfig` |
|
||||
| `komorebi-bar/src/widgets/date.rs` | `DateFormat` |
|
||||
| `komorebi-bar/src/widgets/time.rs` | `TimeFormat` |
|
||||
@@ -1,95 +0,0 @@
|
||||
#[path = "src/identifiers.rs"]
|
||||
mod identifiers;
|
||||
|
||||
use identifiers::CSS;
|
||||
use identifiers::TYPE_CLASSES;
|
||||
use lightningcss::rules::CssRule;
|
||||
use lightningcss::selector::Component;
|
||||
use lightningcss::stylesheet::ParserOptions;
|
||||
use lightningcss::stylesheet::StyleSheet;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use struct_iterable::Iterable;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=src/templates/style.css");
|
||||
println!("cargo:rerun-if-changed=src/identifiers.rs");
|
||||
|
||||
let css_content =
|
||||
fs::read_to_string("src/templates/style.css").expect("Failed to read style.css");
|
||||
|
||||
// Parse CSS and extract class names
|
||||
let css_classes = extract_css_classes(&css_content);
|
||||
|
||||
// Collect all defined classes using struct_iterable's automatic iteration
|
||||
let mut defined_classes: HashSet<&str> = HashSet::new();
|
||||
|
||||
// Iterate over CssClasses fields - automatically includes ALL fields
|
||||
for (_field_name, field_value) in CSS.iter() {
|
||||
if let Some(class) = field_value.downcast_ref::<&str>() {
|
||||
defined_classes.insert(*class);
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over TypeClasses fields - automatically includes ALL fields
|
||||
for (_field_name, field_value) in TYPE_CLASSES.iter() {
|
||||
if let Some(class) = field_value.downcast_ref::<&str>() {
|
||||
defined_classes.insert(*class);
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic classes to skip (generated at runtime)
|
||||
let dynamic_prefixes = ["depth-"];
|
||||
|
||||
// Check for CSS classes not defined in identifiers.rs
|
||||
let undefined: Vec<&String> = css_classes
|
||||
.iter()
|
||||
.filter(|c| !defined_classes.contains(c.as_str()))
|
||||
.filter(|c| !dynamic_prefixes.iter().any(|p| c.starts_with(p)))
|
||||
.collect();
|
||||
|
||||
if !undefined.is_empty() {
|
||||
let undefined_list: Vec<&str> = undefined.iter().map(|s| s.as_str()).collect();
|
||||
panic!(
|
||||
"CSS classes in style.css not defined in identifiers.rs:\n {}",
|
||||
undefined_list.join("\n ")
|
||||
);
|
||||
}
|
||||
|
||||
// Warn about defined classes not used in CSS
|
||||
for class in &defined_classes {
|
||||
if !css_classes.contains(*class) {
|
||||
println!("cargo:warning=Class '{}' defined but not styled", class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_css_classes(css: &str) -> HashSet<String> {
|
||||
let mut classes = HashSet::new();
|
||||
|
||||
let stylesheet = StyleSheet::parse(css, ParserOptions::default()).expect("Failed to parse CSS");
|
||||
|
||||
fn collect_from_rules(rules: &[CssRule], classes: &mut HashSet<String>) {
|
||||
for rule in rules {
|
||||
match rule {
|
||||
CssRule::Style(style_rule) => {
|
||||
for selector in style_rule.selectors.0.iter() {
|
||||
for component in selector.iter_raw_match_order() {
|
||||
if let Component::Class(class_name) = component {
|
||||
classes.insert(class_name.0.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
collect_from_rules(&style_rule.rules.0, classes);
|
||||
}
|
||||
CssRule::Media(media_rule) => {
|
||||
collect_from_rules(&media_rule.rules.0, classes);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collect_from_rules(&stylesheet.rules.0, &mut classes);
|
||||
classes
|
||||
}
|
||||
-1827
File diff suppressed because it is too large.
Load diff
@@ -1,371 +0,0 @@
|
||||
//! Single source of truth for all CSS classes and HTML IDs
|
||||
//!
|
||||
//! This module centralizes all identifier strings used in the generated HTML output.
|
||||
//! By defining them here, we ensure consistency between Rust code, HTML templates,
|
||||
//! CSS styles, and JavaScript.
|
||||
|
||||
use serde::Serialize;
|
||||
use struct_iterable::Iterable;
|
||||
|
||||
/// Static HTML element IDs used for JavaScript interaction
|
||||
#[allow(dead_code)] // Used by main crate, not build script
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct HtmlIds {
|
||||
pub search: &'static str,
|
||||
pub search_results: &'static str,
|
||||
pub sidebar: &'static str,
|
||||
pub sidebar_toggle: &'static str,
|
||||
pub root_schema: &'static str,
|
||||
pub definitions: &'static str,
|
||||
pub modal_overlay: &'static str,
|
||||
}
|
||||
|
||||
/// All static HTML IDs
|
||||
#[allow(dead_code)] // Used by main crate, not build script
|
||||
pub const IDS: HtmlIds = HtmlIds {
|
||||
search: "search",
|
||||
search_results: "search-results",
|
||||
sidebar: "sidebar",
|
||||
sidebar_toggle: "sidebar-toggle",
|
||||
root_schema: "root-schema",
|
||||
definitions: "definitions",
|
||||
modal_overlay: "modal-overlay",
|
||||
};
|
||||
|
||||
/// CSS class names organized by category
|
||||
#[derive(Debug, Clone, Serialize, Iterable)]
|
||||
pub struct CssClasses {
|
||||
// Layout
|
||||
pub header: &'static str,
|
||||
pub header_content: &'static str,
|
||||
pub layout: &'static str,
|
||||
pub main_content: &'static str,
|
||||
|
||||
// Sidebar
|
||||
pub sidebar: &'static str,
|
||||
pub sidebar_open: &'static str,
|
||||
pub sidebar_header: &'static str,
|
||||
pub sidebar_toggle: &'static str,
|
||||
pub sidebar_section: &'static str,
|
||||
pub sidebar_section_title: &'static str,
|
||||
|
||||
// Navigation
|
||||
pub nav_list: &'static str,
|
||||
pub nav_link: &'static str,
|
||||
pub outline_list: &'static str,
|
||||
pub outline_item: &'static str,
|
||||
pub outline_children: &'static str,
|
||||
|
||||
// Search
|
||||
pub search_container: &'static str,
|
||||
pub search_results: &'static str,
|
||||
pub search_results_active: &'static str,
|
||||
pub search_result_item: &'static str,
|
||||
pub no_results: &'static str,
|
||||
pub result_name: &'static str,
|
||||
pub result_path: &'static str,
|
||||
pub result_type: &'static str,
|
||||
|
||||
// Schema sections
|
||||
pub schema_section: &'static str,
|
||||
pub schema_inline: &'static str,
|
||||
pub properties_container: &'static str,
|
||||
|
||||
// Property
|
||||
pub property: &'static str,
|
||||
pub property_header: &'static str,
|
||||
pub property_name: &'static str,
|
||||
pub pattern: &'static str,
|
||||
|
||||
// Badges
|
||||
pub badge: &'static str,
|
||||
pub required: &'static str,
|
||||
pub deprecated: &'static str,
|
||||
pub optional: &'static str,
|
||||
|
||||
// Type badges
|
||||
pub type_badge: &'static str,
|
||||
pub type_ref: &'static str,
|
||||
|
||||
// Map display
|
||||
pub map_key: &'static str,
|
||||
pub key_type: &'static str,
|
||||
pub map_arrow: &'static str,
|
||||
|
||||
// Nested schema
|
||||
pub nested_schema: &'static str,
|
||||
pub enum_details: &'static str,
|
||||
pub array_items: &'static str,
|
||||
pub tuple_items: &'static str,
|
||||
pub tuple_item: &'static str,
|
||||
pub tuple_index: &'static str,
|
||||
|
||||
// Constraints
|
||||
pub constraints: &'static str,
|
||||
pub constraint: &'static str,
|
||||
pub label: &'static str,
|
||||
|
||||
// Variants
|
||||
pub variants: &'static str,
|
||||
pub variant: &'static str,
|
||||
pub enum_values: &'static str,
|
||||
|
||||
// Values
|
||||
pub default_value: &'static str,
|
||||
pub const_value: &'static str,
|
||||
|
||||
// Definition
|
||||
pub definition: &'static str,
|
||||
pub definition_name: &'static str,
|
||||
pub highlight: &'static str,
|
||||
|
||||
// Description
|
||||
pub description: &'static str,
|
||||
|
||||
// Usages
|
||||
pub usages: &'static str,
|
||||
pub usage_section: &'static str,
|
||||
pub usage_list: &'static str,
|
||||
|
||||
// Modal
|
||||
pub modal_overlay: &'static str,
|
||||
pub modal: &'static str,
|
||||
pub modal_active: &'static str,
|
||||
pub modal_header: &'static str,
|
||||
pub modal_title: &'static str,
|
||||
pub modal_close: &'static str,
|
||||
pub modal_content: &'static str,
|
||||
pub modal_nav: &'static str,
|
||||
pub modal_nav_btn: &'static str,
|
||||
pub modal_nav_disabled: &'static str,
|
||||
}
|
||||
|
||||
/// All CSS class names
|
||||
pub const CSS: CssClasses = CssClasses {
|
||||
// Layout
|
||||
header: "header",
|
||||
header_content: "header-content",
|
||||
layout: "layout",
|
||||
main_content: "main-content",
|
||||
|
||||
// Sidebar
|
||||
sidebar: "sidebar",
|
||||
sidebar_open: "open",
|
||||
sidebar_header: "sidebar-header",
|
||||
sidebar_toggle: "sidebar-toggle",
|
||||
sidebar_section: "sidebar-section",
|
||||
sidebar_section_title: "sidebar-section-title",
|
||||
|
||||
// Navigation
|
||||
nav_list: "nav-list",
|
||||
nav_link: "nav-link",
|
||||
outline_list: "outline-list",
|
||||
outline_item: "outline-item",
|
||||
outline_children: "outline-children",
|
||||
|
||||
// Search
|
||||
search_container: "search-container",
|
||||
search_results: "search-results",
|
||||
search_results_active: "active",
|
||||
search_result_item: "search-result-item",
|
||||
no_results: "no-results",
|
||||
result_name: "result-name",
|
||||
result_path: "result-path",
|
||||
result_type: "result-type",
|
||||
|
||||
// Schema sections
|
||||
schema_section: "schema-section",
|
||||
schema_inline: "schema-inline",
|
||||
properties_container: "properties-container",
|
||||
|
||||
// Property
|
||||
property: "property",
|
||||
property_header: "property-header",
|
||||
property_name: "property-name",
|
||||
pattern: "pattern",
|
||||
|
||||
// Badges
|
||||
badge: "badge",
|
||||
required: "required",
|
||||
deprecated: "deprecated",
|
||||
optional: "optional",
|
||||
|
||||
// Type badges
|
||||
type_badge: "type-badge",
|
||||
type_ref: "type-ref",
|
||||
|
||||
// Map display
|
||||
map_key: "map-key",
|
||||
key_type: "key-type",
|
||||
map_arrow: "map-arrow",
|
||||
|
||||
// Nested schema
|
||||
nested_schema: "nested-schema",
|
||||
enum_details: "enum-details",
|
||||
array_items: "array-items",
|
||||
tuple_items: "tuple-items",
|
||||
tuple_item: "tuple-item",
|
||||
tuple_index: "tuple-index",
|
||||
|
||||
// Constraints
|
||||
constraints: "constraints",
|
||||
constraint: "constraint",
|
||||
label: "label",
|
||||
|
||||
// Variants
|
||||
variants: "variants",
|
||||
variant: "variant",
|
||||
enum_values: "enum-values",
|
||||
|
||||
// Values
|
||||
default_value: "default-value",
|
||||
const_value: "const-value",
|
||||
|
||||
// Definition
|
||||
definition: "definition",
|
||||
definition_name: "definition-name",
|
||||
highlight: "highlight",
|
||||
|
||||
// Description
|
||||
description: "description",
|
||||
|
||||
// Usages
|
||||
usages: "usages",
|
||||
usage_section: "usage-section",
|
||||
usage_list: "usage-list",
|
||||
|
||||
// Modal
|
||||
modal_overlay: "modal-overlay",
|
||||
modal: "modal",
|
||||
modal_active: "modal-active",
|
||||
modal_header: "modal-header",
|
||||
modal_title: "modal-title",
|
||||
modal_close: "modal-close",
|
||||
modal_content: "modal-content",
|
||||
modal_nav: "modal-nav",
|
||||
modal_nav_btn: "modal-nav-btn",
|
||||
modal_nav_disabled: "disabled",
|
||||
};
|
||||
|
||||
/// Type-specific badge class suffixes (used with type-badge prefix)
|
||||
#[derive(Debug, Clone, Serialize, Iterable)]
|
||||
pub struct TypeClasses {
|
||||
pub string: &'static str,
|
||||
pub number: &'static str,
|
||||
pub integer: &'static str,
|
||||
pub float: &'static str,
|
||||
pub boolean: &'static str,
|
||||
pub null: &'static str,
|
||||
pub object: &'static str,
|
||||
pub array: &'static str,
|
||||
pub r#enum: &'static str,
|
||||
pub union: &'static str,
|
||||
pub r#const: &'static str,
|
||||
}
|
||||
|
||||
/// Type-specific badge classes
|
||||
pub const TYPE_CLASSES: TypeClasses = TypeClasses {
|
||||
string: "type-string",
|
||||
number: "type-number",
|
||||
integer: "type-integer",
|
||||
float: "type-float",
|
||||
boolean: "type-boolean",
|
||||
null: "type-null",
|
||||
object: "type-object",
|
||||
array: "type-array",
|
||||
r#enum: "type-enum",
|
||||
union: "type-union",
|
||||
r#const: "type-const",
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_ids_are_valid_html_ids() {
|
||||
// HTML IDs should not contain spaces and should be lowercase
|
||||
assert!(!IDS.search.contains(' '));
|
||||
assert!(!IDS.search_results.contains(' '));
|
||||
assert!(!IDS.sidebar.contains(' '));
|
||||
assert!(!IDS.sidebar_toggle.contains(' '));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_css_classes_are_valid() {
|
||||
// CSS classes should not contain spaces (multiple classes are separate fields)
|
||||
assert!(!CSS.header.contains(' '));
|
||||
assert!(!CSS.property.contains(' '));
|
||||
assert!(!CSS.type_badge.contains(' '));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_classes_have_prefix() {
|
||||
// All type classes should start with "type-"
|
||||
assert!(TYPE_CLASSES.string.starts_with("type-"));
|
||||
assert!(TYPE_CLASSES.integer.starts_with("type-"));
|
||||
assert!(TYPE_CLASSES.array.starts_with("type-"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_modal_nav_classes_are_valid() {
|
||||
// Modal navigation CSS classes should not contain spaces
|
||||
assert!(!CSS.modal_nav.contains(' '));
|
||||
assert!(!CSS.modal_nav_btn.contains(' '));
|
||||
assert!(!CSS.modal_nav_disabled.contains(' '));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_css_classes_are_styled() {
|
||||
use regex::Regex;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use struct_iterable::Iterable;
|
||||
|
||||
let css_content =
|
||||
fs::read_to_string("src/templates/style.css").expect("Failed to read style.css");
|
||||
|
||||
// Extract all class names from CSS using regex
|
||||
let class_regex = Regex::new(r"\.([a-zA-Z_][a-zA-Z0-9_-]*)").unwrap();
|
||||
let css_classes: HashSet<&str> = class_regex
|
||||
.captures_iter(&css_content)
|
||||
.filter_map(|c| c.get(1).map(|m| m.as_str()))
|
||||
.collect();
|
||||
|
||||
// Verify enum-details specifically (was false-positive before fix)
|
||||
assert!(
|
||||
css_classes.contains("enum-details"),
|
||||
"enum-details should be found in CSS (compound selector .enum-details .enum-values)"
|
||||
);
|
||||
|
||||
// Dynamic prefixes to skip
|
||||
let dynamic_prefixes = ["depth-"];
|
||||
|
||||
// Collect all defined classes and check they're in CSS
|
||||
let mut missing: Vec<&str> = Vec::new();
|
||||
|
||||
for (_field_name, field_value) in CSS.iter() {
|
||||
if let Some(class) = field_value.downcast_ref::<&str>() {
|
||||
if !css_classes.contains(*class)
|
||||
&& !dynamic_prefixes.iter().any(|p| class.starts_with(p))
|
||||
{
|
||||
missing.push(*class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (_field_name, field_value) in TYPE_CLASSES.iter() {
|
||||
if let Some(class) = field_value.downcast_ref::<&str>() {
|
||||
if !css_classes.contains(*class) {
|
||||
missing.push(*class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
missing.is_empty(),
|
||||
"CSS classes defined but not styled: {:?}",
|
||||
missing
|
||||
);
|
||||
}
|
||||
}
|
||||
+11
-41
@@ -2,22 +2,20 @@
|
||||
|
||||
//! # schemars-docgen
|
||||
//!
|
||||
//! Generate HTML documentation from `schemars::Schema` objects.
|
||||
//! Generate MDX documentation from `schemars::Schema` objects.
|
||||
//!
|
||||
//! This library takes a JSON Schema (as produced by schemars) and generates
|
||||
//! a self-contained HTML documentation page with:
|
||||
//! MDX documentation suitable for Astro Starlight with:
|
||||
//!
|
||||
//! - Responsive design (mobile, tablet, desktop)
|
||||
//! - Dark/light mode following system preference
|
||||
//! - Searchable properties
|
||||
//! - Collapsible nested structures
|
||||
//! - YAML frontmatter
|
||||
//! - Starlight components
|
||||
//! - Markdown rendering for descriptions
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use schemars::schema_for;
|
||||
//! use schemars_docgen::{generate_html, Options};
|
||||
//! use schemars_docgen::{generate_mdx, MdxOptions};
|
||||
//!
|
||||
//! #[derive(schemars::JsonSchema)]
|
||||
//! struct MyConfig {
|
||||
@@ -26,31 +24,18 @@
|
||||
//! }
|
||||
//!
|
||||
//! let schema = schema_for!(MyConfig);
|
||||
//! let options = Options::default();
|
||||
//! let html = generate_html(&schema, &options).unwrap();
|
||||
//! let options = MdxOptions::default();
|
||||
//! let mdx = generate_mdx(&schema, &options).unwrap();
|
||||
//! ```
|
||||
|
||||
mod generator;
|
||||
pub mod identifiers;
|
||||
mod mdx_generator;
|
||||
mod prepare;
|
||||
|
||||
pub use generator::Generator;
|
||||
pub use identifiers::CSS;
|
||||
pub use identifiers::IDS;
|
||||
pub use identifiers::TYPE_CLASSES;
|
||||
pub use mdx_generator::MdxGenerator;
|
||||
|
||||
use schemars::Schema;
|
||||
use serde_json::Value;
|
||||
|
||||
/// Options for HTML generation
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Options {
|
||||
/// Override the schema title
|
||||
pub title_override: Option<String>,
|
||||
}
|
||||
|
||||
/// Options for MDX generation
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct MdxOptions {
|
||||
@@ -70,15 +55,6 @@ pub enum Error {
|
||||
Json(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
/// Generate HTML documentation from a schema
|
||||
///
|
||||
/// This is the main entry point for the library. It takes a `schemars::Schema`
|
||||
/// and returns a self-contained HTML string.
|
||||
pub fn generate_html(schema: &Schema, options: &Options) -> Result<String, Error> {
|
||||
let generator = Generator::new()?;
|
||||
generator.generate(schema, options)
|
||||
}
|
||||
|
||||
/// Generate MDX documentation from a schema
|
||||
///
|
||||
/// This generates an MDX document suitable for use with Astro Starlight.
|
||||
@@ -425,7 +401,7 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let result = generate_html(&schema, &Options::default());
|
||||
let result = generate_mdx(&schema, &MdxOptions::default());
|
||||
assert!(result.is_ok(), "Should handle $ref in prefixItems");
|
||||
}
|
||||
|
||||
@@ -450,7 +426,7 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let result = generate_html(&schema, &Options::default());
|
||||
let result = generate_mdx(&schema, &MdxOptions::default());
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"Should handle mixed $ref and type in prefixItems"
|
||||
@@ -475,7 +451,7 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let result = generate_html(&schema, &Options::default());
|
||||
let result = generate_mdx(&schema, &MdxOptions::default());
|
||||
assert!(result.is_ok(), "Should handle anyOf in prefixItems");
|
||||
}
|
||||
|
||||
@@ -498,13 +474,7 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let result = generate_html(&schema, &Options::default());
|
||||
let result = generate_mdx(&schema, &MdxOptions::default());
|
||||
assert!(result.is_ok());
|
||||
let html = result.unwrap();
|
||||
// Homogeneous tuples should show as "array float; 3" not "Tuple Items"
|
||||
assert!(
|
||||
html.contains("float; 3") || html.contains("number; 3"),
|
||||
"Homogeneous tuple should display as [T; N] format"
|
||||
);
|
||||
}
|
||||
}
|
||||
+7
-34
@@ -1,23 +1,10 @@
|
||||
#![warn(clippy::all)]
|
||||
|
||||
use clap::Parser;
|
||||
use clap::ValueEnum;
|
||||
use schemars_docgen::MdxOptions;
|
||||
use schemars_docgen::Options;
|
||||
use schemars_docgen::generate_html;
|
||||
use schemars_docgen::generate_mdx;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Output format for documentation generation
|
||||
#[derive(Debug, Clone, Copy, Default, ValueEnum)]
|
||||
enum Format {
|
||||
/// HTML output (self-contained single file)
|
||||
#[default]
|
||||
Html,
|
||||
/// MDX output for Astro Starlight
|
||||
Mdx,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "schemars-docgen")]
|
||||
#[command(about = "Generate documentation from JSON Schema")]
|
||||
@@ -25,19 +12,15 @@ struct Cli {
|
||||
/// Input JSON Schema file
|
||||
input: PathBuf,
|
||||
|
||||
/// Output file (defaults to input filename with appropriate extension)
|
||||
/// Output file (defaults to input filename with .mdx extension)
|
||||
#[arg(short, long)]
|
||||
output: Option<PathBuf>,
|
||||
|
||||
/// Output format
|
||||
#[arg(short, long, default_value = "html")]
|
||||
format: Format,
|
||||
|
||||
/// Schema title (overrides title from the schema)
|
||||
#[arg(short, long)]
|
||||
title: Option<String>,
|
||||
|
||||
/// Schema description (overrides description from the schema, MDX only)
|
||||
/// Schema description (overrides description from the schema)
|
||||
#[arg(short, long)]
|
||||
description: Option<String>,
|
||||
}
|
||||
@@ -48,25 +31,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let schema_json = std::fs::read_to_string(&cli.input)?;
|
||||
let schema: schemars::Schema = serde_json::from_str(&schema_json)?;
|
||||
|
||||
let (output, extension) = match cli.format {
|
||||
Format::Html => {
|
||||
let options = Options {
|
||||
title_override: cli.title,
|
||||
};
|
||||
(generate_html(&schema, &options)?, "html")
|
||||
}
|
||||
Format::Mdx => {
|
||||
let options = MdxOptions {
|
||||
title_override: cli.title,
|
||||
description_override: cli.description,
|
||||
};
|
||||
(generate_mdx(&schema, &options)?, "mdx")
|
||||
}
|
||||
let options = MdxOptions {
|
||||
title_override: cli.title,
|
||||
description_override: cli.description,
|
||||
};
|
||||
let output = generate_mdx(&schema, &options)?;
|
||||
|
||||
let output_path = cli.output.unwrap_or_else(|| {
|
||||
let mut path = cli.input.clone();
|
||||
path.set_extension(extension);
|
||||
path.set_extension("mdx");
|
||||
path
|
||||
});
|
||||
|
||||
|
||||
+637
-7
@@ -574,9 +574,9 @@ mod tests {
|
||||
"properties": {
|
||||
"value": {
|
||||
"anyOf": [
|
||||
{ "type": "string" },
|
||||
{ "type": "number" },
|
||||
{ "type": "boolean" }
|
||||
{ "type": "string", "description": "A string value" },
|
||||
{ "type": "number", "description": "A number value" },
|
||||
{ "type": "boolean", "description": "A boolean value" }
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -585,10 +585,24 @@ mod tests {
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
// Should show all variant types
|
||||
assert!(mdx.contains("string"), "Should contain string variant");
|
||||
assert!(mdx.contains("number"), "Should contain number variant");
|
||||
assert!(mdx.contains("boolean"), "Should contain boolean variant");
|
||||
// Should show variant descriptions (not type badges for enum variants)
|
||||
assert!(
|
||||
mdx.contains("A string value"),
|
||||
"Should contain string variant description"
|
||||
);
|
||||
assert!(
|
||||
mdx.contains("A number value"),
|
||||
"Should contain number variant description"
|
||||
);
|
||||
assert!(
|
||||
mdx.contains("A boolean value"),
|
||||
"Should contain boolean variant description"
|
||||
);
|
||||
// Should show enum variants section
|
||||
assert!(
|
||||
mdx.contains("Enum variants"),
|
||||
"Should show enum variants header"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -924,4 +938,620 @@ mod tests {
|
||||
let result = escape_braces_outside_code("`{a}` and `{b}` with {c}");
|
||||
assert_eq!(result, "`{a}` and `{b}` with \\{c\\}");
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Enum Pattern Tests - Ensure Value: is never rendered twice
|
||||
// See ENUMS.md for full pattern documentation
|
||||
// =========================================================================
|
||||
|
||||
/// Helper to count occurrences of a pattern in a string
|
||||
fn count_occurrences(haystack: &str, needle: &str) -> usize {
|
||||
haystack.matches(needle).count()
|
||||
}
|
||||
|
||||
/// Helper to count occurrences of "Value:" followed by a specific value
|
||||
fn count_value_occurrences(mdx: &str, value: &str) -> usize {
|
||||
// Look for patterns like: **Value:** `"Horizontal"`
|
||||
let pattern = format!("**Value:** `\"{}\"`", value);
|
||||
count_occurrences(mdx, &pattern)
|
||||
}
|
||||
|
||||
// Pattern 1: Simple Unit Enums (String Constants)
|
||||
// oneOf with {type: "string", const: "Value"}
|
||||
#[test]
|
||||
fn test_pattern1_simple_unit_enum_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"axis": {
|
||||
"description": "Axis selection",
|
||||
"oneOf": [
|
||||
{ "description": "Horizontal axis", "type": "string", "const": "Horizontal" },
|
||||
{ "description": "Vertical axis", "type": "string", "const": "Vertical" },
|
||||
{ "description": "Both axes", "type": "string", "const": "HorizontalAndVertical" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
// Each variant's Value: should appear exactly once
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "Horizontal"),
|
||||
1,
|
||||
"Horizontal Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "Vertical"),
|
||||
1,
|
||||
"Vertical Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "HorizontalAndVertical"),
|
||||
1,
|
||||
"HorizontalAndVertical Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 2: Unit Enum with Default Value
|
||||
// Same as Pattern 1 but with "default" field at enum level
|
||||
#[test]
|
||||
fn test_pattern2_unit_enum_with_default_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"layout": {
|
||||
"description": "A predefined layout",
|
||||
"default": "BSP",
|
||||
"oneOf": [
|
||||
{ "description": "BSP Layout", "type": "string", "const": "BSP" },
|
||||
{ "description": "Columns Layout", "type": "string", "const": "Columns" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "BSP"),
|
||||
1,
|
||||
"BSP Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "Columns"),
|
||||
1,
|
||||
"Columns Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 3: Mixed Enum (Unit Variants + Newtype Variants)
|
||||
// oneOf with unit variants as {type: "string", const: "Name"} and
|
||||
// newtype variants as objects with variant name as property key
|
||||
#[test]
|
||||
fn test_pattern3_mixed_enum_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"format": {
|
||||
"description": "Date format",
|
||||
"oneOf": [
|
||||
{ "description": "Month/Date/Year format", "type": "string", "const": "MonthDateYear" },
|
||||
{ "description": "Year-Month-Date format", "type": "string", "const": "YearMonthDate" },
|
||||
{
|
||||
"title": "Custom",
|
||||
"description": "Custom format",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Custom": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["Custom"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "MonthDateYear"),
|
||||
1,
|
||||
"MonthDateYear Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "YearMonthDate"),
|
||||
1,
|
||||
"YearMonthDate Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 4a: Untagged with Primitives
|
||||
// anyOf with {type: "integer"} and {$ref: "..."}
|
||||
#[test]
|
||||
fn test_pattern4a_untagged_primitives_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"MonitorConfig": { "type": "object", "properties": { "name": { "type": "string" } } }
|
||||
},
|
||||
"properties": {
|
||||
"monitor": {
|
||||
"description": "Monitor configuration or index",
|
||||
"anyOf": [
|
||||
{ "description": "The monitor index", "type": "integer", "format": "uint", "minimum": 0 },
|
||||
{ "description": "The full config", "$ref": "#/$defs/MonitorConfig" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
// For anyOf with primitives, we should see the type badge, not duplicate values
|
||||
// Count total **Value:** occurrences - should not have duplicates
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
// Each variant should have at most one Value: line
|
||||
assert!(
|
||||
total_value_lines <= 2,
|
||||
"Should have at most 2 Value: lines (one per variant). Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 4b: Untagged with Multiple Struct Refs
|
||||
#[test]
|
||||
fn test_pattern4b_untagged_multiple_refs_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"IndividualSpacing": { "type": "object" },
|
||||
"GroupedSpacing": { "type": "object" }
|
||||
},
|
||||
"properties": {
|
||||
"spacing": {
|
||||
"description": "Spacing kind",
|
||||
"anyOf": [
|
||||
{ "description": "All sides", "type": "number", "format": "float" },
|
||||
{ "description": "Individual", "$ref": "#/$defs/IndividualSpacing" },
|
||||
{ "description": "Grouped", "$ref": "#/$defs/GroupedSpacing" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
assert!(
|
||||
total_value_lines <= 3,
|
||||
"Should have at most 3 Value: lines. Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 4c: Untagged with Two $refs
|
||||
#[test]
|
||||
fn test_pattern4c_untagged_two_refs_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"Rgb": { "type": "object" },
|
||||
"Hex": { "type": "string" }
|
||||
},
|
||||
"properties": {
|
||||
"colour": {
|
||||
"description": "Colour representation",
|
||||
"anyOf": [
|
||||
{ "description": "RGB", "$ref": "#/$defs/Rgb" },
|
||||
{ "description": "Hex", "$ref": "#/$defs/Hex" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
assert!(
|
||||
total_value_lines <= 2,
|
||||
"Should have at most 2 Value: lines. Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 4d: Untagged with Single vs Array
|
||||
#[test]
|
||||
fn test_pattern4d_untagged_single_vs_array_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"IdWithIdentifier": { "type": "object" }
|
||||
},
|
||||
"properties": {
|
||||
"rule": {
|
||||
"description": "Matching rule",
|
||||
"anyOf": [
|
||||
{ "description": "Simple rule", "$ref": "#/$defs/IdWithIdentifier" },
|
||||
{ "description": "Composite rule", "type": "array", "items": { "$ref": "#/$defs/IdWithIdentifier" } }
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
assert!(
|
||||
total_value_lines <= 2,
|
||||
"Should have at most 2 Value: lines. Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 4e: Untagged with Tuple
|
||||
#[test]
|
||||
fn test_pattern4e_untagged_tuple_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"spacing_options": {
|
||||
"description": "Grouped spacing options",
|
||||
"anyOf": [
|
||||
{ "description": "Symmetrical", "type": "number", "format": "float" },
|
||||
{
|
||||
"description": "Split spacing",
|
||||
"type": "array",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"prefixItems": [
|
||||
{ "type": "number", "format": "float" },
|
||||
{ "type": "number", "format": "float" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
assert!(
|
||||
total_value_lines <= 2,
|
||||
"Should have at most 2 Value: lines. Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 5: Internally Tagged Enum (Struct Variants with Discriminator)
|
||||
// oneOf with discriminator field having const value
|
||||
#[test]
|
||||
fn test_pattern5_internally_tagged_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"ThemeName": { "type": "string" }
|
||||
},
|
||||
"properties": {
|
||||
"theme": {
|
||||
"description": "Theme selection",
|
||||
"oneOf": [
|
||||
{
|
||||
"title": "Catppuccin",
|
||||
"description": "A catppuccin theme",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"palette": { "type": "string", "const": "Catppuccin" },
|
||||
"name": { "$ref": "#/$defs/ThemeName" }
|
||||
},
|
||||
"required": ["palette", "name"]
|
||||
},
|
||||
{
|
||||
"title": "Base16",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"palette": { "type": "string", "const": "Base16" },
|
||||
"name": { "$ref": "#/$defs/ThemeName" }
|
||||
},
|
||||
"required": ["palette", "name"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
// The discriminator const values should not cause duplicate Value: lines
|
||||
// Catppuccin and Base16 are titles, not const values to be rendered
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
// With internally tagged, we typically don't render Value: for the discriminator
|
||||
// but we might render it for the variant as a whole
|
||||
assert!(
|
||||
total_value_lines <= 2,
|
||||
"Should have reasonable Value: count. Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 6: Internally Tagged Enum with Flattened Newtype Variants
|
||||
// oneOf with properties + $ref at same level
|
||||
#[test]
|
||||
fn test_pattern6_internally_tagged_flatten_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"GroupingConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"style": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"grouping": {
|
||||
"description": "Grouping mode",
|
||||
"oneOf": [
|
||||
{
|
||||
"title": "None",
|
||||
"description": "No grouping",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": { "type": "string", "const": "None" }
|
||||
},
|
||||
"required": ["kind"]
|
||||
},
|
||||
{
|
||||
"title": "Bar",
|
||||
"description": "Bar grouping",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": { "type": "string", "const": "Bar" }
|
||||
},
|
||||
"$ref": "#/$defs/GroupingConfig",
|
||||
"required": ["kind"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
assert!(
|
||||
total_value_lines <= 2,
|
||||
"Should have reasonable Value: count. Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 7: Externally Tagged Enum (Newtype Variants Only)
|
||||
// oneOf with variant name as property key
|
||||
#[test]
|
||||
fn test_pattern7_externally_tagged_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"ApplicationsConfig": { "type": "object" },
|
||||
"BatteryConfig": { "type": "object" }
|
||||
},
|
||||
"properties": {
|
||||
"widget": {
|
||||
"description": "Widget configuration",
|
||||
"oneOf": [
|
||||
{
|
||||
"title": "Applications",
|
||||
"description": "Applications widget",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Applications": { "$ref": "#/$defs/ApplicationsConfig" }
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["Applications"]
|
||||
},
|
||||
{
|
||||
"title": "Battery",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Battery": { "$ref": "#/$defs/BatteryConfig" }
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["Battery"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
assert!(
|
||||
total_value_lines <= 2,
|
||||
"Should have reasonable Value: count. Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 9: Untagged Hybrid Enum (Unit Variants + $ref Fallback)
|
||||
// anyOf mixing const strings + $ref
|
||||
#[test]
|
||||
fn test_pattern9_untagged_hybrid_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"DisplayFormat": {
|
||||
"oneOf": [
|
||||
{ "type": "string", "const": "Text" },
|
||||
{ "type": "string", "const": "Icon" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"format": {
|
||||
"description": "Display format",
|
||||
"anyOf": [
|
||||
{ "description": "All icons", "type": "string", "const": "AllIcons" },
|
||||
{ "description": "All icons and text", "type": "string", "const": "AllIconsAndText" },
|
||||
{ "$ref": "#/$defs/DisplayFormat" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "AllIcons"),
|
||||
1,
|
||||
"AllIcons Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "AllIconsAndText"),
|
||||
1,
|
||||
"AllIconsAndText Value: should appear exactly once. MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Pattern 10: Generic Enum Instantiations
|
||||
// anyOf with {additionalProperties: T} + T
|
||||
#[test]
|
||||
fn test_pattern10_generic_enum_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"description": "Per-animation config",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Prefixed config",
|
||||
"type": "object",
|
||||
"additionalProperties": { "type": "boolean" }
|
||||
},
|
||||
{
|
||||
"description": "Global config",
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
let total_value_lines = count_occurrences(&mdx, "**Value:**");
|
||||
assert!(
|
||||
total_value_lines <= 2,
|
||||
"Should have at most 2 Value: lines. Found {}. MDX:\n{}",
|
||||
total_value_lines,
|
||||
mdx
|
||||
);
|
||||
}
|
||||
|
||||
// Test for the specific issue reported - Pattern 1 with Axis enum
|
||||
#[test]
|
||||
fn test_axis_enum_exact_case_no_duplicate_value() {
|
||||
let generator = MdxGenerator::new().unwrap();
|
||||
// This is the exact schema structure from the bug report
|
||||
let schema = make_schema(json!({
|
||||
"title": "Test",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"Axis": {
|
||||
"description": "Axis",
|
||||
"oneOf": [
|
||||
{ "description": "Horizontal axis", "type": "string", "const": "Horizontal" },
|
||||
{ "description": "Vertical axis", "type": "string", "const": "Vertical" },
|
||||
{ "description": "Both horizontal and vertical axes", "type": "string", "const": "HorizontalAndVertical" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"axis": { "$ref": "#/$defs/Axis" }
|
||||
}
|
||||
}));
|
||||
|
||||
let options = MdxOptions::default();
|
||||
let mdx = generator.generate(&schema, &options).unwrap();
|
||||
|
||||
// The bug was that each variant's Value: was appearing twice
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "Horizontal"),
|
||||
1,
|
||||
"Horizontal Value: should appear exactly once (was appearing twice). MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "Vertical"),
|
||||
1,
|
||||
"Vertical Value: should appear exactly once (was appearing twice). MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
assert_eq!(
|
||||
count_value_occurrences(&mdx, "HorizontalAndVertical"),
|
||||
1,
|
||||
"HorizontalAndVertical Value: should appear exactly once (was appearing twice). MDX:\n{}",
|
||||
mdx
|
||||
);
|
||||
}
|
||||
}
|
||||
+11
-6
@@ -126,12 +126,11 @@ fn extract_type_ref(map: &Map<String, Value>) -> Option<String> {
|
||||
if null_count == 1 {
|
||||
// Find the non-null variant with a $ref
|
||||
for variant in variants {
|
||||
if variant.get("type").and_then(|t| t.as_str()) != Some("null") {
|
||||
if let Some(ref_str) = variant.get("$ref").and_then(|v| v.as_str())
|
||||
&& let Some(type_name) = ref_str.strip_prefix("#/$defs/")
|
||||
{
|
||||
return Some(type_name.to_string());
|
||||
}
|
||||
if variant.get("type").and_then(|t| t.as_str()) != Some("null")
|
||||
&& let Some(ref_str) = variant.get("$ref").and_then(|v| v.as_str())
|
||||
&& let Some(type_name) = ref_str.strip_prefix("#/$defs/")
|
||||
{
|
||||
return Some(type_name.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -645,6 +644,12 @@ fn build_outline_tree(
|
||||
.and_then(|v| v.as_object())
|
||||
{
|
||||
for (name, prop) in props {
|
||||
// Skip properties with const values (discriminator fields in internally tagged enums)
|
||||
// These are shown as variant headings in templates, not as rendered properties
|
||||
if prop.get("const").is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Build the anchor path using the resolved anchor base
|
||||
let child_anchor_path = if anchor_base.is_empty() {
|
||||
name.clone()
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
{%- import "macros.html" as macros -%}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{{ title | default(value="Schema Documentation") }}</title>
|
||||
<style>
|
||||
{% include "style.css" %}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="{{ css.header }}">
|
||||
<div class="{{ css.header_content }}">
|
||||
<h1>
|
||||
{{ title_html | default(value="Schema Documentation") | safe
|
||||
}}
|
||||
</h1>
|
||||
<div class="{{ css.search_container }}">
|
||||
<input
|
||||
type="search"
|
||||
id="{{ ids.search }}"
|
||||
placeholder="Search properties and types..."
|
||||
autocomplete="off"
|
||||
/>
|
||||
<div
|
||||
id="{{ ids.search_results }}"
|
||||
class="{{ css.search_results }}"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="{{ css.layout }}">
|
||||
<nav class="{{ css.sidebar }}" id="{{ ids.sidebar }}">
|
||||
<div class="{{ css.sidebar_header }}">
|
||||
<h2>Navigation</h2>
|
||||
<button
|
||||
class="{{ css.sidebar_toggle }}"
|
||||
id="{{ ids.sidebar_toggle }}"
|
||||
aria-label="Toggle sidebar"
|
||||
>
|
||||
<span></span>
|
||||
</button>
|
||||
</div>
|
||||
{%- if navigation.outline | length > 0 -%}
|
||||
<div class="{{ css.sidebar_section }}">
|
||||
<h3 class="{{ css.sidebar_section_title }}">Outline</h3>
|
||||
<ul class="{{ css.nav_list }} {{ css.outline_list }}">
|
||||
{%- for entry in navigation.outline -%} {{
|
||||
macros::render_outline_item(entry=entry, depth=0) }} {%-
|
||||
endfor -%}
|
||||
</ul>
|
||||
</div>
|
||||
{%- endif -%} {%- if navigation.definitions | length > 0 -%}
|
||||
<div class="{{ css.sidebar_section }}">
|
||||
<h3 class="{{ css.sidebar_section_title }}">Types</h3>
|
||||
<ul class="{{ css.nav_list }}">
|
||||
{%- for def in navigation.definitions -%}
|
||||
<li>
|
||||
<a
|
||||
href="#{{ def.anchor }}"
|
||||
class="{{ css.nav_link }}"
|
||||
data-search-name="{{ def.name | lower }}"
|
||||
>{{ def.display_name | default(value=def.name)
|
||||
}}</a
|
||||
>
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
</div>
|
||||
{%- endif -%}
|
||||
</nav>
|
||||
<main class="{{ css.main_content }}">
|
||||
<section
|
||||
id="{{ ids.root_schema }}"
|
||||
class="{{ css.schema_section }}"
|
||||
>
|
||||
<h2>Configuration</h2>
|
||||
{%- if schema.properties -%}
|
||||
<div class="{{ css.properties_container }}">
|
||||
{%- for prop_name, prop in schema.properties -%} {%- set
|
||||
is_required = prop_name in required_set -%} {{
|
||||
macros::render_property(name=prop_name, node=prop,
|
||||
required=is_required, depth=0, path=prop_name) }} {%-
|
||||
endfor -%}
|
||||
</div>
|
||||
{%- endif -%}
|
||||
</section>
|
||||
{%- if schema["$defs"] -%}
|
||||
<section
|
||||
id="{{ ids.definitions }}"
|
||||
class="{{ css.schema_section }}"
|
||||
>
|
||||
<h2>Type Definitions</h2>
|
||||
{%- for def_name, def in schema["$defs"] -%}
|
||||
<article
|
||||
id="{{ def_name | lower }}"
|
||||
class="{{ css.definition }}"
|
||||
data-search-name="{{ def_name | lower }}"
|
||||
>
|
||||
<h3 class="{{ css.definition_name }}">
|
||||
{{ def._display_name | default(value=def_name) }}
|
||||
</h3>
|
||||
{%- if def.description_html %}
|
||||
<div class="{{ css.description }}">
|
||||
{{ def.description_html | safe }}
|
||||
</div>
|
||||
{% endif -%} {{ macros::render_schema(node=def, depth=0,
|
||||
path=def_name) }} {# Usages section at bottom - use
|
||||
embedded _usages to avoid lookup issues with special
|
||||
chars #} {%- if def._usages and
|
||||
(def._usages.config_usages | length > 0 or
|
||||
def._usages.type_references | length > 0) -%}
|
||||
<div class="{{ css.usages }}">
|
||||
{%- if def._usages.config_usages | length > 0 -%}
|
||||
<div class="{{ css.usage_section }}">
|
||||
<h4>Configuration Usage</h4>
|
||||
<ul class="{{ css.usage_list }}">
|
||||
{%- for usage in def._usages.config_usages
|
||||
-%}
|
||||
<li>
|
||||
<a href="#{{ usage.anchor }}"
|
||||
><code>{{ usage.path }}</code></a
|
||||
>
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
</div>
|
||||
{%- endif -%} {%- if def._usages.type_references |
|
||||
length > 0 -%}
|
||||
<div class="{{ css.usage_section }}">
|
||||
<h4>Referenced by</h4>
|
||||
<ul class="{{ css.usage_list }}">
|
||||
{%- for ref in def._usages.type_references
|
||||
-%} {%- set ref_display =
|
||||
display_names[ref.type_name] |
|
||||
default(value=ref.type_name) -%}
|
||||
<li>
|
||||
<a href="#{{ ref.anchor }}"
|
||||
>{{ ref_display }}</a
|
||||
>
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
</div>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{%- endif -%}
|
||||
</article>
|
||||
{%- endfor -%}
|
||||
</section>
|
||||
{%- endif -%}
|
||||
</main>
|
||||
</div>
|
||||
<div class="{{ css.modal_overlay }}" id="{{ ids.modal_overlay }}">
|
||||
<div class="{{ css.modal }}">
|
||||
<div class="{{ css.modal_header }}">
|
||||
<div class="{{ css.modal_nav }}">
|
||||
<button
|
||||
class="{{ css.modal_nav_btn }} {{ css.modal_nav_disabled }}"
|
||||
aria-label="Go back"
|
||||
data-dir="back"
|
||||
>
|
||||
←
|
||||
</button>
|
||||
<button
|
||||
class="{{ css.modal_nav_btn }} {{ css.modal_nav_disabled }}"
|
||||
aria-label="Go forward"
|
||||
data-dir="forward"
|
||||
>
|
||||
→
|
||||
</button>
|
||||
</div>
|
||||
<h3 class="{{ css.modal_title }}"></h3>
|
||||
<button
|
||||
class="{{ css.modal_close }}"
|
||||
aria-label="Close modal"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<div class="{{ css.modal_content }}"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function(){const searchInput=document.getElementById('{{ ids.search }}');const searchResults=document.getElementById('{{ ids.search_results }}');const searchIndex={{ search_index | json_encode() | safe }};searchInput.addEventListener('input',function(e){const query=e.target.value.toLowerCase().trim();if(!query){searchResults.innerHTML='';searchResults.classList.remove('{{ css.search_results_active }}');return;}const matches=searchIndex.filter(item=>item.name.toLowerCase().includes(query)||item.path.toLowerCase().includes(query)).slice(0,10);if(matches.length===0){searchResults.innerHTML='<div class="{{ css.search_result_item }} {{ css.no_results }}">No results found</div>';}else{searchResults.innerHTML=matches.map(item=>`<a href="#${item.anchor}" class="{{ css.search_result_item }}"><span class="{{ css.result_name }}">${item.name}</span><span class="{{ css.result_path }}">${item.path}</span><span class="{{ css.result_type }}">${item.entry_type}</span></a>`).join('');}searchResults.classList.add('{{ css.search_results_active }}');});document.addEventListener('click',function(e){if(!searchInput.contains(e.target)&&!searchResults.contains(e.target)){searchResults.classList.remove('{{ css.search_results_active }}');}});searchInput.addEventListener('keydown',function(e){if(e.key==='Escape'){searchResults.classList.remove('{{ css.search_results_active }}');searchInput.blur();}});const sidebarToggle=document.getElementById('{{ ids.sidebar_toggle }}');const sidebar=document.getElementById('{{ ids.sidebar }}');if(sidebarToggle&&sidebar){sidebarToggle.addEventListener('click',function(){sidebar.classList.toggle('{{ css.sidebar_open }}');});}document.querySelectorAll('a[href^="#"]').forEach(anchor=>{anchor.addEventListener('click',function(e){const targetId=this.getAttribute('href').slice(1);const target=document.getElementById(targetId);if(target){target.classList.add('{{ css.highlight }}');setTimeout(()=>target.classList.remove('{{ css.highlight }}'),2000);}if(sidebar){sidebar.classList.remove('{{ css.sidebar_open }}');}searchResults.classList.remove('{{ css.search_results_active }}');});});const modalOverlay=document.getElementById('{{ ids.modal_overlay }}');const modalTitle=modalOverlay.querySelector('.{{ css.modal_title }}');const modalContent=modalOverlay.querySelector('.{{ css.modal_content }}');const modalClose=modalOverlay.querySelector('.{{ css.modal_close }}');const modalNavBtns=modalOverlay.querySelectorAll('.{{ css.modal_nav_btn }}');const configSection=document.getElementById('{{ ids.root_schema }}');let history=[];let historyIndex=-1;function updateNavButtons(){modalNavBtns.forEach(btn=>{const dir=btn.dataset.dir;if(dir==='back'){btn.classList.toggle('{{ css.modal_nav_disabled }}',historyIndex<=0);}else if(dir==='forward'){btn.classList.toggle('{{ css.modal_nav_disabled }}',historyIndex>=history.length-1);}});}function showType(typeName){const typeId=typeName.toLowerCase();const typeDef=document.getElementById(typeId);if(!typeDef)return false;const clone=typeDef.cloneNode(true);clone.removeAttribute('id');const usages=clone.querySelector('.{{ css.usages }}');if(usages)usages.remove();const titleEl=clone.querySelector('.{{ css.definition_name }}');modalTitle.textContent=titleEl?titleEl.textContent:typeName;if(titleEl)titleEl.remove();modalContent.innerHTML='';modalContent.appendChild(clone);return true;}function openTypeModal(typeName,addToHistory=true){if(!showType(typeName))return;if(addToHistory){history=history.slice(0,historyIndex+1);history.push(typeName);historyIndex=history.length-1;}updateNavButtons();modalOverlay.classList.add('{{ css.modal_active }}');document.body.style.overflow='hidden';}function navigateHistory(direction){if(direction==='back'&&historyIndex>0){historyIndex--;showType(history[historyIndex]);updateNavButtons();}else if(direction==='forward'&&historyIndex<history.length-1){historyIndex++;showType(history[historyIndex]);updateNavButtons();}}function closeModal(){modalOverlay.classList.remove('{{ css.modal_active }}');document.body.style.overflow='';history=[];historyIndex=-1;updateNavButtons();}modalNavBtns.forEach(btn=>{btn.addEventListener('click',function(){if(!this.classList.contains('{{ css.modal_nav_disabled }}')){navigateHistory(this.dataset.dir);}});});configSection.addEventListener('click',function(e){const typeRef=e.target.closest('.{{ css.type_ref }}');if(typeRef){e.preventDefault();const href=typeRef.getAttribute('href');const typeName=href.slice(1);openTypeModal(typeName);}});modalContent.addEventListener('click',function(e){const typeRef=e.target.closest('.{{ css.type_ref }}');if(typeRef){e.preventDefault();const href=typeRef.getAttribute('href');const typeName=href.slice(1);openTypeModal(typeName);}});modalOverlay.addEventListener('click',function(e){if(e.target===modalOverlay)closeModal();});modalClose.addEventListener('click',closeModal);document.addEventListener('keydown',function(e){if(!modalOverlay.classList.contains('{{ css.modal_active }}'))rLine truncated
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,372 +0,0 @@
|
||||
{# Render a hierarchical outline item with collapsible children #}
|
||||
{% macro render_outline_item(entry, depth) %}
|
||||
{%- if entry.children | length > 0 -%}
|
||||
<li class="{{ css.outline_item }} depth-{{ depth }}">
|
||||
<details>
|
||||
<summary>
|
||||
<a href="#{{ entry.anchor }}" class="{{ css.nav_link }}" data-search-name="{{ entry.name | lower }}">{{ entry.name }}</a>
|
||||
</summary>
|
||||
<ul class="{{ css.outline_children }}">
|
||||
{%- for child in entry.children -%}
|
||||
{{ self::render_outline_item(entry=child, depth=depth + 1) }}
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
{%- else -%}
|
||||
<li class="{{ css.outline_item }} depth-{{ depth }}">
|
||||
<a href="#{{ entry.anchor }}" class="{{ css.nav_link }}" data-search-name="{{ entry.name | lower }}">{{ entry.name }}</a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{% endmacro render_outline_item %}
|
||||
|
||||
{# Render a property with its name and schema #}
|
||||
{# Note: Using 'node' instead of 'schema' to avoid conflict with global context #}
|
||||
{% macro render_property(name, node, required, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
<div class="{{ css.property }} depth-{{ depth }}" id="{{ path | lower | replace(from=".", to="-") }}" data-search-name="{{ name | lower }}">
|
||||
<div class="{{ css.property_header }}">
|
||||
<code class="{{ css.property_name }}">{{ name }}</code>
|
||||
{%- if required %}<span class="{{ css.badge }} {{ css.required }}">required</span>{% endif -%}
|
||||
{%- if node.deprecated %}<span class="{{ css.badge }} {{ css.deprecated }}">deprecated</span>{% endif -%}
|
||||
{{ self::render_type_badge(node=node) }}
|
||||
</div>
|
||||
{%- if node.description_html %}<div class="{{ css.description }}">{{ node.description_html | safe }}</div>{% endif -%}
|
||||
{{ self::render_constraints(node=node) }}
|
||||
{%- if node.default %}<div class="{{ css.default_value }}"><span class="{{ css.label }}">Default:</span> {% if node._default_ref and schema["$defs"][node._default_ref] %}<code><a href="#{{ node._default_ref | lower }}">{{ node.default | json_encode() }}</a></code>{% else %}<code>{{ node.default | json_encode() }}</code>{% endif %}</div>{% endif -%}
|
||||
{{ self::render_schema_body(node=node, depth=depth, path=path) }}
|
||||
</div>
|
||||
{%- else -%}
|
||||
<div class="{{ css.property }} depth-{{ depth }}">Schema nested too deeply. See type definition.</div>
|
||||
{%- endif -%}
|
||||
{% endmacro render_property %}
|
||||
|
||||
{# Render the type badge for a schema #}
|
||||
{% macro render_type_badge(node) %}
|
||||
{%- if node["$ref"] -%}
|
||||
{%- set ref_name = node["$ref"] | replace(from="#/$defs/", to="") -%}
|
||||
{%- set display = display_names[ref_name] | default(value=ref_name) -%}
|
||||
{%- if schema["$defs"][ref_name] -%}
|
||||
{%- set ref_def = schema["$defs"][ref_name] -%}
|
||||
<a href="#{{ ref_name | lower }}" class="{{ css.type_ref }}">{{ display }}</a>
|
||||
{%- if ref_def._wrapper_inner %} {{ self::render_type_badge(node=ref_def._wrapper_inner) }}{%- endif -%}
|
||||
{%- else -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.object }}">$ref</span>
|
||||
{%- endif -%}
|
||||
{%- elif node.type -%}
|
||||
{%- if node.type is string -%}
|
||||
{%- if node.type == "array" and node.prefixItems -%}
|
||||
{# Check if all prefixItems have the same type (homogeneous tuple) #}
|
||||
{%- set first_type = node.prefixItems | first -%}
|
||||
{%- set_global is_homogeneous = true -%}
|
||||
{%- for item in node.prefixItems -%}
|
||||
{%- if item.type is defined and first_type.type is defined -%}
|
||||
{%- if item.type != first_type.type -%}
|
||||
{%- set_global is_homogeneous = false -%}
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{# If either lacks a direct type (uses $ref, anyOf, etc.), not homogeneous #}
|
||||
{%- set_global is_homogeneous = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- if is_homogeneous and first_type.type -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.array }}">array</span> {% if first_type.type == "number" %}<span class="{{ css.type_badge }} {{ type_classes.float }}">float; {{ node.prefixItems | length }}</span>{% else %}<span class="{{ css.type_badge }} type-{{ first_type.type }}">{{ first_type.type }}; {{ node.prefixItems | length }}</span>{% endif %}
|
||||
{%- else -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.array }}">array</span> <span class="{{ css.type_badge }} {{ type_classes.array }}">tuple</span>
|
||||
{%- endif -%}
|
||||
{%- elif node.type == "array" and node.items -%}
|
||||
{# Show array with item type as separate badge #}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.array }}">array</span> {{ self::render_type_badge(node=node.items) }}
|
||||
{%- else -%}
|
||||
<span class="{{ css.type_badge }} type-{{ node.type }}">{{ node.type }}</span>
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{# Check for Option<T> pattern: type array with exactly 2 types where one is null #}
|
||||
{%- if node.type | length == 2 and "null" in node.type -%}
|
||||
<span class="{{ css.badge }} {{ css.optional }}">optional</span>
|
||||
{%- for t in node.type -%}
|
||||
{%- if t != "null" %} {% if t == "array" and node.items %}<span class="{{ css.type_badge }} {{ type_classes.array }}">array</span> {{ self::render_type_badge(node=node.items) }}{% else %}<span class="{{ css.type_badge }} type-{{ t }}">{{ t }}</span>{% endif %}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- else -%}
|
||||
{%- for t in node.type %} <span class="{{ css.type_badge }} type-{{ t }}">{{ t }}</span>{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- elif node.anyOf -%}
|
||||
{# Check for wrapper type pattern first (detected in prepare.rs) #}
|
||||
{%- if node._wrapper_type -%}
|
||||
{# Wrapper type: show inner type badge (type name shown separately in type definitions) #}
|
||||
{{ self::render_type_badge(node=node._wrapper_inner) }}
|
||||
{# Check for Option<T> pattern: anyOf with exactly 2 variants where one is null #}
|
||||
{%- elif node.anyOf | length == 2 -%}
|
||||
{%- set first = node.anyOf | first -%}
|
||||
{%- set second = node.anyOf | last -%}
|
||||
{%- if second.type and second.type == "null" -%}
|
||||
<span class="{{ css.badge }} {{ css.optional }}">optional</span> {{ self::render_type_badge(node=first) }}
|
||||
{%- elif first.type and first.type == "null" -%}
|
||||
<span class="{{ css.badge }} {{ css.optional }}">optional</span> {{ self::render_type_badge(node=second) }}
|
||||
{%- else -%}
|
||||
{# Check if all variants are string const (enum pattern) #}
|
||||
{%- set_global is_string_enum = true -%}
|
||||
{%- for variant in node.anyOf -%}
|
||||
{%- if variant.type and variant.type == "string" and variant.const -%}
|
||||
{# valid string const #}
|
||||
{%- else -%}
|
||||
{%- set_global is_string_enum = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- if is_string_enum -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.string }}">string</span> <span class="{{ css.type_badge }} {{ type_classes.enum }}">enum</span>
|
||||
{%- else -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.enum }}">enum</span>
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{# Check if all variants are string const (enum pattern) #}
|
||||
{%- set_global is_string_enum = true -%}
|
||||
{%- for variant in node.anyOf -%}
|
||||
{%- if variant.type and variant.type == "string" and variant.const -%}
|
||||
{# valid string const #}
|
||||
{%- else -%}
|
||||
{%- set_global is_string_enum = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- if is_string_enum -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.string }}">string</span> <span class="{{ css.type_badge }} {{ type_classes.enum }}">enum</span>
|
||||
{%- else -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.enum }}">enum</span>
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- elif node.oneOf -%}
|
||||
{# Check if all variants are string const (enum pattern from schemars with doc comments) #}
|
||||
{%- set_global is_string_enum = true -%}
|
||||
{%- for variant in node.oneOf -%}
|
||||
{%- if variant.type and variant.type == "string" and variant.const -%}
|
||||
{# This variant is a string const, keep is_string_enum true #}
|
||||
{%- else -%}
|
||||
{%- set_global is_string_enum = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- if is_string_enum -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.string }}">string</span> <span class="{{ css.type_badge }} {{ type_classes.enum }}">enum</span>
|
||||
{%- else -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.enum }}">enum</span>
|
||||
{%- endif -%}
|
||||
{%- elif node.allOf -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.union }}">allOf</span>
|
||||
{%- elif node.const -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.const }}">const</span>
|
||||
{%- elif node.enum -%}
|
||||
<span class="{{ css.type_badge }} {{ type_classes.enum }}">enum</span>
|
||||
{%- endif -%}
|
||||
{% endmacro render_type_badge %}
|
||||
|
||||
{# Render constraints like min, max, pattern, format #}
|
||||
{% macro render_constraints(node) %}
|
||||
{# Check if this is a homogeneous tuple - skip minItems/maxItems if so #}
|
||||
{%- set_global skip_item_constraints = false -%}
|
||||
{%- if node.prefixItems -%}
|
||||
{%- set first_type = node.prefixItems | first -%}
|
||||
{%- set_global is_homogeneous = true -%}
|
||||
{%- for item in node.prefixItems -%}
|
||||
{%- if item.type is defined and first_type.type is defined -%}
|
||||
{%- if item.type != first_type.type -%}
|
||||
{%- set_global is_homogeneous = false -%}
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{# If either lacks a direct type (uses $ref, anyOf, etc.), not homogeneous #}
|
||||
{%- set_global is_homogeneous = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- if is_homogeneous and first_type.type -%}
|
||||
{%- set_global skip_item_constraints = true -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- if node.format or node.pattern or node.minimum is defined or node.maximum is defined or node.minLength is defined or node.maxLength is defined or (node.minItems is defined and not skip_item_constraints) or (node.maxItems is defined and not skip_item_constraints) -%}
|
||||
<div class="{{ css.constraints }}">
|
||||
{%- if node.format %}<span class="{{ css.constraint }}"><span class="{{ css.label }}">Format:</span> <code>{{ node.format }}</code></span>{% endif -%}
|
||||
{%- if node.pattern %}<span class="{{ css.constraint }}"><span class="{{ css.label }}">Pattern:</span> <code>{{ node.pattern }}</code></span>{% endif -%}
|
||||
{%- if node.minimum is defined %}<span class="{{ css.constraint }}"><span class="{{ css.label }}">Min:</span> {{ node.minimum }}</span>{% endif -%}
|
||||
{%- if node.maximum is defined %}<span class="{{ css.constraint }}"><span class="{{ css.label }}">Max:</span> {{ node.maximum }}</span>{% endif -%}
|
||||
{%- if node.minLength is defined %}<span class="{{ css.constraint }}"><span class="{{ css.label }}">Min length:</span> {{ node.minLength }}</span>{% endif -%}
|
||||
{%- if node.maxLength is defined %}<span class="{{ css.constraint }}"><span class="{{ css.label }}">Max length:</span> {{ node.maxLength }}</span>{% endif -%}
|
||||
{%- if node.minItems is defined and not skip_item_constraints %}<span class="{{ css.constraint }}"><span class="{{ css.label }}">Min items:</span> {{ node.minItems }}</span>{% endif -%}
|
||||
{%- if node.maxItems is defined and not skip_item_constraints %}<span class="{{ css.constraint }}"><span class="{{ css.label }}">Max items:</span> {{ node.maxItems }}</span>{% endif -%}
|
||||
</div>
|
||||
{%- endif -%}
|
||||
{% endmacro render_constraints %}
|
||||
|
||||
{# Render the body of a schema (properties, items, variants, etc.) #}
|
||||
{% macro render_schema_body(node, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
{%- if node["$ref"] -%}
|
||||
{# Reference only, already shown as type badge #}
|
||||
{%- elif node.properties -%}
|
||||
{%- set required_arr = node.required | default(value=[]) -%}
|
||||
<details class="{{ css.nested_schema }}" open>
|
||||
<summary>Properties ({{ node.properties | length }})</summary>
|
||||
<div class="{{ css.properties_container }}">
|
||||
{%- for prop_name, prop in node.properties -%}
|
||||
{%- set is_required = prop_name in required_arr -%}
|
||||
{{ self::render_property(name=prop_name, node=prop, required=is_required, depth=depth + 1, path=path ~ "." ~ prop_name) }}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</details>
|
||||
{%- elif node.patternProperties -%}
|
||||
<div class="{{ css.properties_container }}">
|
||||
{%- for pattern, prop in node.patternProperties -%}
|
||||
<div class="{{ css.property }} depth-{{ depth + 1 }}">
|
||||
<div class="{{ css.property_header }}">
|
||||
{# Convert known patterns to friendly type names - show as quoted string to indicate JSON string key #}
|
||||
{# Note: patterns use single backslash in the parsed JSON value #}
|
||||
{%- if pattern == "^\d+$" or pattern == "^[0-9]+$" or pattern == "^-?\d+$" or pattern == "^-?[0-9]+$" -%}
|
||||
<span class="{{ css.map_key }}">"<<span class="{{ css.key_type }}">integer</span>>"</span>
|
||||
{%- elif pattern == ".*" or pattern == "^.*$" -%}
|
||||
<span class="{{ css.map_key }}">"<<span class="{{ css.key_type }}">string</span>>"</span>
|
||||
{%- else -%}
|
||||
<code class="{{ css.property_name }} {{ css.pattern }}">{{ pattern }}</code>
|
||||
<span class="{{ css.badge }} {{ css.pattern }}">pattern</span>
|
||||
{%- endif -%}
|
||||
<span class="{{ css.map_arrow }}">→</span>
|
||||
{{ self::render_type_badge(node=prop) }}
|
||||
</div>
|
||||
{%- if prop.description_html %}<div class="{{ css.description }}">{{ prop.description_html | safe }}</div>{% endif -%}
|
||||
{{ self::render_schema_body(node=prop, depth=depth + 1, path=path ~ ".[key]") }}
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
{%- elif node.items -%}
|
||||
{%- if node.items["$ref"] -%}
|
||||
{# Already shown in type badge, no dropdown needed #}
|
||||
{%- elif node.items.type and node.items.type is string -%}
|
||||
{# Simple type (string, number, integer, boolean) - already shown in type badge #}
|
||||
{%- else -%}
|
||||
{# Complex item type needs dropdown #}
|
||||
<details class="{{ css.nested_schema }}" open>
|
||||
<summary>Array Items</summary>
|
||||
<div class="{{ css.array_items }}">{{ self::render_schema(node=node.items, depth=depth + 1, path=path ~ "[]") }}</div>
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- elif node.prefixItems -%}
|
||||
{# Check if homogeneous tuple - already shown as [T; N] in badge #}
|
||||
{%- set first_type = node.prefixItems | first -%}
|
||||
{%- set_global is_homogeneous = true -%}
|
||||
{%- for item in node.prefixItems -%}
|
||||
{%- if item.type is defined and first_type.type is defined -%}
|
||||
{%- if item.type != first_type.type -%}
|
||||
{%- set_global is_homogeneous = false -%}
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{# If either lacks a direct type (uses $ref, anyOf, etc.), not homogeneous #}
|
||||
{%- set_global is_homogeneous = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- if is_homogeneous and first_type.type -%}
|
||||
{# Homogeneous tuple - already shown as [T; N] in badge, no dropdown needed #}
|
||||
{%- else -%}
|
||||
{# Heterogeneous tuple - show dropdown #}
|
||||
<details class="{{ css.nested_schema }}" open>
|
||||
<summary>Tuple Items ({{ node.prefixItems | length }})</summary>
|
||||
<div class="{{ css.tuple_items }}">
|
||||
{%- for item in node.prefixItems -%}
|
||||
<div class="{{ css.tuple_item }}"><span class="{{ css.tuple_index }}">[{{ loop.index0 }}]</span>{{ self::render_schema(node=item, depth=depth + 1, path=path ~ "[" ~ loop.index0 ~ "]") }}</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- elif node.anyOf -%}
|
||||
{# Check for wrapper type pattern first (detected in prepare.rs) #}
|
||||
{%- if node._wrapper_type -%}
|
||||
{# Wrapper type - render the inner type's body #}
|
||||
{{ self::render_schema_body(node=node._wrapper_inner, depth=depth, path=path) }}
|
||||
{# Check for Option<T> pattern: anyOf with exactly 2 variants where one is null #}
|
||||
{%- elif node.anyOf | length == 2 -%}
|
||||
{%- set first = node.anyOf | first -%}
|
||||
{%- set second = node.anyOf | last -%}
|
||||
{%- if second.type and second.type == "null" -%}
|
||||
{# Option<T> - just render the non-null variant's body #}
|
||||
{{ self::render_schema_body(node=first, depth=depth, path=path) }}
|
||||
{%- elif first.type and first.type == "null" -%}
|
||||
{# Option<T> with null first - just render the non-null variant's body #}
|
||||
{{ self::render_schema_body(node=second, depth=depth, path=path) }}
|
||||
{%- else -%}
|
||||
{# Check if all variants are string const (enum pattern) #}
|
||||
{%- set_global is_string_enum = true -%}
|
||||
{%- for variant in node.anyOf -%}
|
||||
{%- if variant.type and variant.type == "string" and variant.const -%}
|
||||
{# valid string const #}
|
||||
{%- else -%}
|
||||
{%- set_global is_string_enum = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{# Render all anyOf variants using full schema rendering #}
|
||||
<details class="{{ css.nested_schema }} {{ css.enum_details }}" open>
|
||||
<summary>Enum variants ({{ node.anyOf | length }})</summary>
|
||||
<div class="{{ css.variants }}">
|
||||
{%- for variant in node.anyOf -%}
|
||||
<div class="{{ css.variant }}">{{ self::render_schema(node=variant, depth=depth + 1, path=path ~ ".anyOf[" ~ loop.index0 ~ "]") }}</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{# Render all anyOf variants using full schema rendering #}
|
||||
<details class="{{ css.nested_schema }} {{ css.enum_details }}" open>
|
||||
<summary>Enum variants ({{ node.anyOf | length }})</summary>
|
||||
<div class="{{ css.variants }}">
|
||||
{%- for variant in node.anyOf -%}
|
||||
<div class="{{ css.variant }}">{{ self::render_schema(node=variant, depth=depth + 1, path=path ~ ".anyOf[" ~ loop.index0 ~ "]") }}</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- elif node.oneOf -%}
|
||||
{# Render all oneOf variants using full schema rendering #}
|
||||
<details class="{{ css.nested_schema }} {{ css.enum_details }}" open>
|
||||
<summary>Enum variants ({{ node.oneOf | length }})</summary>
|
||||
<div class="{{ css.variants }}">
|
||||
{%- for variant in node.oneOf -%}
|
||||
<div class="{{ css.variant }}">{{ self::render_schema(node=variant, depth=depth + 1, path=path ~ ".oneOf[" ~ loop.index0 ~ "]") }}</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</details>
|
||||
{%- elif node.allOf -%}
|
||||
<details class="{{ css.nested_schema }}" open>
|
||||
<summary>All of ({{ node.allOf | length }} schemas)</summary>
|
||||
<div class="{{ css.variants }}">
|
||||
{%- for variant in node.allOf -%}
|
||||
<div class="{{ css.variant }}">{{ self::render_schema(node=variant, depth=depth + 1, path=path ~ ".allOf[" ~ loop.index0 ~ "]") }}</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</details>
|
||||
{%- elif node.enum -%}
|
||||
{%- set enum_count = node.enum | length -%}
|
||||
<details class="{{ css.nested_schema }} {{ css.enum_details }}" open>
|
||||
<summary>Enum variants ({{ enum_count }})</summary>
|
||||
<ul class="{{ css.enum_values }}">
|
||||
{%- for value in node.enum -%}<li><code>{{ value | json_encode() }}</code></li>{%- endfor -%}
|
||||
</ul>
|
||||
</details>
|
||||
{%- elif node.const -%}
|
||||
<div class="{{ css.const_value }}"><span class="{{ css.label }}">Value:</span> <code>{{ node.const | json_encode() }}</code></div>
|
||||
{%- endif -%}
|
||||
{%- if node.additionalProperties and node.additionalProperties is object -%}
|
||||
<details class="{{ css.nested_schema }}" open>
|
||||
<summary>Additional Properties</summary>
|
||||
{{ self::render_schema(node=node.additionalProperties, depth=depth + 1, path=path ~ ".[*]") }}
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{% endmacro render_schema_body %}
|
||||
|
||||
{# Render a schema without property wrapper #}
|
||||
{% macro render_schema(node, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
<div class="{{ css.schema_inline }}">
|
||||
{{ self::render_type_badge(node=node) }}{%- if node.description_html %} <div class="{{ css.description }}">{{ node.description_html | safe }}</div>{% endif -%}
|
||||
{{ self::render_constraints(node=node) }}
|
||||
{%- if node.default %}<div class="{{ css.default_value }}"><span class="{{ css.label }}">Default:</span> {% if node._default_ref and schema["$defs"][node._default_ref] %}<code><a href="#{{ node._default_ref | lower }}">{{ node.default | json_encode() }}</a></code>{% else %}<code>{{ node.default | json_encode() }}</code>{% endif %}</div>{% endif -%}
|
||||
{{ self::render_schema_body(node=node, depth=depth, path=path) }}
|
||||
</div>
|
||||
{%- endif -%}
|
||||
{% endmacro render_schema %}
|
||||
@@ -8,10 +8,18 @@ import { Badge } from '@astrojs/starlight/components';
|
||||
|
||||
## Configuration
|
||||
{% if schema.properties %}
|
||||
{# First render required properties #}
|
||||
{% for prop_name, prop in schema.properties -%}
|
||||
{%- set is_required = prop_name in required_set -%}
|
||||
{{ macros::render_property(name=prop_name, node=prop, required=is_required, depth=0, path=prop_name) }}
|
||||
{% endfor %}
|
||||
{%- if prop_name in required_set -%}
|
||||
{{ macros::render_property(name=prop_name, node=prop, required=true, depth=0, path=prop_name) }}
|
||||
{% endif -%}
|
||||
{%- endfor -%}
|
||||
{# Then render optional properties #}
|
||||
{% for prop_name, prop in schema.properties -%}
|
||||
{%- if prop_name not in required_set -%}
|
||||
{{ macros::render_property(name=prop_name, node=prop, required=false, depth=0, path=prop_name) }}
|
||||
{% endif -%}
|
||||
{%- endfor %}
|
||||
{% else %}
|
||||
*No configuration properties defined.*
|
||||
{% endif %}
|
||||
|
||||
+403
-45
@@ -1,18 +1,29 @@
|
||||
{# MDX Macros for Astro Starlight documentation generation #}
|
||||
{# These macros mirror the HTML macro logic for consistent output #}
|
||||
{# ============================================================================ #}
|
||||
{# MDX Macros for Astro Starlight documentation generation #}
|
||||
{# ============================================================================ #}
|
||||
{#
|
||||
Enum Pattern Reference (see ENUMS.md for full details):
|
||||
- Pattern 1: Simple Unit Enums - oneOf with {type: "string", const: "Value"}
|
||||
- Pattern 2: Unit Enum with Default - Pattern 1 + "default" field
|
||||
- Pattern 3: Mixed Enum - oneOf with unit variants + tuple/object variants
|
||||
- Pattern 4a-d: Untagged Enums - anyOf with various combinations ($ref, tuple, array)
|
||||
- Pattern 5: Internally Tagged - oneOf with discriminator field (const) + properties
|
||||
- Pattern 6: Internally Tagged + Flatten - oneOf with properties + $ref at same level
|
||||
- Pattern 7: Externally Tagged - oneOf with variant name as property key
|
||||
- Pattern 8: Untagged Hybrid - anyOf mixing const strings + $ref
|
||||
- Pattern 9: Untagged with Nulls - anyOf with multiple {type: "null"} variants
|
||||
- Pattern 10: Generic Enum - anyOf with {additionalProperties: T} + T
|
||||
- Pattern 11: Nullable Optional - anyOf with $ref + {type: "null"} + default
|
||||
#}
|
||||
|
||||
{# ============================================================================ #}
|
||||
{# SECTION 1: Type Badge Rendering #}
|
||||
{# ============================================================================ #}
|
||||
{# Render the type badge for a schema - outputs inline code or links #}
|
||||
{# Pattern 6: When node has BOTH type AND $ref (flattened config), prioritize type #}
|
||||
|
||||
{# Render the type badge for a schema - outputs inline code or links #}
|
||||
{% macro render_type_badge(node) %}
|
||||
{%- if node["$ref"] -%}
|
||||
{%- set ref_name = node["$ref"] | replace(from="#/$defs/", to="") -%}
|
||||
{%- set display = display_names[ref_name] | default(value=ref_name) -%}
|
||||
{%- if schema["$defs"][ref_name] -%}
|
||||
{%- set ref_def = schema["$defs"][ref_name] -%}
|
||||
[`{{ display }}`](#{{ ref_name | lower }}){% if ref_def._wrapper_inner %} {{ self::render_type_badge(node=ref_def._wrapper_inner) }}{% endif -%}
|
||||
{%- else -%}
|
||||
`$ref`
|
||||
{%- endif -%}
|
||||
{%- elif node.type -%}
|
||||
{%- if node.type -%}
|
||||
{%- if node.type is string -%}
|
||||
{%- if node.type == "array" and node.prefixItems -%}
|
||||
{# Check if all prefixItems have the same type (homogeneous tuple) #}
|
||||
@@ -28,7 +39,7 @@
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- if is_homogeneous and first_type.type -%}
|
||||
`array` {% if first_type.type == "number" %}`[float; {{ node.prefixItems | length }}]`{% else %}`[{{ first_type.type }}; {{ node.prefixItems | length }}]`{% endif %}
|
||||
`array` `[{% if first_type.format %}{{ first_type.format }}{% else %}{{ first_type.type }}{% endif %}; {{ node.prefixItems | length }}]`
|
||||
{%- else -%}
|
||||
`array` `tuple`
|
||||
{%- endif -%}
|
||||
@@ -46,18 +57,19 @@
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- elif node.anyOf -%}
|
||||
{# Check for wrapper type pattern first #}
|
||||
{# Pattern 10: Wrapper type (detected in prepare.rs) #}
|
||||
{%- if node._wrapper_type -%}
|
||||
{{ self::render_type_badge(node=node._wrapper_inner) }}
|
||||
{%- elif node.anyOf | length == 2 -%}
|
||||
{%- set first = node.anyOf | first -%}
|
||||
{%- set second = node.anyOf | last -%}
|
||||
{# Pattern 11: Nullable Optional - anyOf with T + null #}
|
||||
{%- if second.type and second.type == "null" -%}
|
||||
<Badge text="optional" variant="note" /> {{ self::render_type_badge(node=first) }}
|
||||
{%- elif first.type and first.type == "null" -%}
|
||||
<Badge text="optional" variant="note" /> {{ self::render_type_badge(node=second) }}
|
||||
{%- else -%}
|
||||
{# Check if all variants are string const (enum pattern) #}
|
||||
{# Pattern 8: Check if all variants are string const (untagged hybrid) #}
|
||||
{%- set_global is_string_enum = true -%}
|
||||
{%- for variant in node.anyOf -%}
|
||||
{%- if variant.type and variant.type == "string" and variant.const -%}
|
||||
@@ -72,7 +84,7 @@
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{# Check if all variants are string const (enum pattern) #}
|
||||
{# Pattern 4a-d, 8, 9: Untagged enums with 3+ variants #}
|
||||
{%- set_global is_string_enum = true -%}
|
||||
{%- for variant in node.anyOf -%}
|
||||
{%- if variant.type and variant.type == "string" and variant.const -%}
|
||||
@@ -87,11 +99,13 @@
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- elif node.oneOf -%}
|
||||
{# Check if all variants are string const (enum pattern) #}
|
||||
{# Pattern 1-3, 5-7: Tagged enums using oneOf #}
|
||||
{%- set_global is_string_enum = true -%}
|
||||
{%- for variant in node.oneOf -%}
|
||||
{# Pattern 1-2: Simple unit enum with string const #}
|
||||
{%- if variant.type and variant.type == "string" and variant.const -%}
|
||||
{%- else -%}
|
||||
{# Pattern 3, 5, 6, 7: Complex variants (objects, refs, etc.) #}
|
||||
{%- set_global is_string_enum = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
@@ -102,6 +116,16 @@
|
||||
{%- endif -%}
|
||||
{%- elif node.allOf -%}
|
||||
`allOf`
|
||||
{%- elif node["$ref"] -%}
|
||||
{# Reference type (no inline type field) #}
|
||||
{%- set ref_name = node["$ref"] | replace(from="#/$defs/", to="") -%}
|
||||
{%- set display = display_names[ref_name] | default(value=ref_name) -%}
|
||||
{%- if schema["$defs"][ref_name] -%}
|
||||
{%- set ref_def = schema["$defs"][ref_name] -%}
|
||||
[`{{ display }}`](#{{ ref_name | lower }}){% if ref_def._wrapper_inner %} {{ self::render_type_badge(node=ref_def._wrapper_inner) }}{% endif -%}
|
||||
{%- else -%}
|
||||
`$ref`
|
||||
{%- endif -%}
|
||||
{%- elif node.const -%}
|
||||
`const`
|
||||
{%- elif node.enum -%}
|
||||
@@ -109,7 +133,11 @@
|
||||
{%- endif -%}
|
||||
{% endmacro render_type_badge %}
|
||||
|
||||
{# Render constraints like min, max, pattern, format #}
|
||||
{# ============================================================================ #}
|
||||
{# SECTION 2: Constraint Rendering #}
|
||||
{# ============================================================================ #}
|
||||
{# Render constraints like min, max, pattern, format #}
|
||||
|
||||
{% macro render_constraints(node) %}
|
||||
{# Check if this is a homogeneous tuple - skip minItems/maxItems if so #}
|
||||
{%- set_global skip_item_constraints = false -%}
|
||||
@@ -143,7 +171,11 @@
|
||||
{%- endif -%}
|
||||
{% endmacro render_constraints %}
|
||||
|
||||
{# Render the body of a schema (properties, items, variants, etc.) #}
|
||||
{# ============================================================================ #}
|
||||
{# SECTION 3: Schema Body Rendering #}
|
||||
{# ============================================================================ #}
|
||||
{# Render the body of a schema (properties, items, variants, etc.) #}
|
||||
|
||||
{% macro render_schema_body(node, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
{%- if node["$ref"] -%}
|
||||
@@ -151,13 +183,23 @@
|
||||
{%- elif node.properties -%}
|
||||
{%- set required_arr = node.required | default(value=[]) -%}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>Properties ({{ node.properties | length }})</summary>
|
||||
|
||||
{# First render required properties #}
|
||||
{% for prop_name, prop in node.properties -%}
|
||||
{%- set is_required = prop_name in required_arr -%}
|
||||
{%- if prop_name in required_arr -%}
|
||||
{%- set is_required = true -%}
|
||||
{{ self::render_nested_property(name=prop_name, node=prop, required=is_required, depth=depth + 1, path=path ~ "." ~ prop_name) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{%- endfor -%}
|
||||
{# Then render optional properties #}
|
||||
{% for prop_name, prop in node.properties -%}
|
||||
{%- if prop_name not in required_arr -%}
|
||||
{%- set is_required = false -%}
|
||||
{{ self::render_nested_property(name=prop_name, node=prop, required=is_required, depth=depth + 1, path=path ~ "." ~ prop_name) }}
|
||||
{% endif -%}
|
||||
{%- endfor %}
|
||||
</details>
|
||||
{%- elif node.patternProperties -%}
|
||||
|
||||
@@ -181,7 +223,7 @@
|
||||
{# Simple type - already shown in type badge #}
|
||||
{%- else -%}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>Array Items</summary>
|
||||
|
||||
{{ self::render_schema(node=node.items, depth=depth + 1, path=path ~ "[]") }}
|
||||
@@ -204,7 +246,7 @@
|
||||
{# Homogeneous tuple - already shown as [T; N] in badge #}
|
||||
{%- else -%}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>Tuple Items ({{ node.prefixItems | length }})</summary>
|
||||
|
||||
{% for item in node.prefixItems %}
|
||||
@@ -213,51 +255,55 @@
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- elif node.anyOf -%}
|
||||
{# Check for wrapper type pattern first #}
|
||||
{# Pattern 10: Wrapper type (detected in prepare.rs) #}
|
||||
{%- if node._wrapper_type -%}
|
||||
{{ self::render_schema_body(node=node._wrapper_inner, depth=depth, path=path) }}
|
||||
{%- elif node.anyOf | length == 2 -%}
|
||||
{%- set first = node.anyOf | first -%}
|
||||
{%- set second = node.anyOf | last -%}
|
||||
{# Pattern 11: Nullable Optional - unwrap the non-null variant #}
|
||||
{%- if second.type and second.type == "null" -%}
|
||||
{{ self::render_schema_body(node=first, depth=depth, path=path) }}
|
||||
{%- elif first.type and first.type == "null" -%}
|
||||
{{ self::render_schema_body(node=second, depth=depth, path=path) }}
|
||||
{%- else -%}
|
||||
{# Pattern 4a-d, 8: Two non-null variants #}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>Enum variants ({{ node.anyOf | length }})</summary>
|
||||
|
||||
{% for variant in node.anyOf %}
|
||||
---
|
||||
{{ self::render_schema(node=variant, depth=depth + 1, path=path ~ ".anyOf[" ~ loop.index0 ~ "]") }}
|
||||
{{ self::render_enum_variant(node=variant, depth=depth + 1, path=path ~ ".anyOf[" ~ loop.index0 ~ "]") }}
|
||||
{% endfor %}
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{# Pattern 4a-d, 8, 9: Untagged enums with 3+ variants #}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>Enum variants ({{ node.anyOf | length }})</summary>
|
||||
|
||||
{% for variant in node.anyOf %}
|
||||
---
|
||||
{{ self::render_schema(node=variant, depth=depth + 1, path=path ~ ".anyOf[" ~ loop.index0 ~ "]") }}
|
||||
{{ self::render_enum_variant(node=variant, depth=depth + 1, path=path ~ ".anyOf[" ~ loop.index0 ~ "]") }}
|
||||
{% endfor %}
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- elif node.oneOf -%}
|
||||
{# Pattern 1-3, 5-7: Tagged enums using oneOf #}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>Enum variants ({{ node.oneOf | length }})</summary>
|
||||
|
||||
{% for variant in node.oneOf %}
|
||||
---
|
||||
{{ self::render_schema(node=variant, depth=depth + 1, path=path ~ ".oneOf[" ~ loop.index0 ~ "]") }}
|
||||
{{ self::render_enum_variant(node=variant, depth=depth + 1, path=path ~ ".oneOf[" ~ loop.index0 ~ "]") }}
|
||||
{% endfor %}
|
||||
</details>
|
||||
{%- elif node.allOf -%}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>All of ({{ node.allOf | length }} schemas)</summary>
|
||||
|
||||
{% for variant in node.allOf %}
|
||||
@@ -267,7 +313,7 @@
|
||||
</details>
|
||||
{%- elif node.enum -%}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>Enum variants ({{ node.enum | length }})</summary>
|
||||
|
||||
{% for value in node.enum %}- `{{ value | json_encode() }}`
|
||||
@@ -279,7 +325,7 @@
|
||||
{%- endif -%}
|
||||
{%- if node.additionalProperties and node.additionalProperties is object -%}
|
||||
|
||||
<details>
|
||||
<details open>
|
||||
<summary>Additional Properties</summary>
|
||||
|
||||
{{ self::render_schema(node=node.additionalProperties, depth=depth + 1, path=path ~ ".[*]") }}
|
||||
@@ -288,15 +334,25 @@
|
||||
{%- endif -%}
|
||||
{% endmacro render_schema_body %}
|
||||
|
||||
{# Render a schema without property wrapper #}
|
||||
{# ============================================================================ #}
|
||||
{# SECTION 4: Schema Rendering #}
|
||||
{# ============================================================================ #}
|
||||
{# Render a schema without property wrapper #}
|
||||
|
||||
{% macro render_schema(node, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
{# Skip type badge for documented const variants - the value is shown below #}
|
||||
{# For const variants with description, show description then value on separate lines #}
|
||||
{%- if node.const and node.description -%}
|
||||
{{ node.description | mdx_escape }}
|
||||
|
||||
**Value:** `{{ node.const | json_encode() }}`
|
||||
{%- elif node.const -%}
|
||||
**Value:** `{{ node.const | json_encode() }}`
|
||||
{%- else -%}
|
||||
{{ self::render_type_badge(node=node) }}{% if node.description %} - {{ node.description | mdx_escape }}{% endif %}
|
||||
{%- endif -%}
|
||||
{{ self::render_type_badge(node=node) }}
|
||||
{% if node.description %}
|
||||
{{ node.description | mdx_escape }}
|
||||
{% endif %}
|
||||
{{ self::render_constraints(node=node) }}
|
||||
{%- if node.default %}
|
||||
|
||||
@@ -304,9 +360,307 @@
|
||||
{% endif -%}
|
||||
{{ self::render_schema_body(node=node, depth=depth, path=path) }}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{% endmacro render_schema %}
|
||||
|
||||
{# Render a nested property (used within details blocks) #}
|
||||
{# ============================================================================ #}
|
||||
{# SECTION 5: Enum Variant Rendering #}
|
||||
{# ============================================================================ #}
|
||||
{# Render an enum variant - like render_schema but uses render_enum_variant_body #}
|
||||
{# for flat property display. Uses exhaustive fallback chain for variant titles. #}
|
||||
{# #}
|
||||
{# Title extraction priority (see ENUMS.md for pattern details): #}
|
||||
{# 1. node.title (explicit #[schemars(title = "...")]) #}
|
||||
{# 2. node.const (Pattern 1, 2, 3 unit variants, Pattern 9 hybrid) #}
|
||||
{# 3. properties.<tag>.const (Pattern 5, 6, 8 discriminator field) #}
|
||||
{# 4. required[0] when additionalProperties=false (Pattern 7 externally tagged) #}
|
||||
{# 5. $ref type name (Pattern 4, 9, 10 reference types) #}
|
||||
{# 6. Type-based fallback (array, tuple, map, primitives) #}
|
||||
{# ============================================================================ #}
|
||||
|
||||
{% macro render_enum_variant(node, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
{# Extract variant name using exhaustive fallback chain #}
|
||||
{%- set_global variant_name = "" -%}
|
||||
|
||||
{# Priority 1: Explicit title #}
|
||||
{%- if node.title -%}
|
||||
{%- set_global variant_name = node.title -%}
|
||||
|
||||
{# Priority 2: Const value (Pattern 1, 2, 3 unit variants, Pattern 9) #}
|
||||
{%- elif node.const -%}
|
||||
{%- set_global variant_name = node.const -%}
|
||||
|
||||
{# Priority 3 & 4: Properties-based extraction #}
|
||||
{%- elif node.properties -%}
|
||||
{# Priority 3: Discriminator const from properties (Pattern 5, 6, 8) #}
|
||||
{%- for prop_name, prop in node.properties -%}
|
||||
{%- if prop.const and variant_name == "" -%}
|
||||
{%- set_global variant_name = prop.const -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{# Priority 4: Externally tagged - property key (Pattern 7) #}
|
||||
{%- if variant_name == "" and node.additionalProperties is defined and node.additionalProperties == false -%}
|
||||
{%- if node.required and node.required | length > 0 -%}
|
||||
{%- set_global variant_name = node.required | first -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
|
||||
{# Priority 5: $ref type name (Pattern 4, 9, 10) #}
|
||||
{%- elif node["$ref"] -%}
|
||||
{%- set ref_name = node["$ref"] | replace(from="#/$defs/", to="") -%}
|
||||
{%- set_global variant_name = display_names[ref_name] | default(value=ref_name) -%}
|
||||
|
||||
{# Priority 6: Type-based fallback #}
|
||||
{%- elif node.type -%}
|
||||
{%- if node.type is string -%}
|
||||
{%- if node.type == "array" -%}
|
||||
{%- if node.items and node.items["$ref"] -%}
|
||||
{%- set item_ref = node.items["$ref"] | replace(from="#/$defs/", to="") -%}
|
||||
{%- set item_display = display_names[item_ref] | default(value=item_ref) -%}
|
||||
{%- set_global variant_name = item_display ~ " Array" -%}
|
||||
{%- elif node.prefixItems -%}
|
||||
{%- set_global variant_name = "Tuple" -%}
|
||||
{%- else -%}
|
||||
{%- set_global variant_name = "Array" -%}
|
||||
{%- endif -%}
|
||||
{%- elif node.type == "object" and node.additionalProperties -%}
|
||||
{%- set_global variant_name = "Map" -%}
|
||||
{%- else -%}
|
||||
{%- set_global variant_name = node.type | capitalize -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
|
||||
{# Render heading if we have a variant name #}
|
||||
{%- if variant_name %}
|
||||
#### {{ variant_name }}
|
||||
{% endif -%}
|
||||
|
||||
{# Render description #}
|
||||
{% if node.description %}
|
||||
{{ node.description | mdx_escape }}
|
||||
{% endif %}
|
||||
|
||||
{# Render value based on variant type #}
|
||||
{# First check for Pattern 7: Externally Tagged (single property with additionalProperties: false) #}
|
||||
{# These are handled specially in render_enum_variant_body, so skip generic value here #}
|
||||
{%- set_global is_pattern7 = false -%}
|
||||
{%- if node.properties -%}
|
||||
{%- set props_count = node.properties | length -%}
|
||||
{%- if props_count == 1 and node.additionalProperties is defined and node.additionalProperties == false -%}
|
||||
{%- set_global is_pattern7 = true -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- if node.const -%}
|
||||
**Value:** `{{ node.const | json_encode() }}`
|
||||
{%- elif not is_pattern7 and (node["$ref"] or node.type or node.anyOf or node.oneOf or node.allOf) %}
|
||||
**Value:** {{ self::render_type_badge(node=node) }}
|
||||
{%- endif %}
|
||||
|
||||
{{ self::render_constraints(node=node) }}
|
||||
{%- if node.default %}
|
||||
|
||||
**Default:** {% if node._default_ref and schema["$defs"][node._default_ref] %}[`{{ node.default | json_encode() }}`](#{{ node._default_ref | lower }}){% else %}`{{ node.default | json_encode() }}`{% endif %}
|
||||
{% endif -%}
|
||||
{{ self::render_enum_variant_body(node=node, depth=depth, path=path) }}
|
||||
{%- endif -%}
|
||||
{% endmacro render_enum_variant %}
|
||||
|
||||
{# ============================================================================ #}
|
||||
{# SECTION 6: Enum Variant Body Rendering #}
|
||||
{# ============================================================================ #}
|
||||
{# Render the body of an enum variant - properties are shown directly without #}
|
||||
{# details wrapper, required first. #}
|
||||
{# Handles Pattern 3 (mixed), Pattern 5 (internally tagged), #}
|
||||
{# Pattern 6 (internally tagged + flatten), Pattern 7 (externally tagged) #}
|
||||
|
||||
{% macro render_enum_variant_body(node, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
{%- if node.properties -%}
|
||||
{# Check for Pattern 7: Externally Tagged Enum (single property with additionalProperties: false) #}
|
||||
{%- set props_count = node.properties | length -%}
|
||||
{%- if props_count == 1 and node.additionalProperties is defined and node.additionalProperties == false -%}
|
||||
{# Pattern 7: Externally Tagged - render variant name and value inline #}
|
||||
{%- for prop_name, prop in node.properties -%}
|
||||
|
||||
**Value:** `{{ prop_name }}` → {{ self::render_type_badge(node=prop) }}
|
||||
{%- endfor -%}
|
||||
{%- else -%}
|
||||
{# Pattern 5, 6: Object variants with properties (internally tagged) #}
|
||||
{# Pattern 6: Handle properties first - this covers cases where both properties and $ref exist #}
|
||||
{# Skip properties with const values (discriminator fields) - already shown as variant heading #}
|
||||
{%- set required_arr = node.required | default(value=[]) -%}
|
||||
|
||||
{# First render required properties (skip discriminator fields with const) #}
|
||||
{% for prop_name, prop in node.properties -%}
|
||||
{%- if prop_name in required_arr and not prop.const -%}
|
||||
{%- set is_required = true -%}
|
||||
{{ self::render_nested_property(name=prop_name, node=prop, required=is_required, depth=depth + 1, path=path ~ "." ~ prop_name) }}
|
||||
{% endif -%}
|
||||
{%- endfor -%}
|
||||
{# Then render optional properties (skip discriminator fields with const) #}
|
||||
{% for prop_name, prop in node.properties -%}
|
||||
{%- if prop_name not in required_arr and not prop.const -%}
|
||||
{%- set is_required = false -%}
|
||||
{{ self::render_nested_property(name=prop_name, node=prop, required=is_required, depth=depth + 1, path=path ~ "." ~ prop_name) }}
|
||||
{% endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{# Pattern 6: If node has both properties AND $ref, also render the referenced type's properties #}
|
||||
{%- if node["$ref"] -%}
|
||||
{%- set ref_name = node["$ref"] | replace(from="#/$defs/", to="") -%}
|
||||
{%- if schema["$defs"][ref_name] -%}
|
||||
{%- set ref_def = schema["$defs"][ref_name] -%}
|
||||
{%- if ref_def.properties -%}
|
||||
{%- set ref_required_arr = ref_def.required | default(value=[]) -%}
|
||||
{# First render required properties from referenced type #}
|
||||
{% for prop_name, prop in ref_def.properties -%}
|
||||
{%- if prop_name in ref_required_arr -%}
|
||||
{%- set is_required = true -%}
|
||||
{{ self::render_nested_property(name=prop_name, node=prop, required=is_required, depth=depth + 1, path=path ~ "." ~ prop_name) }}
|
||||
{% endif -%}
|
||||
{%- endfor -%}
|
||||
{# Then render optional properties from referenced type #}
|
||||
{% for prop_name, prop in ref_def.properties -%}
|
||||
{%- if prop_name not in ref_required_arr -%}
|
||||
{%- set is_required = false -%}
|
||||
{{ self::render_nested_property(name=prop_name, node=prop, required=is_required, depth=depth + 1, path=path ~ "." ~ prop_name) }}
|
||||
{% endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- elif node["$ref"] -%}
|
||||
{# Reference only, already shown as type badge #}
|
||||
{%- elif node.patternProperties -%}
|
||||
|
||||
{% for pattern, prop in node.patternProperties %}
|
||||
{% if pattern == "^\d+$" or pattern == "^[0-9]+$" or pattern == "^-?\d+$" or pattern == "^-?[0-9]+$" -%}
|
||||
**Key:** `"<integer>"` **→** {{ self::render_type_badge(node=prop) }}
|
||||
{% elif pattern == ".*" or pattern == "^.*$" -%}
|
||||
**Key:** `"<string>"` **→** {{ self::render_type_badge(node=prop) }}
|
||||
{% else -%}
|
||||
**Pattern:** `{{ pattern }}` **→** {{ self::render_type_badge(node=prop) }}
|
||||
{% endif %}
|
||||
{% if prop.description %}{{ prop.description | mdx_escape }}{% endif %}
|
||||
{{ self::render_enum_variant_body(node=prop, depth=depth + 1, path=path ~ ".[key]") }}
|
||||
{% endfor %}
|
||||
{%- elif node.items -%}
|
||||
{%- if node.items["$ref"] -%}
|
||||
{# Already shown in type badge #}
|
||||
{%- elif node.items.type and node.items.type is string -%}
|
||||
{# Simple type - already shown in type badge #}
|
||||
{%- else -%}
|
||||
|
||||
<details open>
|
||||
<summary>Array Items</summary>
|
||||
|
||||
{{ self::render_enum_variant(node=node.items, depth=depth + 1, path=path ~ "[]") }}
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- elif node.prefixItems -%}
|
||||
{%- set first_type = node.prefixItems | first -%}
|
||||
{%- set_global is_homogeneous = true -%}
|
||||
{%- for item in node.prefixItems -%}
|
||||
{%- if item.type is defined and first_type.type is defined -%}
|
||||
{%- if item.type != first_type.type -%}
|
||||
{%- set_global is_homogeneous = false -%}
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{%- set_global is_homogeneous = false -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- if is_homogeneous and first_type.type -%}
|
||||
{# Homogeneous tuple - already shown as [T; N] in badge #}
|
||||
{%- else -%}
|
||||
|
||||
<details open>
|
||||
<summary>Tuple Items ({{ node.prefixItems | length }})</summary>
|
||||
|
||||
{% for item in node.prefixItems %}
|
||||
**[{{ loop.index0 }}]** {{ self::render_enum_variant(node=item, depth=depth + 1, path=path ~ "[" ~ loop.index0 ~ "]") }}
|
||||
{% endfor %}
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- elif node.anyOf -%}
|
||||
{%- if node._wrapper_type -%}
|
||||
{{ self::render_enum_variant_body(node=node._wrapper_inner, depth=depth, path=path) }}
|
||||
{%- elif node.anyOf | length == 2 -%}
|
||||
{%- set first = node.anyOf | first -%}
|
||||
{%- set second = node.anyOf | last -%}
|
||||
{%- if second.type and second.type == "null" -%}
|
||||
{{ self::render_enum_variant_body(node=first, depth=depth, path=path) }}
|
||||
{%- elif first.type and first.type == "null" -%}
|
||||
{{ self::render_enum_variant_body(node=second, depth=depth, path=path) }}
|
||||
{%- else -%}
|
||||
|
||||
<details open>
|
||||
<summary>Enum variants ({{ node.anyOf | length }})</summary>
|
||||
|
||||
{% for variant in node.anyOf %}
|
||||
---
|
||||
{{ self::render_enum_variant(node=variant, depth=depth + 1, path=path ~ ".anyOf[" ~ loop.index0 ~ "]") }}
|
||||
{% endfor %}
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
|
||||
<details open>
|
||||
<summary>Enum variants ({{ node.anyOf | length }})</summary>
|
||||
|
||||
{% for variant in node.anyOf %}
|
||||
---
|
||||
{{ self::render_enum_variant(node=variant, depth=depth + 1, path=path ~ ".anyOf[" ~ loop.index0 ~ "]") }}
|
||||
{% endfor %}
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- elif node.oneOf -%}
|
||||
|
||||
<details open>
|
||||
<summary>Enum variants ({{ node.oneOf | length }})</summary>
|
||||
|
||||
{% for variant in node.oneOf %}
|
||||
---
|
||||
{{ self::render_enum_variant(node=variant, depth=depth + 1, path=path ~ ".oneOf[" ~ loop.index0 ~ "]") }}
|
||||
{% endfor %}
|
||||
</details>
|
||||
{%- elif node.allOf -%}
|
||||
|
||||
<details open>
|
||||
<summary>All of ({{ node.allOf | length }} schemas)</summary>
|
||||
|
||||
{% for variant in node.allOf %}
|
||||
---
|
||||
{{ self::render_enum_variant(node=variant, depth=depth + 1, path=path ~ ".allOf[" ~ loop.index0 ~ "]") }}
|
||||
{% endfor %}
|
||||
</details>
|
||||
{%- elif node.enum -%}
|
||||
|
||||
<details open>
|
||||
<summary>Enum variants ({{ node.enum | length }})</summary>
|
||||
|
||||
{% for value in node.enum %}- `{{ value | json_encode() }}`
|
||||
{% endfor %}
|
||||
</details>
|
||||
{# Note: node.const is NOT handled here - it's already rendered in render_enum_variant #}
|
||||
{%- endif -%}
|
||||
{%- if node.additionalProperties and node.additionalProperties is object -%}
|
||||
|
||||
<details open>
|
||||
<summary>Additional Properties</summary>
|
||||
|
||||
{{ self::render_enum_variant(node=node.additionalProperties, depth=depth + 1, path=path ~ ".[*]") }}
|
||||
</details>
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{% endmacro render_enum_variant_body %}
|
||||
|
||||
{# ============================================================================ #}
|
||||
{# SECTION 7: Property Rendering #}
|
||||
{# ============================================================================ #}
|
||||
{# Render a nested property (used within details blocks) #}
|
||||
|
||||
{% macro render_nested_property(name, node, required, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
{%- set anchor = path | lower | replace(from=".", to="-") -%}
|
||||
@@ -324,7 +678,8 @@
|
||||
{%- endif -%}
|
||||
{% endmacro render_nested_property %}
|
||||
|
||||
{# Render a top-level property as H3 #}
|
||||
{# Render a top-level property as H3 #}
|
||||
|
||||
{% macro render_property(name, node, required, depth, path) %}
|
||||
{%- if depth < 10 -%}
|
||||
{%- set anchor = path | lower | replace(from=".", to="-") -%}
|
||||
@@ -345,7 +700,11 @@
|
||||
{%- endif -%}
|
||||
{% endmacro render_property %}
|
||||
|
||||
{# Render usages section for a type definition #}
|
||||
{# ============================================================================ #}
|
||||
{# SECTION 8: Definition & Usage Rendering #}
|
||||
{# ============================================================================ #}
|
||||
{# Render usages section for a type definition #}
|
||||
|
||||
{% macro render_usages(def) %}
|
||||
{%- if def._usages and (def._usages.config_usages | length > 0 or def._usages.type_references | length > 0) -%}
|
||||
|
||||
@@ -365,13 +724,12 @@
|
||||
{%- endif -%}
|
||||
{% endmacro render_usages %}
|
||||
|
||||
{# Render a type definition as H3 #}
|
||||
{# Render a type definition as H3 #}
|
||||
|
||||
{% macro render_definition(def_name, def) %}
|
||||
{%- set anchor = def_name | lower | replace(from=".", to="-") -%}
|
||||
### {{ def._display_name | default(value=def_name) }} {{"{"}}#{{ anchor }}{{"}"}}
|
||||
|
||||
{{ self::render_type_badge(node=def) }}
|
||||
|
||||
{% if def.description %}{{ def.description | mdx_escape }}{% endif %}
|
||||
{{ self::render_constraints(node=def) }}
|
||||
{{ self::render_schema_body(node=def, depth=0, path=def_name) }}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,313 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>JSON Schema Test Suite - Generated Documentation</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg-primary: #1a1a2e;
|
||||
--bg-secondary: #16213e;
|
||||
--bg-card: #1f2937;
|
||||
--text-primary: #e2e8f0;
|
||||
--text-secondary: #94a3b8;
|
||||
--accent: #818cf8;
|
||||
--accent-hover: #a5b4fc;
|
||||
--border: #374151;
|
||||
--green: #34d399;
|
||||
--yellow: #fbbf24;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
Oxygen, Ubuntu, sans-serif;
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
padding: 2rem;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--accent);
|
||||
}
|
||||
.subtitle {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.stats {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
padding: 1rem;
|
||||
background: var(--bg-secondary);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.stat {
|
||||
text-align: center;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
color: var(--accent);
|
||||
}
|
||||
.stat-value.green {
|
||||
color: var(--green);
|
||||
}
|
||||
.stat-value.yellow {
|
||||
color: var(--yellow);
|
||||
}
|
||||
.stat-label {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
.build-info {
|
||||
margin-bottom: 2rem;
|
||||
padding: 1rem;
|
||||
background: var(--bg-secondary);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
.build-info h3 {
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.build-info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0.25rem 1rem;
|
||||
}
|
||||
.build-info-label {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.build-info-value {
|
||||
font-family: "SF Mono", Consolas, monospace;
|
||||
}
|
||||
.dirty-badge {
|
||||
display: inline-block;
|
||||
padding: 0.125rem 0.5rem;
|
||||
margin-left: 0.5rem;
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
color: #ef4444;
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.clean-badge {
|
||||
display: inline-block;
|
||||
padding: 0.125rem 0.5rem;
|
||||
margin-left: 0.5rem;
|
||||
background: rgba(52, 211, 153, 0.2);
|
||||
color: var(--green);
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.legend {
|
||||
margin-bottom: 2rem;
|
||||
padding: 1rem;
|
||||
background: var(--bg-secondary);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.legend h3 {
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.legend-items {
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.badge-content {
|
||||
background: rgba(52, 211, 153, 0.2);
|
||||
color: var(--green);
|
||||
}
|
||||
.badge-empty {
|
||||
background: rgba(251, 191, 36, 0.2);
|
||||
color: var(--yellow);
|
||||
}
|
||||
.file-group {
|
||||
margin-bottom: 1.5rem;
|
||||
background: var(--bg-card);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
overflow: hidden;
|
||||
}
|
||||
.file-header {
|
||||
padding: 0.75rem 1rem;
|
||||
background: var(--bg-secondary);
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-weight: 600;
|
||||
font-family: "SF Mono", Consolas, monospace;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.schema-list {
|
||||
list-style: none;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
.schema-item {
|
||||
padding: 0.5rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.schema-item:hover {
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
.schema-link {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.schema-link:hover {
|
||||
color: var(--accent-hover);
|
||||
}
|
||||
.schema-index {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.75rem;
|
||||
font-family: "SF Mono", Consolas, monospace;
|
||||
min-width: 2rem;
|
||||
}
|
||||
.schema-desc {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
}
|
||||
.schema-features {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.feature-tag {
|
||||
display: inline-block;
|
||||
padding: 0.0625rem 0.375rem;
|
||||
background: var(--bg-secondary);
|
||||
border-radius: 3px;
|
||||
font-size: 0.625rem;
|
||||
font-family: "SF Mono", Consolas, monospace;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>JSON Schema Test Suite</h1>
|
||||
<p class="subtitle">
|
||||
Generated HTML documentation for draft2020-12 test schemas
|
||||
</p>
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<div class="stat-value">{{ total_schemas }}</div>
|
||||
<div class="stat-label">Total Schemas</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value">{{ total_files }}</div>
|
||||
<div class="stat-label">Test Files</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value green">{{ with_content }}</div>
|
||||
<div class="stat-label">With Content</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value yellow">{{ without_content }}</div>
|
||||
<div class="stat-label">Empty (Expected)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-info">
|
||||
<h3>Build Information</h3>
|
||||
<div class="build-info-grid">
|
||||
<span class="build-info-label">Commit:</span>
|
||||
<span class="build-info-value">
|
||||
{{ commit_hash }} {%- if is_dirty %}
|
||||
<span class="dirty-badge">dirty</span>
|
||||
{%- else %}
|
||||
<span class="clean-badge">clean</span>
|
||||
{%- endif %}
|
||||
</span>
|
||||
<span class="build-info-label">Time (UTC):</span>
|
||||
<span class="build-info-value">{{ time_utc }}</span>
|
||||
<span class="build-info-label">Time (Local):</span>
|
||||
<span class="build-info-value">{{ time_local }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="legend">
|
||||
<h3>Legend</h3>
|
||||
<div class="legend-items">
|
||||
<div class="legend-item">
|
||||
<span class="badge badge-content">content</span>
|
||||
<span
|
||||
>Schema has properties or $defs -
|
||||
Configuration/Types sections populated</span
|
||||
>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<span class="badge badge-empty">empty</span>
|
||||
<span
|
||||
>Schema lacks properties/$defs - empty sections
|
||||
expected</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{%- for group in groups %}
|
||||
<div class="file-group">
|
||||
<div class="file-header">{{ group.file_path }}</div>
|
||||
<ul class="schema-list">
|
||||
{%- for schema in group.schemas %}
|
||||
<li class="schema-item">
|
||||
<a
|
||||
class="schema-link"
|
||||
href="{{ schema.output_path | safe }}"
|
||||
>
|
||||
<span class="schema-index"
|
||||
>[{{ schema.index }}]</span
|
||||
>
|
||||
{%- if schema.has_content %}
|
||||
<span class="badge badge-content">content</span>
|
||||
{%- else %}
|
||||
<span class="badge badge-empty">empty</span>
|
||||
{%- endif %}
|
||||
<span class="schema-desc"
|
||||
>{{ schema.description }}</span
|
||||
>
|
||||
<span class="schema-features">
|
||||
{%- for feature in schema.features %}
|
||||
<span class="feature-tag">{{ feature }}</span>
|
||||
{%- endfor %}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description":
|
||||
"additionalProperties being false does not allow other properties",
|
||||
"specification": [ { "core":"10.3.2.3", "quote": "The value of \"additionalProperties\" MUST be a valid JSON Schema. Boolean \"false\" forbids everything." } ],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {"foo": {}, "bar": {}},
|
||||
"patternProperties": { "^v": {} },
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "no additional properties is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an additional property is invalid",
|
||||
"data": {"foo" : 1, "bar" : 2, "quux" : "boom"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [1, 2, 3],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foobarbaz",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "patternProperties are not additional properties",
|
||||
"data": {"foo":1, "vroom": 2},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "non-ASCII pattern with additionalProperties",
|
||||
"specification": [ { "core":"10.3.2.3"} ],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"patternProperties": {"^á": {}},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matching the pattern is valid",
|
||||
"data": {"ármányos": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "not matching the pattern is invalid",
|
||||
"data": {"élmény": 2},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties with schema",
|
||||
"specification": [ { "core":"10.3.2.3", "quote": "The value of \"additionalProperties\" MUST be a valid JSON Schema." } ],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {"foo": {}, "bar": {}},
|
||||
"additionalProperties": {"type": "boolean"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "no additional properties is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an additional valid property is valid",
|
||||
"data": {"foo" : 1, "bar" : 2, "quux" : true},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an additional invalid property is invalid",
|
||||
"data": {"foo" : 1, "bar" : 2, "quux" : 12},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties can exist by itself",
|
||||
"specification": [ { "core":"10.3.2.3", "quote": "With no other applicator applying to object instances. This validates all the instance values irrespective of their property names" } ],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"additionalProperties": {"type": "boolean"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an additional valid property is valid",
|
||||
"data": {"foo" : true},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an additional invalid property is invalid",
|
||||
"data": {"foo" : 1},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties are allowed by default",
|
||||
"specification": [ { "core":"10.3.2.3", "quote": "Omitting this keyword has the same assertion behavior as an empty schema." } ],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {"foo": {}, "bar": {}}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "additional properties are allowed",
|
||||
"data": {"foo": 1, "bar": 2, "quux": true},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties does not look in applicators",
|
||||
"specification":[ { "core": "10.2", "quote": "Subschemas of applicator keywords evaluate the instance completely independently such that the results of one such subschema MUST NOT impact the results of sibling subschemas." } ],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{"properties": {"foo": {}}}
|
||||
],
|
||||
"additionalProperties": {"type": "boolean"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "properties defined in allOf are not examined",
|
||||
"data": {"foo": 1, "bar": true},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties with null valued instance properties",
|
||||
"specification": [ { "core":"10.3.2.3" } ],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"additionalProperties": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allows null values",
|
||||
"data": {"foo": null},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties with propertyNames",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"propertyNames": {
|
||||
"maxLength": 5
|
||||
},
|
||||
"additionalProperties": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Valid against both keywords",
|
||||
"data": { "apple": 4 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Valid against propertyNames, but not additionalProperties",
|
||||
"data": { "fig": 2, "pear": "available" },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "dependentSchemas with additionalProperties",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {"foo2": {}},
|
||||
"dependentSchemas": {
|
||||
"foo" : {},
|
||||
"foo2": {
|
||||
"properties": {
|
||||
"bar": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "additionalProperties doesn't consider dependentSchemas",
|
||||
"data": {"foo": ""},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties can't see bar",
|
||||
"data": {"bar": ""},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties can't see bar even when foo2 is present",
|
||||
"data": {"foo2": "", "bar": ""},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,312 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "allOf",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": {"type": "integer"}
|
||||
},
|
||||
"required": ["bar"]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": {"type": "string"}
|
||||
},
|
||||
"required": ["foo"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allOf",
|
||||
"data": {"foo": "baz", "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch second",
|
||||
"data": {"foo": "baz"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "mismatch first",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "wrong type",
|
||||
"data": {"foo": "baz", "bar": "quux"},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with base schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {"bar": {"type": "integer"}},
|
||||
"required": ["bar"],
|
||||
"allOf" : [
|
||||
{
|
||||
"properties": {
|
||||
"foo": {"type": "string"}
|
||||
},
|
||||
"required": ["foo"]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"baz": {"type": "null"}
|
||||
},
|
||||
"required": ["baz"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid",
|
||||
"data": {"foo": "quux", "bar": 2, "baz": null},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch base schema",
|
||||
"data": {"foo": "quux", "baz": null},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "mismatch first allOf",
|
||||
"data": {"bar": 2, "baz": null},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "mismatch second allOf",
|
||||
"data": {"foo": "quux", "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "mismatch both",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf simple types",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{"maximum": 30},
|
||||
{"minimum": 20}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid",
|
||||
"data": 25,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch one",
|
||||
"data": 35,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with boolean schemas, all true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [true, true]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with boolean schemas, some false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [true, false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with boolean schemas, all false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [false, false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with one empty schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any data is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with two empty schemas",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any data is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with the first empty schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{},
|
||||
{ "type": "number" }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with the last empty schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{ "type": "number" },
|
||||
{}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nested allOf, to check validation semantics",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "anything non-null is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf combined with anyOf, oneOf",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [ { "multipleOf": 2 } ],
|
||||
"anyOf": [ { "multipleOf": 3 } ],
|
||||
"oneOf": [ { "multipleOf": 5 } ]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allOf: false, anyOf: false, oneOf: false",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "allOf: false, anyOf: false, oneOf: true",
|
||||
"data": 5,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "allOf: false, anyOf: true, oneOf: false",
|
||||
"data": 3,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "allOf: false, anyOf: true, oneOf: true",
|
||||
"data": 15,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "allOf: true, anyOf: false, oneOf: false",
|
||||
"data": 2,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "allOf: true, anyOf: false, oneOf: true",
|
||||
"data": 10,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "allOf: true, anyOf: true, oneOf: false",
|
||||
"data": 6,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "allOf: true, anyOf: true, oneOf: true",
|
||||
"data": 30,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,120 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "Location-independent identifier",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "#foo",
|
||||
"$defs": {
|
||||
"A": {
|
||||
"$anchor": "foo",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"data": 1,
|
||||
"description": "match",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"data": "a",
|
||||
"description": "mismatch",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Location-independent identifier with absolute URI",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/draft2020-12/bar#foo",
|
||||
"$defs": {
|
||||
"A": {
|
||||
"$id": "http://localhost:1234/draft2020-12/bar",
|
||||
"$anchor": "foo",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"data": 1,
|
||||
"description": "match",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"data": "a",
|
||||
"description": "mismatch",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Location-independent identifier with base URI change in subschema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/root",
|
||||
"$ref": "http://localhost:1234/draft2020-12/nested.json#foo",
|
||||
"$defs": {
|
||||
"A": {
|
||||
"$id": "nested.json",
|
||||
"$defs": {
|
||||
"B": {
|
||||
"$anchor": "foo",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"data": 1,
|
||||
"description": "match",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"data": "a",
|
||||
"description": "mismatch",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "same $anchor with different base uri",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/foobar",
|
||||
"$defs": {
|
||||
"A": {
|
||||
"$id": "child1",
|
||||
"allOf": [
|
||||
{
|
||||
"$id": "child2",
|
||||
"$anchor": "my_anchor",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"$anchor": "my_anchor",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"$ref": "child1#my_anchor"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "$ref resolves to /$defs/A/allOf/1",
|
||||
"data": "a",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "$ref does not resolve to /$defs/A/allOf/0",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,203 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "anyOf",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"minimum": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first anyOf valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "second anyOf valid",
|
||||
"data": 2.5,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both anyOf valid",
|
||||
"data": 3,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "neither anyOf valid",
|
||||
"data": 1.5,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf with base schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"anyOf" : [
|
||||
{
|
||||
"maxLength": 2
|
||||
},
|
||||
{
|
||||
"minLength": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "mismatch base schema",
|
||||
"data": 3,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "one anyOf valid",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both anyOf invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf with boolean schemas, all true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"anyOf": [true, true]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf with boolean schemas, some true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"anyOf": [true, false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf with boolean schemas, all false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"anyOf": [false, false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf complex types",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"anyOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": {"type": "integer"}
|
||||
},
|
||||
"required": ["bar"]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": {"type": "string"}
|
||||
},
|
||||
"required": ["foo"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first anyOf valid (complex)",
|
||||
"data": {"bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "second anyOf valid (complex)",
|
||||
"data": {"foo": "baz"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both anyOf valid (complex)",
|
||||
"data": {"foo": "baz", "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "neither anyOf valid (complex)",
|
||||
"data": {"foo": 2, "bar": "quux"},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf with one empty schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"anyOf": [
|
||||
{ "type": "number" },
|
||||
{}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 123,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nested anyOf, to check validation semantics",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "anything non-null is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,104 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "boolean schema 'true'",
|
||||
"schema": true,
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boolean true is valid",
|
||||
"data": true,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boolean false is valid",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object is valid",
|
||||
"data": {"foo": "bar"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array is valid",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty array is valid",
|
||||
"data": [],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "boolean schema 'false'",
|
||||
"schema": false,
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "boolean true is invalid",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "boolean false is invalid",
|
||||
"data": false,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is invalid",
|
||||
"data": null,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object is invalid",
|
||||
"data": {"foo": "bar"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is invalid",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "array is invalid",
|
||||
"data": ["foo"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,431 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "const validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "same value is valid",
|
||||
"data": 2,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "another value is invalid",
|
||||
"data": 5,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "another type is invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with object",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": {"foo": "bar", "baz": "bax"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "same object is valid",
|
||||
"data": {"foo": "bar", "baz": "bax"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "same object with different property order is valid",
|
||||
"data": {"baz": "bax", "foo": "bar"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "another object is invalid",
|
||||
"data": {"foo": "bar"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "another type is invalid",
|
||||
"data": [1, 2],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with array",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": [{ "foo": "bar" }]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "same array is valid",
|
||||
"data": [{"foo": "bar"}],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "another array item is invalid",
|
||||
"data": [2],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "array with additional items is invalid",
|
||||
"data": [1, 2, 3],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with null",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": null
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "not null is invalid",
|
||||
"data": 0,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with false does not match 0",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "false is valid",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "integer zero is invalid",
|
||||
"data": 0,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "float zero is invalid",
|
||||
"data": 0.0,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with true does not match 1",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": true
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "true is valid",
|
||||
"data": true,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "integer one is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "float one is invalid",
|
||||
"data": 1.0,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with [false] does not match [0]",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": [false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[false] is valid",
|
||||
"data": [false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[0] is invalid",
|
||||
"data": [0],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "[0.0] is invalid",
|
||||
"data": [0.0],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with [true] does not match [1]",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": [true]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[true] is valid",
|
||||
"data": [true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[1] is invalid",
|
||||
"data": [1],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "[1.0] is invalid",
|
||||
"data": [1.0],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with {\"a\": false} does not match {\"a\": 0}",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": {"a": false}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "{\"a\": false} is valid",
|
||||
"data": {"a": false},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "{\"a\": 0} is invalid",
|
||||
"data": {"a": 0},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "{\"a\": 0.0} is invalid",
|
||||
"data": {"a": 0.0},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with {\"a\": true} does not match {\"a\": 1}",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": {"a": true}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "{\"a\": true} is valid",
|
||||
"data": {"a": true},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "{\"a\": 1} is invalid",
|
||||
"data": {"a": 1},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "{\"a\": 1.0} is invalid",
|
||||
"data": {"a": 1.0},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with 0 does not match other zero-like types",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": 0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "false is invalid",
|
||||
"data": false,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "integer zero is valid",
|
||||
"data": 0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "float zero is valid",
|
||||
"data": 0.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty object is invalid",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty string is invalid",
|
||||
"data": "",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with 1 does not match true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": 1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "true is invalid",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "integer one is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "float one is valid",
|
||||
"data": 1.0,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "const with -2.0 matches integer and float types",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": -2.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "integer -2 is valid",
|
||||
"data": -2,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "integer 2 is invalid",
|
||||
"data": 2,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "float -2.0 is valid",
|
||||
"data": -2.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "float 2.0 is invalid",
|
||||
"data": 2.0,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "float -2.00001 is invalid",
|
||||
"data": -2.00001,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "float and integers are equal up to 64-bit representation limits",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": 9007199254740992
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "integer is valid",
|
||||
"data": 9007199254740992,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "integer minus one is invalid",
|
||||
"data": 9007199254740991,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "float is valid",
|
||||
"data": 9007199254740992.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "float minus one is invalid",
|
||||
"data": 9007199254740991.0,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nul characters in strings",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": "hello\u0000there"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match string with nul",
|
||||
"data": "hello\u0000there",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "do not match string lacking nul",
|
||||
"data": "hellothere",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "characters with the same visual representation but different codepoint",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": "μ",
|
||||
"$comment": "U+03BC"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "character uses the same codepoint",
|
||||
"data": "μ",
|
||||
"comment": "U+03BC",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "character looks the same but uses a different codepoint",
|
||||
"data": "µ",
|
||||
"comment": "U+00B5",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "characters with the same visual representation, but different number of codepoints",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"const": "ä",
|
||||
"$comment": "U+00E4"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "character uses the same codepoint",
|
||||
"data": "ä",
|
||||
"comment": "U+00E4",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "character looks the same but uses combining marks",
|
||||
"data": "ä",
|
||||
"comment": "a, U+0308",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,176 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "contains keyword validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"minimum": 5}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "array with item matching schema (5) is valid",
|
||||
"data": [3, 4, 5],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array with item matching schema (6) is valid",
|
||||
"data": [3, 4, 6],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array with two items matching schema (5, 6) is valid",
|
||||
"data": [3, 4, 5, 6],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array without items matching schema is invalid",
|
||||
"data": [2, 3, 4],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not array is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "contains keyword with const keyword",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": { "const": 5 }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "array with item 5 is valid",
|
||||
"data": [3, 4, 5],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array with two items 5 is valid",
|
||||
"data": [3, 4, 5, 5],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array without item 5 is invalid",
|
||||
"data": [1, 2, 3, 4],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "contains keyword with boolean schema true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": true
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any non-empty array is valid",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "contains keyword with boolean schema false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any non-empty array is invalid",
|
||||
"data": ["foo"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-arrays are valid",
|
||||
"data": "contains does not apply to strings",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "items + contains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"items": { "multipleOf": 2 },
|
||||
"contains": { "multipleOf": 3 }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches items, does not match contains",
|
||||
"data": [ 2, 4, 8 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "does not match items, matches contains",
|
||||
"data": [ 3, 6, 9 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "matches both items and contains",
|
||||
"data": [ 6, 12 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "matches neither items nor contains",
|
||||
"data": [ 1, 5 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "contains with false if subschema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {
|
||||
"if": false,
|
||||
"else": true
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any non-empty array is valid",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "contains with null instance elements",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allows null items",
|
||||
"data": [ null ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,131 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of string-encoded content based on media type",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contentMediaType": "application/json"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid JSON document",
|
||||
"data": "{\"foo\": \"bar\"}",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid JSON document; validates true",
|
||||
"data": "{:}",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 100,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validation of binary string-encoding",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contentEncoding": "base64"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid base64 string",
|
||||
"data": "eyJmb28iOiAiYmFyIn0K",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid base64 string (% is not a valid character); validates true",
|
||||
"data": "eyJmb28iOi%iYmFyIn0K",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 100,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validation of binary-encoded media type documents",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contentMediaType": "application/json",
|
||||
"contentEncoding": "base64"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid base64-encoded JSON document",
|
||||
"data": "eyJmb28iOiAiYmFyIn0K",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a validly-encoded invalid JSON document; validates true",
|
||||
"data": "ezp9Cg==",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid base64 string that is valid JSON; validates true",
|
||||
"data": "{}",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 100,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validation of binary-encoded media type documents with schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contentMediaType": "application/json",
|
||||
"contentEncoding": "base64",
|
||||
"contentSchema": { "type": "object", "required": ["foo"], "properties": { "foo": { "type": "string" } } }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid base64-encoded JSON document",
|
||||
"data": "eyJmb28iOiAiYmFyIn0K",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "another valid base64-encoded JSON document",
|
||||
"data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid base64-encoded JSON document; validates true",
|
||||
"data": "eyJib28iOiAyMH0=",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an empty object as a base64-encoded JSON document; validates true",
|
||||
"data": "e30=",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an empty array as a base64-encoded JSON document",
|
||||
"data": "W10=",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a validly-encoded invalid JSON document; validates true",
|
||||
"data": "ezp9Cg==",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid base64 string that is valid JSON; validates true",
|
||||
"data": "{}",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 100,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,82 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "invalid type for default",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "integer",
|
||||
"default": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when property is specified",
|
||||
"data": {"foo": 13},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "still valid when the invalid default is used",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "invalid string value for default",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "string",
|
||||
"minLength": 4,
|
||||
"default": "bad"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when property is specified",
|
||||
"data": {"bar": "good"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "still valid when the invalid default is used",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "the default keyword does not do anything if the property is missing",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alpha": {
|
||||
"type": "number",
|
||||
"maximum": 3,
|
||||
"default": 5
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an explicit property value is checked against maximum (passing)",
|
||||
"data": { "alpha": 1 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an explicit property value is checked against maximum (failing)",
|
||||
"data": { "alpha": 5 },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing properties are not filled in with the default",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,21 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validate definition against metaschema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "https://json-schema.org/draft/2020-12/schema"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid definition schema",
|
||||
"data": {"$defs": {"foo": {"type": "integer"}}},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid definition schema",
|
||||
"data": {"$defs": {"foo": {"type": 1}}},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,152 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "single dependency",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependentRequired": {"bar": ["foo"]}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "neither",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "nondependant",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with dependency",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "missing dependency",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": ["bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "empty dependents",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependentRequired": {"bar": []}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty object",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with one property",
|
||||
"data": {"bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-object is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "multiple dependents required",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependentRequired": {"quux": ["foo", "bar"]}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "neither",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "nondependants",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with dependencies",
|
||||
"data": {"foo": 1, "bar": 2, "quux": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "missing dependency",
|
||||
"data": {"foo": 1, "quux": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing other dependency",
|
||||
"data": {"bar": 1, "quux": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing both dependencies",
|
||||
"data": {"quux": 1},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "dependencies with escaped characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependentRequired": {
|
||||
"foo\nbar": ["foo\rbar"],
|
||||
"foo\"bar": ["foo'bar"]
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "CRLF",
|
||||
"data": {
|
||||
"foo\nbar": 1,
|
||||
"foo\rbar": 2
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "quoted quotes",
|
||||
"data": {
|
||||
"foo'bar": 1,
|
||||
"foo\"bar": 2
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "CRLF missing dependent",
|
||||
"data": {
|
||||
"foo\nbar": 1,
|
||||
"foo": 2
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "quoted quotes missing dependent",
|
||||
"data": {
|
||||
"foo\"bar": 2
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,171 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "single dependency",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependentSchemas": {
|
||||
"bar": {
|
||||
"properties": {
|
||||
"foo": {"type": "integer"},
|
||||
"bar": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "no dependency",
|
||||
"data": {"foo": "quux"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "wrong type",
|
||||
"data": {"foo": "quux", "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "wrong type other",
|
||||
"data": {"foo": 2, "bar": "quux"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "wrong type both",
|
||||
"data": {"foo": "quux", "bar": "quux"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": ["bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "boolean subschemas",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependentSchemas": {
|
||||
"foo": true,
|
||||
"bar": false
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with property having schema true is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with property having schema false is invalid",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object with both properties is invalid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "dependencies with escaped characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependentSchemas": {
|
||||
"foo\tbar": {"minProperties": 4},
|
||||
"foo'bar": {"required": ["foo\"bar"]}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "quoted tab",
|
||||
"data": {
|
||||
"foo\tbar": 1,
|
||||
"a": 2,
|
||||
"b": 3,
|
||||
"c": 4
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "quoted quote",
|
||||
"data": {
|
||||
"foo'bar": {"foo\"bar": 1}
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "quoted tab invalid under dependent schema",
|
||||
"data": {
|
||||
"foo\tbar": 1,
|
||||
"a": 2
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "quoted quote invalid under dependent schema",
|
||||
"data": {"foo'bar": 1},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "dependent subschema incompatible with root",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {}
|
||||
},
|
||||
"dependentSchemas": {
|
||||
"foo": {
|
||||
"properties": {
|
||||
"bar": {}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches root",
|
||||
"data": {"foo": 1},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "matches dependency",
|
||||
"data": {"bar": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "matches both",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no dependency",
|
||||
"data": {"baz": 1},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,873 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "A $dynamicRef to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamicRef-dynamicAnchor-same-schema/root",
|
||||
"type": "array",
|
||||
"items": { "$dynamicRef": "#items" },
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$dynamicAnchor": "items",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "An array of strings is valid",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "An array containing non-strings is invalid",
|
||||
"data": ["foo", 42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $dynamicRef to an $anchor in the same schema resource behaves like a normal $ref to an $anchor",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamicRef-anchor-same-schema/root",
|
||||
"type": "array",
|
||||
"items": { "$dynamicRef": "#items" },
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$anchor": "items",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "An array of strings is valid",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "An array containing non-strings is invalid",
|
||||
"data": ["foo", 42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $ref to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/ref-dynamicAnchor-same-schema/root",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#items" },
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$dynamicAnchor": "items",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "An array of strings is valid",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "An array containing non-strings is invalid",
|
||||
"data": ["foo", 42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $dynamicRef resolves to the first $dynamicAnchor still in scope that is encountered when the schema is evaluated",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/typical-dynamic-resolution/root",
|
||||
"$ref": "list",
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$dynamicAnchor": "items",
|
||||
"type": "string"
|
||||
},
|
||||
"list": {
|
||||
"$id": "list",
|
||||
"type": "array",
|
||||
"items": { "$dynamicRef": "#items" },
|
||||
"$defs": {
|
||||
"items": {
|
||||
"$comment": "This is only needed to satisfy the bookending requirement",
|
||||
"$dynamicAnchor": "items"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "An array of strings is valid",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "An array containing non-strings is invalid",
|
||||
"data": ["foo", 42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $dynamicRef without anchor in fragment behaves identical to $ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamicRef-without-anchor/root",
|
||||
"$ref": "list",
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$dynamicAnchor": "items",
|
||||
"type": "string"
|
||||
},
|
||||
"list": {
|
||||
"$id": "list",
|
||||
"type": "array",
|
||||
"items": { "$dynamicRef": "#/$defs/items" },
|
||||
"$defs": {
|
||||
"items": {
|
||||
"$comment": "This is only needed to satisfy the bookending requirement",
|
||||
"$dynamicAnchor": "items",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "An array of strings is invalid",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "An array of numbers is valid",
|
||||
"data": [24, 42],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor does not affect dynamic scope resolution",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamic-resolution-with-intermediate-scopes/root",
|
||||
"$ref": "intermediate-scope",
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$dynamicAnchor": "items",
|
||||
"type": "string"
|
||||
},
|
||||
"intermediate-scope": {
|
||||
"$id": "intermediate-scope",
|
||||
"$ref": "list"
|
||||
},
|
||||
"list": {
|
||||
"$id": "list",
|
||||
"type": "array",
|
||||
"items": { "$dynamicRef": "#items" },
|
||||
"$defs": {
|
||||
"items": {
|
||||
"$comment": "This is only needed to satisfy the bookending requirement",
|
||||
"$dynamicAnchor": "items"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "An array of strings is valid",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "An array containing non-strings is invalid",
|
||||
"data": ["foo", 42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "An $anchor with the same name as a $dynamicAnchor is not used for dynamic scope resolution",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamic-resolution-ignores-anchors/root",
|
||||
"$ref": "list",
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$anchor": "items",
|
||||
"type": "string"
|
||||
},
|
||||
"list": {
|
||||
"$id": "list",
|
||||
"type": "array",
|
||||
"items": { "$dynamicRef": "#items" },
|
||||
"$defs": {
|
||||
"items": {
|
||||
"$comment": "This is only needed to satisfy the bookending requirement",
|
||||
"$dynamicAnchor": "items"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Any array is valid",
|
||||
"data": ["foo", 42],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $dynamicRef without a matching $dynamicAnchor in the same schema resource behaves like a normal $ref to $anchor",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamic-resolution-without-bookend/root",
|
||||
"$ref": "list",
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$dynamicAnchor": "items",
|
||||
"type": "string"
|
||||
},
|
||||
"list": {
|
||||
"$id": "list",
|
||||
"type": "array",
|
||||
"items": { "$dynamicRef": "#items" },
|
||||
"$defs": {
|
||||
"items": {
|
||||
"$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref",
|
||||
"$anchor": "items"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Any array is valid",
|
||||
"data": ["foo", 42],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $dynamicRef with a non-matching $dynamicAnchor in the same schema resource behaves like a normal $ref to $anchor",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/unmatched-dynamic-anchor/root",
|
||||
"$ref": "list",
|
||||
"$defs": {
|
||||
"foo": {
|
||||
"$dynamicAnchor": "items",
|
||||
"type": "string"
|
||||
},
|
||||
"list": {
|
||||
"$id": "list",
|
||||
"type": "array",
|
||||
"items": { "$dynamicRef": "#items" },
|
||||
"$defs": {
|
||||
"items": {
|
||||
"$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref",
|
||||
"$anchor": "items",
|
||||
"$dynamicAnchor": "foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Any array is valid",
|
||||
"data": ["foo", 42],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor resolves to the first $dynamicAnchor in the dynamic scope",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/relative-dynamic-reference/root",
|
||||
"$dynamicAnchor": "meta",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": { "const": "pass" }
|
||||
},
|
||||
"$ref": "extended",
|
||||
"$defs": {
|
||||
"extended": {
|
||||
"$id": "extended",
|
||||
"$dynamicAnchor": "meta",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bar": { "$ref": "bar" }
|
||||
}
|
||||
},
|
||||
"bar": {
|
||||
"$id": "bar",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"baz": { "$dynamicRef": "extended#meta" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "The recursive part is valid against the root",
|
||||
"data": {
|
||||
"foo": "pass",
|
||||
"bar": {
|
||||
"baz": { "foo": "pass" }
|
||||
}
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "The recursive part is not valid against the root",
|
||||
"data": {
|
||||
"foo": "pass",
|
||||
"bar": {
|
||||
"baz": { "foo": "fail" }
|
||||
}
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A $dynamicRef that initially resolves to a schema without a matching $dynamicAnchor behaves like a normal $ref to $anchor",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/relative-dynamic-reference-without-bookend/root",
|
||||
"$dynamicAnchor": "meta",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": { "const": "pass" }
|
||||
},
|
||||
"$ref": "extended",
|
||||
"$defs": {
|
||||
"extended": {
|
||||
"$id": "extended",
|
||||
"$anchor": "meta",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bar": { "$ref": "bar" }
|
||||
}
|
||||
},
|
||||
"bar": {
|
||||
"$id": "bar",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"baz": { "$dynamicRef": "extended#meta" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "The recursive part doesn't need to validate against the root",
|
||||
"data": {
|
||||
"foo": "pass",
|
||||
"bar": {
|
||||
"baz": { "foo": "fail" }
|
||||
}
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "multiple dynamic paths to the $dynamicRef keyword",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main",
|
||||
"if": {
|
||||
"properties": {
|
||||
"kindOfList": { "const": "numbers" }
|
||||
},
|
||||
"required": ["kindOfList"]
|
||||
},
|
||||
"then": { "$ref": "numberList" },
|
||||
"else": { "$ref": "stringList" },
|
||||
|
||||
"$defs": {
|
||||
"genericList": {
|
||||
"$id": "genericList",
|
||||
"properties": {
|
||||
"list": {
|
||||
"items": { "$dynamicRef": "#itemType" }
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"defaultItemType": {
|
||||
"$comment": "Only needed to satisfy bookending requirement",
|
||||
"$dynamicAnchor": "itemType"
|
||||
}
|
||||
}
|
||||
},
|
||||
"numberList": {
|
||||
"$id": "numberList",
|
||||
"$defs": {
|
||||
"itemType": {
|
||||
"$dynamicAnchor": "itemType",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"$ref": "genericList"
|
||||
},
|
||||
"stringList": {
|
||||
"$id": "stringList",
|
||||
"$defs": {
|
||||
"itemType": {
|
||||
"$dynamicAnchor": "itemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"$ref": "genericList"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number list with number values",
|
||||
"data": {
|
||||
"kindOfList": "numbers",
|
||||
"list": [1.1]
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "number list with string values",
|
||||
"data": {
|
||||
"kindOfList": "numbers",
|
||||
"list": ["foo"]
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string list with number values",
|
||||
"data": {
|
||||
"kindOfList": "strings",
|
||||
"list": [1.1]
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string list with string values",
|
||||
"data": {
|
||||
"kindOfList": "strings",
|
||||
"list": ["foo"]
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "after leaving a dynamic scope, it is not used by a $dynamicRef",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main",
|
||||
"if": {
|
||||
"$id": "first_scope",
|
||||
"$defs": {
|
||||
"thingy": {
|
||||
"$comment": "this is first_scope#thingy",
|
||||
"$dynamicAnchor": "thingy",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"$id": "second_scope",
|
||||
"$ref": "start",
|
||||
"$defs": {
|
||||
"thingy": {
|
||||
"$comment": "this is second_scope#thingy, the final destination of the $dynamicRef",
|
||||
"$dynamicAnchor": "thingy",
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"start": {
|
||||
"$comment": "this is the landing spot from $ref",
|
||||
"$id": "start",
|
||||
"$dynamicRef": "inner_scope#thingy"
|
||||
},
|
||||
"thingy": {
|
||||
"$comment": "this is the first stop for the $dynamicRef",
|
||||
"$id": "inner_scope",
|
||||
"$dynamicAnchor": "thingy",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "string matches /$defs/thingy, but the $dynamicRef does not stop here",
|
||||
"data": "a string",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "first_scope is not in dynamic scope for the $dynamicRef",
|
||||
"data": 42,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "/then/$defs/thingy is the final stop for the $dynamicRef",
|
||||
"data": null,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "strict-tree schema, guards against misspelled properties",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/strict-tree.json",
|
||||
"$dynamicAnchor": "node",
|
||||
|
||||
"$ref": "tree.json",
|
||||
"unevaluatedProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "instance with misspelled field",
|
||||
"data": {
|
||||
"children": [{
|
||||
"daat": 1
|
||||
}]
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "instance with correct field",
|
||||
"data": {
|
||||
"children": [{
|
||||
"data": 1
|
||||
}]
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "tests for implementation dynamic anchor and reference link",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/strict-extendible.json",
|
||||
"$ref": "extendible-dynamic-ref.json",
|
||||
"$defs": {
|
||||
"elements": {
|
||||
"$dynamicAnchor": "elements",
|
||||
"properties": {
|
||||
"a": true
|
||||
},
|
||||
"required": ["a"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "incorrect parent schema",
|
||||
"data": {
|
||||
"a": true
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "incorrect extended schema",
|
||||
"data": {
|
||||
"elements": [
|
||||
{ "b": 1 }
|
||||
]
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "correct extended schema",
|
||||
"data": {
|
||||
"elements": [
|
||||
{ "a": 1 }
|
||||
]
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref and $dynamicAnchor are independent of order - $defs first",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/strict-extendible-allof-defs-first.json",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "extendible-dynamic-ref.json"
|
||||
},
|
||||
{
|
||||
"$defs": {
|
||||
"elements": {
|
||||
"$dynamicAnchor": "elements",
|
||||
"properties": {
|
||||
"a": true
|
||||
},
|
||||
"required": ["a"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "incorrect parent schema",
|
||||
"data": {
|
||||
"a": true
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "incorrect extended schema",
|
||||
"data": {
|
||||
"elements": [
|
||||
{ "b": 1 }
|
||||
]
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "correct extended schema",
|
||||
"data": {
|
||||
"elements": [
|
||||
{ "a": 1 }
|
||||
]
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref and $dynamicAnchor are independent of order - $ref first",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/strict-extendible-allof-ref-first.json",
|
||||
"allOf": [
|
||||
{
|
||||
"$defs": {
|
||||
"elements": {
|
||||
"$dynamicAnchor": "elements",
|
||||
"properties": {
|
||||
"a": true
|
||||
},
|
||||
"required": ["a"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "extendible-dynamic-ref.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "incorrect parent schema",
|
||||
"data": {
|
||||
"a": true
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "incorrect extended schema",
|
||||
"data": {
|
||||
"elements": [
|
||||
{ "b": 1 }
|
||||
]
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "correct extended schema",
|
||||
"data": {
|
||||
"elements": [
|
||||
{ "a": 1 }
|
||||
]
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref to $dynamicRef finds detached $dynamicAnchor",
|
||||
"schema": {
|
||||
"$ref": "http://localhost:1234/draft2020-12/detached-dynamicref.json#/$defs/foo"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-number is invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$dynamicRef points to a boolean schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$defs": {
|
||||
"true": true,
|
||||
"false": false
|
||||
},
|
||||
"properties": {
|
||||
"true": {
|
||||
"$dynamicRef": "#/$defs/true"
|
||||
},
|
||||
"false": {
|
||||
"$dynamicRef": "#/$defs/false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "follow $dynamicRef to a true schema",
|
||||
"data": { "true": 1 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "follow $dynamicRef to a false schema",
|
||||
"data": { "false": 1 },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$dynamicRef skips over intermediate resources - direct reference",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/main",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bar-item": {
|
||||
"$ref": "item"
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"bar": {
|
||||
"$id": "bar",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "item"
|
||||
},
|
||||
"$defs": {
|
||||
"item": {
|
||||
"$id": "item",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"$dynamicRef": "#content"
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"defaultContent": {
|
||||
"$dynamicAnchor": "content",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"$dynamicAnchor": "content",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "integer property passes",
|
||||
"data": { "bar-item": { "content": 42 } },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string property fails",
|
||||
"data": { "bar-item": { "content": "value" } },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$dynamicRef avoids the root of each schema, but scopes are still registered",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamic-ref-avoids-root-of-each-schema/base",
|
||||
"$ref": "first#/$defs/stuff",
|
||||
"$defs": {
|
||||
"first": {
|
||||
"$id": "first",
|
||||
"$defs": {
|
||||
"stuff": {
|
||||
"$ref": "second#/$defs/stuff"
|
||||
},
|
||||
"length": {
|
||||
"$comment": "unused, because there is no $dynamicAnchor here",
|
||||
"maxLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"second": {
|
||||
"$id": "second",
|
||||
"$defs": {
|
||||
"stuff": {
|
||||
"$ref": "third#/$defs/stuff"
|
||||
},
|
||||
"length": {
|
||||
"$dynamicAnchor": "length",
|
||||
"maxLength": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"third": {
|
||||
"$id": "third",
|
||||
"$defs": {
|
||||
"stuff": {
|
||||
"$dynamicRef": "#length"
|
||||
},
|
||||
"length": {
|
||||
"$dynamicAnchor": "length",
|
||||
"maxLength": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "data is sufficient for schema at second#/$defs/length",
|
||||
"data": "hi",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "data is not sufficient for schema at second#/$defs/length",
|
||||
"data": "hey",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,358 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "simple enum validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [1, 2, 3]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "one of the enum is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "something else is invalid",
|
||||
"data": 4,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "heterogeneous enum validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [6, "foo", [], true, {"foo": 12}]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "one of the enum is valid",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "something else is invalid",
|
||||
"data": null,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "objects are deep compared",
|
||||
"data": {"foo": false},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid object matches",
|
||||
"data": {"foo": 12},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "extra properties in object is invalid",
|
||||
"data": {"foo": 12, "boo": 42},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "heterogeneous enum-with-null validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [6, null]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 6,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "something else is invalid",
|
||||
"data": "test",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enums in properties",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type":"object",
|
||||
"properties": {
|
||||
"foo": {"enum":["foo"]},
|
||||
"bar": {"enum":["bar"]}
|
||||
},
|
||||
"required": ["bar"]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "both properties are valid",
|
||||
"data": {"foo":"foo", "bar":"bar"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "wrong foo value",
|
||||
"data": {"foo":"foot", "bar":"bar"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "wrong bar value",
|
||||
"data": {"foo":"foo", "bar":"bart"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing optional property is valid",
|
||||
"data": {"bar":"bar"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "missing required property is invalid",
|
||||
"data": {"foo":"foo"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing all properties is invalid",
|
||||
"data": {},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with escaped characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": ["foo\nbar", "foo\rbar"]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "member 1 is valid",
|
||||
"data": "foo\nbar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "member 2 is valid",
|
||||
"data": "foo\rbar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "another string is invalid",
|
||||
"data": "abc",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with false does not match 0",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "false is valid",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "integer zero is invalid",
|
||||
"data": 0,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "float zero is invalid",
|
||||
"data": 0.0,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with [false] does not match [0]",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [[false]]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[false] is valid",
|
||||
"data": [false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[0] is invalid",
|
||||
"data": [0],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "[0.0] is invalid",
|
||||
"data": [0.0],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with true does not match 1",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [true]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "true is valid",
|
||||
"data": true,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "integer one is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "float one is invalid",
|
||||
"data": 1.0,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with [true] does not match [1]",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [[true]]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[true] is valid",
|
||||
"data": [true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[1] is invalid",
|
||||
"data": [1],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "[1.0] is invalid",
|
||||
"data": [1.0],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with 0 does not match false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [0]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "false is invalid",
|
||||
"data": false,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "integer zero is valid",
|
||||
"data": 0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "float zero is valid",
|
||||
"data": 0.0,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with [0] does not match [false]",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [[0]]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[false] is invalid",
|
||||
"data": [false],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "[0] is valid",
|
||||
"data": [0],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[0.0] is valid",
|
||||
"data": [0.0],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with 1 does not match true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [1]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "true is invalid",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "integer one is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "float one is valid",
|
||||
"data": 1.0,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "enum with [1] does not match [true]",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [[1]]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[true] is invalid",
|
||||
"data": [true],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "[1] is valid",
|
||||
"data": [1],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[1.0] is valid",
|
||||
"data": [1.0],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nul characters in strings",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"enum": [ "hello\u0000there" ]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match string with nul",
|
||||
"data": "hello\u0000there",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "do not match string lacking nul",
|
||||
"data": "hellothere",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,31 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "exclusiveMaximum validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"exclusiveMaximum": 3.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "below the exclusiveMaximum is valid",
|
||||
"data": 2.2,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boundary point is invalid",
|
||||
"data": 3.0,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "above the exclusiveMaximum is invalid",
|
||||
"data": 3.5,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-numbers",
|
||||
"data": "x",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,31 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "exclusiveMinimum validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"exclusiveMinimum": 1.1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "above the exclusiveMinimum is valid",
|
||||
"data": 1.2,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boundary point is invalid",
|
||||
"data": 1.1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "below the exclusiveMinimum is invalid",
|
||||
"data": 0.6,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-numbers",
|
||||
"data": "x",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,838 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "email format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "email"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid email string is only an annotation by default",
|
||||
"data": "2962",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "idn-email format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "idn-email"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid idn-email string is only an annotation by default",
|
||||
"data": "2962",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "regex format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "regex"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid regex string is only an annotation by default",
|
||||
"data": "^(abc]",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ipv4 format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "ipv4"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid ipv4 string is only an annotation by default",
|
||||
"data": "127.0.0.0.1",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ipv6 format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "ipv6"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid ipv6 string is only an annotation by default",
|
||||
"data": "12345::",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "idn-hostname format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "idn-hostname"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid idn-hostname string is only an annotation by default",
|
||||
"data": "〮실례.테스트",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "hostname format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "hostname"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid hostname string is only an annotation by default",
|
||||
"data": "-a-host-name-that-starts-with--",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "date format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "date"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid date string is only an annotation by default",
|
||||
"data": "06/19/1963",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "date-time format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "date-time"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid date-time string is only an annotation by default",
|
||||
"data": "1990-02-31T15:59:60.123-08:00",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "time format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "time"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid time string is only an annotation by default",
|
||||
"data": "08:30:06 PST",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "json-pointer format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "json-pointer"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid json-pointer string is only an annotation by default",
|
||||
"data": "/foo/bar~",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "relative-json-pointer format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "relative-json-pointer"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid relative-json-pointer string is only an annotation by default",
|
||||
"data": "/foo/bar",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "iri format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "iri"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid iri string is only an annotation by default",
|
||||
"data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "iri-reference format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "iri-reference"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid iri-reference string is only an annotation by default",
|
||||
"data": "\\\\WINDOWS\\filëßåré",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uri format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "uri"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid uri string is only an annotation by default",
|
||||
"data": "//foo.bar/?baz=qux#quux",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uri-reference format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid uri-reference string is only an annotation by default",
|
||||
"data": "\\\\WINDOWS\\fileshare",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uri-template format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "uri-template"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid uri-template string is only an annotation by default",
|
||||
"data": "http://example.com/dictionary/{term:1}/{term",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uuid format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "uuid"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid uuid string is only an annotation by default",
|
||||
"data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "duration format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "duration"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid duration string is only an annotation by default",
|
||||
"data": "PT1D",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,268 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "ignore if without then or else",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"if": {
|
||||
"const": 0
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when valid against lone if",
|
||||
"data": 0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid when invalid against lone if",
|
||||
"data": "hello",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ignore then without if",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"then": {
|
||||
"const": 0
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when valid against lone then",
|
||||
"data": 0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid when invalid against lone then",
|
||||
"data": "hello",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ignore else without if",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"else": {
|
||||
"const": 0
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when valid against lone else",
|
||||
"data": 0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid when invalid against lone else",
|
||||
"data": "hello",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if and then without else",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"if": {
|
||||
"exclusiveMaximum": 0
|
||||
},
|
||||
"then": {
|
||||
"minimum": -10
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid through then",
|
||||
"data": -1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid through then",
|
||||
"data": -100,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid when if test fails",
|
||||
"data": 3,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if and else without then",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"if": {
|
||||
"exclusiveMaximum": 0
|
||||
},
|
||||
"else": {
|
||||
"multipleOf": 2
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when if test passes",
|
||||
"data": -1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid through else",
|
||||
"data": 4,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid through else",
|
||||
"data": 3,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validate against correct branch, then vs else",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"if": {
|
||||
"exclusiveMaximum": 0
|
||||
},
|
||||
"then": {
|
||||
"minimum": -10
|
||||
},
|
||||
"else": {
|
||||
"multipleOf": 2
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid through then",
|
||||
"data": -1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid through then",
|
||||
"data": -100,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid through else",
|
||||
"data": 4,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid through else",
|
||||
"data": 3,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "non-interference across combined schemas",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"exclusiveMaximum": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"then": {
|
||||
"minimum": -10
|
||||
}
|
||||
},
|
||||
{
|
||||
"else": {
|
||||
"multipleOf": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid, but would have been invalid through then",
|
||||
"data": -100,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid, but would have been invalid through else",
|
||||
"data": 3,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if with boolean schema true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"if": true,
|
||||
"then": { "const": "then" },
|
||||
"else": { "const": "else" }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "boolean schema true in if always chooses the then path (valid)",
|
||||
"data": "then",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boolean schema true in if always chooses the then path (invalid)",
|
||||
"data": "else",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if with boolean schema false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"if": false,
|
||||
"then": { "const": "then" },
|
||||
"else": { "const": "else" }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "boolean schema false in if always chooses the else path (invalid)",
|
||||
"data": "then",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "boolean schema false in if always chooses the else path (valid)",
|
||||
"data": "else",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if appears at the end when serialized (keyword processing sequence)",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"then": { "const": "yes" },
|
||||
"else": { "const": "other" },
|
||||
"if": { "maxLength": 4 }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "yes redirects to then and passes",
|
||||
"data": "yes",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "other redirects to else and passes",
|
||||
"data": "other",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "no redirects to then and fails",
|
||||
"data": "no",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid redirects to else and fails",
|
||||
"data": "invalid",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$defs": {
|
||||
"int": { "type": "integer" }
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"$ref": "#/$defs/int"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"$ref": "#/$defs/int"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "passing case",
|
||||
"data": { "foo": 1 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "failing case",
|
||||
"data": { "foo": "a string" },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,304 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "a schema given for items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"items": {"type": "integer"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid items",
|
||||
"data": [ 1, 2, 3 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "wrong type of items",
|
||||
"data": [1, "x"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-arrays",
|
||||
"data": {"foo" : "bar"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "JavaScript pseudo-array is valid",
|
||||
"data": {
|
||||
"0": "invalid",
|
||||
"length": 1
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "items with boolean schema (true)",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"items": true
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any array is valid",
|
||||
"data": [ 1, "foo", true ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty array is valid",
|
||||
"data": [],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "items with boolean schema (false)",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"items": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any non-empty array is invalid",
|
||||
"data": [ 1, "foo", true ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty array is valid",
|
||||
"data": [],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "items and subitems",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$defs": {
|
||||
"item": {
|
||||
"type": "array",
|
||||
"items": false,
|
||||
"prefixItems": [
|
||||
{ "$ref": "#/$defs/sub-item" },
|
||||
{ "$ref": "#/$defs/sub-item" }
|
||||
]
|
||||
},
|
||||
"sub-item": {
|
||||
"type": "object",
|
||||
"required": ["foo"]
|
||||
}
|
||||
},
|
||||
"type": "array",
|
||||
"items": false,
|
||||
"prefixItems": [
|
||||
{ "$ref": "#/$defs/item" },
|
||||
{ "$ref": "#/$defs/item" },
|
||||
{ "$ref": "#/$defs/item" }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid items",
|
||||
"data": [
|
||||
[ {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ]
|
||||
],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too many items",
|
||||
"data": [
|
||||
[ {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ]
|
||||
],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "too many sub-items",
|
||||
"data": [
|
||||
[ {"foo": null}, {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ]
|
||||
],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "wrong item",
|
||||
"data": [
|
||||
{"foo": null},
|
||||
[ {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ]
|
||||
],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "wrong sub-item",
|
||||
"data": [
|
||||
[ {}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ],
|
||||
[ {"foo": null}, {"foo": null} ]
|
||||
],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "fewer items is valid",
|
||||
"data": [
|
||||
[ {"foo": null} ],
|
||||
[ {"foo": null} ]
|
||||
],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nested items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid nested array",
|
||||
"data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "nested array with invalid type",
|
||||
"data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not deep enough",
|
||||
"data": [[[1], [2],[3]], [[4], [5], [6]]],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "prefixItems with no additional items allowed",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [{}, {}, {}],
|
||||
"items": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty array",
|
||||
"data": [ ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "fewer number of items present (1)",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "fewer number of items present (2)",
|
||||
"data": [ 1, 2 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "equal number of items present",
|
||||
"data": [ 1, 2, 3 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "additional items are not permitted",
|
||||
"data": [ 1, 2, 3, 4 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "items does not look in applicators, valid case",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{ "prefixItems": [ { "minimum": 3 } ] }
|
||||
],
|
||||
"items": { "minimum": 5 }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "prefixItems in allOf does not constrain items, invalid case",
|
||||
"data": [ 3, 5 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "prefixItems in allOf does not constrain items, valid case",
|
||||
"data": [ 5, 5 ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "prefixItems validation adjusts the starting index for items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [ { "type": "string" } ],
|
||||
"items": { "type": "integer" }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid items",
|
||||
"data": [ "x", 2, 3 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "wrong type of second item",
|
||||
"data": [ "x", "y" ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "items with heterogeneous array",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [{}],
|
||||
"items": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "heterogeneous invalid instance",
|
||||
"data": [ "foo", "bar", 37 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid instance",
|
||||
"data": [ null ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "items with null instance elements",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"items": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allows null elements",
|
||||
"data": [ null ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,102 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "maxContains without contains is ignored",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maxContains": 1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "one item valid against lone maxContains",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "two items still valid against lone maxContains",
|
||||
"data": [ 1, 2 ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maxContains with contains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"maxContains": 1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty data",
|
||||
"data": [ ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all elements match, valid maxContains",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all elements match, invalid maxContains",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "some elements match, valid maxContains",
|
||||
"data": [ 1, 2 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "some elements match, invalid maxContains",
|
||||
"data": [ 1, 2, 1 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maxContains with contains, value with a decimal",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"maxContains": 1.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "one element matches, valid maxContains",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too many elements match, invalid maxContains",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minContains < maxContains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"minContains": 1,
|
||||
"maxContains": 3
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "actual < minContains < maxContains",
|
||||
"data": [ ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "minContains < actual < maxContains",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "minContains < maxContains < actual",
|
||||
"data": [ 1, 1, 1, 1 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,50 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "maxItems validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maxItems": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "shorter is valid",
|
||||
"data": [1],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "exact length is valid",
|
||||
"data": [1, 2],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too long is invalid",
|
||||
"data": [1, 2, 3],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-arrays",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maxItems validation with a decimal",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maxItems": 2.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "shorter is valid",
|
||||
"data": [1],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too long is invalid",
|
||||
"data": [1, 2, 3],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,55 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "maxLength validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maxLength": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "shorter is valid",
|
||||
"data": "f",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "exact length is valid",
|
||||
"data": "fo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too long is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 100,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "two graphemes is long enough",
|
||||
"data": "\uD83D\uDCA9\uD83D\uDCA9",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maxLength validation with a decimal",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maxLength": 2.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "shorter is valid",
|
||||
"data": "f",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too long is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,79 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "maxProperties validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maxProperties": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "shorter is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "exact length is valid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too long is invalid",
|
||||
"data": {"foo": 1, "bar": 2, "baz": 3},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [1, 2, 3],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maxProperties validation with a decimal",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maxProperties": 2.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "shorter is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too long is invalid",
|
||||
"data": {"foo": 1, "bar": 2, "baz": 3},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maxProperties = 0 means the object is empty",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maxProperties": 0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "no properties is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "one property is invalid",
|
||||
"data": { "foo": 1 },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,60 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "maximum validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maximum": 3.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "below the maximum is valid",
|
||||
"data": 2.6,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boundary point is valid",
|
||||
"data": 3.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "above the maximum is invalid",
|
||||
"data": 3.5,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-numbers",
|
||||
"data": "x",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maximum validation with unsigned integer",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maximum": 300
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "below the maximum is invalid",
|
||||
"data": 299.97,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boundary point integer is valid",
|
||||
"data": 300,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boundary point float is valid",
|
||||
"data": 300.00,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "above the maximum is invalid",
|
||||
"data": 300.5,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,224 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "minContains without contains is ignored",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minContains": 1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "one item valid against lone minContains",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "zero items still valid against lone minContains",
|
||||
"data": [],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minContains=1 with contains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"minContains": 1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty data",
|
||||
"data": [ ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no elements match",
|
||||
"data": [ 2 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "single element matches, valid minContains",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "some elements match, valid minContains",
|
||||
"data": [ 1, 2 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all elements match, valid minContains",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minContains=2 with contains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"minContains": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty data",
|
||||
"data": [ ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all elements match, invalid minContains",
|
||||
"data": [ 1 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "some elements match, invalid minContains",
|
||||
"data": [ 1, 2 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all elements match, valid minContains (exactly as needed)",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all elements match, valid minContains (more than needed)",
|
||||
"data": [ 1, 1, 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "some elements match, valid minContains",
|
||||
"data": [ 1, 2, 1 ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minContains=2 with contains with a decimal value",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"minContains": 2.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "one element matches, invalid minContains",
|
||||
"data": [ 1 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "both elements match, valid minContains",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maxContains = minContains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"maxContains": 2,
|
||||
"minContains": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty data",
|
||||
"data": [ ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all elements match, invalid minContains",
|
||||
"data": [ 1 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all elements match, invalid maxContains",
|
||||
"data": [ 1, 1, 1 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all elements match, valid maxContains and minContains",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maxContains < minContains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"maxContains": 1,
|
||||
"minContains": 3
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty data",
|
||||
"data": [ ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid minContains",
|
||||
"data": [ 1 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid maxContains",
|
||||
"data": [ 1, 1, 1 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid maxContains and minContains",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minContains = 0",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"minContains": 0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty data",
|
||||
"data": [ ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "minContains = 0 makes contains always pass",
|
||||
"data": [ 2 ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minContains = 0 with maxContains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"const": 1},
|
||||
"minContains": 0,
|
||||
"maxContains": 1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty data",
|
||||
"data": [ ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "not more than maxContains",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too many",
|
||||
"data": [ 1, 1 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,50 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "minItems validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minItems": 1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "longer is valid",
|
||||
"data": [1, 2],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "exact length is valid",
|
||||
"data": [1],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too short is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-arrays",
|
||||
"data": "",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minItems validation with a decimal",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minItems": 1.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "longer is valid",
|
||||
"data": [1, 2],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too short is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,55 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "minLength validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minLength": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "longer is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "exact length is valid",
|
||||
"data": "fo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too short is invalid",
|
||||
"data": "f",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "one grapheme is not long enough",
|
||||
"data": "\uD83D\uDCA9",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minLength validation with a decimal",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minLength": 2.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "longer is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too short is invalid",
|
||||
"data": "f",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,60 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "minProperties validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minProperties": 1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "longer is valid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "exact length is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too short is invalid",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minProperties validation with a decimal",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minProperties": 1.0
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "longer is valid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "too short is invalid",
|
||||
"data": {},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,75 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "minimum validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minimum": 1.1
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "above the minimum is valid",
|
||||
"data": 2.6,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boundary point is valid",
|
||||
"data": 1.1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "below the minimum is invalid",
|
||||
"data": 0.6,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-numbers",
|
||||
"data": "x",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minimum validation with signed integer",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minimum": -2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "negative above the minimum is valid",
|
||||
"data": -1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "positive above the minimum is valid",
|
||||
"data": 0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boundary point is valid",
|
||||
"data": -2,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boundary point with float is valid",
|
||||
"data": -2.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "float below the minimum is invalid",
|
||||
"data": -2.0001,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "int below the minimum is invalid",
|
||||
"data": -3,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-numbers",
|
||||
"data": "x",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,97 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "by int",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"multipleOf": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "int by int",
|
||||
"data": 10,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "int by int fail",
|
||||
"data": 7,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-numbers",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "by number",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"multipleOf": 1.5
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "zero is multiple of anything",
|
||||
"data": 0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "4.5 is multiple of 1.5",
|
||||
"data": 4.5,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "35 is not multiple of 1.5",
|
||||
"data": 35,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "by small number",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"multipleOf": 0.0001
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "0.0075 is multiple of 0.0001",
|
||||
"data": 0.0075,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "0.00751 is not multiple of 0.0001",
|
||||
"data": 0.00751,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "float division = inf",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "integer", "multipleOf": 0.123456789
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "always invalid, but naive implementations may raise an overflow error",
|
||||
"data": 1e308,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "small multiple of large integer",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "integer", "multipleOf": 1e-8
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any integer is a multiple of 1e-8",
|
||||
"data": 12391239123,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,301 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "not",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"not": {"type": "integer"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allowed",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "disallowed",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "not multiple types",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"not": {"type": ["integer", "boolean"]}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "other mismatch",
|
||||
"data": true,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "not more complex schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"not": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "other match",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": {"foo": "bar"},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "forbidden property",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"not": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "property present",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "property absent",
|
||||
"data": {"bar": 1, "baz": 2},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "forbid everything with empty schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"not": {}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "boolean true is invalid",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "boolean false is invalid",
|
||||
"data": false,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is invalid",
|
||||
"data": null,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object is invalid",
|
||||
"data": {"foo": "bar"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is invalid",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "array is invalid",
|
||||
"data": ["foo"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "forbid everything with boolean schema true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"not": true
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "boolean true is invalid",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "boolean false is invalid",
|
||||
"data": false,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is invalid",
|
||||
"data": null,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object is invalid",
|
||||
"data": {"foo": "bar"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is invalid",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "array is invalid",
|
||||
"data": ["foo"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow everything with boolean schema false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"not": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boolean true is valid",
|
||||
"data": true,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "boolean false is valid",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object is valid",
|
||||
"data": {"foo": "bar"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array is valid",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty array is valid",
|
||||
"data": [],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "double negation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"not": { "not": {} }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "collect annotations inside a 'not', even if collection is disabled",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"not": {
|
||||
"$comment": "this subschema must still produce annotations internally, even though the 'not' will ultimately discard them",
|
||||
"anyOf": [
|
||||
true,
|
||||
{ "properties": { "foo": true } }
|
||||
],
|
||||
"unevaluatedProperties": false
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "unevaluated property",
|
||||
"data": { "bar": 1 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "annotations are still collected inside a 'not'",
|
||||
"data": { "foo": 1 },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,293 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "oneOf",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"minimum": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first oneOf valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "second oneOf valid",
|
||||
"data": 2.5,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both oneOf valid",
|
||||
"data": 3,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "neither oneOf valid",
|
||||
"data": 1.5,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with base schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"oneOf" : [
|
||||
{
|
||||
"minLength": 2
|
||||
},
|
||||
{
|
||||
"maxLength": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "mismatch base schema",
|
||||
"data": 3,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "one oneOf valid",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both oneOf valid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, all true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [true, true, true]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, one true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [true, false, false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, more than one true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [true, true, false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, all false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [false, false, false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf complex types",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": {"type": "integer"}
|
||||
},
|
||||
"required": ["bar"]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": {"type": "string"}
|
||||
},
|
||||
"required": ["foo"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first oneOf valid (complex)",
|
||||
"data": {"bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "second oneOf valid (complex)",
|
||||
"data": {"foo": "baz"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both oneOf valid (complex)",
|
||||
"data": {"foo": "baz", "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "neither oneOf valid (complex)",
|
||||
"data": {"foo": 2, "bar": "quux"},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with empty schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [
|
||||
{ "type": "number" },
|
||||
{}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "one valid - valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both valid - invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with required",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"oneOf": [
|
||||
{ "required": ["foo", "bar"] },
|
||||
{ "required": ["foo", "baz"] }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "both invalid - invalid",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "first valid - valid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "second valid - valid",
|
||||
"data": {"foo": 1, "baz": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both valid - invalid",
|
||||
"data": {"foo": 1, "bar": 2, "baz" : 3},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with missing optional property",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": true,
|
||||
"baz": true
|
||||
},
|
||||
"required": ["bar"]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": true
|
||||
},
|
||||
"required": ["foo"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first oneOf valid",
|
||||
"data": {"bar": 8},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "second oneOf valid",
|
||||
"data": {"foo": "foo"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "both oneOf valid",
|
||||
"data": {"foo": "foo", "bar": 8},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "neither oneOf valid",
|
||||
"data": {"baz": "quux"},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nested oneOf, to check validation semantics",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"oneOf": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "anything non-null is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,60 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "$anchor inside an enum is not a real identifier",
|
||||
"comment": "the implementation must not be confused by an $anchor buried in the enum",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$defs": {
|
||||
"anchor_in_enum": {
|
||||
"enum": [
|
||||
{
|
||||
"$anchor": "my_anchor",
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"real_identifier_in_schema": {
|
||||
"$anchor": "my_anchor",
|
||||
"type": "string"
|
||||
},
|
||||
"zzz_anchor_in_const": {
|
||||
"const": {
|
||||
"$anchor": "my_anchor",
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{ "$ref": "#/$defs/anchor_in_enum" },
|
||||
{ "$ref": "#my_anchor" }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "exact match to enum, and type matches",
|
||||
"data": {
|
||||
"$anchor": "my_anchor",
|
||||
"type": "null"
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "in implementations that strip $anchor, this may match either $def",
|
||||
"data": {
|
||||
"type": "null"
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "match $ref to $anchor",
|
||||
"data": "a string to match #/$defs/anchor_in_enum",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "no match on enum or $ref to $anchor",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,110 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "integer",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "integer"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a bignum is an integer",
|
||||
"data": 12345678910111213141516171819202122232425262728293031,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a negative bignum is an integer",
|
||||
"data": -12345678910111213141516171819202122232425262728293031,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "number",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "number"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a bignum is a number",
|
||||
"data": 98249283749234923498293171823948729348710298301928331,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a negative bignum is a number",
|
||||
"data": -98249283749234923498293171823948729348710298301928331,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "string",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a bignum is not a string",
|
||||
"data": 98249283749234923498293171823948729348710298301928331,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "maximum integer comparison",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"maximum": 18446744073709551615
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "comparison works for high numbers",
|
||||
"data": 18446744073709551600,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "float comparison with high precision",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"exclusiveMaximum": 972783798187987123879878123.18878137
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "comparison works for high numbers",
|
||||
"data": 972783798187987123879878123.188781371,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "minimum integer comparison",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"minimum": -18446744073709551615
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "comparison works for very negative numbers",
|
||||
"data": -18446744073709551600,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "float comparison with high precision on negative numbers",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"exclusiveMinimum": -972783798187987123879878123.18878137
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "comparison works for very negative numbers",
|
||||
"data": -972783798187987123879878123.188781371,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "refs to historic drafts are processed as historic drafts",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "array",
|
||||
"$ref": "http://localhost:1234/draft2019-09/ignore-prefixItems.json"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first item not a string is valid",
|
||||
"comment": "if the implementation is not processing the $ref as a 2019-09 schema, this test will fail",
|
||||
"data": [1, 2, 3],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Vendored
-282
@@ -1,282 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "single dependency",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependencies": {"bar": ["foo"]}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "neither",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "nondependant",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with dependency",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "missing dependency",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": ["bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "empty dependents",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependencies": {"bar": []}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty object",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with one property",
|
||||
"data": {"bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-object is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "multiple dependents required",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependencies": {"quux": ["foo", "bar"]}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "neither",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "nondependants",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with dependencies",
|
||||
"data": {"foo": 1, "bar": 2, "quux": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "missing dependency",
|
||||
"data": {"foo": 1, "quux": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing other dependency",
|
||||
"data": {"bar": 1, "quux": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing both dependencies",
|
||||
"data": {"quux": 1},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "dependencies with escaped characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependencies": {
|
||||
"foo\nbar": ["foo\rbar"],
|
||||
"foo\"bar": ["foo'bar"]
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "CRLF",
|
||||
"data": {
|
||||
"foo\nbar": 1,
|
||||
"foo\rbar": 2
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "quoted quotes",
|
||||
"data": {
|
||||
"foo'bar": 1,
|
||||
"foo\"bar": 2
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "CRLF missing dependent",
|
||||
"data": {
|
||||
"foo\nbar": 1,
|
||||
"foo": 2
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "quoted quotes missing dependent",
|
||||
"data": {
|
||||
"foo\"bar": 2
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "single schema dependency",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependencies": {
|
||||
"bar": {
|
||||
"properties": {
|
||||
"foo": {"type": "integer"},
|
||||
"bar": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "no dependency",
|
||||
"data": {"foo": "quux"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "wrong type",
|
||||
"data": {"foo": "quux", "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "wrong type other",
|
||||
"data": {"foo": 2, "bar": "quux"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "wrong type both",
|
||||
"data": {"foo": "quux", "bar": "quux"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": ["bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "boolean subschemas",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependencies": {
|
||||
"foo": true,
|
||||
"bar": false
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with property having schema true is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with property having schema false is invalid",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object with both properties is invalid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "schema dependencies with escaped characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"dependencies": {
|
||||
"foo\tbar": {"minProperties": 4},
|
||||
"foo'bar": {"required": ["foo\"bar"]}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "quoted tab",
|
||||
"data": {
|
||||
"foo\tbar": 1,
|
||||
"a": 2,
|
||||
"b": 3,
|
||||
"c": 4
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "quoted quote",
|
||||
"data": {
|
||||
"foo'bar": {"foo\"bar": 1}
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "quoted tab invalid under dependent schema",
|
||||
"data": {
|
||||
"foo\tbar": 1,
|
||||
"a": 2
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "quoted quote invalid under dependent schema",
|
||||
"data": {"foo'bar": 1},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,56 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "$dynamicRef skips over intermediate resources - pointer reference across resource boundary",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/optional/main",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bar-item": {
|
||||
"$ref": "bar#/$defs/item"
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"bar": {
|
||||
"$id": "bar",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "item"
|
||||
},
|
||||
"$defs": {
|
||||
"item": {
|
||||
"$id": "item",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"$dynamicRef": "#content"
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"defaultContent": {
|
||||
"$dynamicAnchor": "content",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"$dynamicAnchor": "content",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "integer property passes",
|
||||
"data": { "bar-item": { "content": 42 } },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string property fails",
|
||||
"data": { "bar-item": { "content": "value" } },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}]
|
||||
-582
@@ -1,582 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "ECMA 262 regex $ does not match trailing newline",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^abc$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches in Python, but not in ECMA 262",
|
||||
"data": "abc\\n",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "matches",
|
||||
"data": "abc",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 regex converts \\t to horizontal tab",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\t$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "does not match",
|
||||
"data": "\\t",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "matches",
|
||||
"data": "\u0009",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 regex escapes control codes with \\c and upper letter",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\cC$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "does not match",
|
||||
"data": "\\cC",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "matches",
|
||||
"data": "\u0003",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 regex escapes control codes with \\c and lower letter",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\cc$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "does not match",
|
||||
"data": "\\cc",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "matches",
|
||||
"data": "\u0003",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 \\d matches ascii digits only",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\d$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ASCII zero matches",
|
||||
"data": "0",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "NKO DIGIT ZERO does not match (unlike e.g. Python)",
|
||||
"data": "߀",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "NKO DIGIT ZERO (as \\u escape) does not match",
|
||||
"data": "\u07c0",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 \\D matches everything but ascii digits",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\D$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ASCII zero does not match",
|
||||
"data": "0",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "NKO DIGIT ZERO matches (unlike e.g. Python)",
|
||||
"data": "߀",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "NKO DIGIT ZERO (as \\u escape) matches",
|
||||
"data": "\u07c0",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 \\w matches ascii letters only",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\w$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ASCII 'a' matches",
|
||||
"data": "a",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "latin-1 e-acute does not match (unlike e.g. Python)",
|
||||
"data": "é",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 \\W matches everything but ascii letters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\W$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ASCII 'a' does not match",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "latin-1 e-acute matches (unlike e.g. Python)",
|
||||
"data": "é",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 \\s matches whitespace",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\s$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ASCII space matches",
|
||||
"data": " ",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Character tabulation matches",
|
||||
"data": "\t",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Line tabulation matches",
|
||||
"data": "\u000b",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Form feed matches",
|
||||
"data": "\u000c",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "latin-1 non-breaking-space matches",
|
||||
"data": "\u00a0",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "zero-width whitespace matches",
|
||||
"data": "\ufeff",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "line feed matches (line terminator)",
|
||||
"data": "\u000a",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "paragraph separator matches (line terminator)",
|
||||
"data": "\u2029",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "EM SPACE matches (Space_Separator)",
|
||||
"data": "\u2003",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Non-whitespace control does not match",
|
||||
"data": "\u0001",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Non-whitespace does not match",
|
||||
"data": "\u2013",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 \\S matches everything but whitespace",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string",
|
||||
"pattern": "^\\S$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ASCII space does not match",
|
||||
"data": " ",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Character tabulation does not match",
|
||||
"data": "\t",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Line tabulation does not match",
|
||||
"data": "\u000b",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Form feed does not match",
|
||||
"data": "\u000c",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "latin-1 non-breaking-space does not match",
|
||||
"data": "\u00a0",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "zero-width whitespace does not match",
|
||||
"data": "\ufeff",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "line feed does not match (line terminator)",
|
||||
"data": "\u000a",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "paragraph separator does not match (line terminator)",
|
||||
"data": "\u2029",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "EM SPACE does not match (Space_Separator)",
|
||||
"data": "\u2003",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Non-whitespace control matches",
|
||||
"data": "\u0001",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Non-whitespace matches",
|
||||
"data": "\u2013",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "patterns always use unicode semantics with pattern",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"pattern": "\\p{Letter}cole"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ascii character in json string",
|
||||
"data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "literal unicode character in json string",
|
||||
"data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unicode character in hex format in string",
|
||||
"data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unicode matching is case-sensitive",
|
||||
"data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"pattern": "\\wcole"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ascii character in json string",
|
||||
"data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "literal unicode character in json string",
|
||||
"data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unicode character in hex format in string",
|
||||
"data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unicode matching is case-sensitive",
|
||||
"data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "pattern with ASCII ranges",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"pattern": "[a-z]cole"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "literal unicode character in json string",
|
||||
"data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unicode character in hex format in string",
|
||||
"data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ascii characters match",
|
||||
"data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "\\d in pattern matches [0-9], not unicode digits",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"pattern": "^\\d+$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ascii digits",
|
||||
"data": "42",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ascii non-digits",
|
||||
"data": "-%#",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)",
|
||||
"data": "৪২",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "pattern with non-ASCII digits",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"pattern": "^\\p{digit}+$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ascii digits",
|
||||
"data": "42",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ascii non-digits",
|
||||
"data": "-%#",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)",
|
||||
"data": "৪২",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "patterns always use unicode semantics with patternProperties",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"\\p{Letter}cole": true
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ascii character in json string",
|
||||
"data": { "l'ecole": "pas de vraie vie" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "literal unicode character in json string",
|
||||
"data": { "l'école": "pas de vraie vie" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unicode character in hex format in string",
|
||||
"data": { "l'\u00e9cole": "pas de vraie vie" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unicode matching is case-sensitive",
|
||||
"data": { "L'ÉCOLE": "PAS DE VRAIE VIE" },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"\\wcole": true
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ascii character in json string",
|
||||
"data": { "l'ecole": "pas de vraie vie" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "literal unicode character in json string",
|
||||
"data": { "l'école": "pas de vraie vie" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unicode character in hex format in string",
|
||||
"data": { "l'\u00e9cole": "pas de vraie vie" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unicode matching is case-sensitive",
|
||||
"data": { "L'ÉCOLE": "PAS DE VRAIE VIE" },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "patternProperties with ASCII ranges",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"[a-z]cole": true
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "literal unicode character in json string",
|
||||
"data": { "l'école": "pas de vraie vie" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unicode character in hex format in string",
|
||||
"data": { "l'\u00e9cole": "pas de vraie vie" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ascii characters match",
|
||||
"data": { "l'ecole": "pas de vraie vie" },
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "\\d in patternProperties matches [0-9], not unicode digits",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^\\d+$": true
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ascii digits",
|
||||
"data": { "42": "life, the universe, and everything" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ascii non-digits",
|
||||
"data": { "-%#": "spending the year dead for tax reasons" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)",
|
||||
"data": { "৪২": "khajit has wares if you have coin" },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "patternProperties with non-ASCII digits",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^\\p{digit}+$": true
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ascii digits",
|
||||
"data": { "42": "life, the universe, and everything" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ascii non-digits",
|
||||
"data": { "-%#": "spending the year dead for tax reasons" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)",
|
||||
"data": { "৪২": "khajit has wares if you have coin" },
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "all integers are multiples of 0.5, if overflow is handled",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "integer",
|
||||
"multipleOf": 0.5
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid if optional overflow handling is implemented",
|
||||
"data": 1e308,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "schema that uses custom metaschema with format-assertion: false",
|
||||
"schema": {
|
||||
"$id": "https://schema/using/format-assertion/false",
|
||||
"$schema": "http://localhost:1234/draft2020-12/format-assertion-false.json",
|
||||
"format": "ipv4"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "format-assertion: false: valid string",
|
||||
"data": "127.0.0.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "format-assertion: false: invalid string",
|
||||
"data": "not-an-ipv4",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "schema that uses custom metaschema with format-assertion: true",
|
||||
"schema": {
|
||||
"$id": "https://schema/using/format-assertion/true",
|
||||
"$schema": "http://localhost:1234/draft2020-12/format-assertion-true.json",
|
||||
"format": "ipv4"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "format-assertion: true: valid string",
|
||||
"data": "127.0.0.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "format-assertion: true: invalid string",
|
||||
"data": "not-an-ipv4",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of date-time strings",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "date-time"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid date-time string",
|
||||
"data": "1963-06-19T08:30:06.283185Z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid date-time string without second fraction",
|
||||
"data": "1963-06-19T08:30:06Z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid date-time string with plus offset",
|
||||
"data": "1937-01-01T12:00:27.87+00:20",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid date-time string with minus offset",
|
||||
"data": "1990-12-31T15:59:50.123-08:00",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid date-time with a leap second, UTC",
|
||||
"data": "1998-12-31T23:59:60Z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid date-time with a leap second, with minus offset",
|
||||
"data": "1998-12-31T15:59:60.123-08:00",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid date-time past leap second, UTC",
|
||||
"data": "1998-12-31T23:59:61Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid date-time with leap second on a wrong minute, UTC",
|
||||
"data": "1998-12-31T23:58:60Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid date-time with leap second on a wrong hour, UTC",
|
||||
"data": "1998-12-31T22:59:60Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid day in date-time string",
|
||||
"data": "1990-02-31T15:59:59.123-08:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid offset in date-time string",
|
||||
"data": "1990-12-31T15:59:59-24:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid closing Z after time-zone offset",
|
||||
"data": "1963-06-19T08:30:06.28123+01:00Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid date-time string",
|
||||
"data": "06/19/1963 08:30:06 PST",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "case-insensitive T and Z",
|
||||
"data": "1963-06-19t08:30:06.283185z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "only RFC3339 not all of ISO 8601 are valid",
|
||||
"data": "2013-350T01:01:01",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid non-padded month dates",
|
||||
"data": "1963-6-19T08:30:06.283185Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid non-padded day dates",
|
||||
"data": "1963-06-1T08:30:06.283185Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid non-ASCII '৪' (a Bengali 4) in date portion",
|
||||
"data": "1963-06-1৪T00:00:00Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid non-ASCII '৪' (a Bengali 4) in time portion",
|
||||
"data": "1963-06-11T0৪:00:00Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid extended year",
|
||||
"data": "+11963-06-19T08:30:06.283185Z",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-251
@@ -1,251 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of date strings",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "date"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid date string",
|
||||
"data": "1963-06-19",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 31 days in January",
|
||||
"data": "2020-01-31",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 32 days in January",
|
||||
"data": "2020-01-32",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 28 days in February (normal)",
|
||||
"data": "2021-02-28",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 29 days in February (normal)",
|
||||
"data": "2021-02-29",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 29 days in February (leap)",
|
||||
"data": "2020-02-29",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 30 days in February (leap)",
|
||||
"data": "2020-02-30",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 31 days in March",
|
||||
"data": "2020-03-31",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 32 days in March",
|
||||
"data": "2020-03-32",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 30 days in April",
|
||||
"data": "2020-04-30",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 31 days in April",
|
||||
"data": "2020-04-31",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 31 days in May",
|
||||
"data": "2020-05-31",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 32 days in May",
|
||||
"data": "2020-05-32",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 30 days in June",
|
||||
"data": "2020-06-30",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 31 days in June",
|
||||
"data": "2020-06-31",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 31 days in July",
|
||||
"data": "2020-07-31",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 32 days in July",
|
||||
"data": "2020-07-32",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 31 days in August",
|
||||
"data": "2020-08-31",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 32 days in August",
|
||||
"data": "2020-08-32",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 30 days in September",
|
||||
"data": "2020-09-30",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 31 days in September",
|
||||
"data": "2020-09-31",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 31 days in October",
|
||||
"data": "2020-10-31",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 32 days in October",
|
||||
"data": "2020-10-32",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 30 days in November",
|
||||
"data": "2020-11-30",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 31 days in November",
|
||||
"data": "2020-11-31",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid date string with 31 days in December",
|
||||
"data": "2020-12-31",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with 32 days in December",
|
||||
"data": "2020-12-32",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a invalid date string with invalid month",
|
||||
"data": "2020-13-01",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid date string",
|
||||
"data": "06/19/1963",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "only RFC3339 not all of ISO 8601 are valid",
|
||||
"data": "2013-350",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-padded month dates are not valid",
|
||||
"data": "1998-1-20",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-padded day dates are not valid",
|
||||
"data": "1998-01-1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid month",
|
||||
"data": "1998-13-01",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid month-day combination",
|
||||
"data": "1998-04-31",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "2021 is not a leap year",
|
||||
"data": "2021-02-29",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "2020 is a leap year",
|
||||
"data": "2020-02-29",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid non-ASCII '৪' (a Bengali 4)",
|
||||
"data": "1963-06-1৪",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ISO8601 / non-RFC3339: YYYYMMDD without dashes (2023-03-28)",
|
||||
"data": "20230328",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ISO8601 / non-RFC3339: week number implicit day of week (2023-01-02)",
|
||||
"data": "2023-W01",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ISO8601 / non-RFC3339: week number with day of week (2023-03-28)",
|
||||
"data": "2023-W13-2",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ISO8601 / non-RFC3339: week number rollover to next year (2023-01-01)",
|
||||
"data": "2022W527",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string in date-time format",
|
||||
"data": "2020-11-28T23:55:45Z",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of duration strings",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "duration"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid duration string",
|
||||
"data": "P4DT12H30M5S",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid duration string",
|
||||
"data": "PT1D",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "must start with P",
|
||||
"data": "4DT12H30M5S",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no elements present",
|
||||
"data": "P",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no time elements present",
|
||||
"data": "P1YT",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no date or time elements present",
|
||||
"data": "PT",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "elements out of order",
|
||||
"data": "P2D1Y",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing time separator",
|
||||
"data": "P1D2H",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "time element in the date position",
|
||||
"data": "P2S",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "four years duration",
|
||||
"data": "P4Y",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "zero time, in seconds",
|
||||
"data": "PT0S",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "zero time, in days",
|
||||
"data": "P0D",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "one month duration",
|
||||
"data": "P1M",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "one minute duration",
|
||||
"data": "PT1M",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "one and a half days, in hours",
|
||||
"data": "PT36H",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "one and a half days, in days and hours",
|
||||
"data": "P1DT12H",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "two weeks",
|
||||
"data": "P2W",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "weeks cannot be combined with other units",
|
||||
"data": "P1Y2W",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid non-ASCII '২' (a Bengali 2)",
|
||||
"data": "P২Y",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "element without unit",
|
||||
"data": "P1",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "\\a is not an ECMA 262 control escape",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "regex"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "when used as a pattern",
|
||||
"data": "\\a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of e-mail addresses",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "email"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid e-mail address",
|
||||
"data": "joe.bloggs@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid e-mail address",
|
||||
"data": "2962",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "tilde in local part is valid",
|
||||
"data": "te~st@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "tilde before local part is valid",
|
||||
"data": "~test@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "tilde after local part is valid",
|
||||
"data": "test~@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a quoted string with a space in the local part is valid",
|
||||
"data": "\"joe bloggs\"@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a quoted string with a double dot in the local part is valid",
|
||||
"data": "\"joe..bloggs\"@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a quoted string with a @ in the local part is valid",
|
||||
"data": "\"joe@bloggs\"@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an IPv4-address-literal after the @ is valid",
|
||||
"data": "joe.bloggs@[127.0.0.1]",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an IPv6-address-literal after the @ is valid",
|
||||
"data": "joe.bloggs@[IPv6:::1]",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "dot before local part is not valid",
|
||||
"data": ".test@example.com",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "dot after local part is not valid",
|
||||
"data": "test.@example.com",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "two separated dots inside local part are valid",
|
||||
"data": "te.s.t@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "two subsequent dots inside local part are not valid",
|
||||
"data": "te..st@example.com",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid domain",
|
||||
"data": "joe.bloggs@invalid=domain.com",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid IPv4-address-literal",
|
||||
"data": "joe.bloggs@[127.0.0.300]",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "two email addresses is not valid",
|
||||
"data": "user1@oceania.org, user2@oceania.org",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "full \"From\" header is invalid",
|
||||
"data": "\"Winston Smith\" <winston.smith@recdep.minitrue> (Records Department)",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-361
@@ -1,361 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of host names",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "hostname"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid host name",
|
||||
"data": "www.example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label",
|
||||
"data": "hostname",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label with digits",
|
||||
"data": "h0stn4me",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label starting with digit",
|
||||
"data": "1host",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label ending with digit",
|
||||
"data": "hostnam3",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty string",
|
||||
"data": "",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "single dot",
|
||||
"data": ".",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "leading dot",
|
||||
"data": ".example",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "trailing dot",
|
||||
"data": "example.",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "IDN label separator",
|
||||
"data": "example\uff0ecom",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "single label with hyphen",
|
||||
"data": "host-name",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "starts with hyphen",
|
||||
"data": "-hostname",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ends with hyphen",
|
||||
"data": "hostname-",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "contains \"--\" in the 3rd and 4th position",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1",
|
||||
"data": "XN--aa---o47jg78q",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "contains underscore",
|
||||
"data": "host_name",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "exceeds maximum overall length (256)",
|
||||
"data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "maximum label length (63)",
|
||||
"data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "exceeds maximum label length (63)",
|
||||
"data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validation of A-label (punycode) host names",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "hostname"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid Punycode",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1",
|
||||
"data": "xn--X",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid host name (example.test in Hangul)",
|
||||
"data": "xn--9n2bp8q.xn--9t4b11yi5a",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "contains illegal char U+302E Hangul single dot tone mark",
|
||||
"data": "xn--07jt112bpxg.xn--9t4b11yi5a",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Begins with a Spacing Combining Mark",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2",
|
||||
"data": "xn--hello-txk",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Begins with a Nonspacing Mark",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2",
|
||||
"data": "xn--hello-zed",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Begins with an Enclosing Mark",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2",
|
||||
"data": "xn--hello-6bf",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Exceptions that are PVALID, left-to-right chars",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6",
|
||||
"data": "xn--zca29lwxobi7a",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Exceptions that are PVALID, right-to-left chars",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6",
|
||||
"data": "xn--qmbc",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Exceptions that are DISALLOWED, right-to-left chars",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6",
|
||||
"data": "xn--chb89f",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Exceptions that are DISALLOWED, left-to-right chars",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start",
|
||||
"data": "xn--07jceefgh4c",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with no preceding 'l'",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "xn--al-0ea",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with nothing preceding",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "xn--l-fda",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with no following 'l'",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "xn--la-0ea",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with nothing following",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "xn--l-gda",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with surrounding 'l's",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "xn--ll-0ea",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Greek KERAIA not followed by Greek",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4",
|
||||
"data": "xn--S-jib3p",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Greek KERAIA not followed by anything",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4",
|
||||
"data": "xn--wva3j",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Greek KERAIA followed by Greek",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4",
|
||||
"data": "xn--wva3je",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERESH not preceded by Hebrew",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5",
|
||||
"data": "xn--A-2hc5h",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERESH not preceded by anything",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5",
|
||||
"data": "xn--5db1e",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERESH preceded by Hebrew",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5",
|
||||
"data": "xn--4dbc5h",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERSHAYIM not preceded by Hebrew",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6",
|
||||
"data": "xn--A-2hc8h",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERSHAYIM not preceded by anything",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6",
|
||||
"data": "xn--5db3e",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERSHAYIM preceded by Hebrew",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6",
|
||||
"data": "xn--4dbc8h",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "xn--defabc-k64e",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with no other characters",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "xn--vek",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with Hiragana",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "xn--k8j5u",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with Katakana",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "xn--bck0j",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with Han",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "xn--vek778f",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8",
|
||||
"data": "xn--ngb6iyr",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8",
|
||||
"data": "xn--ngba1o",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9",
|
||||
"data": "xn--0-gyc",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH JOINER not preceded by Virama",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf",
|
||||
"data": "xn--11b2er09f",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH JOINER not preceded by anything",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf",
|
||||
"data": "xn--02b508i",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH JOINER preceded by Virama",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf",
|
||||
"data": "xn--11b2ezcw70k",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH NON-JOINER preceded by Virama",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1",
|
||||
"data": "xn--11b2ezcs70k",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement",
|
||||
"data": "xn--ngba5hb2804a",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of an internationalized e-mail addresses",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "idn-email"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid idn e-mail (example@example.test in Hangul)",
|
||||
"data": "실례@실례.테스트",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid idn e-mail address",
|
||||
"data": "2962",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid e-mail address",
|
||||
"data": "joe.bloggs@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid e-mail address",
|
||||
"data": "2962",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-449
@@ -1,449 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of internationalized host names",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "idn-hostname"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid host name (example.test in Hangul)",
|
||||
"data": "실례.테스트",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "illegal first char U+302E Hangul single dot tone mark",
|
||||
"data": "〮실례.테스트",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "contains illegal char U+302E Hangul single dot tone mark",
|
||||
"data": "실〮례.테스트",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a host name with a component too long",
|
||||
"data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid label, correct Punycode",
|
||||
"comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1",
|
||||
"data": "-> $1.00 <--",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid Chinese Punycode",
|
||||
"comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4",
|
||||
"data": "xn--ihqwcrb4cv8a8dqg056pqjye",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid Punycode",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1",
|
||||
"data": "xn--X",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "U-label contains \"--\" in the 3rd and 4th position",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1",
|
||||
"data": "XN--aa---o47jg78q",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "U-label starts with a dash",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1",
|
||||
"data": "-hello",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "U-label ends with a dash",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1",
|
||||
"data": "hello-",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "U-label starts and ends with a dash",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1",
|
||||
"data": "-hello-",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Begins with a Spacing Combining Mark",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2",
|
||||
"data": "\u0903hello",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Begins with a Nonspacing Mark",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2",
|
||||
"data": "\u0300hello",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Begins with an Enclosing Mark",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2",
|
||||
"data": "\u0488hello",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Exceptions that are PVALID, left-to-right chars",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6",
|
||||
"data": "\u00df\u03c2\u0f0b\u3007",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Exceptions that are PVALID, right-to-left chars",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6",
|
||||
"data": "\u06fd\u06fe",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Exceptions that are DISALLOWED, right-to-left chars",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6",
|
||||
"data": "\u0640\u07fa",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Exceptions that are DISALLOWED, left-to-right chars",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start",
|
||||
"data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with no preceding 'l'",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "a\u00b7l",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with nothing preceding",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "\u00b7l",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with no following 'l'",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "l\u00b7a",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with nothing following",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "l\u00b7",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "MIDDLE DOT with surrounding 'l's",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3",
|
||||
"data": "l\u00b7l",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Greek KERAIA not followed by Greek",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4",
|
||||
"data": "\u03b1\u0375S",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Greek KERAIA not followed by anything",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4",
|
||||
"data": "\u03b1\u0375",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Greek KERAIA followed by Greek",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4",
|
||||
"data": "\u03b1\u0375\u03b2",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERESH not preceded by Hebrew",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5",
|
||||
"data": "A\u05f3\u05d1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERESH not preceded by anything",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5",
|
||||
"data": "\u05f3\u05d1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERESH preceded by Hebrew",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5",
|
||||
"data": "\u05d0\u05f3\u05d1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERSHAYIM not preceded by Hebrew",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6",
|
||||
"data": "A\u05f4\u05d1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERSHAYIM not preceded by anything",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6",
|
||||
"data": "\u05f4\u05d1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Hebrew GERSHAYIM preceded by Hebrew",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6",
|
||||
"data": "\u05d0\u05f4\u05d1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "def\u30fbabc",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with no other characters",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "\u30fb",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with Hiragana",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "\u30fb\u3041",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with Katakana",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "\u30fb\u30a1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "KATAKANA MIDDLE DOT with Han",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7",
|
||||
"data": "\u30fb\u4e08",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8",
|
||||
"data": "\u0628\u0660\u06f0",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8",
|
||||
"data": "\u0628\u0660\u0628",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9",
|
||||
"data": "\u06f00",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH JOINER not preceded by Virama",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf",
|
||||
"data": "\u0915\u200d\u0937",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH JOINER not preceded by anything",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf",
|
||||
"data": "\u200d\u0937",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH JOINER preceded by Virama",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf",
|
||||
"data": "\u0915\u094d\u200d\u0937",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH NON-JOINER preceded by Virama",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1",
|
||||
"data": "\u0915\u094d\u200c\u0937",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp",
|
||||
"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement",
|
||||
"data": "\u0628\u064a\u200c\u0628\u064a",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label",
|
||||
"data": "hostname",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label with hyphen",
|
||||
"data": "host-name",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label with digits",
|
||||
"data": "h0stn4me",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label starting with digit",
|
||||
"data": "1host",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "single label ending with digit",
|
||||
"data": "hostnam3",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty string",
|
||||
"data": "",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validation of separators in internationalized host names",
|
||||
"specification": [
|
||||
{"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"}
|
||||
],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "idn-hostname"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "single dot",
|
||||
"data": ".",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "single ideographic full stop",
|
||||
"data": "\u3002",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "single fullwidth full stop",
|
||||
"data": "\uff0e",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "single halfwidth ideographic full stop",
|
||||
"data": "\uff61",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "dot as label separator",
|
||||
"data": "a.b",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ideographic full stop as label separator",
|
||||
"data": "a\u3002b",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "fullwidth full stop as label separator",
|
||||
"data": "a\uff0eb",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "halfwidth ideographic full stop as label separator",
|
||||
"data": "a\uff61b",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "leading dot",
|
||||
"data": ".example",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "leading ideographic full stop",
|
||||
"data": "\u3002example",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "leading fullwidth full stop",
|
||||
"data": "\uff0eexample",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "leading halfwidth ideographic full stop",
|
||||
"data": "\uff61example",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "trailing dot",
|
||||
"data": "example.",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "trailing ideographic full stop",
|
||||
"data": "example\u3002",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "trailing fullwidth full stop",
|
||||
"data": "example\uff0e",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "trailing halfwidth ideographic full stop",
|
||||
"data": "example\uff61",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "label too long if separator ignored (full stop)",
|
||||
"data": "παράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπα.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "label too long if separator ignored (ideographic full stop)",
|
||||
"data": "παράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπα\u3002com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "label too long if separator ignored (fullwidth full stop)",
|
||||
"data": "παράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπα\uff0ecom",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "label too long if separator ignored (halfwidth ideographic full stop)",
|
||||
"data": "παράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπα\uff61com",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,92 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of IP addresses",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "ipv4"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IP address",
|
||||
"data": "192.168.0.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an IP address with too many components",
|
||||
"data": "127.0.0.0.1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an IP address with out-of-range values",
|
||||
"data": "256.256.256.256",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an IP address without 4 components",
|
||||
"data": "127.0",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an IP address as an integer",
|
||||
"data": "0x7f000001",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an IP address as an integer (decimal)",
|
||||
"data": "2130706433",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid leading zeroes, as they are treated as octals",
|
||||
"comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
|
||||
"data": "087.10.0.1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "value without leading zero is valid",
|
||||
"data": "87.10.0.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid non-ASCII '২' (a Bengali 2)",
|
||||
"data": "1২7.0.0.1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "netmask is not a part of ipv4 address",
|
||||
"data": "192.168.1.0/24",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-211
@@ -1,211 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of IPv6 addresses",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "ipv6"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IPv6 address",
|
||||
"data": "::1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an IPv6 address with out-of-range values",
|
||||
"data": "12345::",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "trailing 4 hex symbols is valid",
|
||||
"data": "::abef",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "trailing 5 hex symbols is invalid",
|
||||
"data": "::abcef",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an IPv6 address with too many components",
|
||||
"data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an IPv6 address containing illegal characters",
|
||||
"data": "::laptop",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no digits is valid",
|
||||
"data": "::",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "leading colons is valid",
|
||||
"data": "::42:ff:1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "trailing colons is valid",
|
||||
"data": "d6::",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "missing leading octet is invalid",
|
||||
"data": ":2:3:4:5:6:7:8",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing trailing octet is invalid",
|
||||
"data": "1:2:3:4:5:6:7:",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing leading octet with omitted octets later",
|
||||
"data": ":2:3:4::8",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "single set of double colons in the middle is valid",
|
||||
"data": "1:d6::42",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "two sets of double colons is invalid",
|
||||
"data": "1::d6::42",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "mixed format with the ipv4 section as decimal octets",
|
||||
"data": "1::d6:192.168.0.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mixed format with double colons between the sections",
|
||||
"data": "1:2::192.168.0.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mixed format with ipv4 section with octet out of range",
|
||||
"data": "1::2:192.168.256.1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "mixed format with ipv4 section with a hex octet",
|
||||
"data": "1::2:192.168.ff.1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "mixed format with leading double colons (ipv4-mapped ipv6 address)",
|
||||
"data": "::ffff:192.168.0.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "triple colons is invalid",
|
||||
"data": "1:2:3:4:5:::8",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "8 octets",
|
||||
"data": "1:2:3:4:5:6:7:8",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "insufficient octets without double colons",
|
||||
"data": "1:2:3:4:5:6:7",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no colons is invalid",
|
||||
"data": "1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ipv4 is not ipv6",
|
||||
"data": "127.0.0.1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ipv4 segment must have 4 octets",
|
||||
"data": "1:2:3:4:1.2.3",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "leading whitespace is invalid",
|
||||
"data": " ::1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "trailing whitespace is invalid",
|
||||
"data": "::1 ",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "netmask is not a part of ipv6 address",
|
||||
"data": "fe80::/64",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "zone id is not a part of ipv6 address",
|
||||
"data": "fe80::a%eth1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a long valid ipv6",
|
||||
"data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a long invalid ipv6, below length limit, first",
|
||||
"data": "100:100:100:100:100:100:255.255.255.255.255",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a long invalid ipv6, below length limit, second",
|
||||
"data": "100:100:100:100:100:100:100:255.255.255.255",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid non-ASCII '৪' (a Bengali 4)",
|
||||
"data": "1:2:3:4:5:6:7:৪",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion",
|
||||
"data": "1:2::192.16৪.0.1",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-76
@@ -1,76 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of IRI References",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "iri-reference"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IRI",
|
||||
"data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid protocol-relative IRI Reference",
|
||||
"data": "//ƒøø.ßår/?∂éœ=πîx#πîüx",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid relative IRI Reference",
|
||||
"data": "/âππ",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid IRI Reference",
|
||||
"data": "\\\\WINDOWS\\filëßåré",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid IRI Reference",
|
||||
"data": "âππ",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IRI fragment",
|
||||
"data": "#ƒrägmênt",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid IRI fragment",
|
||||
"data": "#ƒräg\\mênt",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,86 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of IRIs",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "iri"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IRI with anchor tag",
|
||||
"data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IRI with anchor tag and parentheses",
|
||||
"data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IRI with URL-encoded stuff",
|
||||
"data": "http://ƒøø.ßår/?q=Test%20URL-encoded%20stuff",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IRI with many special characters",
|
||||
"data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid IRI based on IPv6",
|
||||
"data": "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid IRI based on IPv6",
|
||||
"data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid relative IRI Reference",
|
||||
"data": "/abc",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid IRI",
|
||||
"data": "\\\\WINDOWS\\filëßåré",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid IRI though valid IRI reference",
|
||||
"data": "âππ",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-201
@@ -1,201 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of JSON-pointers (JSON String Representation)",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "json-pointer"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid JSON-pointer",
|
||||
"data": "/foo/bar~0/baz~1/%a",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (~ not escaped)",
|
||||
"data": "/foo/bar~",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer with empty segment",
|
||||
"data": "/foo//bar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer with the last empty segment",
|
||||
"data": "/foo/bar/",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #1",
|
||||
"data": "",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #2",
|
||||
"data": "/foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #3",
|
||||
"data": "/foo/0",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #4",
|
||||
"data": "/",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #5",
|
||||
"data": "/a~1b",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #6",
|
||||
"data": "/c%d",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #7",
|
||||
"data": "/e^f",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #8",
|
||||
"data": "/g|h",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #9",
|
||||
"data": "/i\\j",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #10",
|
||||
"data": "/k\"l",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #11",
|
||||
"data": "/ ",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer as stated in RFC 6901 #12",
|
||||
"data": "/m~0n",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer used adding to the last array position",
|
||||
"data": "/foo/-",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer (- used as object member name)",
|
||||
"data": "/foo/-/bar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer (multiple escaped characters)",
|
||||
"data": "/~1~0~0~1~1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer (escaped with fraction part) #1",
|
||||
"data": "/~1.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid JSON-pointer (escaped with fraction part) #2",
|
||||
"data": "/~0.1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (URI Fragment Identifier) #1",
|
||||
"data": "#",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (URI Fragment Identifier) #2",
|
||||
"data": "#/",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (URI Fragment Identifier) #3",
|
||||
"data": "#a",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (some escaped, but not all) #1",
|
||||
"data": "/~0~",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (some escaped, but not all) #2",
|
||||
"data": "/~0/~",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (wrong escape character) #1",
|
||||
"data": "/~2",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (wrong escape character) #2",
|
||||
"data": "/~-1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (multiple characters not escaped)",
|
||||
"data": "/~~",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (isn't empty nor starts with /) #1",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (isn't empty nor starts with /) #2",
|
||||
"data": "0",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "not a valid JSON-pointer (isn't empty nor starts with /) #3",
|
||||
"data": "a/a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of regular expressions",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "regex"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid regular expression",
|
||||
"data": "([abc])+\\s+$",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a regular expression with unclosed parens is invalid",
|
||||
"data": "^(abc]",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Vendored
-101
@@ -1,101 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of Relative JSON Pointers (RJP)",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "relative-json-pointer"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid upwards RJP",
|
||||
"data": "1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid downwards RJP",
|
||||
"data": "0/foo/bar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid up and then down RJP, with array index",
|
||||
"data": "2/0/baz/1/zip",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid RJP taking the member or index name",
|
||||
"data": "0#",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid RJP that is a valid JSON Pointer",
|
||||
"data": "/foo/bar",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "negative prefix",
|
||||
"data": "-1/foo/bar",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "explicit positive prefix",
|
||||
"data": "+1/foo/bar",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "## is not a valid json-pointer",
|
||||
"data": "0##",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "zero cannot be followed by other digits, plus json-pointer",
|
||||
"data": "01/a",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "zero cannot be followed by other digits, plus octothorpe",
|
||||
"data": "01#",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty string",
|
||||
"data": "",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "multi-digit integer prefix",
|
||||
"data": "120/foo/bar",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-241
@@ -1,241 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of time strings",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "time"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid time string",
|
||||
"data": "08:30:06Z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid time string with extra leading zeros",
|
||||
"data": "008:030:006Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid time string with no leading zero for single digit",
|
||||
"data": "8:3:6Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "hour, minute, second must be two digits",
|
||||
"data": "8:0030:6Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid time string with leap second, Zulu",
|
||||
"data": "23:59:60Z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid leap second, Zulu (wrong hour)",
|
||||
"data": "22:59:60Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid leap second, Zulu (wrong minute)",
|
||||
"data": "23:58:60Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid leap second, zero time-offset",
|
||||
"data": "23:59:60+00:00",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid leap second, zero time-offset (wrong hour)",
|
||||
"data": "22:59:60+00:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid leap second, zero time-offset (wrong minute)",
|
||||
"data": "23:58:60+00:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid leap second, positive time-offset",
|
||||
"data": "01:29:60+01:30",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid leap second, large positive time-offset",
|
||||
"data": "23:29:60+23:30",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid leap second, positive time-offset (wrong hour)",
|
||||
"data": "23:59:60+01:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid leap second, positive time-offset (wrong minute)",
|
||||
"data": "23:59:60+00:30",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid leap second, negative time-offset",
|
||||
"data": "15:59:60-08:00",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid leap second, large negative time-offset",
|
||||
"data": "00:29:60-23:30",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid leap second, negative time-offset (wrong hour)",
|
||||
"data": "23:59:60-01:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid leap second, negative time-offset (wrong minute)",
|
||||
"data": "23:59:60-00:30",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid time string with second fraction",
|
||||
"data": "23:20:50.52Z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid time string with precise second fraction",
|
||||
"data": "08:30:06.283185Z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid time string with plus offset",
|
||||
"data": "08:30:06+00:20",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid time string with minus offset",
|
||||
"data": "08:30:06-08:00",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "hour, minute in time-offset must be two digits",
|
||||
"data": "08:30:06-8:000",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid time string with case-insensitive Z",
|
||||
"data": "08:30:06z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string with invalid hour",
|
||||
"data": "24:00:00Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string with invalid minute",
|
||||
"data": "00:60:00Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string with invalid second",
|
||||
"data": "00:00:61Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string with invalid leap second (wrong hour)",
|
||||
"data": "22:59:60Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string with invalid leap second (wrong minute)",
|
||||
"data": "23:58:60Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string with invalid time numoffset hour",
|
||||
"data": "01:02:03+24:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string with invalid time numoffset minute",
|
||||
"data": "01:02:03+00:60",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string with invalid time with both Z and numoffset",
|
||||
"data": "01:02:03Z+00:30",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid offset indicator",
|
||||
"data": "08:30:06 PST",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "only RFC3339 not all of ISO 8601 are valid",
|
||||
"data": "01:01:01,1111",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no time offset",
|
||||
"data": "12:00:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no time offset with second fraction",
|
||||
"data": "12:00:00.52",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid non-ASCII '২' (a Bengali 2)",
|
||||
"data": "1২:00:00Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "offset not starting with plus or minus",
|
||||
"data": "08:30:06#00:20",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "contains letters",
|
||||
"data": "ab:cd:ef",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid time string in date-time format",
|
||||
"data": "2020-11-28T23:55:45Z",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "unknown format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "unknown"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "unknown formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unknown formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unknown formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unknown formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unknown formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unknown formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unknown formats ignore strings",
|
||||
"data": "string",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of URI References",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URI",
|
||||
"data": "http://foo.bar/?baz=qux#quux",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid protocol-relative URI Reference",
|
||||
"data": "//foo.bar/?baz=qux#quux",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid relative URI Reference",
|
||||
"data": "/abc",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid URI Reference",
|
||||
"data": "\\\\WINDOWS\\fileshare",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid URI Reference",
|
||||
"data": "abc",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URI fragment",
|
||||
"data": "#fragment",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid URI fragment",
|
||||
"data": "#frag\\ment",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unescaped non US-ASCII characters",
|
||||
"data": "/foobar®.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid backslash character",
|
||||
"data": "https://example.org/foobar\\.txt",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "format: uri-template",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "uri-template"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid uri-template",
|
||||
"data": "http://example.com/dictionary/{term:1}/{term}",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid uri-template",
|
||||
"data": "http://example.com/dictionary/{term:1}/{term",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a valid uri-template without variables",
|
||||
"data": "http://example.com/dictionary",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid relative uri-template",
|
||||
"data": "dictionary/{term:1}/{term}",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,191 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of URIs",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "uri"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URL with anchor tag",
|
||||
"data": "http://foo.bar/?baz=qux#quux",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URL with anchor tag and parentheses",
|
||||
"data": "http://foo.com/blah_(wikipedia)_blah#cite-1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URL with URL-encoded stuff",
|
||||
"data": "http://foo.bar/?q=Test%20URL-encoded%20stuff",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid puny-coded URL ",
|
||||
"data": "http://xn--nw2a.xn--j6w193g/",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URL with many special characters",
|
||||
"data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URL based on IPv4",
|
||||
"data": "http://223.255.255.254",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URL with ftp scheme",
|
||||
"data": "ftp://ftp.is.co.za/rfc/rfc1808.txt",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URL for a simple text file",
|
||||
"data": "http://www.ietf.org/rfc/rfc2396.txt",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URL ",
|
||||
"data": "ldap://[2001:db8::7]/c=GB?objectClass?one",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid mailto URI",
|
||||
"data": "mailto:John.Doe@example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid newsgroup URI",
|
||||
"data": "news:comp.infosystems.www.servers.unix",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid tel URI",
|
||||
"data": "tel:+1-816-555-1212",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid URN",
|
||||
"data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid protocol-relative URI Reference",
|
||||
"data": "//foo.bar/?baz=qux#quux",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid relative URI Reference",
|
||||
"data": "/abc",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid URI",
|
||||
"data": "\\\\WINDOWS\\fileshare",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid URI though valid URI reference",
|
||||
"data": "abc",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid URI with spaces",
|
||||
"data": "http:// shouldfail.com",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid URI with spaces and missing scheme",
|
||||
"data": ":// should fail",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid URI with comma in scheme",
|
||||
"data": "bar,baz:foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid userinfo",
|
||||
"data": "https://[@example.org/test.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unescaped non US-ASCII characters",
|
||||
"data": "https://example.org/foobar®.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid backslash character",
|
||||
"data": "https://example.org/foobar\\.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid \" character",
|
||||
"data": "https://example.org/foobar\".txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid <> characters",
|
||||
"data": "https://example.org/foobar<>.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid {} characters",
|
||||
"data": "https://example.org/foobar{}.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid ^ character",
|
||||
"data": "https://example.org/foobar^.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid ` character",
|
||||
"data": "https://example.org/foobar`.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid SPACE character",
|
||||
"data": "https://example.org/foo bar.txt",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid | character",
|
||||
"data": "https://example.org/foobar|.txt",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "uuid format",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"format": "uuid"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all string formats ignore integers",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore floats",
|
||||
"data": 13.7,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore booleans",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all string formats ignore nulls",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all upper-case",
|
||||
"data": "2EB8AA08-AA98-11EA-B4AA-73B441D16380",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all lower-case",
|
||||
"data": "2eb8aa08-aa98-11ea-b4aa-73b441d16380",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mixed case",
|
||||
"data": "2eb8aa08-AA98-11ea-B4Aa-73B441D16380",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "all zeroes is valid",
|
||||
"data": "00000000-0000-0000-0000-000000000000",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "wrong length",
|
||||
"data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "missing section",
|
||||
"data": "2eb8aa08-aa98-11ea-73b441d16380",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "bad characters (not hex)",
|
||||
"data": "2eb8aa08-aa98-11ea-b4ga-73b441d16380",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no dashes",
|
||||
"data": "2eb8aa08aa9811eab4aa73b441d16380",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "too few dashes",
|
||||
"data": "2eb8aa08aa98-11ea-b4aa73b441d16380",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "too many dashes",
|
||||
"data": "2eb8-aa08-aa98-11ea-b4aa73b44-1d16380",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "dashes in the wrong spot",
|
||||
"data": "2eb8aa08aa9811eab4aa73b441d16380----",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "shifted dashes",
|
||||
"data": "2eb8aa0-8aa98-11e-ab4aa7-3b441d16380",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid version 4",
|
||||
"data": "98d80576-482e-427f-8434-7f86890ab222",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid version 5",
|
||||
"data": "99c17cbb-656f-564a-940f-1a4568f03487",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "hypothetical version 6",
|
||||
"data": "99c17cbb-656f-664a-940f-1a4568f03487",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "hypothetical version 15",
|
||||
"data": "99c17cbb-656f-f64a-940f-1a4568f03487",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,53 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "$id inside an enum is not a real identifier",
|
||||
"comment": "the implementation must not be confused by an $id buried in the enum",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$defs": {
|
||||
"id_in_enum": {
|
||||
"enum": [
|
||||
{
|
||||
"$id": "https://localhost:1234/draft2020-12/id/my_identifier.json",
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"real_id_in_schema": {
|
||||
"$id": "https://localhost:1234/draft2020-12/id/my_identifier.json",
|
||||
"type": "string"
|
||||
},
|
||||
"zzz_id_in_const": {
|
||||
"const": {
|
||||
"$id": "https://localhost:1234/draft2020-12/id/my_identifier.json",
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{ "$ref": "#/$defs/id_in_enum" },
|
||||
{ "$ref": "https://localhost:1234/draft2020-12/id/my_identifier.json" }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "exact match to enum, and type matches",
|
||||
"data": {
|
||||
"$id": "https://localhost:1234/draft2020-12/id/my_identifier.json",
|
||||
"type": "null"
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "match $ref to $id",
|
||||
"data": "a string to match #/$defs/id_in_enum",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "no match on enum or $ref to $id",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,26 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "validation without $schema",
|
||||
"comment": "minLength is the same across all drafts",
|
||||
"schema": {
|
||||
"minLength": 2
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a 3-character string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a 1-character string is not valid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a non-string is valid",
|
||||
"data": 5,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "Proper UTF-16 surrogate pair handling: pattern",
|
||||
"comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"pattern": "^🐲*$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches empty",
|
||||
"data": "",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "matches single",
|
||||
"data": "🐲",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "matches two",
|
||||
"data": "🐲🐲",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "doesn't match one",
|
||||
"data": "🐉",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "doesn't match two",
|
||||
"data": "🐉🐉",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "doesn't match one ASCII",
|
||||
"data": "D",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "doesn't match two ASCII",
|
||||
"data": "DD",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Proper UTF-16 surrogate pair handling: patternProperties",
|
||||
"comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"patternProperties": {
|
||||
"^🐲*$": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches empty",
|
||||
"data": { "": 1 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "matches single",
|
||||
"data": { "🐲": 1 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "matches two",
|
||||
"data": { "🐲🐲": 1 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "doesn't match one",
|
||||
"data": { "🐲": "hello" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "doesn't match two",
|
||||
"data": { "🐲🐲": "hello" },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "reference of a root arbitrary keyword ",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unknown-keyword": {"type": "integer"},
|
||||
"properties": {
|
||||
"bar": {"$ref": "#/unknown-keyword"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match",
|
||||
"data": {"bar": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": {"bar": true},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "reference of a root arbitrary keyword with encoded ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unknown/keyword": {"type": "integer"},
|
||||
"properties": {
|
||||
"bar": {"$ref": "#/unknown~1keyword"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match",
|
||||
"data": {"bar": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": {"bar": true},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "reference of an arbitrary keyword of a sub-schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {"unknown-keyword": {"type": "integer"}},
|
||||
"bar": {"$ref": "#/properties/foo/unknown-keyword"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match",
|
||||
"data": {"bar": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": {"bar": true},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "reference internals of known non-applicator",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "/base",
|
||||
"examples": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"$ref": "#/examples/0"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match",
|
||||
"data": "a string",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": 42,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "reference of an arbitrary keyword of a sub-schema with encoded ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {"unknown/keyword": {"type": "integer"}},
|
||||
"bar": {"$ref": "#/properties/foo/unknown~1keyword"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match",
|
||||
"data": {"bar": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": {"bar": true},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "$id inside an unknown keyword is not a real identifier",
|
||||
"comment": "the implementation must not be confused by an $id in locations we do not know how to parse",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$defs": {
|
||||
"id_in_unknown0": {
|
||||
"not": {
|
||||
"array_of_schemas": [
|
||||
{
|
||||
"$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json",
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"real_id_in_schema": {
|
||||
"$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json",
|
||||
"type": "string"
|
||||
},
|
||||
"id_in_unknown1": {
|
||||
"not": {
|
||||
"object_of_schemas": {
|
||||
"foo": {
|
||||
"$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{ "$ref": "#/$defs/id_in_unknown0" },
|
||||
{ "$ref": "#/$defs/id_in_unknown1" },
|
||||
{ "$ref": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json" }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "type matches second anyOf, which has a real schema in it",
|
||||
"data": "a string",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "type matches non-schema in first anyOf",
|
||||
"data": null,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "type matches non-schema in third anyOf",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,65 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "pattern validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"pattern": "^a*$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a matching pattern is valid",
|
||||
"data": "aaa",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a non-matching pattern is invalid",
|
||||
"data": "abc",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores booleans",
|
||||
"data": true,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores integers",
|
||||
"data": 123,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores floats",
|
||||
"data": 1.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores null",
|
||||
"data": null,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "pattern is not anchored",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"pattern": "a+"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches a substring",
|
||||
"data": "xxaayy",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,176 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description":
|
||||
"patternProperties validates properties matching a regex",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"patternProperties": {
|
||||
"f.*o": {"type": "integer"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a single valid match is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "multiple valid matches is valid",
|
||||
"data": {"foo": 1, "foooooo" : 2},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a single invalid match is invalid",
|
||||
"data": {"foo": "bar", "fooooo": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "multiple invalid matches is invalid",
|
||||
"data": {"foo": "bar", "foooooo" : "baz"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "multiple simultaneous patternProperties are validated",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"patternProperties": {
|
||||
"a*": {"type": "integer"},
|
||||
"aaa*": {"maximum": 20}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a single valid match is valid",
|
||||
"data": {"a": 21},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a simultaneous match is valid",
|
||||
"data": {"aaaa": 18},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "multiple matches is valid",
|
||||
"data": {"a": 21, "aaaa": 18},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid due to one is invalid",
|
||||
"data": {"a": "bar"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid due to the other is invalid",
|
||||
"data": {"aaaa": 31},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid due to both is invalid",
|
||||
"data": {"aaa": "foo", "aaaa": 31},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "regexes are not anchored by default and are case sensitive",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"patternProperties": {
|
||||
"[0-9]{2,}": { "type": "boolean" },
|
||||
"X_": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "non recognized members are ignored",
|
||||
"data": { "answer 1": "42" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "recognized members are accounted for",
|
||||
"data": { "a31b": null },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "regexes are case sensitive",
|
||||
"data": { "a_x_3": 3 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "regexes are case sensitive, 2",
|
||||
"data": { "a_X_3": 3 },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "patternProperties with boolean schemas",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"patternProperties": {
|
||||
"f.*": true,
|
||||
"b.*": false
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with property matching schema true is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with property matching schema false is invalid",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object with both properties is invalid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object with a property matching both true and false is invalid",
|
||||
"data": {"foobar":1},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "patternProperties with null valued instance properties",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"patternProperties": {
|
||||
"^.*bar$": {"type": "null"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allows null values",
|
||||
"data": {"foobar": null},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,104 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "a schema given for prefixItems",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{"type": "integer"},
|
||||
{"type": "string"}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "correct types",
|
||||
"data": [ 1, "foo" ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "wrong types",
|
||||
"data": [ "foo", 1 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "incomplete array of items",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array with additional items",
|
||||
"data": [ 1, "foo", true ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty array",
|
||||
"data": [ ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "JavaScript pseudo-array is valid",
|
||||
"data": {
|
||||
"0": "invalid",
|
||||
"1": "valid",
|
||||
"length": 2
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "prefixItems with boolean schemas",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [true, false]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "array with one item is valid",
|
||||
"data": [ 1 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "array with two items is invalid",
|
||||
"data": [ 1, "foo" ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty array is valid",
|
||||
"data": [],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additional items are allowed by default",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [{"type": "integer"}]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "only the first item is validated",
|
||||
"data": [1, "foo", false],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "prefixItems with null instance elements",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allows null elements",
|
||||
"data": [ null ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,242 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "object properties validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {"type": "integer"},
|
||||
"bar": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "both properties present and valid is valid",
|
||||
"data": {"foo": 1, "bar": "baz"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "one property invalid is invalid",
|
||||
"data": {"foo": 1, "bar": {}},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "both properties invalid is invalid",
|
||||
"data": {"foo": [], "bar": {}},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "doesn't invalidate other properties",
|
||||
"data": {"quux": []},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description":
|
||||
"properties, patternProperties, additionalProperties interaction",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {"type": "array", "maxItems": 3},
|
||||
"bar": {"type": "array"}
|
||||
},
|
||||
"patternProperties": {"f.o": {"minItems": 2}},
|
||||
"additionalProperties": {"type": "integer"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "property validates property",
|
||||
"data": {"foo": [1, 2]},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "property invalidates property",
|
||||
"data": {"foo": [1, 2, 3, 4]},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "patternProperty invalidates property",
|
||||
"data": {"foo": []},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "patternProperty validates nonproperty",
|
||||
"data": {"fxo": [1, 2]},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "patternProperty invalidates nonproperty",
|
||||
"data": {"fxo": []},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "additionalProperty ignores property",
|
||||
"data": {"bar": []},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "additionalProperty validates others",
|
||||
"data": {"quux": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "additionalProperty invalidates others",
|
||||
"data": {"quux": "foo"},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "properties with boolean schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": true,
|
||||
"bar": false
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "no property present is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "only 'true' property present is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "only 'false' property present is invalid",
|
||||
"data": {"bar": 2},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "both properties present is invalid",
|
||||
"data": {"foo": 1, "bar": 2},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "properties with escaped characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo\nbar": {"type": "number"},
|
||||
"foo\"bar": {"type": "number"},
|
||||
"foo\\bar": {"type": "number"},
|
||||
"foo\rbar": {"type": "number"},
|
||||
"foo\tbar": {"type": "number"},
|
||||
"foo\fbar": {"type": "number"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with all numbers is valid",
|
||||
"data": {
|
||||
"foo\nbar": 1,
|
||||
"foo\"bar": 1,
|
||||
"foo\\bar": 1,
|
||||
"foo\rbar": 1,
|
||||
"foo\tbar": 1,
|
||||
"foo\fbar": 1
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with strings is invalid",
|
||||
"data": {
|
||||
"foo\nbar": "1",
|
||||
"foo\"bar": "1",
|
||||
"foo\\bar": "1",
|
||||
"foo\rbar": "1",
|
||||
"foo\tbar": "1",
|
||||
"foo\fbar": "1"
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "properties with null valued instance properties",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {"type": "null"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allows null values",
|
||||
"data": {"foo": null},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "properties whose names are Javascript object property names",
|
||||
"comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"__proto__": {"type": "number"},
|
||||
"toString": {
|
||||
"properties": { "length": { "type": "string" } }
|
||||
},
|
||||
"constructor": {"type": "number"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "none of the properties mentioned",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "__proto__ not valid",
|
||||
"data": { "__proto__": "foo" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "toString not valid",
|
||||
"data": { "toString": { "length": 37 } },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "constructor not valid",
|
||||
"data": { "constructor": { "length": 37 } },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all present and valid",
|
||||
"data": {
|
||||
"__proto__": 12,
|
||||
"toString": { "length": "foo" },
|
||||
"constructor": 37
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,168 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "propertyNames validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"propertyNames": {"maxLength": 3}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all property names valid",
|
||||
"data": {
|
||||
"f": {},
|
||||
"foo": {}
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "some property names invalid",
|
||||
"data": {
|
||||
"foo": {},
|
||||
"foobar": {}
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object without properties is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [1, 2, 3, 4],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foobar",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "propertyNames validation with pattern",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"propertyNames": { "pattern": "^a+$" }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matching property names valid",
|
||||
"data": {
|
||||
"a": {},
|
||||
"aa": {},
|
||||
"aaa": {}
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-matching property name is invalid",
|
||||
"data": {
|
||||
"aaA": {}
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "object without properties is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "propertyNames with boolean schema true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"propertyNames": true
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with any properties is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "propertyNames with boolean schema false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"propertyNames": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with any properties is invalid",
|
||||
"data": {"foo": 1},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "propertyNames with const",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"propertyNames": {"const": "foo"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with property foo is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with any other property is invalid",
|
||||
"data": {"bar": 1},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "propertyNames with enum",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"propertyNames": {"enum": ["foo", "bar"]}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with property foo is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with property foo and bar is valid",
|
||||
"data": {"foo": 1, "bar": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with any other property is invalid",
|
||||
"data": {"baz": 1},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,342 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "remote ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/draft2020-12/integer.json"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "remote ref valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "remote ref invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "fragment within remote ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/draft2020-12/subSchemas.json#/$defs/integer"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "remote fragment valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "remote fragment invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anchor within remote ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/draft2020-12/locationIndependentIdentifier.json#foo"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "remote anchor valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "remote anchor invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ref within remote ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/draft2020-12/subSchemas.json#/$defs/refToInteger"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ref within ref valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ref within ref invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "base URI change",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/",
|
||||
"items": {
|
||||
"$id": "baseUriChange/",
|
||||
"items": {"$ref": "folderInteger.json"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "base URI change ref valid",
|
||||
"data": [[1]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "base URI change ref invalid",
|
||||
"data": [["a"]],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "base URI change - change folder",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/scope_change_defs1.json",
|
||||
"type" : "object",
|
||||
"properties": {"list": {"$ref": "baseUriChangeFolder/"}},
|
||||
"$defs": {
|
||||
"baz": {
|
||||
"$id": "baseUriChangeFolder/",
|
||||
"type": "array",
|
||||
"items": {"$ref": "folderInteger.json"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": {"list": [1]},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": {"list": ["a"]},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "base URI change - change folder in subschema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/scope_change_defs2.json",
|
||||
"type" : "object",
|
||||
"properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}},
|
||||
"$defs": {
|
||||
"baz": {
|
||||
"$id": "baseUriChangeFolderInSubschema/",
|
||||
"$defs": {
|
||||
"bar": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "folderInteger.json"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": {"list": [1]},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": {"list": ["a"]},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "root ref in remote ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/object",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"$ref": "name-defs.json#/$defs/orNull"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": {
|
||||
"name": "foo"
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": {
|
||||
"name": null
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object is invalid",
|
||||
"data": {
|
||||
"name": {
|
||||
"name": null
|
||||
}
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "remote ref with ref to defs",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/schema-remote-ref-ref-defs1.json",
|
||||
"$ref": "ref-and-defs.json"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid",
|
||||
"data": {
|
||||
"bar": 1
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid",
|
||||
"data": {
|
||||
"bar": "a"
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Location-independent identifier in remote ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/draft2020-12/locationIndependentIdentifier.json#/$defs/refToInteger"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "integer is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "retrieved nested refs resolve relative to their URI not $id",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "http://localhost:1234/draft2020-12/some-id",
|
||||
"properties": {
|
||||
"name": {"$ref": "nested/foo-ref-string.json"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": {
|
||||
"name": {"foo": 1}
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": {
|
||||
"name": {"foo": "a"}
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "remote HTTP ref with different $id",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/different-id-ref-string.json"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "remote HTTP ref with different URN $id",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/urn-ref-string.json"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "remote HTTP ref with nested absolute ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/nested-absolute-ref-to-string.json"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref to $ref finds detached $anchor",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "http://localhost:1234/draft2020-12/detached-ref.json#/$defs/foo"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-number is invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,158 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "required validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {},
|
||||
"bar": {}
|
||||
},
|
||||
"required": ["foo"]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "present required property is valid",
|
||||
"data": {"foo": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-present required property is invalid",
|
||||
"data": {"bar": 1},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "required default validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "not required by default",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "required with empty array",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "property not required",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "required with escaped characters",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"required": [
|
||||
"foo\nbar",
|
||||
"foo\"bar",
|
||||
"foo\\bar",
|
||||
"foo\rbar",
|
||||
"foo\tbar",
|
||||
"foo\fbar"
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with all properties present is valid",
|
||||
"data": {
|
||||
"foo\nbar": 1,
|
||||
"foo\"bar": 1,
|
||||
"foo\\bar": 1,
|
||||
"foo\rbar": 1,
|
||||
"foo\tbar": 1,
|
||||
"foo\fbar": 1
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with some properties missing is invalid",
|
||||
"data": {
|
||||
"foo\nbar": "1",
|
||||
"foo\"bar": "1"
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "required properties whose names are Javascript object property names",
|
||||
"comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"required": ["__proto__", "toString", "constructor"]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ignores arrays",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores other non-objects",
|
||||
"data": 12,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "none of the properties mentioned",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "__proto__ present",
|
||||
"data": { "__proto__": "foo" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "toString present",
|
||||
"data": { "toString": { "length": 37 } },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "constructor present",
|
||||
"data": { "constructor": { "length": 37 } },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all present",
|
||||
"data": {
|
||||
"__proto__": 12,
|
||||
"toString": { "length": "foo" },
|
||||
"constructor": 37
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,501 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "integer type matches integers",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "integer"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an integer is an integer",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a float with zero fractional part is an integer",
|
||||
"data": 1.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a float is not an integer",
|
||||
"data": 1.1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a string is not an integer",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a string is still not an integer, even if it looks like one",
|
||||
"data": "1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an object is not an integer",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an array is not an integer",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a boolean is not an integer",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is not an integer",
|
||||
"data": null,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "number type matches numbers",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "number"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an integer is a number",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a float with zero fractional part is a number (and an integer)",
|
||||
"data": 1.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a float is a number",
|
||||
"data": 1.1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a string is not a number",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a string is still not a number, even if it looks like one",
|
||||
"data": "1",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an object is not a number",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an array is not a number",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a boolean is not a number",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is not a number",
|
||||
"data": null,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "string type matches strings",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "string"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "1 is not a string",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a float is not a string",
|
||||
"data": 1.1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a string is a string",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a string is still a string, even if it looks like a number",
|
||||
"data": "1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an empty string is still a string",
|
||||
"data": "",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an object is not a string",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an array is not a string",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a boolean is not a string",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is not a string",
|
||||
"data": null,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "object type matches objects",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an integer is not an object",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a float is not an object",
|
||||
"data": 1.1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a string is not an object",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an object is an object",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an array is not an object",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a boolean is not an object",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is not an object",
|
||||
"data": null,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "array type matches arrays",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "array"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an integer is not an array",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a float is not an array",
|
||||
"data": 1.1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a string is not an array",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an object is not an array",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an array is an array",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a boolean is not an array",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is not an array",
|
||||
"data": null,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "boolean type matches booleans",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "boolean"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an integer is not a boolean",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "zero is not a boolean",
|
||||
"data": 0,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a float is not a boolean",
|
||||
"data": 1.1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a string is not a boolean",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an empty string is not a boolean",
|
||||
"data": "",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an object is not a boolean",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an array is not a boolean",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "true is a boolean",
|
||||
"data": true,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "false is a boolean",
|
||||
"data": false,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "null is not a boolean",
|
||||
"data": null,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "null type matches only the null object",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "null"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an integer is not null",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a float is not null",
|
||||
"data": 1.1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "zero is not null",
|
||||
"data": 0,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a string is not null",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an empty string is not null",
|
||||
"data": "",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an object is not null",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an array is not null",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "true is not null",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "false is not null",
|
||||
"data": false,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is null",
|
||||
"data": null,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "multiple types can be specified in an array",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": ["integer", "string"]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an integer is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a float is invalid",
|
||||
"data": 1.1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an object is invalid",
|
||||
"data": {},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an array is invalid",
|
||||
"data": [],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a boolean is invalid",
|
||||
"data": true,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is invalid",
|
||||
"data": null,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "type as array with one item",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": ["string"]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "string is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "type: array or object",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": ["array", "object"]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "array is valid",
|
||||
"data": [1,2,3],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object is valid",
|
||||
"data": {"foo": 123},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "null is invalid",
|
||||
"data": null,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "type: array, object or null",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": ["array", "object", "null"]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "array is valid",
|
||||
"data": [1,2,3],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object is valid",
|
||||
"data": {"foo": 123},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,854 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "unevaluatedItems true",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unevaluatedItems": true
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems as schema",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unevaluatedItems": { "type": "string" }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with valid unevaluated items",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with invalid unevaluated items",
|
||||
"data": [42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with uniform items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"items": { "type": "string" },
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "unevaluatedItems doesn't apply",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with tuple",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with items and prefixItems",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"items": true,
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "unevaluatedItems doesn't apply",
|
||||
"data": ["foo", 42],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"items": {"type": "number"},
|
||||
"unevaluatedItems": {"type": "string"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid under items",
|
||||
"comment": "no elements are considered by unevaluatedItems",
|
||||
"data": [5, 6, 7, 8],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid under items",
|
||||
"data": ["foo", "bar", "baz"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with nested tuple",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "type": "number" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": ["foo", 42],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo", 42, true],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with nested items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unevaluatedItems": {"type": "boolean"},
|
||||
"anyOf": [
|
||||
{ "items": {"type": "string"} },
|
||||
true
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with only (valid) additional items",
|
||||
"data": [true, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with no additional items",
|
||||
"data": ["yes", "no"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with invalid additional item",
|
||||
"data": ["yes", false],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with nested prefixItems and items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"items": true
|
||||
}
|
||||
],
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no additional items",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with additional items",
|
||||
"data": ["foo", 42, true],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with nested unevaluatedItems",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
]
|
||||
},
|
||||
{ "unevaluatedItems": true }
|
||||
],
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no additional items",
|
||||
"data": ["foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with additional items",
|
||||
"data": ["foo", 42, true],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with anyOf",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{ "const": "foo" }
|
||||
],
|
||||
"anyOf": [
|
||||
{
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "const": "bar" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"prefixItems": [
|
||||
true,
|
||||
true,
|
||||
{ "const": "baz" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "when one schema matches and has no unevaluated items",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "when one schema matches and has unevaluated items",
|
||||
"data": ["foo", "bar", 42],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "when two schemas match and has no unevaluated items",
|
||||
"data": ["foo", "bar", "baz"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "when two schemas match and has unevaluated items",
|
||||
"data": ["foo", "bar", "baz", 42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with oneOf",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{ "const": "foo" }
|
||||
],
|
||||
"oneOf": [
|
||||
{
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "const": "bar" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "const": "baz" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo", "bar", 42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with not",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{ "const": "foo" }
|
||||
],
|
||||
"not": {
|
||||
"not": {
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "const": "bar" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with if/then/else",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{ "const": "foo" }
|
||||
],
|
||||
"if": {
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "const": "bar" }
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"prefixItems": [
|
||||
true,
|
||||
true,
|
||||
{ "const": "then" }
|
||||
]
|
||||
},
|
||||
"else": {
|
||||
"prefixItems": [
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
{ "const": "else" }
|
||||
]
|
||||
},
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "when if matches and it has no unevaluated items",
|
||||
"data": ["foo", "bar", "then"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "when if matches and it has unevaluated items",
|
||||
"data": ["foo", "bar", "then", "else"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "when if doesn't match and it has no unevaluated items",
|
||||
"data": ["foo", 42, 42, "else"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "when if doesn't match and it has unevaluated items",
|
||||
"data": ["foo", 42, 42, "else", 42],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with boolean schemas",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [true],
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with $ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "#/$defs/bar",
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"unevaluatedItems": false,
|
||||
"$defs": {
|
||||
"bar": {
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "type": "string" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo", "bar", "baz"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems before $ref",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unevaluatedItems": false,
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"$ref": "#/$defs/bar",
|
||||
"$defs": {
|
||||
"bar": {
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "type": "string" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo", "bar", "baz"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with $dynamicRef",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://example.com/unevaluated-items-with-dynamic-ref/derived",
|
||||
|
||||
"$ref": "./baseSchema",
|
||||
|
||||
"$defs": {
|
||||
"derived": {
|
||||
"$dynamicAnchor": "addons",
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "type": "string" }
|
||||
]
|
||||
},
|
||||
"baseSchema": {
|
||||
"$id": "./baseSchema",
|
||||
|
||||
"$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering",
|
||||
"unevaluatedItems": false,
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"$dynamicRef": "#addons",
|
||||
|
||||
"$defs": {
|
||||
"defaultAddons": {
|
||||
"$comment": "Needed to satisfy the bookending requirement",
|
||||
"$dynamicAnchor": "addons"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with no unevaluated items",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "with unevaluated items",
|
||||
"data": ["foo", "bar", "baz"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems can't see inside cousins",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{
|
||||
"prefixItems": [ true ]
|
||||
},
|
||||
{ "unevaluatedItems": false }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "always fails",
|
||||
"data": [ 1 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "item is evaluated in an uncle schema to unevaluatedItems",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"prefixItems": [
|
||||
{ "type": "string" }
|
||||
],
|
||||
"unevaluatedItems": false
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "type": "string" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "no extra items",
|
||||
"data": {
|
||||
"foo": [
|
||||
"test"
|
||||
]
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "uncle keyword evaluation is not significant",
|
||||
"data": {
|
||||
"foo": [
|
||||
"test",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems depends on adjacent contains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [true],
|
||||
"contains": {"type": "string"},
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "second item is evaluated by contains",
|
||||
"data": [ 1, "foo" ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "contains fails, second item is not evaluated",
|
||||
"data": [ 1, 2 ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "contains passes, second item is not evaluated",
|
||||
"data": [ 1, 2, "foo" ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems depends on multiple nested contains",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{ "contains": { "multipleOf": 2 } },
|
||||
{ "contains": { "multipleOf": 3 } }
|
||||
],
|
||||
"unevaluatedItems": { "multipleOf": 5 }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "5 not evaluated, passes unevaluatedItems",
|
||||
"data": [ 2, 3, 4, 5, 6 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "7 not evaluated, fails unevaluatedItems",
|
||||
"data": [ 2, 3, 4, 7, 8 ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems and contains interact to control item dependency relationship",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"if": {
|
||||
"contains": {"const": "a"}
|
||||
},
|
||||
"then": {
|
||||
"if": {
|
||||
"contains": {"const": "b"}
|
||||
},
|
||||
"then": {
|
||||
"if": {
|
||||
"contains": {"const": "c"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "empty array is valid",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "only a's are valid",
|
||||
"data": [ "a", "a" ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a's and b's are valid",
|
||||
"data": [ "a", "b", "a", "b", "a" ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a's, b's and c's are valid",
|
||||
"data": [ "c", "a", "c", "c", "b", "a" ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "only b's are invalid",
|
||||
"data": [ "b", "b" ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "only c's are invalid",
|
||||
"data": [ "c", "c" ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "only b's and c's are invalid",
|
||||
"data": [ "c", "b", "c", "b", "c" ],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "only a's and c's are invalid",
|
||||
"data": [ "c", "a", "c", "a", "c" ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description" : "unevaluatedItems with minContains = 0",
|
||||
"schema" : {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"contains": {"type": "string"},
|
||||
"minContains": 0,
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests" : [
|
||||
{
|
||||
"description": "empty array is valid",
|
||||
"data": [],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "no items evaluated by contains",
|
||||
"data": [0],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "some but not all items evaluated by contains",
|
||||
"data": ["foo", 0],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "all items evaluated by contains",
|
||||
"data": ["foo", "bar"],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "non-array instances are valid",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ignores booleans",
|
||||
"data": true,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores integers",
|
||||
"data": 123,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores floats",
|
||||
"data": 1.0,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores objects",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores strings",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores null",
|
||||
"data": null,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems with null instance elements",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"unevaluatedItems": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allows null elements",
|
||||
"data": [ null ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unevaluatedItems can see annotations from if without then and else",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"if": {
|
||||
"prefixItems": [{"const": "a"}]
|
||||
},
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid in case if is evaluated",
|
||||
"data": [ "a" ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid in case if is evaluated",
|
||||
"data": [ "b" ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Evaluated items collection needs to consider instance location",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [
|
||||
{
|
||||
"prefixItems": [
|
||||
true,
|
||||
{ "type": "string" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"unevaluatedItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "with an unevaluated item that exists at another location",
|
||||
"data": [
|
||||
["foo", "bar"],
|
||||
"bar"
|
||||
],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-1613
File diff suppressed because it is too large.
Load diff
@@ -1,419 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "uniqueItems validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"uniqueItems": true
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "unique array of integers is valid",
|
||||
"data": [1, 2],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of integers is invalid",
|
||||
"data": [1, 1],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of more than two integers is invalid",
|
||||
"data": [1, 2, 1],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "numbers are unique if mathematically unequal",
|
||||
"data": [1.0, 1.00, 1],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "false is not equal to zero",
|
||||
"data": [0, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "true is not equal to one",
|
||||
"data": [1, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique array of strings is valid",
|
||||
"data": ["foo", "bar", "baz"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of strings is invalid",
|
||||
"data": ["foo", "bar", "foo"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unique array of objects is valid",
|
||||
"data": [{"foo": "bar"}, {"foo": "baz"}],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of objects is invalid",
|
||||
"data": [{"foo": "bar"}, {"foo": "bar"}],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "property order of array of objects is ignored",
|
||||
"data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unique array of nested objects is valid",
|
||||
"data": [
|
||||
{"foo": {"bar" : {"baz" : true}}},
|
||||
{"foo": {"bar" : {"baz" : false}}}
|
||||
],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of nested objects is invalid",
|
||||
"data": [
|
||||
{"foo": {"bar" : {"baz" : true}}},
|
||||
{"foo": {"bar" : {"baz" : true}}}
|
||||
],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unique array of arrays is valid",
|
||||
"data": [["foo"], ["bar"]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of arrays is invalid",
|
||||
"data": [["foo"], ["foo"]],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of more than two arrays is invalid",
|
||||
"data": [["foo"], ["bar"], ["foo"]],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "1 and true are unique",
|
||||
"data": [1, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "0 and false are unique",
|
||||
"data": [0, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[1] and [true] are unique",
|
||||
"data": [[1], [true]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[0] and [false] are unique",
|
||||
"data": [[0], [false]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "nested [1] and [true] are unique",
|
||||
"data": [[[1], "foo"], [[true], "foo"]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "nested [0] and [false] are unique",
|
||||
"data": [[[0], "foo"], [[false], "foo"]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique heterogeneous types are valid",
|
||||
"data": [{}, [1], true, null, 1, "{}"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique heterogeneous types are invalid",
|
||||
"data": [{}, [1], true, null, {}, 1],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "different objects are unique",
|
||||
"data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "objects are non-unique despite key order",
|
||||
"data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "{\"a\": false} and {\"a\": 0} are unique",
|
||||
"data": [{"a": false}, {"a": 0}],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "{\"a\": true} and {\"a\": 1} are unique",
|
||||
"data": [{"a": true}, {"a": 1}],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uniqueItems with an array of items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [{"type": "boolean"}, {"type": "boolean"}],
|
||||
"uniqueItems": true
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[false, true] from items array is valid",
|
||||
"data": [false, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[true, false] from items array is valid",
|
||||
"data": [true, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[false, false] from items array is not valid",
|
||||
"data": [false, false],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "[true, true] from items array is not valid",
|
||||
"data": [true, true],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "unique array extended from [false, true] is valid",
|
||||
"data": [false, true, "foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique array extended from [true, false] is valid",
|
||||
"data": [true, false, "foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array extended from [false, true] is not valid",
|
||||
"data": [false, true, "foo", "foo"],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-unique array extended from [true, false] is not valid",
|
||||
"data": [true, false, "foo", "foo"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uniqueItems with an array of items and additionalItems=false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [{"type": "boolean"}, {"type": "boolean"}],
|
||||
"uniqueItems": true,
|
||||
"items": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[false, true] from items array is valid",
|
||||
"data": [false, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[true, false] from items array is valid",
|
||||
"data": [true, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[false, false] from items array is not valid",
|
||||
"data": [false, false],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "[true, true] from items array is not valid",
|
||||
"data": [true, true],
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "extra items are invalid even if unique",
|
||||
"data": [false, true, null],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uniqueItems=false validation",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"uniqueItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "unique array of integers is valid",
|
||||
"data": [1, 2],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of integers is valid",
|
||||
"data": [1, 1],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "numbers are unique if mathematically unequal",
|
||||
"data": [1.0, 1.00, 1],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "false is not equal to zero",
|
||||
"data": [0, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "true is not equal to one",
|
||||
"data": [1, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique array of objects is valid",
|
||||
"data": [{"foo": "bar"}, {"foo": "baz"}],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of objects is valid",
|
||||
"data": [{"foo": "bar"}, {"foo": "bar"}],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique array of nested objects is valid",
|
||||
"data": [
|
||||
{"foo": {"bar" : {"baz" : true}}},
|
||||
{"foo": {"bar" : {"baz" : false}}}
|
||||
],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of nested objects is valid",
|
||||
"data": [
|
||||
{"foo": {"bar" : {"baz" : true}}},
|
||||
{"foo": {"bar" : {"baz" : true}}}
|
||||
],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique array of arrays is valid",
|
||||
"data": [["foo"], ["bar"]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array of arrays is valid",
|
||||
"data": [["foo"], ["foo"]],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "1 and true are unique",
|
||||
"data": [1, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "0 and false are unique",
|
||||
"data": [0, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique heterogeneous types are valid",
|
||||
"data": [{}, [1], true, null, 1],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique heterogeneous types are valid",
|
||||
"data": [{}, [1], true, null, {}, 1],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uniqueItems=false with an array of items",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [{"type": "boolean"}, {"type": "boolean"}],
|
||||
"uniqueItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[false, true] from items array is valid",
|
||||
"data": [false, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[true, false] from items array is valid",
|
||||
"data": [true, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[false, false] from items array is valid",
|
||||
"data": [false, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[true, true] from items array is valid",
|
||||
"data": [true, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique array extended from [false, true] is valid",
|
||||
"data": [false, true, "foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "unique array extended from [true, false] is valid",
|
||||
"data": [true, false, "foo", "bar"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array extended from [false, true] is valid",
|
||||
"data": [false, true, "foo", "foo"],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "non-unique array extended from [true, false] is valid",
|
||||
"data": [true, false, "foo", "foo"],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "uniqueItems=false with an array of items and additionalItems=false",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"prefixItems": [{"type": "boolean"}, {"type": "boolean"}],
|
||||
"uniqueItems": false,
|
||||
"items": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "[false, true] from items array is valid",
|
||||
"data": [false, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[true, false] from items array is valid",
|
||||
"data": [true, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[false, false] from items array is valid",
|
||||
"data": [false, false],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "[true, true] from items array is valid",
|
||||
"data": [true, true],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "extra items are invalid even if unique",
|
||||
"data": [false, true, null],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,57 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "schema that uses custom metaschema with with no validation vocabulary",
|
||||
"schema": {
|
||||
"$id": "https://schema/using/no/validation",
|
||||
"$schema": "http://localhost:1234/draft2020-12/metaschema-no-validation.json",
|
||||
"properties": {
|
||||
"badProperty": false,
|
||||
"numberProperty": {
|
||||
"minimum": 10
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "applicator vocabulary still works",
|
||||
"data": {
|
||||
"badProperty": "this property should not exist"
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "no validation: valid number",
|
||||
"data": {
|
||||
"numberProperty": 20
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "no validation: invalid number, but it still validates",
|
||||
"data": {
|
||||
"numberProperty": 1
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ignore unrecognized optional vocabulary",
|
||||
"schema": {
|
||||
"$schema": "http://localhost:1234/draft2020-12/metaschema-optional-vocabulary.json",
|
||||
"type": "number"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "string value",
|
||||
"data": "foobar",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "number value",
|
||||
"data": 20,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,501 +0,0 @@
|
||||
//! Integration tests for JSON Schema Test Suite compatibility
|
||||
//!
|
||||
//! This module tests that schemars-docgen can generate HTML documentation
|
||||
//! for all schemas in the JSON-Schema-Test-Suite draft2020-12 examples
|
||||
//! without crashing.
|
||||
|
||||
use chrono::Local;
|
||||
use chrono::Utc;
|
||||
use rayon::prelude::*;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
use tera::Context;
|
||||
use tera::Tera;
|
||||
|
||||
/// Represents a test suite from the JSON Schema Test Suite
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct TestSuite {
|
||||
description: String,
|
||||
schema: serde_json::Value,
|
||||
#[serde(default)]
|
||||
#[allow(dead_code)]
|
||||
tests: Vec<serde_json::Value>,
|
||||
}
|
||||
|
||||
/// A schema test case with all context needed for parallel execution
|
||||
#[derive(Debug)]
|
||||
struct SchemaTestCase {
|
||||
#[allow(dead_code)]
|
||||
file_path: PathBuf,
|
||||
relative_path: String,
|
||||
index: usize,
|
||||
description: String,
|
||||
schema: serde_json::Value,
|
||||
output_path: PathBuf,
|
||||
}
|
||||
|
||||
/// Get the project root directory
|
||||
fn project_root() -> PathBuf {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
}
|
||||
|
||||
/// Get the fixtures directory
|
||||
fn fixtures_dir() -> PathBuf {
|
||||
project_root().join("tests/fixtures/json-schema-test-suite/draft2020-12")
|
||||
}
|
||||
|
||||
/// Get the test output directory
|
||||
fn output_dir() -> PathBuf {
|
||||
project_root().join("tests/outputs/json-schema-test-suite/draft2020-12")
|
||||
}
|
||||
|
||||
/// Extract all schemas from a test suite file
|
||||
fn extract_schemas(file_path: &Path) -> Vec<(String, serde_json::Value)> {
|
||||
let content = fs::read_to_string(file_path).expect("Failed to read test file");
|
||||
let suites: Vec<TestSuite> = serde_json::from_str(&content).expect("Failed to parse test file");
|
||||
|
||||
suites
|
||||
.into_iter()
|
||||
.map(|suite| (suite.description, suite.schema))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Run the CLI against a schema and return success/failure
|
||||
fn run_cli(schema: &serde_json::Value, output_path: &Path) -> Result<(), String> {
|
||||
// Create a unique temporary file for the schema (use thread id to avoid conflicts)
|
||||
let temp_dir = std::env::temp_dir();
|
||||
let schema_file = temp_dir.join(format!(
|
||||
"test_schema_{:?}_{}.json",
|
||||
std::thread::current().id(),
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos()
|
||||
));
|
||||
|
||||
fs::write(&schema_file, serde_json::to_string_pretty(schema).unwrap())
|
||||
.map_err(|e| format!("Failed to write schema file: {}", e))?;
|
||||
|
||||
// Ensure output directory exists
|
||||
if let Some(parent) = output_path.parent() {
|
||||
fs::create_dir_all(parent)
|
||||
.map_err(|e| format!("Failed to create output directory: {}", e))?;
|
||||
}
|
||||
|
||||
// Run the CLI
|
||||
let output = Command::new(env!("CARGO_BIN_EXE_schemars-docgen"))
|
||||
.arg(&schema_file)
|
||||
.arg("-o")
|
||||
.arg(output_path)
|
||||
.output()
|
||||
.map_err(|e| format!("Failed to execute CLI: {}", e))?;
|
||||
|
||||
// Clean up temp file
|
||||
let _ = fs::remove_file(&schema_file);
|
||||
|
||||
if output.status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
Err(format!(
|
||||
"CLI failed with status {:?}\nstderr: {}\nstdout: {}",
|
||||
output.status.code(),
|
||||
stderr,
|
||||
stdout
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect all JSON test files from a directory recursively
|
||||
fn collect_test_files(dir: &Path) -> Vec<PathBuf> {
|
||||
let mut files = Vec::new();
|
||||
|
||||
if dir.is_dir() {
|
||||
for entry in fs::read_dir(dir).expect("Failed to read directory") {
|
||||
let entry = entry.expect("Failed to read entry");
|
||||
let path = entry.path();
|
||||
|
||||
if path.is_dir() {
|
||||
files.extend(collect_test_files(&path));
|
||||
} else if path.extension().is_some_and(|ext| ext == "json") {
|
||||
files.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
files.sort();
|
||||
files
|
||||
}
|
||||
|
||||
/// Convert a fixture file path to its corresponding output directory
|
||||
fn fixture_to_output_dir(fixture_path: &Path) -> PathBuf {
|
||||
let fixtures_base = fixtures_dir();
|
||||
let relative = fixture_path
|
||||
.strip_prefix(&fixtures_base)
|
||||
.expect("Fixture path should be under fixtures dir");
|
||||
|
||||
// Remove .json extension and use as directory name
|
||||
let stem = relative.with_extension("");
|
||||
output_dir().join(stem)
|
||||
}
|
||||
|
||||
/// Collect all test cases from all fixture files
|
||||
fn collect_all_test_cases() -> Vec<SchemaTestCase> {
|
||||
let fixtures = fixtures_dir();
|
||||
let test_files = collect_test_files(&fixtures);
|
||||
|
||||
test_files
|
||||
.into_iter()
|
||||
.flat_map(|file_path| {
|
||||
let schemas = extract_schemas(&file_path);
|
||||
let output_base = fixture_to_output_dir(&file_path);
|
||||
let relative_path = file_path
|
||||
.strip_prefix(&fixtures)
|
||||
.unwrap_or(&file_path)
|
||||
.display()
|
||||
.to_string();
|
||||
|
||||
schemas
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(move |(idx, (description, schema))| SchemaTestCase {
|
||||
file_path: file_path.clone(),
|
||||
relative_path: relative_path.clone(),
|
||||
index: idx,
|
||||
description,
|
||||
schema,
|
||||
output_path: output_base.join(format!("{}.html", idx)),
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Data structure for a schema entry in the index template
|
||||
#[derive(Debug, Serialize)]
|
||||
struct IndexSchema {
|
||||
index: usize,
|
||||
description: String,
|
||||
output_path: String,
|
||||
has_content: bool,
|
||||
features: Vec<String>,
|
||||
}
|
||||
|
||||
/// Data structure for a file group in the index template
|
||||
#[derive(Debug, Serialize)]
|
||||
struct IndexGroup {
|
||||
file_path: String,
|
||||
schemas: Vec<IndexSchema>,
|
||||
}
|
||||
|
||||
/// Analyze a schema and return (has_content, features)
|
||||
/// has_content is true if the schema has properties or $defs (will show Configuration/Types)
|
||||
/// features lists the JSON Schema keywords present in the schema
|
||||
fn analyze_schema(schema: &serde_json::Value) -> (bool, Vec<String>) {
|
||||
let mut features = Vec::new();
|
||||
|
||||
let obj = match schema.as_object() {
|
||||
Some(o) => o,
|
||||
None => {
|
||||
// Handle boolean schemas
|
||||
if schema.as_bool() == Some(true) {
|
||||
return (false, vec!["boolean: true".to_string()]);
|
||||
} else if schema.as_bool() == Some(false) {
|
||||
return (false, vec!["boolean: false".to_string()]);
|
||||
}
|
||||
return (false, vec!["non-object".to_string()]);
|
||||
}
|
||||
};
|
||||
|
||||
if obj.is_empty() {
|
||||
return (false, vec!["empty schema".to_string()]);
|
||||
}
|
||||
|
||||
let has_properties = obj.contains_key("properties");
|
||||
let has_defs = obj.contains_key("$defs") || obj.contains_key("definitions");
|
||||
|
||||
// Collect features
|
||||
if has_properties {
|
||||
features.push("properties".to_string());
|
||||
}
|
||||
if has_defs {
|
||||
features.push("$defs".to_string());
|
||||
}
|
||||
if obj.contains_key("$ref") {
|
||||
features.push("$ref".to_string());
|
||||
}
|
||||
if let Some(t) = obj.get("type") {
|
||||
if let Some(s) = t.as_str() {
|
||||
features.push(format!("type: {}", s));
|
||||
} else if let Some(arr) = t.as_array() {
|
||||
let types: Vec<_> = arr.iter().filter_map(|v| v.as_str()).collect();
|
||||
features.push(format!("type: [{}]", types.join(", ")));
|
||||
}
|
||||
}
|
||||
if obj.contains_key("items") {
|
||||
features.push("items".to_string());
|
||||
}
|
||||
if obj.contains_key("prefixItems") {
|
||||
features.push("prefixItems".to_string());
|
||||
}
|
||||
if obj.contains_key("additionalProperties") {
|
||||
features.push("additionalProperties".to_string());
|
||||
}
|
||||
if obj.contains_key("patternProperties") {
|
||||
features.push("patternProperties".to_string());
|
||||
}
|
||||
if obj.contains_key("allOf") {
|
||||
features.push("allOf".to_string());
|
||||
}
|
||||
if obj.contains_key("anyOf") {
|
||||
features.push("anyOf".to_string());
|
||||
}
|
||||
if obj.contains_key("oneOf") {
|
||||
features.push("oneOf".to_string());
|
||||
}
|
||||
if obj.contains_key("not") {
|
||||
features.push("not".to_string());
|
||||
}
|
||||
if obj.contains_key("if") {
|
||||
features.push("if/then/else".to_string());
|
||||
}
|
||||
if obj.contains_key("const") {
|
||||
features.push("const".to_string());
|
||||
}
|
||||
if obj.contains_key("enum") {
|
||||
features.push("enum".to_string());
|
||||
}
|
||||
if obj.contains_key("$dynamicRef") {
|
||||
features.push("$dynamicRef".to_string());
|
||||
}
|
||||
if obj.contains_key("$dynamicAnchor") {
|
||||
features.push("$dynamicAnchor".to_string());
|
||||
}
|
||||
if obj.contains_key("contains") {
|
||||
features.push("contains".to_string());
|
||||
}
|
||||
if obj.contains_key("dependentSchemas") {
|
||||
features.push("dependentSchemas".to_string());
|
||||
}
|
||||
if obj.contains_key("dependentRequired") {
|
||||
features.push("dependentRequired".to_string());
|
||||
}
|
||||
if obj.contains_key("unevaluatedItems") {
|
||||
features.push("unevaluatedItems".to_string());
|
||||
}
|
||||
if obj.contains_key("unevaluatedProperties") {
|
||||
features.push("unevaluatedProperties".to_string());
|
||||
}
|
||||
|
||||
// If no features found, list what keys are present
|
||||
if features.is_empty() {
|
||||
let keys: Vec<_> = obj.keys().take(3).cloned().collect();
|
||||
features.push(format!("other: {}", keys.join(", ")));
|
||||
}
|
||||
|
||||
(has_properties || has_defs, features)
|
||||
}
|
||||
|
||||
/// Get git commit hash
|
||||
fn get_git_commit_hash() -> String {
|
||||
Command::new("git")
|
||||
.args(["rev-parse", "HEAD"])
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|o| {
|
||||
if o.status.success() {
|
||||
String::from_utf8(o.stdout)
|
||||
.ok()
|
||||
.map(|s| s.trim().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| "unknown".to_string())
|
||||
}
|
||||
|
||||
/// Check if git repo is dirty
|
||||
fn is_git_dirty() -> bool {
|
||||
Command::new("git")
|
||||
.args(["status", "--porcelain"])
|
||||
.output()
|
||||
.ok()
|
||||
.map(|o| !o.stdout.is_empty())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Generate an index.html file with links to all test outputs using Tera
|
||||
fn generate_index_html(test_cases: &[SchemaTestCase]) {
|
||||
let output_base = project_root().join("tests/outputs");
|
||||
let index_path = output_base.join("index.html");
|
||||
|
||||
// Group test cases by their source file (relative_path)
|
||||
let mut grouped: BTreeMap<String, Vec<&SchemaTestCase>> = BTreeMap::new();
|
||||
for test_case in test_cases {
|
||||
grouped
|
||||
.entry(test_case.relative_path.clone())
|
||||
.or_default()
|
||||
.push(test_case);
|
||||
}
|
||||
|
||||
// Convert to template-friendly structure
|
||||
let mut with_content = 0;
|
||||
let mut without_content = 0;
|
||||
|
||||
let groups: Vec<IndexGroup> = grouped
|
||||
.into_iter()
|
||||
.map(|(file_path, cases)| {
|
||||
let schemas = cases
|
||||
.into_iter()
|
||||
.map(|case| {
|
||||
let relative_output = case
|
||||
.output_path
|
||||
.strip_prefix(&output_base)
|
||||
.expect("Output path should be under output base");
|
||||
let (has_content, features) = analyze_schema(&case.schema);
|
||||
if has_content {
|
||||
with_content += 1;
|
||||
} else {
|
||||
without_content += 1;
|
||||
}
|
||||
IndexSchema {
|
||||
index: case.index,
|
||||
description: case.description.clone(),
|
||||
output_path: relative_output.display().to_string(),
|
||||
has_content,
|
||||
features,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
IndexGroup { file_path, schemas }
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Load and render template
|
||||
let template_path = project_root().join("src/templates/test_index.html");
|
||||
let template_content =
|
||||
fs::read_to_string(&template_path).expect("Failed to read test_index.html template");
|
||||
|
||||
let mut tera = Tera::default();
|
||||
tera.add_raw_template("test_index.html", &template_content)
|
||||
.expect("Failed to parse template");
|
||||
|
||||
// Get git and time info
|
||||
let commit_hash = get_git_commit_hash();
|
||||
let is_dirty = is_git_dirty();
|
||||
let time_utc = Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string();
|
||||
let time_local = Local::now().format("%Y-%m-%d %H:%M:%S %Z").to_string();
|
||||
|
||||
let mut context = Context::new();
|
||||
context.insert("total_schemas", &test_cases.len());
|
||||
context.insert("total_files", &groups.len());
|
||||
context.insert("with_content", &with_content);
|
||||
context.insert("without_content", &without_content);
|
||||
context.insert("commit_hash", &commit_hash);
|
||||
context.insert("is_dirty", &is_dirty);
|
||||
context.insert("time_utc", &time_utc);
|
||||
context.insert("time_local", &time_local);
|
||||
context.insert("groups", &groups);
|
||||
|
||||
let html = tera
|
||||
.render("test_index.html", &context)
|
||||
.expect("Failed to render template");
|
||||
|
||||
fs::write(&index_path, html).expect("Failed to write index.html");
|
||||
println!("Generated index.html at {:?}", index_path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_json_schema_test_suite_schemas() {
|
||||
let fixtures = fixtures_dir();
|
||||
if !fixtures.exists() {
|
||||
panic!(
|
||||
"Fixtures directory not found: {:?}\n\
|
||||
Please run: git clone --depth 1 https://github.com/json-schema-org/JSON-Schema-Test-Suite.git /tmp/json-schema-test-suite && \
|
||||
mkdir -p fixtures/json-schema-test-suite && \
|
||||
cp -r /tmp/json-schema-test-suite/tests/draft2020-12 fixtures/json-schema-test-suite/ && \
|
||||
rm -rf /tmp/json-schema-test-suite",
|
||||
fixtures
|
||||
);
|
||||
}
|
||||
|
||||
// Collect all test cases upfront
|
||||
let test_cases = collect_all_test_cases();
|
||||
let total_schemas = test_cases.len();
|
||||
println!("Found {} schemas to test", total_schemas);
|
||||
|
||||
// Counters for progress
|
||||
let passed = AtomicUsize::new(0);
|
||||
type FailedTest = (String, usize, String, serde_json::Value, String);
|
||||
let failed: Mutex<Vec<FailedTest>> = Mutex::new(Vec::new());
|
||||
|
||||
// Run tests in parallel
|
||||
test_cases.par_iter().for_each(|test_case| {
|
||||
match run_cli(&test_case.schema, &test_case.output_path) {
|
||||
Ok(()) => {
|
||||
passed.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
Err(e) => {
|
||||
failed.lock().unwrap().push((
|
||||
test_case.relative_path.clone(),
|
||||
test_case.index,
|
||||
test_case.description.clone(),
|
||||
test_case.schema.clone(),
|
||||
e,
|
||||
));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let passed_count = passed.load(Ordering::Relaxed);
|
||||
let failed_list = failed.into_inner().unwrap();
|
||||
|
||||
println!("\n=== Summary ===");
|
||||
println!("Total schemas: {}", total_schemas);
|
||||
println!("Passed: {}", passed_count);
|
||||
println!("Failed: {}", failed_list.len());
|
||||
|
||||
if !failed_list.is_empty() {
|
||||
println!("\n=== Failed Schemas ===");
|
||||
for (relative_path, idx, desc, schema, error) in &failed_list {
|
||||
println!("\n--- {}[{}]: {} ---", relative_path, idx, desc);
|
||||
println!("Schema: {}", serde_json::to_string_pretty(schema).unwrap());
|
||||
println!("Error: {}", error);
|
||||
}
|
||||
panic!(
|
||||
"{} schemas failed to generate documentation",
|
||||
failed_list.len()
|
||||
);
|
||||
}
|
||||
|
||||
// Generate index.html with links to all outputs
|
||||
generate_index_html(&test_cases);
|
||||
}
|
||||
|
||||
/// Test a single schema file - useful for debugging specific failures
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_single_schema_file() {
|
||||
let file_path = fixtures_dir().join("type.json");
|
||||
let schemas = extract_schemas(&file_path);
|
||||
let output_base = fixture_to_output_dir(&file_path);
|
||||
|
||||
for (idx, (description, schema)) in schemas.iter().enumerate() {
|
||||
let output_path = output_base.join(format!("{}.html", idx));
|
||||
println!("Testing: {} - {}", idx, description);
|
||||
println!("Schema: {}", serde_json::to_string_pretty(schema).unwrap());
|
||||
|
||||
match run_cli(schema, &output_path) {
|
||||
Ok(()) => println!(" PASS"),
|
||||
Err(e) => panic!(" FAIL: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user