Ajout du validateur json + correctif factory metadata
This commit is contained in:
98
lib/All/json-schema-validator/test/CMakeLists.txt
Normal file
98
lib/All/json-schema-validator/test/CMakeLists.txt
Normal file
@@ -0,0 +1,98 @@
|
||||
set(PIPE_IN_TEST_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/test-pipe-in.sh)
|
||||
|
||||
# simple nlohmann_json_schema_validator-executable
|
||||
add_executable(json-schema-validate json-schema-validate.cpp)
|
||||
target_link_libraries(json-schema-validate nlohmann_json_schema_validator)
|
||||
|
||||
function(add_test_simple_schema name schema instance)
|
||||
add_test(
|
||||
NAME ${name}
|
||||
COMMAND ${PIPE_IN_TEST_SCRIPT}
|
||||
$<TARGET_FILE:json-schema-validate>
|
||||
${schema}
|
||||
${instance}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endfunction()
|
||||
|
||||
file(GLOB TEST_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/*)
|
||||
|
||||
foreach(DIR ${TEST_DIRS})
|
||||
if(IS_DIRECTORY ${DIR})
|
||||
add_subdirectory(${DIR})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_executable(uri uri.cpp)
|
||||
target_link_libraries(uri nlohmann_json_schema_validator)
|
||||
add_test(NAME uri COMMAND uri)
|
||||
|
||||
add_executable(errors errors.cpp)
|
||||
target_link_libraries(errors nlohmann_json_schema_validator)
|
||||
add_test(NAME errors COMMAND errors)
|
||||
|
||||
add_executable(issue-70 issue-70.cpp)
|
||||
target_link_libraries(issue-70 nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-70 COMMAND issue-70)
|
||||
|
||||
add_executable(issue-70-root-schema-constructor issue-70-root-schema-constructor.cpp)
|
||||
target_link_libraries(issue-70-root-schema-constructor nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-70-root-schema-constructor COMMAND issue-70-root-schema-constructor)
|
||||
|
||||
add_executable(issue-25-default-values issue-25-default-values.cpp)
|
||||
target_link_libraries(issue-25-default-values nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-25-default-values COMMAND issue-25-default-values)
|
||||
|
||||
add_executable(issue-98 issue-98.cpp)
|
||||
target_link_libraries(issue-98 nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-98-erase-exception-unknown-keywords COMMAND issue-98)
|
||||
|
||||
add_executable(issue-293 issue-293.cpp)
|
||||
target_link_libraries(issue-293 nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-293-float-point-error COMMAND issue-293)
|
||||
|
||||
# Unit test for string format checks
|
||||
add_executable(string-format-check-test string-format-check-test.cpp)
|
||||
target_include_directories(string-format-check-test PRIVATE ${PROJECT_SOURCE_DIR}/src/)
|
||||
target_link_libraries(string-format-check-test nlohmann_json_schema_validator)
|
||||
|
||||
add_test(NAME string-format-check-test COMMAND string-format-check-test)
|
||||
|
||||
# Unit test for json-patch
|
||||
add_executable(json-patch json-patch.cpp)
|
||||
target_include_directories(json-patch PRIVATE ${PROJECT_SOURCE_DIR}/src)
|
||||
target_link_libraries(json-patch nlohmann_json_schema_validator)
|
||||
add_test(NAME json-patch COMMAND json-patch)
|
||||
|
||||
# Unit test for format checker fail at schema parsing time
|
||||
add_executable(issue-117-format-error issue-117-format-error.cpp)
|
||||
target_link_libraries(issue-117-format-error nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-117-format-error COMMAND issue-117-format-error)
|
||||
|
||||
add_executable(binary-validation binary-validation.cpp)
|
||||
target_include_directories(binary-validation PRIVATE ${PROJECT_SOURCE_DIR}/src)
|
||||
target_link_libraries(binary-validation PRIVATE nlohmann_json_schema_validator)
|
||||
add_test(NAME binary-validation COMMAND binary-validation)
|
||||
|
||||
add_executable(issue-149-entry-selection issue-149-entry-selection.cpp)
|
||||
target_link_libraries(issue-149-entry-selection PRIVATE nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-149-entry-selection COMMAND issue-149-entry-selection)
|
||||
|
||||
add_executable(issue-189-default-values issue-189-default-values.cpp)
|
||||
target_link_libraries(issue-189-default-values nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-189-default-values COMMAND issue-189-default-values)
|
||||
|
||||
add_executable(issue-229-oneof-default-values issue-229-oneof-default-values.cpp)
|
||||
target_link_libraries(issue-229-oneof-default-values nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-229-oneof-default-values COMMAND issue-229-oneof-default-values)
|
||||
|
||||
add_executable(issue-243-root-default-values issue-243-root-default-values.cpp)
|
||||
target_link_libraries(issue-243-root-default-values nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-243-root-default-values COMMAND issue-243-root-default-values)
|
||||
|
||||
add_executable(issue-255-error-message-limit-precision issue-255-error-message-limit-precision.cpp)
|
||||
target_link_libraries(issue-255-error-message-limit-precision nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-255-error-message-limit-precision COMMAND issue-255-error-message-limit-precision)
|
||||
|
||||
add_executable(issue-105-verbose-combination-errors issue-105-verbose-combination-errors.cpp)
|
||||
target_link_libraries(issue-105-verbose-combination-errors nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-105-verbose-combination-errors COMMAND issue-105-verbose-combination-errors)
|
||||
@@ -0,0 +1,70 @@
|
||||
set(JSON_SCHEMA_TEST_PREFIX "JSON-Suite" CACHE STRING "prefix for JSON-tests added to ctest")
|
||||
|
||||
set(DRAFT "draft7")
|
||||
|
||||
# find schema-test-suite
|
||||
find_path(JSON_SCHEMA_TEST_SUITE_PATH
|
||||
NAMES
|
||||
tests/${DRAFT})
|
||||
|
||||
if (NOT JSON_SCHEMA_TEST_SUITE_PATH)
|
||||
message(STATUS "Set JSON_SCHEMA_TEST_SUITE_PATH to a path in which JSON-Schema-Test-Suite is located (github.com/json-schema-org/JSON-Schema-Test-Suite). Using internal test-suite which might be out of date.")
|
||||
set(JSON_SCHEMA_TEST_SUITE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
if(JSON_SCHEMA_TEST_SUITE_PATH)
|
||||
# json-schema-validator-tester
|
||||
add_executable(json-schema-test json-schema-test.cpp)
|
||||
target_link_libraries(json-schema-test nlohmann_json_schema_validator)
|
||||
target_compile_definitions(json-schema-test
|
||||
PRIVATE
|
||||
JSON_SCHEMA_TEST_SUITE_PATH="${JSON_SCHEMA_TEST_SUITE_PATH}")
|
||||
|
||||
option(JSON_SCHEMA_ENABLE_OPTIONAL_TESTS "Enable optional tests of the JSONSchema Test Suite" ON)
|
||||
|
||||
# create tests foreach test-file
|
||||
file(GLOB TEST_FILES ${JSON_SCHEMA_TEST_SUITE_PATH}/tests/${DRAFT}/*.json)
|
||||
|
||||
foreach(TEST_FILE ${TEST_FILES})
|
||||
get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE)
|
||||
add_test(NAME "${JSON_SCHEMA_TEST_PREFIX}::${TEST_NAME}"
|
||||
COMMAND ${PIPE_IN_TEST_SCRIPT} $<TARGET_FILE:json-schema-test> ${TEST_FILE})
|
||||
endforeach()
|
||||
|
||||
if (JSON_SCHEMA_ENABLE_OPTIONAL_TESTS)
|
||||
file(GLOB OPT_TEST_FILES ${JSON_SCHEMA_TEST_SUITE_PATH}/tests/${DRAFT}/optional/*.json)
|
||||
file(GLOB FORMAT_TEST_FILES ${JSON_SCHEMA_TEST_SUITE_PATH}/tests/${DRAFT}/optional/format/*.json)
|
||||
|
||||
foreach(TEST_FILE ${OPT_TEST_FILES})
|
||||
get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE)
|
||||
add_test(NAME "${JSON_SCHEMA_TEST_PREFIX}::Optional::${TEST_NAME}"
|
||||
COMMAND ${PIPE_IN_TEST_SCRIPT} $<TARGET_FILE:json-schema-test> ${TEST_FILE})
|
||||
endforeach()
|
||||
|
||||
foreach(TEST_FILE ${FORMAT_TEST_FILES})
|
||||
get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE)
|
||||
add_test(NAME "${JSON_SCHEMA_TEST_PREFIX}::Optional::Format::${TEST_NAME}"
|
||||
COMMAND ${PIPE_IN_TEST_SCRIPT} $<TARGET_FILE:json-schema-test> ${TEST_FILE})
|
||||
endforeach()
|
||||
|
||||
# some optional tests will fail
|
||||
set_tests_properties(
|
||||
JSON-Suite::Optional::bignum
|
||||
JSON-Suite::Optional::non-bmp-regex
|
||||
JSON-Suite::Optional::float-overflow
|
||||
|
||||
JSON-Suite::Optional::ecmascript-regex
|
||||
JSON-Suite::Optional::Format::idn-hostname
|
||||
JSON-Suite::Optional::Format::iri-reference
|
||||
JSON-Suite::Optional::Format::iri
|
||||
JSON-Suite::Optional::Format::json-pointer
|
||||
JSON-Suite::Optional::Format::relative-json-pointer
|
||||
JSON-Suite::Optional::Format::uri-reference
|
||||
JSON-Suite::Optional::Format::uri-template
|
||||
JSON-Suite::Optional::unicode
|
||||
|
||||
PROPERTIES
|
||||
WILL_FAIL ON)
|
||||
endif()
|
||||
else()
|
||||
endif()
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* JSON schema validator for JSON for modern C++
|
||||
*
|
||||
* Copyright (c) 2016-2019 Patrick Boettcher <p@yai.se>.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
|
||||
using nlohmann::json;
|
||||
using nlohmann::json_uri;
|
||||
using nlohmann::json_schema::json_validator;
|
||||
|
||||
static void loader(const json_uri &uri, json &schema)
|
||||
{
|
||||
if (uri.location() == "http://json-schema.org/draft-07/schema") {
|
||||
schema = nlohmann::json_schema::draft7_schema_builtin;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fn = JSON_SCHEMA_TEST_SUITE_PATH;
|
||||
fn += "/remotes";
|
||||
fn += uri.path();
|
||||
std::cerr << fn << "\n";
|
||||
|
||||
std::fstream s(fn.c_str());
|
||||
if (!s.good())
|
||||
throw std::invalid_argument("could not open " + uri.url() + " for schema loading\n");
|
||||
|
||||
try {
|
||||
s >> schema;
|
||||
} catch (std::exception &e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// from here
|
||||
// https://stackoverflow.com/a/34571089/880584
|
||||
static std::string base64_decode(const std::string &in)
|
||||
{
|
||||
std::string out;
|
||||
|
||||
std::vector<int> T(256, -1);
|
||||
for (int i = 0; i < 64; i++)
|
||||
T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
|
||||
|
||||
unsigned val = 0;
|
||||
int valb = -8;
|
||||
for (uint8_t c : in) {
|
||||
if (c == '=')
|
||||
break;
|
||||
|
||||
if (T[c] == -1) {
|
||||
throw std::invalid_argument("base64-decode: unexpected character in encode string: '" + std::string(1, c) + "'");
|
||||
}
|
||||
val = (val << 6) + T[c];
|
||||
valb += 6;
|
||||
if (valb >= 0) {
|
||||
out.push_back(char((val >> valb) & 0xFF));
|
||||
valb -= 8;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void content(const std::string &contentEncoding, const std::string &contentMediaType, const json &instance)
|
||||
{
|
||||
std::string content = instance;
|
||||
|
||||
if (contentEncoding == "base64")
|
||||
content = base64_decode(instance);
|
||||
else if (contentEncoding != "")
|
||||
throw std::invalid_argument("unable to check for contentEncoding '" + contentEncoding + "'");
|
||||
|
||||
if (contentMediaType == "application/json")
|
||||
auto dummy = json::parse(content); // throws if conversion fails
|
||||
else if (contentMediaType != "")
|
||||
throw std::invalid_argument("unable to check for contentMediaType '" + contentMediaType + "'");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
json validation; // a validation case following the JSON-test-suite-schema
|
||||
|
||||
try {
|
||||
std::cin >> validation;
|
||||
} catch (std::exception &e) {
|
||||
std::cout << e.what() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
size_t total_failed = 0,
|
||||
total = 0;
|
||||
|
||||
for (auto &test_group : validation) {
|
||||
size_t group_failed = 0,
|
||||
group_total = 0;
|
||||
|
||||
std::cout << "Testing Group " << test_group["description"] << "\n";
|
||||
|
||||
const auto &schema = test_group["schema"];
|
||||
|
||||
json_validator validator(loader,
|
||||
nlohmann::json_schema::default_string_format_check,
|
||||
content);
|
||||
|
||||
validator.set_root_schema(schema);
|
||||
|
||||
for (auto &test_case : test_group["tests"]) {
|
||||
std::cout << " Testing Case " << test_case["description"] << "\n";
|
||||
|
||||
bool valid = true;
|
||||
|
||||
try {
|
||||
validator.validate(test_case["data"]);
|
||||
} catch (const std::out_of_range &e) {
|
||||
valid = false;
|
||||
std::cout << " Test Case Exception (out of range): " << e.what() << "\n";
|
||||
|
||||
} catch (const std::invalid_argument &e) {
|
||||
valid = false;
|
||||
std::cout << " Test Case Exception (invalid argument): " << e.what() << "\n";
|
||||
|
||||
} catch (const std::logic_error &e) {
|
||||
valid = !test_case["valid"]; /* force test-case failure */
|
||||
std::cout << " Not yet implemented: " << e.what() << "\n";
|
||||
}
|
||||
|
||||
if (valid == test_case["valid"])
|
||||
std::cout << " --> Test Case exited with " << valid << " as expected.\n";
|
||||
else {
|
||||
group_failed++;
|
||||
std::cout << " --> Test Case exited with " << valid << " NOT expected.\n";
|
||||
}
|
||||
group_total++;
|
||||
std::cout << "\n";
|
||||
}
|
||||
total_failed += group_failed;
|
||||
total += group_total;
|
||||
std::cout << "Group RESULT: " << test_group["description"] << " "
|
||||
<< (group_total - group_failed) << " of " << group_total
|
||||
<< " have succeeded - " << group_failed << " failed\n";
|
||||
std::cout << "-------------\n";
|
||||
}
|
||||
|
||||
std::cout << "Total RESULT: " << (total - total_failed) << " of " << total << " have succeeded - " << total_failed << " failed\n";
|
||||
|
||||
return total_failed;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "integer"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "integer"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "integer"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "integer"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "integer"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$defs": {
|
||||
"orNull": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "string"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"definitions": {
|
||||
"orNull": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "string"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$id": "http://localhost:1234/ref-and-definitions.json",
|
||||
"definitions": {
|
||||
"inner": {
|
||||
"properties": {
|
||||
"bar": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"allOf": [ { "$ref": "#/definitions/inner" } ]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$id": "http://localhost:1234/ref-and-defs.json",
|
||||
"$defs": {
|
||||
"inner": {
|
||||
"properties": {
|
||||
"bar": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"$ref": "#/$defs/inner"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"$defs": {
|
||||
"integer": {
|
||||
"type": "integer"
|
||||
},
|
||||
"refToInteger": {
|
||||
"$ref": "#/$defs/integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"integer": {
|
||||
"type": "integer"
|
||||
},
|
||||
"refToInteger": {
|
||||
"$ref": "#/integer"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
[
|
||||
{
|
||||
"description": "additionalItems as schema",
|
||||
"schema": {
|
||||
"items": [{}],
|
||||
"additionalItems": {"type": "integer"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "additional items match schema",
|
||||
"data": [ null, 2, 3, 4 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "additional items do not match schema",
|
||||
"data": [ null, 2, 3, "foo" ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "when items is schema, additionalItems does nothing",
|
||||
"schema": {
|
||||
"items": {},
|
||||
"additionalItems": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "all items match schema",
|
||||
"data": [ 1, 2, 3, 4, 5 ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "array of items with no additionalItems permitted",
|
||||
"schema": {
|
||||
"items": [{}, {}, {}],
|
||||
"additionalItems": 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": "additionalItems as false without items",
|
||||
"schema": {"additionalItems": false},
|
||||
"tests": [
|
||||
{
|
||||
"description":
|
||||
"items defaults to empty schema so everything is valid",
|
||||
"data": [ 1, 2, 3, 4, 5 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ignores non-arrays",
|
||||
"data": {"foo" : "bar"},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalItems are allowed by default",
|
||||
"schema": {"items": [{"type": "integer"}]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "only the first item is validated",
|
||||
"data": [1, "foo", false],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalItems should not look in applicators, valid case",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{ "items": [ { "type": "integer" } ] }
|
||||
],
|
||||
"additionalItems": { "type": "boolean" }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "items defined in allOf are not examined",
|
||||
"data": [ 1, null ],
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalItems should not look in applicators, invalid case",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{ "items": [ { "type": "integer" }, { "type": "string" } ] }
|
||||
],
|
||||
"items": [ {"type": "integer" } ],
|
||||
"additionalItems": { "type": "boolean" }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "items defined in allOf are not examined",
|
||||
"data": [ 1, "hello" ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "items validation adjusts the starting index for additionalItems",
|
||||
"schema": {
|
||||
"items": [ { "type": "string" } ],
|
||||
"additionalItems": { "type": "integer" }
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid items",
|
||||
"data": [ "x", 2, 3 ],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "wrong type of second item",
|
||||
"data": [ "x", "y" ],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,133 @@
|
||||
[
|
||||
{
|
||||
"description":
|
||||
"additionalProperties being false does not allow other properties",
|
||||
"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",
|
||||
"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 allows a schema which should validate",
|
||||
"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",
|
||||
"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",
|
||||
"schema": {"properties": {"foo": {}, "bar": {}}},
|
||||
"tests": [
|
||||
{
|
||||
"description": "additional properties are allowed",
|
||||
"data": {"foo": 1, "bar": 2, "quux": true},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "additionalProperties should not look in applicators",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{"properties": {"foo": {}}}
|
||||
],
|
||||
"additionalProperties": {"type": "boolean"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "properties defined in allOf are not examined",
|
||||
"data": {"foo": 1, "bar": true},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,294 @@
|
||||
[
|
||||
{
|
||||
"description": "allOf",
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {"allOf": [true, true]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with boolean schemas, some false",
|
||||
"schema": {"allOf": [true, false]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with boolean schemas, all false",
|
||||
"schema": {"allOf": [false, false]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with one empty schema",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any data is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with two empty schemas",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any data is valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with the first empty schema",
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,215 @@
|
||||
[
|
||||
{
|
||||
"description": "anyOf",
|
||||
"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": {
|
||||
"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": {"anyOf": [true, true]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf with boolean schemas, some true",
|
||||
"schema": {"anyOf": [true, false]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf with boolean schemas, all false",
|
||||
"schema": {"anyOf": [false, false]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "anyOf complex types",
|
||||
"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": {
|
||||
"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": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "anything non-null is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nested anyOf, to check validation semantics",
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "anything non-null is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,104 @@
|
||||
[
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,342 @@
|
||||
[
|
||||
{
|
||||
"description": "const validation",
|
||||
"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": {"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": {"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": {"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": {"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": {"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": {"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": {"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": {"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": {"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": {"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": {"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": {"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": {"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": { "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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,150 @@
|
||||
[
|
||||
{
|
||||
"description": "contains keyword validation",
|
||||
"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": {
|
||||
"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": {"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": {"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": {
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,79 @@
|
||||
[
|
||||
{
|
||||
"description": "invalid type for default",
|
||||
"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": {
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"description": "validate definition against metaschema",
|
||||
"schema": {"$ref": "http://json-schema.org/draft-07/schema#"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid definition schema",
|
||||
"data": {
|
||||
"definitions": {
|
||||
"foo": {"type": "integer"}
|
||||
}
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid definition schema",
|
||||
"data": {
|
||||
"definitions": {
|
||||
"foo": {"type": 1}
|
||||
}
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,248 @@
|
||||
[
|
||||
{
|
||||
"description": "dependencies",
|
||||
"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": "dependencies with empty array",
|
||||
"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 dependencies",
|
||||
"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": "multiple dependencies subschema",
|
||||
"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": "dependencies with boolean subschemas",
|
||||
"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": "dependencies with escaped characters",
|
||||
"schema": {
|
||||
"dependencies": {
|
||||
"foo\nbar": ["foo\rbar"],
|
||||
"foo\tbar": {
|
||||
"minProperties": 4
|
||||
},
|
||||
"foo'bar": {"required": ["foo\"bar"]},
|
||||
"foo\"bar": ["foo'bar"]
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid object 1",
|
||||
"data": {
|
||||
"foo\nbar": 1,
|
||||
"foo\rbar": 2
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid object 2",
|
||||
"data": {
|
||||
"foo\tbar": 1,
|
||||
"a": 2,
|
||||
"b": 3,
|
||||
"c": 4
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "valid object 3",
|
||||
"data": {
|
||||
"foo'bar": 1,
|
||||
"foo\"bar": 2
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid object 1",
|
||||
"data": {
|
||||
"foo\nbar": 1,
|
||||
"foo": 2
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid object 2",
|
||||
"data": {
|
||||
"foo\tbar": 1,
|
||||
"a": 2
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid object 3",
|
||||
"data": {
|
||||
"foo'bar": 1
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid object 4",
|
||||
"data": {
|
||||
"foo\"bar": 2
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,236 @@
|
||||
[
|
||||
{
|
||||
"description": "simple enum validation",
|
||||
"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": {"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": { "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": {
|
||||
"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": {
|
||||
"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": {"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 true does not match 1",
|
||||
"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 0 does not match false",
|
||||
"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 1 does not match true",
|
||||
"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": "nul characters in strings",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
[
|
||||
{
|
||||
"description": "exclusiveMaximum validation",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
[
|
||||
{
|
||||
"description": "exclusiveMinimum validation",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,614 @@
|
||||
[
|
||||
{
|
||||
"description": "email format",
|
||||
"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": "idn-email format",
|
||||
"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": "regex format",
|
||||
"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": "ipv4 format",
|
||||
"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": "ipv6 format",
|
||||
"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": "idn-hostname format",
|
||||
"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": "hostname format",
|
||||
"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": "date format",
|
||||
"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": "date-time format",
|
||||
"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": "time format",
|
||||
"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": "json-pointer format",
|
||||
"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": "relative-json-pointer format",
|
||||
"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": "iri format",
|
||||
"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": "iri-reference format",
|
||||
"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": "uri format",
|
||||
"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": "uri-reference format",
|
||||
"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": "uri-template format",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,53 @@
|
||||
[
|
||||
{
|
||||
"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": {
|
||||
"definitions": {
|
||||
"id_in_enum": {
|
||||
"enum": [
|
||||
{
|
||||
"$id": "https://localhost:1234/id/my_identifier.json",
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"real_id_in_schema": {
|
||||
"$id": "https://localhost:1234/id/my_identifier.json",
|
||||
"type": "string"
|
||||
},
|
||||
"zzz_id_in_const": {
|
||||
"const": {
|
||||
"$id": "https://localhost:1234/id/my_identifier.json",
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/id_in_enum" },
|
||||
{ "$ref": "https://localhost:1234/id/my_identifier.json" }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "exact match to enum, and type matches",
|
||||
"data": {
|
||||
"$id": "https://localhost:1234/id/my_identifier.json",
|
||||
"type": "null"
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "match $ref to id",
|
||||
"data": "a string to match #/definitions/id_in_enum",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "no match on enum or $ref to id",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
@@ -0,0 +1,258 @@
|
||||
[
|
||||
{
|
||||
"description": "ignore if without then or else",
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,36 @@
|
||||
[
|
||||
{
|
||||
"description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop",
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"int": { "type": "integer" }
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"$ref": "#/definitions/int"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/int"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "passing case",
|
||||
"data": { "foo": 1 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "failing case",
|
||||
"data": { "foo": "a string" },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,250 @@
|
||||
[
|
||||
{
|
||||
"description": "a schema given for items",
|
||||
"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": "an array of schemas for items",
|
||||
"schema": {
|
||||
"items": [
|
||||
{"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": "items with boolean schema (true)",
|
||||
"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": {"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 with boolean schemas",
|
||||
"schema": {
|
||||
"items": [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": "items and subitems",
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"item": {
|
||||
"type": "array",
|
||||
"additionalItems": false,
|
||||
"items": [
|
||||
{ "$ref": "#/definitions/sub-item" },
|
||||
{ "$ref": "#/definitions/sub-item" }
|
||||
]
|
||||
},
|
||||
"sub-item": {
|
||||
"type": "object",
|
||||
"required": ["foo"]
|
||||
}
|
||||
},
|
||||
"type": "array",
|
||||
"additionalItems": false,
|
||||
"items": [
|
||||
{ "$ref": "#/definitions/item" },
|
||||
{ "$ref": "#/definitions/item" },
|
||||
{ "$ref": "#/definitions/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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"description": "maxItems validation",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
[
|
||||
{
|
||||
"description": "maxLength validation",
|
||||
"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 supplementary Unicode code points is long enough",
|
||||
"data": "\uD83D\uDCA9\uD83D\uDCA9",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
[
|
||||
{
|
||||
"description": "maxProperties validation",
|
||||
"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 = 0 means the object is empty",
|
||||
"schema": { "maxProperties": 0 },
|
||||
"tests": [
|
||||
{
|
||||
"description": "no properties is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "one property is invalid",
|
||||
"data": { "foo": 1 },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
[
|
||||
{
|
||||
"description": "maximum validation",
|
||||
"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": {"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"description": "minItems validation",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
[
|
||||
{
|
||||
"description": "minLength validation",
|
||||
"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 supplementary Unicode code point is not long enough",
|
||||
"data": "\uD83D\uDCA9",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"description": "minProperties validation",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,69 @@
|
||||
[
|
||||
{
|
||||
"description": "minimum validation",
|
||||
"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": {"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,71 @@
|
||||
[
|
||||
{
|
||||
"description": "by int",
|
||||
"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": {"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": {"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": "invalid instance should not raise error when float division = inf",
|
||||
"schema": {"type": "integer", "multipleOf": 0.123456789},
|
||||
"tests": [
|
||||
{
|
||||
"description": "always invalid, but naive implementations may raise an overflow error",
|
||||
"data": 1e308,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,117 @@
|
||||
[
|
||||
{
|
||||
"description": "not",
|
||||
"schema": {
|
||||
"not": {"type": "integer"}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allowed",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "disallowed",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "not multiple types",
|
||||
"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": {
|
||||
"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": {
|
||||
"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": "not with boolean schema true",
|
||||
"schema": {"not": true},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "not with boolean schema false",
|
||||
"schema": {"not": false},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,274 @@
|
||||
[
|
||||
{
|
||||
"description": "oneOf",
|
||||
"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": {
|
||||
"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": {"oneOf": [true, true, true]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, one true",
|
||||
"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": {"oneOf": [true, true, false]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, all false",
|
||||
"schema": {"oneOf": [false, false, false]},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf complex types",
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"oneOf": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "anything non-null is invalid",
|
||||
"data": 123,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,93 @@
|
||||
[
|
||||
{
|
||||
"description": "integer",
|
||||
"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": { "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": { "type": "string" },
|
||||
"tests": [
|
||||
{
|
||||
"description": "a bignum is not a string",
|
||||
"data": 98249283749234923498293171823948729348710298301928331,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "integer comparison",
|
||||
"schema": { "maximum": 18446744073709551615 },
|
||||
"tests": [
|
||||
{
|
||||
"description": "comparison works for high numbers",
|
||||
"data": 18446744073709551600,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "float comparison with high precision",
|
||||
"schema": {
|
||||
"exclusiveMaximum": 972783798187987123879878123.18878137
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "comparison works for high numbers",
|
||||
"data": 972783798187987123879878123.188781371,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "integer comparison",
|
||||
"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": {
|
||||
"exclusiveMinimum": -972783798187987123879878123.18878137
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "comparison works for very negative numbers",
|
||||
"data": -972783798187987123879878123.188781371,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,77 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of string-encoded content based on media type",
|
||||
"schema": {
|
||||
"contentMediaType": "application/json"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid JSON document",
|
||||
"data": "{\"foo\": \"bar\"}",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid JSON document",
|
||||
"data": "{:}",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 100,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validation of binary string-encoding",
|
||||
"schema": {
|
||||
"contentEncoding": "base64"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid base64 string",
|
||||
"data": "eyJmb28iOiAiYmFyIn0K",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an invalid base64 string (% is not a valid character)",
|
||||
"data": "eyJmb28iOi%iYmFyIn0K",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 100,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validation of binary-encoded media type documents",
|
||||
"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",
|
||||
"data": "ezp9Cg==",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid base64 string that is valid JSON",
|
||||
"data": "{}",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ignores non-strings",
|
||||
"data": 100,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,292 @@
|
||||
[
|
||||
{
|
||||
"description": "ECMA 262 regex $ does not match trailing newline",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"pattern": "^abc$"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches in Python, but should not in jsonschema",
|
||||
"data": "abc\\n",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "should match",
|
||||
"data": "abc",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ECMA 262 regex converts \\t to horizontal tab",
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,13 @@
|
||||
[
|
||||
{
|
||||
"description": "all integers are multiples of 0.5, if overflow is handled",
|
||||
"schema": {"type": "integer", "multipleOf": 0.5},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid if optional overflow handling is implemented",
|
||||
"data": 1e308,
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,73 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of date-time strings",
|
||||
"schema": {"format": "date-time"},
|
||||
"tests": [
|
||||
{
|
||||
"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 invalid day in date-time string",
|
||||
"data": "1990-02-31T15:59:60.123-08:00",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "an invalid offset in date-time string",
|
||||
"data": "1990-12-31T15:59:60-24:00",
|
||||
"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": "non-ascii digits should be rejected in the date portion",
|
||||
"data": "1963-06-1৪T00:00:00Z",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-ascii digits should be rejected in the time portion",
|
||||
"data": "1963-06-11T0৪:00:00Z",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,193 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of date strings",
|
||||
"schema": {"format": "date"},
|
||||
"tests": [
|
||||
{
|
||||
"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": "non-ascii digits should be rejected",
|
||||
"data": "1963-06-1৪",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,53 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of e-mail addresses",
|
||||
"schema": {"format": "email"},
|
||||
"tests": [
|
||||
{
|
||||
"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": "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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,68 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of host names",
|
||||
"schema": {"format": "hostname"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid host name",
|
||||
"data": "www.example.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a valid punycoded IDN hostname",
|
||||
"data": "xn--4gbwdl.xn--wgbh1c",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a host name starting with an illegal character",
|
||||
"data": "-a-host-name-that-starts-with--",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a host name containing illegal characters",
|
||||
"data": "not_a_valid_host_name",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "a host name with a component too long",
|
||||
"data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "starts with hyphen",
|
||||
"data": "-hostname",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ends with hyphen",
|
||||
"data": "hostname-",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "starts with underscore",
|
||||
"data": "_hostname",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "ends with underscore",
|
||||
"data": "hostname_",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "contains underscore",
|
||||
"data": "host_name",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "maximum label length",
|
||||
"data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "exceeds maximum label length",
|
||||
"data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of an internationalized e-mail addresses",
|
||||
"schema": {"format": "idn-email"},
|
||||
"tests": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,274 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of internationalized host names",
|
||||
"schema": {"format": "idn-hostname"},
|
||||
"tests": [
|
||||
{
|
||||
"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/rfc/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": "\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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of IP addresses",
|
||||
"schema": {"format": "ipv4"},
|
||||
"tests": [
|
||||
{
|
||||
"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": "leading zeroes should be rejected, 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": "non-ascii digits should be rejected",
|
||||
"data": "1২7.0.0.1",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,163 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of IPv6 addresses",
|
||||
"schema": {"format": "ipv6"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid IPv6 address",
|
||||
"data": "::1",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "an IPv6 address with out-of-range values",
|
||||
"data": "12345::",
|
||||
"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": "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": "non-ascii digits should be rejected",
|
||||
"data": "1:2:3:4:5:6:7:৪",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "non-ascii digits should be rejected in the ipv4 portion also",
|
||||
"data": "1:2::192.16৪.0.1",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,43 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of IRI References",
|
||||
"schema": {"format": "iri-reference"},
|
||||
"tests": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,53 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of IRIs",
|
||||
"schema": {"format": "iri"},
|
||||
"tests": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,168 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of JSON-pointers (JSON String Representation)",
|
||||
"schema": {"format": "json-pointer"},
|
||||
"tests": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of regular expressions",
|
||||
"schema": {"format": "regex"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid regular expression",
|
||||
"data": "([abc])+\\s+$",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "a regular expression with unclosed parens is invalid",
|
||||
"data": "^(abc]",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,53 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of Relative JSON Pointers (RJP)",
|
||||
"schema": {"format": "relative-json-pointer"},
|
||||
"tests": [
|
||||
{
|
||||
"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": "## 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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,168 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of time strings",
|
||||
"schema": {"format": "time"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "a valid time string",
|
||||
"data": "08:30:06Z",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"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": "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": "non-ascii digits should be rejected",
|
||||
"data": "1২:00:00Z",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,43 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of URI References",
|
||||
"schema": {"format": "uri-reference"},
|
||||
"tests": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"description": "format: uri-template",
|
||||
"schema": {"format": "uri-template"},
|
||||
"tests": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,108 @@
|
||||
[
|
||||
{
|
||||
"description": "validation of URIs",
|
||||
"schema": {"format": "uri"},
|
||||
"tests": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,85 @@
|
||||
[
|
||||
{
|
||||
"description": "uuid format",
|
||||
"schema": {
|
||||
"format": "uuid"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"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": "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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"description": "Proper UTF-16 surrogate pair handling: pattern",
|
||||
"comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters",
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,146 @@
|
||||
[
|
||||
{
|
||||
"description": "unicode semantics should be used for all pattern matching",
|
||||
"schema": { "pattern": "\\wcole" },
|
||||
"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": 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": "unicode characters do not match ascii ranges",
|
||||
"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": "unicode digits are more than 0 through 9",
|
||||
"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": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "unicode semantics should be used for all patternProperties matching",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"\\wcole": true
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"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": "unicode characters do not match ascii ranges",
|
||||
"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": "unicode digits are more than 0 through 9",
|
||||
"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": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,59 @@
|
||||
[
|
||||
{
|
||||
"description": "pattern validation",
|
||||
"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": {"pattern": "a+"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches a substring",
|
||||
"data": "xxaayy",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,156 @@
|
||||
[
|
||||
{
|
||||
"description":
|
||||
"patternProperties validates properties matching a regex",
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,167 @@
|
||||
[
|
||||
{
|
||||
"description": "object properties validation",
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,107 @@
|
||||
[
|
||||
{
|
||||
"description": "propertyNames validation",
|
||||
"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": {
|
||||
"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": {"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": {"propertyNames": false},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with any properties is invalid",
|
||||
"data": {"foo": 1},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "empty object is valid",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,612 @@
|
||||
[
|
||||
{
|
||||
"description": "root pointer ref",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"foo": {"$ref": "#"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match",
|
||||
"data": {"foo": false},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "recursive match",
|
||||
"data": {"foo": {"foo": false}},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": {"bar": false},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "recursive mismatch",
|
||||
"data": {"foo": {"bar": false}},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "relative pointer ref to object",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"foo": {"type": "integer"},
|
||||
"bar": {"$ref": "#/properties/foo"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match",
|
||||
"data": {"bar": 3},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch",
|
||||
"data": {"bar": true},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "relative pointer ref to array",
|
||||
"schema": {
|
||||
"items": [
|
||||
{"type": "integer"},
|
||||
{"$ref": "#/items/0"}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "match array",
|
||||
"data": [1, 2],
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "mismatch array",
|
||||
"data": [1, "foo"],
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "escaped pointer ref",
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"tilde~field": {"type": "integer"},
|
||||
"slash/field": {"type": "integer"},
|
||||
"percent%field": {"type": "integer"}
|
||||
},
|
||||
"properties": {
|
||||
"tilde": {"$ref": "#/definitions/tilde~0field"},
|
||||
"slash": {"$ref": "#/definitions/slash~1field"},
|
||||
"percent": {"$ref": "#/definitions/percent%25field"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "slash invalid",
|
||||
"data": {"slash": "aoeu"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "tilde invalid",
|
||||
"data": {"tilde": "aoeu"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "percent invalid",
|
||||
"data": {"percent": "aoeu"},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "slash valid",
|
||||
"data": {"slash": 123},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "tilde valid",
|
||||
"data": {"tilde": 123},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "percent valid",
|
||||
"data": {"percent": 123},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nested refs",
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"a": {"type": "integer"},
|
||||
"b": {"$ref": "#/definitions/a"},
|
||||
"c": {"$ref": "#/definitions/b"}
|
||||
},
|
||||
"allOf": [{ "$ref": "#/definitions/c" }]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "nested ref valid",
|
||||
"data": 5,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "nested ref invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ref overrides any sibling keywords",
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"reffed": {
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"foo": {
|
||||
"$ref": "#/definitions/reffed",
|
||||
"maxItems": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ref valid",
|
||||
"data": { "foo": [] },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ref valid, maxItems ignored",
|
||||
"data": { "foo": [ 1, 2, 3] },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "ref invalid",
|
||||
"data": { "foo": "string" },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref prevents a sibling $id from changing the base uri",
|
||||
"schema": {
|
||||
"$id": "http://localhost:1234/sibling_id/base/",
|
||||
"definitions": {
|
||||
"foo": {
|
||||
"$id": "http://localhost:1234/sibling_id/foo.json",
|
||||
"minimum": 2
|
||||
},
|
||||
"base_foo": {
|
||||
"$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json",
|
||||
"$id": "foo.json",
|
||||
"minimum": 5
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not ttp://localhost:1234/sibling_id/foo.json",
|
||||
"$id": "http://localhost:1234/sibling_id/",
|
||||
"$ref": "foo.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "$ref resolves to /definitions/foo, data validates",
|
||||
"data": 10,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "$ref resolves to /definitions/foo, data does not validate",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "remote ref, containing refs itself",
|
||||
"schema": {"$ref": "http://json-schema.org/draft-07/schema#"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "remote ref valid",
|
||||
"data": {"minLength": 1},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "remote ref invalid",
|
||||
"data": {"minLength": -1},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "property named $ref that is not a reference",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"$ref": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "property named $ref valid",
|
||||
"data": {"$ref": "a"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "property named $ref invalid",
|
||||
"data": {"$ref": 2},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "property named $ref, containing an actual $ref",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"$ref": {"$ref": "#/definitions/is-string"}
|
||||
},
|
||||
"definitions": {
|
||||
"is-string": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "property named $ref valid",
|
||||
"data": {"$ref": "a"},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "property named $ref invalid",
|
||||
"data": {"$ref": 2},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref to boolean schema true",
|
||||
"schema": {
|
||||
"allOf": [{ "$ref": "#/definitions/bool" }],
|
||||
"definitions": {
|
||||
"bool": true
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref to boolean schema false",
|
||||
"schema": {
|
||||
"allOf": [{ "$ref": "#/definitions/bool" }],
|
||||
"definitions": {
|
||||
"bool": false
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Recursive references between schemas",
|
||||
"schema": {
|
||||
"$id": "http://localhost:1234/tree",
|
||||
"description": "tree of nodes",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"meta": {"type": "string"},
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "node"}
|
||||
}
|
||||
},
|
||||
"required": ["meta", "nodes"],
|
||||
"definitions": {
|
||||
"node": {
|
||||
"$id": "http://localhost:1234/node",
|
||||
"description": "node",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {"type": "number"},
|
||||
"subtree": {"$ref": "tree"}
|
||||
},
|
||||
"required": ["value"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid tree",
|
||||
"data": {
|
||||
"meta": "root",
|
||||
"nodes": [
|
||||
{
|
||||
"value": 1,
|
||||
"subtree": {
|
||||
"meta": "child",
|
||||
"nodes": [
|
||||
{"value": 1.1},
|
||||
{"value": 1.2}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 2,
|
||||
"subtree": {
|
||||
"meta": "child",
|
||||
"nodes": [
|
||||
{"value": 2.1},
|
||||
{"value": 2.2}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid tree",
|
||||
"data": {
|
||||
"meta": "root",
|
||||
"nodes": [
|
||||
{
|
||||
"value": 1,
|
||||
"subtree": {
|
||||
"meta": "child",
|
||||
"nodes": [
|
||||
{"value": "string is invalid"},
|
||||
{"value": 1.2}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 2,
|
||||
"subtree": {
|
||||
"meta": "child",
|
||||
"nodes": [
|
||||
{"value": 2.1},
|
||||
{"value": 2.2}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "refs with quote",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"foo\"bar": {"$ref": "#/definitions/foo%22bar"}
|
||||
},
|
||||
"definitions": {
|
||||
"foo\"bar": {"type": "number"}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with numbers is valid",
|
||||
"data": {
|
||||
"foo\"bar": 1
|
||||
},
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "object with strings is invalid",
|
||||
"data": {
|
||||
"foo\"bar": "1"
|
||||
},
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Location-independent identifier",
|
||||
"schema": {
|
||||
"allOf": [{
|
||||
"$ref": "#foo"
|
||||
}],
|
||||
"definitions": {
|
||||
"A": {
|
||||
"$id": "#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": {
|
||||
"$id": "http://localhost:1234/root",
|
||||
"allOf": [{
|
||||
"$ref": "http://localhost:1234/nested.json#foo"
|
||||
}],
|
||||
"definitions": {
|
||||
"A": {
|
||||
"$id": "nested.json",
|
||||
"definitions": {
|
||||
"B": {
|
||||
"$id": "#foo",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"data": 1,
|
||||
"description": "match",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"data": "a",
|
||||
"description": "mismatch",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "naive replacement of $ref with its destination is not correct",
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"a_string": { "type": "string" }
|
||||
},
|
||||
"enum": [
|
||||
{ "$ref": "#/definitions/a_string" }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "do not evaluate the $ref inside the enum, matching any string",
|
||||
"data": "this is a string",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "do not evaluate the $ref inside the enum, definition exact match",
|
||||
"data": { "type": "string" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "match the enum exactly",
|
||||
"data": { "$ref": "#/definitions/a_string" },
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "refs with relative uris and defs",
|
||||
"schema": {
|
||||
"$id": "http://example.com/schema-relative-uri-defs1.json",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"$id": "schema-relative-uri-defs2.json",
|
||||
"definitions": {
|
||||
"inner": {
|
||||
"properties": {
|
||||
"bar": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"allOf": [ { "$ref": "#/definitions/inner" } ]
|
||||
}
|
||||
},
|
||||
"allOf": [ { "$ref": "schema-relative-uri-defs2.json" } ]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid on inner field",
|
||||
"data": {
|
||||
"foo": {
|
||||
"bar": 1
|
||||
},
|
||||
"bar": "a"
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid on outer field",
|
||||
"data": {
|
||||
"foo": {
|
||||
"bar": "a"
|
||||
},
|
||||
"bar": 1
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid on both fields",
|
||||
"data": {
|
||||
"foo": {
|
||||
"bar": "a"
|
||||
},
|
||||
"bar": "a"
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "relative refs with absolute uris and defs",
|
||||
"schema": {
|
||||
"$id": "http://example.com/schema-refs-absolute-uris-defs1.json",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"$id": "http://example.com/schema-refs-absolute-uris-defs2.json",
|
||||
"definitions": {
|
||||
"inner": {
|
||||
"properties": {
|
||||
"bar": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"allOf": [ { "$ref": "#/definitions/inner" } ]
|
||||
}
|
||||
},
|
||||
"allOf": [ { "$ref": "schema-refs-absolute-uris-defs2.json" } ]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid on inner field",
|
||||
"data": {
|
||||
"foo": {
|
||||
"bar": 1
|
||||
},
|
||||
"bar": "a"
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid on outer field",
|
||||
"data": {
|
||||
"foo": {
|
||||
"bar": "a"
|
||||
},
|
||||
"bar": 1
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid on both fields",
|
||||
"data": {
|
||||
"foo": {
|
||||
"bar": "a"
|
||||
},
|
||||
"bar": "a"
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,196 @@
|
||||
[
|
||||
{
|
||||
"description": "remote ref",
|
||||
"schema": {"$ref": "http://localhost:1234/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": {"$ref": "http://localhost:1234/subSchemas.json#/integer"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "remote fragment valid",
|
||||
"data": 1,
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "remote fragment invalid",
|
||||
"data": "a",
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ref within remote ref",
|
||||
"schema": {
|
||||
"$ref": "http://localhost:1234/subSchemas.json#/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": {
|
||||
"$id": "http://localhost:1234/",
|
||||
"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": {
|
||||
"$id": "http://localhost:1234/scope_change_defs1.json",
|
||||
"type" : "object",
|
||||
"properties": {
|
||||
"list": {"$ref": "#/definitions/baz"}
|
||||
},
|
||||
"definitions": {
|
||||
"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": {
|
||||
"$id": "http://localhost:1234/scope_change_defs2.json",
|
||||
"type" : "object",
|
||||
"properties": {
|
||||
"list": {"$ref": "#/definitions/baz/definitions/bar"}
|
||||
},
|
||||
"definitions": {
|
||||
"baz": {
|
||||
"$id": "baseUriChangeFolderInSubschema/",
|
||||
"definitions": {
|
||||
"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": {
|
||||
"$id": "http://localhost:1234/object",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"$ref": "name.json#/definitions/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 definitions",
|
||||
"schema": {
|
||||
"$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json",
|
||||
"allOf": [
|
||||
{ "$ref": "ref-and-definitions.json" }
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid",
|
||||
"data": {
|
||||
"bar": 1
|
||||
},
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "valid",
|
||||
"data": {
|
||||
"bar": "a"
|
||||
},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,105 @@
|
||||
[
|
||||
{
|
||||
"description": "required validation",
|
||||
"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": {
|
||||
"properties": {
|
||||
"foo": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "not required by default",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "required with empty array",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"foo": {}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "property not required",
|
||||
"data": {},
|
||||
"valid": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "required with escaped characters",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,469 @@
|
||||
[
|
||||
{
|
||||
"description": "integer type matches integers",
|
||||
"schema": {"type": "integer"},
|
||||
"tests": [
|
||||
{
|
||||
"description": "an integer is an integer",
|
||||
"data": 1,
|
||||
"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": {"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": {"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": {"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": {"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": {"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": {"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": {"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,384 @@
|
||||
[
|
||||
{
|
||||
"description": "uniqueItems validation",
|
||||
"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": "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 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": "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": "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": {
|
||||
"items": [{"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": {
|
||||
"items": [{"type": "boolean"}, {"type": "boolean"}],
|
||||
"uniqueItems": true,
|
||||
"additionalItems": 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": { "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": {
|
||||
"items": [{"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": {
|
||||
"items": [{"type": "boolean"}, {"type": "boolean"}],
|
||||
"uniqueItems": false,
|
||||
"additionalItems": 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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,56 @@
|
||||
[
|
||||
{
|
||||
"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": {
|
||||
"definitions": {
|
||||
"id_in_unknown0": {
|
||||
"not": {
|
||||
"array_of_schemas": [
|
||||
{
|
||||
"$id": "https://localhost:1234/unknownKeyword/my_identifier.json",
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"real_id_in_schema": {
|
||||
"$id": "https://localhost:1234/unknownKeyword/my_identifier.json",
|
||||
"type": "string"
|
||||
},
|
||||
"id_in_unknown1": {
|
||||
"not": {
|
||||
"object_of_schemas": {
|
||||
"foo": {
|
||||
"$id": "https://localhost:1234/unknownKeyword/my_identifier.json",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/id_in_unknown0" },
|
||||
{ "$ref": "#/definitions/id_in_unknown1" },
|
||||
{ "$ref": "https://localhost:1234/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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
175
lib/All/json-schema-validator/test/binary-validation.cpp
Normal file
175
lib/All/json-schema-validator/test/binary-validation.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
// bson-validate.cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
static int error_count = 0;
|
||||
|
||||
#define EXPECT_EQ(a, b) \
|
||||
do { \
|
||||
if (a != b) { \
|
||||
std::cerr << "Failed: '" << a << "' != '" << b << "'\n"; \
|
||||
error_count++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_THROW(foo) \
|
||||
{ \
|
||||
bool ok = false; \
|
||||
try { \
|
||||
foo; \
|
||||
} catch (std::exception &) { \
|
||||
ok = true; \
|
||||
} \
|
||||
if (ok == false) { \
|
||||
error_count++; \
|
||||
} \
|
||||
}
|
||||
|
||||
using json = nlohmann::json;
|
||||
using validator = nlohmann::json_schema::json_validator;
|
||||
|
||||
// check binary data validation
|
||||
const json bson_schema = json::parse(R"(
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"standard_string": {
|
||||
"type": "string"
|
||||
},
|
||||
"binary_data": {
|
||||
"type": "string",
|
||||
"contentEncoding": "binary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
)");
|
||||
|
||||
const json array_of_types = json::parse(R"(
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"something": {
|
||||
"type": ["string", "number", "boolean"],
|
||||
"contentEncoding": "binary"
|
||||
}
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
const json array_of_types_without_binary = json::parse(R"(
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"something": {
|
||||
"type": ["string", "number", "boolean"]
|
||||
}
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
class store_ptr_err_handler : public nlohmann::json_schema::basic_error_handler
|
||||
{
|
||||
void error(const nlohmann::json::json_pointer &ptr, const json &, const std::string &message) override
|
||||
{
|
||||
nlohmann::json_schema::basic_error_handler::error(ptr, "", message);
|
||||
std::cerr << "ERROR: '" << ptr << "' - '"
|
||||
<< ""
|
||||
<< "': " << message << "\n";
|
||||
failed_pointers.push_back(ptr);
|
||||
}
|
||||
|
||||
public:
|
||||
std::vector<nlohmann::json::json_pointer> failed_pointers;
|
||||
|
||||
void reset() override
|
||||
{
|
||||
nlohmann::json_schema::basic_error_handler::reset();
|
||||
failed_pointers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
static void content(const std::string &contentEncoding, const std::string &contentMediaType, const json &instance)
|
||||
{
|
||||
std::cerr << "mediaType: '" << contentMediaType << "', encoding: '" << contentEncoding << "'\n";
|
||||
|
||||
if (contentEncoding == "binary") {
|
||||
if (instance.type() != json::value_t::binary) {
|
||||
throw std::invalid_argument{"expected binary data"};
|
||||
}
|
||||
} else {
|
||||
if (instance.type() == json::value_t::binary) {
|
||||
throw std::invalid_argument{"expected string, but get binary"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
validator val(nullptr, nullptr, content);
|
||||
|
||||
// create some bson doc
|
||||
json::binary_t arr;
|
||||
std::string as_binary = "hello world";
|
||||
std::copy(as_binary.begin(), as_binary.end(), std::back_inserter(arr));
|
||||
|
||||
json binary = json::binary(arr);
|
||||
|
||||
store_ptr_err_handler err;
|
||||
|
||||
/////////////////////////////////////
|
||||
val.set_root_schema(bson_schema);
|
||||
|
||||
// all right
|
||||
val.validate({{"standard_string", "some string"}, {"binary_data", binary}}, err);
|
||||
EXPECT_EQ(err.failed_pointers.size(), 0);
|
||||
err.reset();
|
||||
|
||||
// invalid binary data
|
||||
val.validate({{"binary_data", "string, but expect binary data"}}, err);
|
||||
EXPECT_EQ(err.failed_pointers.size(), 1);
|
||||
EXPECT_EQ(err.failed_pointers[0].to_string(), "/binary_data");
|
||||
err.reset();
|
||||
|
||||
// also check that simple string not accept binary data
|
||||
val.validate({{"standard_string", binary}, {"binary_data", binary}}, err);
|
||||
EXPECT_EQ(err.failed_pointers.size(), 1);
|
||||
EXPECT_EQ(err.failed_pointers[0].to_string(), "/standard_string");
|
||||
err.reset();
|
||||
|
||||
/////////////////////////////////////
|
||||
// check with array of types
|
||||
|
||||
// check simple types
|
||||
val.set_root_schema(array_of_types);
|
||||
val.validate({{"something", 1}}, err);
|
||||
val.validate({{"something", false}}, err);
|
||||
// TODO when we set `string` in array and set `contentEncoding` = "binary" - what it means? We expected string or binary?
|
||||
// Or we expect only binary? Now if you set `contentEncoding` = "binary", then it means that you expect only binary data,
|
||||
// not string
|
||||
// val.validate({{"something", "string"}}, err); -> produce error about type
|
||||
EXPECT_EQ(err.failed_pointers.size(), 0);
|
||||
err.reset();
|
||||
|
||||
// check binary data
|
||||
val.validate({{"something", binary}}, err);
|
||||
EXPECT_EQ(err.failed_pointers.size(), 0);
|
||||
err.reset();
|
||||
|
||||
/////////////////////////////////////
|
||||
// and check that you can't set binary data if contentEncoding don't set
|
||||
val.set_root_schema(array_of_types_without_binary);
|
||||
val.validate({{"something", binary}}, err);
|
||||
EXPECT_EQ(err.failed_pointers.size(), 1);
|
||||
EXPECT_EQ(err.failed_pointers[0].to_string(), "/something");
|
||||
err.reset();
|
||||
|
||||
// check that without content callback you get exception with schema with contentEncoding or contentMeditType
|
||||
validator val_no_content;
|
||||
|
||||
EXPECT_THROW(val_no_content.set_root_schema(bson_schema));
|
||||
|
||||
return error_count;
|
||||
}
|
||||
130
lib/All/json-schema-validator/test/errors.cpp
Normal file
130
lib/All/json-schema-validator/test/errors.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
static int error_count;
|
||||
|
||||
#define EXPECT_EQ(a, b) \
|
||||
do { \
|
||||
if (a != b) { \
|
||||
std::cerr << "Failed: '" << a << "' != '" << b << "'\n"; \
|
||||
error_count++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
using nlohmann::json;
|
||||
using nlohmann::json_schema::json_validator;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// The schema is defined based upon a string literal
|
||||
static json person_schema = R"(
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "A person",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Name",
|
||||
"type": "string"
|
||||
},
|
||||
"age": {
|
||||
"description": "Age of the person",
|
||||
"type": "number",
|
||||
"minimum": 2,
|
||||
"maximum": 200
|
||||
},
|
||||
"phones": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"age"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
})"_json;
|
||||
|
||||
class store_ptr_err_handler : public nlohmann::json_schema::basic_error_handler
|
||||
{
|
||||
void error(const nlohmann::json::json_pointer &ptr, const json &instance, const std::string &message) override
|
||||
{
|
||||
nlohmann::json_schema::basic_error_handler::error(ptr, instance, message);
|
||||
std::cerr << "ERROR: '" << ptr << "' - '" << instance << "': " << message << "\n";
|
||||
failed_pointers.push_back(ptr);
|
||||
}
|
||||
|
||||
public:
|
||||
std::vector<nlohmann::json::json_pointer> failed_pointers;
|
||||
|
||||
void reset() override
|
||||
{
|
||||
nlohmann::json_schema::basic_error_handler::reset();
|
||||
failed_pointers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(void)
|
||||
{
|
||||
json_validator validator;
|
||||
|
||||
try {
|
||||
validator.set_root_schema(person_schema); // insert root-schema
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Validation of schema failed, here is why: " << e.what() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
store_ptr_err_handler err;
|
||||
|
||||
validator.validate({{"age", 42}, {"name", "John"}}, err); // OK
|
||||
EXPECT_EQ(err.failed_pointers.size(), 0);
|
||||
err.reset();
|
||||
|
||||
validator.validate({{"age", 42}}, err); // no name
|
||||
|
||||
EXPECT_EQ(err.failed_pointers.size(), 1);
|
||||
EXPECT_EQ(err.failed_pointers[0].to_string(), "");
|
||||
err.reset();
|
||||
|
||||
validator.validate({{"street", "Boulevard"}}, err); // no name and no age
|
||||
EXPECT_EQ(err.failed_pointers.size(), 3);
|
||||
EXPECT_EQ(err.failed_pointers[0].to_string(), "");
|
||||
EXPECT_EQ(err.failed_pointers[1].to_string(), "");
|
||||
EXPECT_EQ(err.failed_pointers[2].to_string(), "");
|
||||
err.reset();
|
||||
|
||||
validator.validate({{"age", 42}, {"name", 12}}, err); // name must be a string
|
||||
EXPECT_EQ(err.failed_pointers.size(), 1);
|
||||
EXPECT_EQ(err.failed_pointers[0].to_string(), "/name");
|
||||
err.reset();
|
||||
|
||||
validator.validate({
|
||||
{"age", 42},
|
||||
{"name", "John"},
|
||||
{"phones", {1234, "223"}},
|
||||
},
|
||||
err); // name must be a string
|
||||
EXPECT_EQ(err.failed_pointers.size(), 1);
|
||||
EXPECT_EQ(err.failed_pointers[0].to_string(), "/phones/1");
|
||||
err.reset();
|
||||
|
||||
validator.validate({
|
||||
{"age", 42},
|
||||
{"name", "John"},
|
||||
{"phones", {0}},
|
||||
{"post-code", 12345},
|
||||
},
|
||||
err); // name must be a string
|
||||
EXPECT_EQ(err.failed_pointers.size(), 1);
|
||||
EXPECT_EQ(err.failed_pointers[0].to_string(), "");
|
||||
err.reset();
|
||||
|
||||
return error_count;
|
||||
}
|
||||
146
lib/All/json-schema-validator/test/id-ref.cpp
Normal file
146
lib/All/json-schema-validator/test/id-ref.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
auto schema_draft = R"(
|
||||
{
|
||||
"$id": "http://example.com/root.json",
|
||||
"definitions": {
|
||||
"A": { "$id": "#foo" },
|
||||
"B": {
|
||||
"$id": "other.json",
|
||||
"definitions": {
|
||||
"X": { "$id": "#bar" },
|
||||
"Y": { "$id": "t/inner.json" }
|
||||
}
|
||||
},
|
||||
"C": {
|
||||
|
||||
"$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f",
|
||||
"definitions": {
|
||||
"Z": { "$id": "#bar" },
|
||||
"9": { "$id": "http://example.com/drole.json" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)"_json;
|
||||
|
||||
/* # (document root)
|
||||
|
||||
http://example.com/root.json
|
||||
http://example.com/root.json#
|
||||
|
||||
#/definitions/A
|
||||
|
||||
http://example.com/root.json#foo
|
||||
http://example.com/root.json#/definitions/A
|
||||
|
||||
#/definitions/B
|
||||
|
||||
http://example.com/other.json
|
||||
http://example.com/other.json#
|
||||
http://example.com/root.json#/definitions/B
|
||||
|
||||
#/definitions/B/definitions/X
|
||||
|
||||
http://example.com/other.json#bar
|
||||
http://example.com/other.json#/definitions/X
|
||||
http://example.com/root.json#/definitions/B/definitions/X
|
||||
|
||||
#/definitions/B/definitions/Y
|
||||
|
||||
http://example.com/t/inner.json
|
||||
http://example.com/t/inner.json#
|
||||
http://example.com/other.json#/definitions/Y
|
||||
http://example.com/root.json#/definitions/B/definitions/Y
|
||||
|
||||
#/definitions/C
|
||||
|
||||
urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f
|
||||
urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#
|
||||
http://example.com/root.json#/definitions/C
|
||||
*/
|
||||
|
||||
auto schema = R"(
|
||||
{
|
||||
"id": "http://localhost:1234/scope_change_defs2.json",
|
||||
"type" : "object",
|
||||
"properties": {
|
||||
"list": {"$ref": "#/definitions/baz/definitions/bar"}
|
||||
},
|
||||
"definitions": {
|
||||
"baz": {
|
||||
"id": "folder/",
|
||||
"definitions": {
|
||||
"bar": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "folderInteger.json"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})"_json;
|
||||
|
||||
class json_schema_validator
|
||||
{
|
||||
public:
|
||||
std::vector<json> schemas_;
|
||||
std::map<nlohmann::json_uri, const json *> schema_store_;
|
||||
|
||||
public:
|
||||
void insert_schema(json &s, std::vector<nlohmann::json_uri> base_uris)
|
||||
{
|
||||
auto id = s.find("$id");
|
||||
if (id != s.end())
|
||||
base_uris.push_back(base_uris.back().derive(id.value()));
|
||||
|
||||
for (auto &u : base_uris)
|
||||
schema_store_[u] = &s;
|
||||
|
||||
for (auto i = s.begin();
|
||||
i != s.end();
|
||||
++i) {
|
||||
|
||||
switch (i.value().type()) {
|
||||
case json::value_t::object: { // child is object, thus a schema
|
||||
std::vector<nlohmann::json_uri> subschema_uri = base_uris;
|
||||
|
||||
for (auto &ss : subschema_uri)
|
||||
ss = ss.append(nlohmann::json_uri::escape(i.key()));
|
||||
|
||||
insert_schema(i.value(), subschema_uri);
|
||||
} break;
|
||||
|
||||
case json::value_t::string:
|
||||
// this schema is a reference
|
||||
if (i.key() == "$ref") {
|
||||
auto id = base_uris.back().derive(i.value());
|
||||
i.value() = id.to_string();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
json_schema_validator store;
|
||||
|
||||
store.insert_schema(schema_draft, {{"#"}});
|
||||
|
||||
for (auto &i : store.schema_store_) {
|
||||
std::cerr << i.first << " " << *i.second << "\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
add_test_simple_schema(Issue::100
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/schema.json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/instance.json)
|
||||
set_tests_properties(Issue::100
|
||||
PROPERTIES
|
||||
WILL_FAIL 1)
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"Prop1": 1,
|
||||
"Prop2": []
|
||||
}
|
||||
15
lib/All/json-schema-validator/test/issue-100/schema.json
Normal file
15
lib/All/json-schema-validator/test/issue-100/schema.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$id": "http://xxx.local/schemas/mySchema.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Prop1": {
|
||||
"type": "integer",
|
||||
"$comment": "Just a comment"
|
||||
},
|
||||
"Prop2": {
|
||||
"$ref": "#random_ref"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
add_test_simple_schema(Issue::101
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/schema.json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/instance.json)
|
||||
set_tests_properties(Issue::101
|
||||
PROPERTIES
|
||||
WILL_FAIL 1)
|
||||
@@ -0,0 +1 @@
|
||||
{"top": 1}
|
||||
12
lib/All/json-schema-validator/test/issue-101/schema.json
Normal file
12
lib/All/json-schema-validator/test/issue-101/schema.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$id": "http://xxx.local/schemas/mySchema.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"top": {
|
||||
"type": "integer"
|
||||
},
|
||||
"required": ["top"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
#include "nlohmann/json-schema.hpp"
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//==============================================================================
|
||||
// Test macros
|
||||
//==============================================================================
|
||||
#define LOG_ERROR(LOG_ERROR__ARGS) \
|
||||
std::cerr << __FILE__ << ":" << __LINE__ << ": " << LOG_ERROR__ARGS << std::endl
|
||||
|
||||
#define EXPECT_THROW_WITH_MESSAGE(EXPRESSION, MESSAGE) \
|
||||
do { \
|
||||
try { \
|
||||
EXPRESSION; \
|
||||
LOG_ERROR("Expected exception not thrown with matching regex: \"" << MESSAGE << "\""); \
|
||||
++g_error_count; \
|
||||
} catch (const std::exception &error) { \
|
||||
const std::regex error_re{MESSAGE}; \
|
||||
if (!std::regex_search(error.what(), error_re)) { \
|
||||
LOG_ERROR("Expected exception with matching regex: \"" << MESSAGE << "\", but got this instead: " << error.what()); \
|
||||
++g_error_count; \
|
||||
} \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define ASSERT_OR_EXPECT_EQ(FIRST_THING, SECOND_THING, RETURN_IN_CASE_OF_ERROR) \
|
||||
do { \
|
||||
if ((FIRST_THING) != (SECOND_THING)) { \
|
||||
LOG_ERROR("The two values of " << (FIRST_THING) << " (" #FIRST_THING << ") and " << (SECOND_THING) << " (" #SECOND_THING << ") should be equal"); \
|
||||
if (RETURN_IN_CASE_OF_ERROR) { \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define ASSERT_EQ(FIRST_THING, SECOND_THING) ASSERT_OR_EXPECT_EQ(FIRST_THING, SECOND_THING, true)
|
||||
#define EXPECT_EQ(FIRST_THING, SECOND_THING) ASSERT_OR_EXPECT_EQ(FIRST_THING, SECOND_THING, true)
|
||||
|
||||
#define EXPECT_MATCH(STRING, REGEX) \
|
||||
do { \
|
||||
if (!std::regex_search((STRING), std::regex{(REGEX)})) { \
|
||||
LOG_ERROR("String \"" << (STRING) << "\" doesn't match with regex: \"" << (REGEX) << "\""); \
|
||||
++g_error_count; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
// Test environment
|
||||
//==============================================================================
|
||||
int g_error_count = 0;
|
||||
|
||||
//==============================================================================
|
||||
// The schema used for testing
|
||||
//==============================================================================
|
||||
const std::string g_schema_template = R"(
|
||||
{
|
||||
"properties": {
|
||||
"first": {
|
||||
"%COMBINATION_FIRST_LEVEL%": [
|
||||
{
|
||||
"properties": {
|
||||
"second": {
|
||||
"%COMBINATION_SECOND_LEVEL%": [
|
||||
{
|
||||
"minimum": 5,
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"multipleOf": 2,
|
||||
"type": "integer"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"minimum": 20,
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"minLength": 10,
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
)";
|
||||
|
||||
auto generateSchema(const std::string &first_combination, const std::string &second_combination) -> nlohmann::json
|
||||
{
|
||||
static const std::regex first_replace_re{"%COMBINATION_FIRST_LEVEL%"};
|
||||
static const std::regex second_replace_re{"%COMBINATION_SECOND_LEVEL%"};
|
||||
|
||||
std::string intermediate = std::regex_replace(g_schema_template, first_replace_re, first_combination);
|
||||
|
||||
return nlohmann::json::parse(std::regex_replace(intermediate, second_replace_re, second_combination));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Error handler to catch all the errors generated by the validator - also inside the combinations
|
||||
//==============================================================================
|
||||
class MyErrorHandler : public nlohmann::json_schema::error_handler
|
||||
{
|
||||
public:
|
||||
struct ErrorEntry {
|
||||
nlohmann::json::json_pointer ptr;
|
||||
nlohmann::json intance;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
using ErrorEntryList = std::vector<ErrorEntry>;
|
||||
|
||||
auto getErrors() const -> const ErrorEntryList &
|
||||
{
|
||||
return m_error_list;
|
||||
}
|
||||
|
||||
private:
|
||||
auto error(const nlohmann::json::json_pointer &ptr, const nlohmann::json &instance, const std::string &message) -> void override
|
||||
{
|
||||
m_error_list.push_back(ErrorEntry{ptr, instance, message});
|
||||
}
|
||||
|
||||
ErrorEntryList m_error_list;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Error string helpers
|
||||
//==============================================================================
|
||||
auto operator<<(std::string first, const std::string &second) -> std::string
|
||||
{
|
||||
first += ".*";
|
||||
first += second;
|
||||
return first;
|
||||
}
|
||||
|
||||
auto rootError(const std::string &combination_type, std::size_t number_of_subschemas) -> std::string
|
||||
{
|
||||
return "no subschema has succeeded, but one of them is required to validate. Type: " + combination_type + ", number of failed subschemas: " + std::to_string(number_of_subschemas);
|
||||
}
|
||||
|
||||
auto combinationError(const std::string &combination_type, std::size_t test_case_number) -> std::string
|
||||
{
|
||||
return "[combination: " + combination_type + " / case#" + std::to_string(test_case_number) + "]";
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Validator function - for simplicity
|
||||
//==============================================================================
|
||||
auto validate(const nlohmann::json &schema, const nlohmann::json &instance, nlohmann::json_schema::error_handler *error_handler = nullptr) -> void
|
||||
{
|
||||
nlohmann::json_schema::json_validator validator;
|
||||
validator.set_root_schema(schema);
|
||||
|
||||
if (error_handler) {
|
||||
validator.validate(instance, *error_handler);
|
||||
} else {
|
||||
validator.validate(instance);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// The test cases
|
||||
//==============================================================================
|
||||
auto simpleTest(const std::string &first_combination, const std::string &second_combination) -> void
|
||||
{
|
||||
const nlohmann::json schema = generateSchema(first_combination, second_combination);
|
||||
EXPECT_THROW_WITH_MESSAGE(validate(schema, nlohmann::json{{"first", {{"second", 1}}}}), rootError(first_combination, 3));
|
||||
if (second_combination == "oneOf") {
|
||||
EXPECT_THROW_WITH_MESSAGE(validate(schema, nlohmann::json{{"first", {{"second", 8}}}}), rootError(first_combination, 3));
|
||||
}
|
||||
EXPECT_THROW_WITH_MESSAGE(validate(schema, nlohmann::json{{"first", 10}}), rootError(first_combination, 3));
|
||||
EXPECT_THROW_WITH_MESSAGE(validate(schema, nlohmann::json{{"first", "short"}}), rootError(first_combination, 3));
|
||||
}
|
||||
|
||||
auto verboseTest(const std::string &first_combination, const std::string &second_combination) -> void
|
||||
{
|
||||
const nlohmann::json schema = generateSchema(first_combination, second_combination);
|
||||
|
||||
{
|
||||
MyErrorHandler error_handler;
|
||||
validate(schema, nlohmann::json{{"first", {{"second", 1}}}}, &error_handler);
|
||||
|
||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
||||
EXPECT_EQ(error_list.size(), 6);
|
||||
|
||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
||||
|
||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first/second"});
|
||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << rootError(second_combination, 2));
|
||||
|
||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first/second"});
|
||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 0) << combinationError(second_combination, 0) << "instance is below minimum of 5");
|
||||
|
||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first/second"});
|
||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 0) << combinationError(second_combination, 1) << "instance is not a multiple of 2.0");
|
||||
|
||||
EXPECT_EQ(error_list[4].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[4].message, combinationError(first_combination, 1) << "unexpected instance type");
|
||||
|
||||
EXPECT_EQ(error_list[5].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[5].message, combinationError(first_combination, 2) << "unexpected instance type");
|
||||
}
|
||||
|
||||
{
|
||||
MyErrorHandler error_handler;
|
||||
validate(schema, nlohmann::json{{"first", {{"second", "not-an-integer"}}}}, &error_handler);
|
||||
|
||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
||||
EXPECT_EQ(error_list.size(), 6);
|
||||
|
||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
||||
|
||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first/second"});
|
||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << rootError(second_combination, 2));
|
||||
|
||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first/second"});
|
||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 0) << combinationError(second_combination, 0) << "unexpected instance type");
|
||||
|
||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first/second"});
|
||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 0) << combinationError(second_combination, 1) << "unexpected instance type");
|
||||
|
||||
EXPECT_EQ(error_list[4].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[4].message, combinationError(first_combination, 1) << "unexpected instance type");
|
||||
|
||||
EXPECT_EQ(error_list[5].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[5].message, combinationError(first_combination, 2) << "unexpected instance type");
|
||||
}
|
||||
|
||||
if (second_combination == "oneOf") {
|
||||
MyErrorHandler error_handler;
|
||||
validate(schema, nlohmann::json{{"first", {{"second", 8}}}}, &error_handler);
|
||||
|
||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
||||
EXPECT_EQ(error_list.size(), 4);
|
||||
|
||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
||||
|
||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first/second"});
|
||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << "more than one subschema has succeeded, but exactly one of them is required to validate");
|
||||
|
||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 1) << "unexpected instance type");
|
||||
|
||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 2) << "unexpected instance type");
|
||||
}
|
||||
|
||||
{
|
||||
MyErrorHandler error_handler;
|
||||
validate(schema, nlohmann::json{{"first", 10}}, &error_handler);
|
||||
|
||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
||||
EXPECT_EQ(error_list.size(), 4);
|
||||
|
||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
||||
|
||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << "unexpected instance type");
|
||||
|
||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 1) << "instance is below minimum of 20");
|
||||
|
||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 2) << "unexpected instance type");
|
||||
}
|
||||
|
||||
{
|
||||
MyErrorHandler error_handler;
|
||||
validate(schema, nlohmann::json{{"first", "short"}}, &error_handler);
|
||||
|
||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
||||
EXPECT_EQ(error_list.size(), 4);
|
||||
|
||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
||||
|
||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << "unexpected instance type");
|
||||
|
||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 1) << "unexpected instance type");
|
||||
|
||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first"});
|
||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 2) << "instance is too short as per minLength:10");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//==============================================================================
|
||||
// MAIN - calling the test cases
|
||||
//==============================================================================
|
||||
auto main() -> int
|
||||
{
|
||||
simpleTest("anyOf", "anyOf");
|
||||
simpleTest("anyOf", "oneOf");
|
||||
simpleTest("oneOf", "anyOf");
|
||||
simpleTest("oneOf", "oneOf");
|
||||
|
||||
verboseTest("anyOf", "anyOf");
|
||||
verboseTest("anyOf", "oneOf");
|
||||
verboseTest("oneOf", "anyOf");
|
||||
verboseTest("oneOf", "oneOf");
|
||||
|
||||
return g_error_count;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// issue-00-format-error.cpp
|
||||
|
||||
#include "nlohmann/json-schema.hpp"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include <iostream>
|
||||
|
||||
static int error_count = 0;
|
||||
|
||||
#define CHECK_THROW(x, msg) \
|
||||
{ \
|
||||
bool fail = false; \
|
||||
try { \
|
||||
x; \
|
||||
} catch (std::exception &) { \
|
||||
fail = true; \
|
||||
} \
|
||||
if (fail == false) { \
|
||||
++error_count; \
|
||||
std::cout << msg << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_NO_THROW(x, msg) \
|
||||
{ \
|
||||
bool fail = false; \
|
||||
std::string exception_error; \
|
||||
try { \
|
||||
x; \
|
||||
} catch (std::exception & e) { \
|
||||
fail = true; \
|
||||
exception_error = e.what(); \
|
||||
} \
|
||||
if (fail == true) { \
|
||||
++error_count; \
|
||||
std::cout << msg << ": " << exception_error << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
using json = nlohmann::json;
|
||||
using validator = nlohmann::json_schema::json_validator;
|
||||
|
||||
json schema_with_format = json::parse(R"(
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"str": {
|
||||
"type": "string",
|
||||
"format": "placeholder"
|
||||
}
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
int main()
|
||||
{
|
||||
// check that if we get validator without format checker we get error at schema loading
|
||||
validator without_format_checker;
|
||||
|
||||
CHECK_THROW(without_format_checker.set_root_schema(schema_with_format), "validator without format checker must fail at schema loading");
|
||||
|
||||
// check that with format checker all works fine
|
||||
validator with_format_checker{nullptr, [](const std::string &, const std::string &) {}};
|
||||
|
||||
CHECK_NO_THROW(with_format_checker.set_root_schema(schema_with_format), "schema must be succesed by validator with format checker");
|
||||
|
||||
CHECK_NO_THROW(with_format_checker.validate(json{{"str", "placeholder"}}), "validator must not throw while validation schema with format");
|
||||
|
||||
return error_count;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
add_test_simple_schema(Issue::12
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/schema.json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/instance.json)
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"x": 1503681668603
|
||||
}
|
||||
10
lib/All/json-schema-validator/test/issue-12/schema.json
Normal file
10
lib/All/json-schema-validator/test/issue-12/schema.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"properties": {
|
||||
"x": {
|
||||
"type": "integer",
|
||||
"minimum": 1000000000000,
|
||||
"maximum": 2000000000000
|
||||
}
|
||||
}
|
||||
}
|
||||
13
lib/All/json-schema-validator/test/issue-143/CMakeLists.txt
Normal file
13
lib/All/json-schema-validator/test/issue-143/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
add_test_simple_schema(Issue::143-1
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/schema.json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/instance-fail-1.json)
|
||||
add_test_simple_schema(Issue::143-a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/schema.json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/instance-fail-a.json)
|
||||
add_test_simple_schema(Issue::143-ok
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/schema.json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/instance.json)
|
||||
|
||||
set_tests_properties(Issue::143-1 Issue::143-a
|
||||
PROPERTIES
|
||||
WILL_FAIL 1)
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"ref1": "a",
|
||||
"refa": "a"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"ref1": 12,
|
||||
"refa": 12
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"ref1": 12,
|
||||
"refa": "a"
|
||||
}
|
||||
21
lib/All/json-schema-validator/test/issue-143/schema.json
Normal file
21
lib/All/json-schema-validator/test/issue-143/schema.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"type": "object",
|
||||
|
||||
"properties": {
|
||||
"unknown_keyword_storage": {
|
||||
"1": {
|
||||
"type": "number"
|
||||
},
|
||||
"a": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ref1": {
|
||||
"$ref": "#/properties/unknown_keyword_storage/1"
|
||||
},
|
||||
"refa": {
|
||||
"$ref": "#/properties/unknown_keyword_storage/a"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using nlohmann::json;
|
||||
using nlohmann::json_uri;
|
||||
using nlohmann::json_schema::json_validator;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static int error_count;
|
||||
#define EXPECT_EQ(a, b) \
|
||||
do { \
|
||||
if (a != b) { \
|
||||
std::cerr << "Failed: '" << a << "' != '" << b << "'\n"; \
|
||||
error_count++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// The schema is defined based upon a string literal
|
||||
static json person_schema = R"(
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "integer",
|
||||
"definitions": {
|
||||
"A": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"b": {
|
||||
"$ref": "#/definitions/B"
|
||||
}
|
||||
}
|
||||
},
|
||||
"B": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
})"_json;
|
||||
|
||||
class store_err_handler : public nlohmann::json_schema::basic_error_handler
|
||||
{
|
||||
void error(const nlohmann::json::json_pointer &ptr, const json &instance, const std::string &message) override
|
||||
{
|
||||
nlohmann::json_schema::basic_error_handler::error(ptr, instance, message);
|
||||
std::cerr << "ERROR: '" << ptr << "' - '" << instance << "': " << message << "\n";
|
||||
failed.push_back(ptr);
|
||||
}
|
||||
|
||||
public:
|
||||
std::vector<nlohmann::json::json_pointer> failed;
|
||||
|
||||
void reset() override
|
||||
{
|
||||
nlohmann::json_schema::basic_error_handler::reset();
|
||||
failed.clear();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static json_validator validator(person_schema);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
store_err_handler err;
|
||||
|
||||
validator.validate(1, err); // OK
|
||||
EXPECT_EQ(err.failed.size(), 0);
|
||||
err.reset();
|
||||
|
||||
validator.validate("1", err); // no name
|
||||
EXPECT_EQ(err.failed.size(), 1);
|
||||
err.reset();
|
||||
|
||||
validator.validate(1, err, json_uri("#/definitions/B"));
|
||||
EXPECT_EQ(err.failed.size(), 0);
|
||||
err.reset();
|
||||
|
||||
validator.validate("1", err, json_uri("#/definitions/B"));
|
||||
EXPECT_EQ(err.failed.size(), 1);
|
||||
err.reset();
|
||||
|
||||
validator.validate({{"b", 1}}, err, json_uri("#/definitions/A"));
|
||||
EXPECT_EQ(err.failed.size(), 0);
|
||||
err.reset();
|
||||
|
||||
validator.validate({{"b", "1"}}, err, json_uri("#/definitions/A"));
|
||||
EXPECT_EQ(err.failed.size(), 1);
|
||||
err.reset();
|
||||
|
||||
return error_count;
|
||||
}
|
||||
109
lib/All/json-schema-validator/test/issue-189-default-values.cpp
Normal file
109
lib/All/json-schema-validator/test/issue-189-default-values.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
|
||||
using nlohmann::json;
|
||||
using nlohmann::json_uri;
|
||||
using nlohmann::json_schema::json_validator;
|
||||
|
||||
static const json rectangle_schema = R"(
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"width": {
|
||||
"$ref": "#/definitions/length",
|
||||
"default": 20
|
||||
},
|
||||
"height": {
|
||||
"$ref": "#/definitions/length"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"length": {
|
||||
"type": "integer",
|
||||
"default": 10
|
||||
}
|
||||
}
|
||||
})"_json;
|
||||
|
||||
static const json quad_schema = R"(
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"width": {
|
||||
"$ref": "#/properties/height",
|
||||
"default": 20
|
||||
},
|
||||
"height": {
|
||||
"$ref": "#/definitions/length"
|
||||
},
|
||||
"depth": {
|
||||
"$ref": "default_schema#/definitions/defaultLength"
|
||||
},
|
||||
"time": {
|
||||
"$ref": "#/definitions/time"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"length": {
|
||||
"$ref": "default_schema#/definitions/defaultLength",
|
||||
"default": 10
|
||||
},
|
||||
"time": {
|
||||
"type": "integer",
|
||||
"default": 15
|
||||
}
|
||||
}
|
||||
})"_json;
|
||||
|
||||
static const json default_schema = R"(
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"defaultLength": {
|
||||
"default": 5
|
||||
}
|
||||
}
|
||||
})"_json;
|
||||
|
||||
static void loader(const json_uri &uri, json &schema)
|
||||
{
|
||||
schema = default_schema;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
json_validator validator(loader);
|
||||
|
||||
validator.set_root_schema(quad_schema);
|
||||
|
||||
{
|
||||
json empty_quad = R"({})"_json;
|
||||
|
||||
const auto default_patch = validator.validate(empty_quad);
|
||||
const auto actual = empty_quad.patch(default_patch);
|
||||
|
||||
const auto expected = R"({"height":10,"width":20,"depth":5,"time":15})"_json;
|
||||
if (actual != expected) {
|
||||
std::cerr << "Patch with defaults contains wrong value: '" << actual << "' instead of expected '" << expected.dump() << "'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
validator.set_root_schema(rectangle_schema);
|
||||
|
||||
{
|
||||
json empty_rectangle = R"({})"_json;
|
||||
|
||||
const auto default_patch = validator.validate(empty_rectangle);
|
||||
const auto actual = empty_rectangle.patch(default_patch);
|
||||
|
||||
// height must be 10 according to the default specified in the length definition while width must be 10 overridden by the width element
|
||||
const auto expected = R"({"height":10,"width":20})"_json;
|
||||
if (actual != expected) {
|
||||
std::cerr << "Patch with defaults contains wrong value: '" << actual << "' instead of expected '" << expected.dump() << "'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
add_test_simple_schema(Issue::209
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/entities.schema.json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/instance.json)
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://example.invalid/color.schema.json",
|
||||
"title": "color",
|
||||
"description": "X11/HTML/CSS color name as a JSON string",
|
||||
"type": "string",
|
||||
"enum": [ "White", "Black", "Red" ]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user