diff --git a/ports/javascript/index.mjs b/ports/javascript/index.mjs index 5cdccfd17..5ea8cc4c7 100644 --- a/ports/javascript/index.mjs +++ b/ports/javascript/index.mjs @@ -1,10 +1,10 @@ -const JSON_VERSION = 1; +const JSON_VERSION = 2; const DEPTH_LIMIT = 300; const ANNOTATION_EMIT = 44; const ANNOTATION_TO_PARENT = 45; const ANNOTATION_BASENAME_TO_PARENT = 46; -const CONTROL_GROUP_START = 85; -const CONTROL_EVALUATE_END = 89; +const CONTROL_GROUP_START = 86; +const CONTROL_EVALUATE_END = 90; const URI_REGEX = /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/; function buildJsonPointer(tokens, length) { @@ -150,7 +150,7 @@ function prepareInstruction(instruction) { function resolveJumpTargets(instructions, targets) { for (let index = 0; index < instructions.length; index++) { const instruction = instructions[index]; - if (instruction[0] === 91) { + if (instruction[0] === 92) { const targetIndex = instruction[5]; if (targetIndex < targets.length) { instruction[5] = targets[targetIndex]; @@ -185,7 +185,7 @@ function collectAnchorNames(targets, result) { function collectAnchorNamesFromInstructions(instructions, result) { for (let index = 0; index < instructions.length; index++) { const instruction = instructions[index]; - if (instruction[0] === 90 && typeof instruction[5] === 'string') { + if (instruction[0] === 91 && typeof instruction[5] === 'string') { result.add(instruction[5]); } if (instruction[6]) { @@ -321,14 +321,14 @@ function compileInstructionToCode(instruction, captures, visited, budget) { case 79: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j0)c+=seq(children,'i'); return c+'return true;'; } - case 87: { var c=IO+'if(!Object.hasOwn(i,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; } - case 88: { var c='if(_jt(i)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; } - case 89: return 'return true;'; - case 90: return fb(90); - case 91: { if(!value)return 'return true;'; if(visited&&visited.has(instruction))return fb(91); if(!visited)visited=new Set(); visited.add(instruction); var r=R('t'); if(!r)return fb(91); var c=r; for(var j=0;j0)c+=seq(children,'i'); return c+'return true;'; } + case 88: { var c=IO+'if(!Object.hasOwn(i,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; } + case 89: { var c='if(_jt(i)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; } + case 90: return 'return true;'; + case 91: return fb(91); + case 92: { if(!value)return 'return true;'; if(visited&&visited.has(instruction))return fb(92); if(!visited)visited=new Set(); visited.add(instruction); var r=R('t'); if(!r)return fb(92); var c=r; for(var j=0;j 89) { + if (type < 86 || type > 90) { if (evaluator.trackMode) { evaluator.pushPath(instruction[1]); } @@ -2288,6 +2288,28 @@ function LoopItemsPropertiesExactlyTypeStrictHash(instruction, instance, depth, if (evaluator.callbackMode) evaluator.callbackPop(instruction, true); return true; }; + +function LoopItemsIntegerBounded(instruction, instance, depth, template, evaluator) { + const target = resolveInstance(instance, instruction[2]); + if (!Array.isArray(target) || target.length === 0) return true; + if (evaluator.callbackMode) evaluator.callbackPush(instruction); + const minimum = instruction[5][0]; + const maximum = instruction[5][1]; + for (let index = 0; index < target.length; index++) { + const element = target[index]; + if (typeof element !== 'number') { + if (evaluator.callbackMode) evaluator.callbackPop(instruction, false); + return false; + } + if (element < minimum || element > maximum) { + if (evaluator.callbackMode) evaluator.callbackPop(instruction, false); + return false; + } + } + if (evaluator.callbackMode) evaluator.callbackPop(instruction, true); + return true; +}; + function LoopContains(instruction, instance, depth, template, evaluator) { const target = resolveInstance(instance, instruction[2]); if (!Array.isArray(target)) return true; @@ -2516,14 +2538,15 @@ const handlers = [ LoopItemsTypeStrictAny, // 81 LoopItemsPropertiesExactlyTypeStrictHash, // 82 LoopItemsPropertiesExactlyTypeStrictHash, // 83 - LoopContains, // 84 - ControlGroup, // 85 - ControlGroupWhenDefines, // 86 - ControlGroupWhenDefinesDirect, // 87 - ControlGroupWhenType, // 88 - ControlEvaluate, // 89 - ControlDynamicAnchorJump, // 90 - ControlJump // 91 + LoopItemsIntegerBounded, // 84 + LoopContains, // 85 + ControlGroup, // 86 + ControlGroupWhenDefines, // 87 + ControlGroupWhenDefinesDirect, // 88 + ControlGroupWhenType, // 89 + ControlEvaluate, // 90 + ControlDynamicAnchorJump, // 91 + ControlJump // 92 ]; function AssertionTypeArrayBounded_fast(instruction, instance, depth, template, evaluator) { @@ -3622,6 +3645,18 @@ function ControlDynamicAnchorJump_fast(instruction, instance, depth, template, e return false; } +function LoopItemsIntegerBounded_fast(instruction, instance, depth, template, evaluator) { + const target = resolveInstance(instance, instruction[2]); + if (!Array.isArray(target) || target.length === 0) return true; + const minimum = instruction[5][0]; + const maximum = instruction[5][1]; + for (let index = 0; index < target.length; index++) { + const element = target[index]; + if (typeof element !== 'number' || element < minimum || element > maximum) return false; + } + return true; +} + const fastHandlers = handlers.slice(); fastHandlers[15] = AssertionTypeArrayBounded_fast; fastHandlers[81] = LoopItemsTypeStrictAny_fast; @@ -3631,7 +3666,7 @@ fastHandlers[4] = AssertionDefinesAllStrict_fast; fastHandlers[26] = AssertionEqual_fast; fastHandlers[59] = LoopPropertiesMatch_fast; fastHandlers[50] = LogicalOr_fast; -fastHandlers[91] = ControlJump_fast; +fastHandlers[92] = ControlJump_fast; fastHandlers[28] = AssertionEqualsAnyStringHash_fast; fastHandlers[52] = LogicalXor_fast; fastHandlers[2] = AssertionDefinesStrict_fast; @@ -3649,7 +3684,7 @@ fastHandlers[1] = AssertionDefines_fast; fastHandlers[54] = LogicalWhenType_fast; fastHandlers[55] = LogicalWhenDefines_fast; fastHandlers[0] = AssertionFail_fast; -fastHandlers[84] = LoopContains_fast; +fastHandlers[85] = LoopContains_fast; fastHandlers[48] = LogicalNot_fast; fastHandlers[79] = LoopItemsType_fast; fastHandlers[80] = LoopItemsTypeStrict_fast; @@ -3709,6 +3744,7 @@ fastHandlers[77] = LoopItemsFrom_fast; fastHandlers[78] = LoopItemsUnevaluated_fast; fastHandlers[82] = LoopItemsPropertiesExactlyTypeStrictHash_fast; fastHandlers[83] = LoopItemsPropertiesExactlyTypeStrictHash_fast; -fastHandlers[90] = ControlDynamicAnchorJump_fast; +fastHandlers[84] = LoopItemsIntegerBounded_fast; +fastHandlers[91] = ControlDynamicAnchorJump_fast; export { Blaze }; diff --git a/ports/javascript/test.mjs b/ports/javascript/test.mjs index 8057cbd1a..d4cb353e1 100644 --- a/ports/javascript/test.mjs +++ b/ports/javascript/test.mjs @@ -116,15 +116,15 @@ for (const [subdirectory, blacklist] of Object.entries(BLACKLISTS)) { describe('version', () => { it('rejects a template with an unsupported version', () => { - const template = [2, false, false, [[]], []]; + const template = [3, false, false, [[]], []]; assert.throws(() => new Blaze(template), { - message: 'Only version 1 of the compiled template is supported by this version of the evaluator' + message: 'Only version 2 of the compiled template is supported by this version of the evaluator' }); }); it('rejects a template that is not an array', () => { assert.throws(() => new Blaze({}), { - message: 'Only version 1 of the compiled template is supported by this version of the evaluator' + message: 'Only version 2 of the compiled template is supported by this version of the evaluator' }); }); }); diff --git a/ports/javascript/trace.mjs b/ports/javascript/trace.mjs index a61292ba0..723d1e139 100644 --- a/ports/javascript/trace.mjs +++ b/ports/javascript/trace.mjs @@ -95,14 +95,15 @@ const INSTRUCTION_NAMES = { "LoopItemsTypeStrictAny": 81, "LoopItemsPropertiesExactlyTypeStrictHash": 82, "LoopItemsPropertiesExactlyTypeStrictHash3": 83, - "LoopContains": 84, - "ControlGroup": 85, - "ControlGroupWhenDefines": 86, - "ControlGroupWhenDefinesDirect": 87, - "ControlGroupWhenType": 88, - "ControlEvaluate": 89, - "ControlDynamicAnchorJump": 90, - "ControlJump": 91, + "LoopItemsIntegerBounded": 84, + "LoopContains": 85, + "ControlGroup": 86, + "ControlGroupWhenDefines": 87, + "ControlGroupWhenDefinesDirect": 88, + "ControlGroupWhenType": 89, + "ControlEvaluate": 90, + "ControlDynamicAnchorJump": 91, + "ControlJump": 92, "Annotation": -1 }; diff --git a/src/compiler/default_compiler_draft4.h b/src/compiler/default_compiler_draft4.h index caa145c51..ac13b6428 100644 --- a/src/compiler/default_compiler_draft4.h +++ b/src/compiler/default_compiler_draft4.h @@ -1474,6 +1474,64 @@ auto compiler_draft4_applicator_items_array( } } +auto is_number_type_check(const Instruction &instruction) -> bool { + if (instruction.type != InstructionIndex::AssertionTypeStrictAny) { + return false; + } + + const auto &value{std::get(instruction.value)}; + const auto numeric_count{ + static_cast(value.test( + std::to_underlying(sourcemeta::core::JSON::Type::Integer))) + + static_cast( + value.test(std::to_underlying(sourcemeta::core::JSON::Type::Real))) + + static_cast(value.test( + std::to_underlying(sourcemeta::core::JSON::Type::Decimal)))}; + return numeric_count >= 2 && value.count() == numeric_count; +} + +auto is_integer_bounded_pattern(const Instructions &children) -> bool { + if (children.size() != 3) { + return false; + } + + bool has_type{false}; + bool has_min{false}; + bool has_max{false}; + for (const auto &child : children) { + if (is_number_type_check(child)) { + has_type = true; + } else if (child.type == InstructionIndex::AssertionGreaterEqual) { + if (!std::get(child.value).is_integer()) { + return false; + } + has_min = true; + } else if (child.type == InstructionIndex::AssertionLessEqual) { + if (!std::get(child.value).is_integer()) { + return false; + } + has_max = true; + } + } + + return has_type && has_min && has_max; +} + +auto extract_integer_bounds(const Instructions &children) + -> ValueIntegerBounds { + std::int64_t minimum{0}; + std::int64_t maximum{0}; + for (const auto &child : children) { + if (child.type == InstructionIndex::AssertionGreaterEqual) { + minimum = std::get(child.value).to_integer(); + } else if (child.type == InstructionIndex::AssertionLessEqual) { + maximum = std::get(child.value).to_integer(); + } + } + + return {minimum, maximum}; +} + auto compiler_draft4_applicator_items_with_options( const Context &context, const SchemaContext &schema_context, const DynamicContext &dynamic_context, const bool annotate, @@ -1539,6 +1597,13 @@ auto compiler_draft4_applicator_items_with_options( return {}; } + if (context.mode == Mode::FastValidation && children.size() == 3 && + is_integer_bounded_pattern(children)) { + return {make(sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBounded, + context, schema_context, dynamic_context, + extract_integer_bounds(children))}; + } + if (context.mode == Mode::FastValidation && children.size() == 1) { if (children.front().type == InstructionIndex::AssertionTypeStrict) { return {make(sourcemeta::blaze::InstructionIndex::LoopItemsTypeStrict, @@ -1614,6 +1679,15 @@ auto compiler_draft4_applicator_additionalitems_from_cursor( Instructions children; if (!subchildren.empty()) { + if (context.mode == Mode::FastValidation && cursor == 0 && !annotate && + !track_evaluation && is_integer_bounded_pattern(subchildren)) { + children.push_back( + make(sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBounded, + context, schema_context, dynamic_context, + extract_integer_bounds(subchildren))); + return children; + } + children.push_back(make(sourcemeta::blaze::InstructionIndex::LoopItemsFrom, context, schema_context, dynamic_context, ValueUnsignedInteger{cursor}, diff --git a/src/compiler/default_compiler_draft6.h b/src/compiler/default_compiler_draft6.h index c60bbcd2e..d548aba64 100644 --- a/src/compiler/default_compiler_draft6.h +++ b/src/compiler/default_compiler_draft6.h @@ -107,7 +107,9 @@ auto compiler_draft6_validation_type(const Context &context, LoopItemsPropertiesExactlyTypeStrictHash || current.back().type == sourcemeta::blaze::InstructionIndex:: - LoopItemsPropertiesExactlyTypeStrictHash3) && + LoopItemsPropertiesExactlyTypeStrictHash3 || + current.back().type == + sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBounded) && current.back().relative_instance_location == to_pointer(dynamic_context.base_instance_location)) { return {}; diff --git a/src/evaluator/evaluator_describe.cc b/src/evaluator/evaluator_describe.cc index c60d9a931..6752790ac 100644 --- a/src/evaluator/evaluator_describe.cc +++ b/src/evaluator/evaluator_describe.cc @@ -775,6 +775,12 @@ auto describe(const bool valid, const Instruction &step, return message.str(); } + if (step.type == + sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBounded) { + return "Every item in the array was expected to be a number within the " + "given range"; + } + if (step.type == sourcemeta::blaze::InstructionIndex::LoopPropertiesType) { std::ostringstream message; message << "The object properties were expected to be of type " diff --git a/src/evaluator/evaluator_json.cc b/src/evaluator/evaluator_json.cc index 62ef81594..65da19fd1 100644 --- a/src/evaluator/evaluator_json.cc +++ b/src/evaluator/evaluator_json.cc @@ -40,6 +40,13 @@ auto value_from_json(const sourcemeta::core::JSON &wrapper) case 19: return sourcemeta::core::from_json(value); case 20: return sourcemeta::core::from_json(value); case 21: return sourcemeta::core::from_json(value); + case 22: + if (value.is_array() && value.array_size() == 2 && + value.at(0).is_integer() && value.at(1).is_integer()) { + return ValueIntegerBounds{value.at(0).to_integer(), + value.at(1).to_integer()}; + } + return std::nullopt; // clang-format on default: std::unreachable(); diff --git a/src/evaluator/include/sourcemeta/blaze/evaluator.h b/src/evaluator/include/sourcemeta/blaze/evaluator.h index 04b9f3803..933953e5f 100644 --- a/src/evaluator/include/sourcemeta/blaze/evaluator.h +++ b/src/evaluator/include/sourcemeta/blaze/evaluator.h @@ -44,7 +44,7 @@ struct Template { }; /// @ingroup evaluator -constexpr std::size_t JSON_VERSION{1}; +constexpr std::size_t JSON_VERSION{2}; /// @ingroup evaluator /// Parse a template from JSON diff --git a/src/evaluator/include/sourcemeta/blaze/evaluator_dispatch.h b/src/evaluator/include/sourcemeta/blaze/evaluator_dispatch.h index 68f5f0e74..9fced7fb1 100644 --- a/src/evaluator/include/sourcemeta/blaze/evaluator_dispatch.h +++ b/src/evaluator/include/sourcemeta/blaze/evaluator_dispatch.h @@ -2207,6 +2207,43 @@ INSTRUCTION_HANDLER(LoopItemsPropertiesExactlyTypeStrictHash3) { EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash3); } +INSTRUCTION_HANDLER(LoopItemsIntegerBounded) { + EVALUATE_BEGIN_NON_STRING(LoopItemsIntegerBounded, + target.is_array() && !target.empty()); + const auto value{assume_value_copy(instruction.value)}; + result = true; + for (const auto &element : target.as_array()) { + if (!element.is_number()) [[unlikely]] { + result = false; + break; + } + + if (element.is_integer()) { + const auto integer{element.to_integer()}; + if (integer < value.first || integer > value.second) [[unlikely]] { + result = false; + break; + } + } else if (element.is_real()) { + const auto real{element.to_real()}; + if (real < static_cast(value.first) || + real > static_cast(value.second)) [[unlikely]] { + result = false; + break; + } + } else { + const auto real{element.to_decimal().to_double()}; + if (real < static_cast(value.first) || + real > static_cast(value.second)) [[unlikely]] { + result = false; + break; + } + } + } + + EVALUATE_END(LoopItemsIntegerBounded); +} + INSTRUCTION_HANDLER(LoopContains) { EVALUATE_BEGIN_NON_STRING(LoopContains, target.is_array()); assert(!instruction.children.empty()); @@ -2277,7 +2314,7 @@ using DispatchHandler = bool (*)( template // Must have same order as InstructionIndex // NOLINTNEXTLINE(modernize-avoid-c-arrays) -static constexpr DispatchHandler handlers[95] = { +static constexpr DispatchHandler handlers[93] = { AssertionFail, AssertionDefines, AssertionDefinesStrict, @@ -2362,6 +2399,7 @@ static constexpr DispatchHandler handlers[95] = { LoopItemsTypeStrictAny, LoopItemsPropertiesExactlyTypeStrictHash, LoopItemsPropertiesExactlyTypeStrictHash3, + LoopItemsIntegerBounded, LoopContains, ControlGroup, ControlGroupWhenDefines, diff --git a/src/evaluator/include/sourcemeta/blaze/evaluator_instruction.h b/src/evaluator/include/sourcemeta/blaze/evaluator_instruction.h index 4caea7870..13d82111b 100644 --- a/src/evaluator/include/sourcemeta/blaze/evaluator_instruction.h +++ b/src/evaluator/include/sourcemeta/blaze/evaluator_instruction.h @@ -104,6 +104,7 @@ enum class InstructionIndex : std::uint8_t { LoopItemsTypeStrictAny, LoopItemsPropertiesExactlyTypeStrictHash, LoopItemsPropertiesExactlyTypeStrictHash3, + LoopItemsIntegerBounded, LoopContains, ControlGroup, ControlGroupWhenDefines, @@ -201,6 +202,7 @@ constexpr std::string_view InstructionNames[] = { "LoopItemsTypeStrictAny", "LoopItemsPropertiesExactlyTypeStrictHash", "LoopItemsPropertiesExactlyTypeStrictHash3", + "LoopItemsIntegerBounded", "LoopContains", "ControlGroup", "ControlGroupWhenDefines", diff --git a/src/evaluator/include/sourcemeta/blaze/evaluator_value.h b/src/evaluator/include/sourcemeta/blaze/evaluator_value.h index b55e6d720..c8fcc495b 100644 --- a/src/evaluator/include/sourcemeta/blaze/evaluator_value.h +++ b/src/evaluator/include/sourcemeta/blaze/evaluator_value.h @@ -155,6 +155,10 @@ using ValueStringHashes = /// Represents a compiler step types property hashes value using ValueTypedHashes = std::pair; +/// @ingroup evaluator +/// Represents integer bounds with minimum and maximum +using ValueIntegerBounds = std::pair; + /// @ingroup evaluator using Value = std::variant; + ValueTypedProperties, ValueStringHashes, ValueTypedHashes, + ValueIntegerBounds>; } // namespace sourcemeta::blaze diff --git a/test/compiler/compiler_json_test.cc b/test/compiler/compiler_json_test.cc index 145143a8c..8ae4b2471 100644 --- a/test/compiler/compiler_json_test.cc +++ b/test/compiler/compiler_json_test.cc @@ -31,7 +31,7 @@ TEST(Compiler_JSON, example_1) { sourcemeta::blaze::default_schema_compiler)}; const sourcemeta::core::JSON expected{sourcemeta::core::parse_json(R"JSON([ - 1, + 2, false, false, [ @@ -67,7 +67,7 @@ TEST(Compiler_JSON, example_2) { sourcemeta::blaze::default_schema_compiler)}; const sourcemeta::core::JSON expected{sourcemeta::core::parse_json(R"JSON([ - 1, + 2, false, false, [ @@ -118,7 +118,7 @@ TEST(Compiler_JSON, example_3) { sourcemeta::blaze::default_schema_compiler)}; const sourcemeta::core::JSON expected{sourcemeta::core::parse_json(R"JSON([ - 1, + 2, false, false, [ @@ -156,7 +156,7 @@ TEST(Compiler_JSON, example_4) { sourcemeta::blaze::default_schema_compiler)}; const sourcemeta::core::JSON expected{sourcemeta::core::parse_json(R"JSON([ - 1, + 2, false, false, [ @@ -233,7 +233,7 @@ TEST(Compiler_JSON, example_5) { sourcemeta::blaze::Mode::Exhaustive)}; const sourcemeta::core::JSON expected{sourcemeta::core::parse_json(R"JSON([ - 1, + 2, false, true, [ @@ -278,7 +278,7 @@ TEST(Compiler_JSON, example_6) { sourcemeta::blaze::Mode::Exhaustive)}; const sourcemeta::core::JSON expected{sourcemeta::core::parse_json(R"JSON([ - 1, + 2, false, true, [ @@ -408,7 +408,7 @@ TEST(Compiler_JSON, invalid_1) { TEST(Compiler_JSON, invalid_version) { const auto input{sourcemeta::core::parse_json(R"JSON([ - 2, + 3, false, false, [ diff --git a/test/evaluator/evaluator_2020_12.json b/test/evaluator/evaluator_2020_12.json index ce14d40de..96d65218b 100644 --- a/test/evaluator/evaluator_2020_12.json +++ b/test/evaluator/evaluator_2020_12.json @@ -1670,5 +1670,354 @@ "The unrecognized keyword \"example\" was collected as the annotation {\"name\":\"Rex\",\"petType\":\"dog\"}" ] } + }, + { + "description": "items_integer_bounded_1", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10, 50, 99 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItemsFrom", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/2" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/2" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/2" ], + [ "LogicalWhenArraySizeGreater", "/items", "#/items", "" ], + [ "Annotation", "/items", "#/items", "" ] + ], + "post": [ + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/2" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/2" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/2" ], + [ true, "LoopItemsFrom", "/items", "#/items", "" ], + [ true, "Annotation", "/items", "#/items", "", true ], + [ true, "LogicalWhenArraySizeGreater", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number", + "The integer value 10 was expected to be less than or equal to the integer 100", + "The integer value 10 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 99 was expected to be less than or equal to the integer 100", + "The integer value 99 was expected to be greater than or equal to the integer 0", + "Every item in the array value was expected to validate against the given subschema", + "Every item in the array value was successfully validated", + "The array value contains 3 additional items not described by related keywords" + ] + } + }, + { + "description": "items_integer_bounded_2", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10, 200, 50 ], + "valid": false, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ false, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItemsFrom", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ] + ], + "post": [ + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ false, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ false, "LoopItemsFrom", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number", + "The integer value 10 was expected to be less than or equal to the integer 100", + "The integer value 10 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 200 was expected to be less than or equal to the integer 100", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_3", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ "foo" ], + "valid": false, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ false, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItemsFrom", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ] + ], + "post": [ + [ false, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ false, "LoopItemsFrom", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number but it was of type string", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_4", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": "not an array", + "valid": true, + "fast": {}, + "exhaustive": {} + }, + { + "description": "items_integer_bounded_5", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [], + "valid": true, + "fast": {}, + "exhaustive": {} + }, + { + "description": "items_integer_bounded_6", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10.5, 99.9 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItemsFrom", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "LogicalWhenArraySizeGreater", "/items", "#/items", "" ], + [ "Annotation", "/items", "#/items", "" ] + ], + "post": [ + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "LoopItemsFrom", "/items", "#/items", "" ], + [ true, "Annotation", "/items", "#/items", "", true ], + [ true, "LogicalWhenArraySizeGreater", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number", + "The number value 10.5 was expected to be less than or equal to the integer 100", + "The number value 10.5 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The number value 99.9 was expected to be less than or equal to the integer 100", + "The number value 99.9 was expected to be greater than or equal to the integer 0", + "Every item in the array value was expected to validate against the given subschema", + "Every item in the array value was successfully validated", + "The array value contains 2 additional items not described by related keywords" + ] + } + }, + { + "description": "items_integer_bounded_7_real_bounds", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "items": { "type": "number", "minimum": 0.5, "maximum": 100 } + }, + "instance": [ 1, 50 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsFrom", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ] + ], + "post": [ + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "LoopItemsFrom", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number", + "The integer value 1 was expected to be less than or equal to the integer 100", + "The integer value 1 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the number 0.5", + "Every item in the array value was expected to validate against the given subschema" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItemsFrom", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "LogicalWhenArraySizeGreater", "/items", "#/items", "" ], + [ "Annotation", "/items", "#/items", "" ] + ], + "post": [ + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "LoopItemsFrom", "/items", "#/items", "" ], + [ true, "Annotation", "/items", "#/items", "", true ], + [ true, "LogicalWhenArraySizeGreater", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number", + "The integer value 1 was expected to be less than or equal to the integer 100", + "The integer value 1 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the number 0.5", + "Every item in the array value was expected to validate against the given subschema", + "Every item in the array value was successfully validated", + "The array value contains 2 additional items not described by related keywords" + ] + } + }, + { + "description": "items_integer_bounded_8_boundary_values", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 0, 100 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItemsFrom", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "LogicalWhenArraySizeGreater", "/items", "#/items", "" ], + [ "Annotation", "/items", "#/items", "" ] + ], + "post": [ + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "LoopItemsFrom", "/items", "#/items", "" ], + [ true, "Annotation", "/items", "#/items", "", true ], + [ true, "LogicalWhenArraySizeGreater", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number", + "The integer value 0 was expected to be less than or equal to the integer 100", + "The integer value 0 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 100 was expected to be less than or equal to the integer 100", + "The integer value 100 was expected to be greater than or equal to the integer 0", + "Every item in the array value was expected to validate against the given subschema", + "Every item in the array value was successfully validated", + "The array value contains 2 additional items not described by related keywords" + ] + } } ] diff --git a/test/evaluator/evaluator_draft4.json b/test/evaluator/evaluator_draft4.json index b482fedcc..6d493bb22 100644 --- a/test/evaluator/evaluator_draft4.json +++ b/test/evaluator/evaluator_draft4.json @@ -9822,5 +9822,435 @@ "The string value was expected to validate against the given subschema" ] } + }, + { + "description": "items_integer_bounded_1", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10, 50, 99 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/2" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/2" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/2" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/2" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/2" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/2" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 10 was expected to be less than or equal to the integer 100", + "The integer value 10 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 99 was expected to be less than or equal to the integer 100", + "The integer value 99 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_2", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10, 200, 50 ], + "valid": false, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ false, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ false, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ false, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 10 was expected to be less than or equal to the integer 100", + "The integer value 10 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 200 was expected to be less than or equal to the integer 100", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_3", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ "foo" ], + "valid": false, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ false, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ] + ], + "post": [ + [ false, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ false, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number but it was of type string", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_4", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": "not an array", + "valid": true, + "fast": {}, + "exhaustive": {} + }, + { + "description": "items_integer_bounded_5", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [], + "valid": true, + "fast": {}, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_6", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10.5, 99.9 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The number value 10.5 was expected to be less than or equal to the integer 100", + "The number value 10.5 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The number value 99.9 was expected to be less than or equal to the integer 100", + "The number value 99.9 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_7_real_bounds", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0.5, "maximum": 100 } + }, + "instance": [ 1, 50 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 1 was expected to be less than or equal to the integer 100", + "The integer value 1 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 1 was expected to be less than or equal to the integer 100", + "The integer value 1 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_8_boundary_values", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 0, 100 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 0 was expected to be less than or equal to the integer 100", + "The integer value 0 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 100 was expected to be less than or equal to the integer 100", + "The integer value 100 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_9_type_integer_no_optimization", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "integer", "minimum": 0, "maximum": 100 } + }, + "instance": [ 3.5 ], + "valid": false, + "fast": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrict", "/items/type", "#/items/type", "/0" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ false, "AssertionTypeStrict", "/items/type", "#/items/type", "/0" ], + [ false, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The number value 3.5 was expected to be less than or equal to the integer 100", + "The number value 3.5 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type integer but it was of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrict", "/items/type", "#/items/type", "/0" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ false, "AssertionTypeStrict", "/items/type", "#/items/type", "/0" ], + [ false, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The number value 3.5 was expected to be less than or equal to the integer 100", + "The number value 3.5 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type integer but it was of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_10_type_integer_valid", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "integer", "minimum": 0, "maximum": 100 } + }, + "instance": [ 50 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrict", "/items/type", "#/items/type", "/0" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrict", "/items/type", "#/items/type", "/0" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type integer", + "Every item in the array value was expected to validate against the given subschema" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrict", "/items/type", "#/items/type", "/0" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrict", "/items/type", "#/items/type", "/0" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type integer", + "Every item in the array value was expected to validate against the given subschema" + ] + } } ] diff --git a/test/evaluator/evaluator_draft4_test.cc b/test/evaluator/evaluator_draft4_test.cc index 3d0a1e063..b2c29a478 100644 --- a/test/evaluator/evaluator_draft4_test.cc +++ b/test/evaluator/evaluator_draft4_test.cc @@ -1367,3 +1367,50 @@ TEST(Evaluator_draft4, enum_17) { instance, 1, "The value was expected to be of type integer but it was of type number"); } + +TEST(Evaluator_draft4, items_integer_bounded_decimal_in_range) { + const sourcemeta::core::JSON schema{sourcemeta::core::parse_json(R"JSON({ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + })JSON")}; + + sourcemeta::core::JSON instance{sourcemeta::core::JSON::Array{}}; + instance.push_back(sourcemeta::core::JSON{sourcemeta::core::Decimal{"50.5"}}); + EVALUATE_WITH_TRACE_FAST_SUCCESS(schema, instance, 1, ""); + + EVALUATE_TRACE_PRE(0, LoopItemsIntegerBounded, "/items", "#/items", ""); + EVALUATE_TRACE_POST_SUCCESS(0, LoopItemsIntegerBounded, "/items", "#/items", + ""); +} + +TEST(Evaluator_draft4, items_integer_bounded_decimal_out_of_range) { + const sourcemeta::core::JSON schema{sourcemeta::core::parse_json(R"JSON({ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + })JSON")}; + + sourcemeta::core::JSON instance{sourcemeta::core::JSON::Array{}}; + instance.push_back( + sourcemeta::core::JSON{sourcemeta::core::Decimal{"200.5"}}); + EVALUATE_WITH_TRACE_FAST_FAILURE(schema, instance, 1, ""); + + EVALUATE_TRACE_PRE(0, LoopItemsIntegerBounded, "/items", "#/items", ""); + EVALUATE_TRACE_POST_FAILURE(0, LoopItemsIntegerBounded, "/items", "#/items", + ""); +} + +TEST(Evaluator_draft4, items_integer_bounded_large_decimal_in_range) { + const sourcemeta::core::JSON schema{sourcemeta::core::parse_json(R"JSON({ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + })JSON")}; + + sourcemeta::core::JSON instance{sourcemeta::core::JSON::Array{}}; + instance.push_back(sourcemeta::core::JSON{ + sourcemeta::core::Decimal{"99.99999999999999999999999999999"}}); + EVALUATE_WITH_TRACE_FAST_SUCCESS(schema, instance, 1, ""); + + EVALUATE_TRACE_PRE(0, LoopItemsIntegerBounded, "/items", "#/items", ""); + EVALUATE_TRACE_POST_SUCCESS(0, LoopItemsIntegerBounded, "/items", "#/items", + ""); +} diff --git a/test/evaluator/evaluator_draft6.json b/test/evaluator/evaluator_draft6.json index 760836c75..3bd49e3f9 100644 --- a/test/evaluator/evaluator_draft6.json +++ b/test/evaluator/evaluator_draft6.json @@ -3260,5 +3260,337 @@ "The integer value was expected to validate against the 2 given subschemas" ] } + }, + { + "description": "items_integer_bounded_1", + "schema": { + "$schema": "http://json-schema.org/draft-06/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10, 50, 99 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/2" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/2" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/2" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/2" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/2" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/2" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 10 was expected to be less than or equal to the integer 100", + "The integer value 10 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 99 was expected to be less than or equal to the integer 100", + "The integer value 99 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_2", + "schema": { + "$schema": "http://json-schema.org/draft-06/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10, 200, 50 ], + "valid": false, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ false, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ false, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ false, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 10 was expected to be less than or equal to the integer 100", + "The integer value 10 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 200 was expected to be less than or equal to the integer 100", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_3", + "schema": { + "$schema": "http://json-schema.org/draft-06/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ "foo" ], + "valid": false, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ false, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ] + ], + "post": [ + [ false, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ false, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The value was expected to be of type number but it was of type string", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_4", + "schema": { + "$schema": "http://json-schema.org/draft-06/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": "not an array", + "valid": true, + "fast": {}, + "exhaustive": {} + }, + { + "description": "items_integer_bounded_5", + "schema": { + "$schema": "http://json-schema.org/draft-06/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [], + "valid": true, + "fast": {}, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_6", + "schema": { + "$schema": "http://json-schema.org/draft-06/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 10.5, 99.9 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The number value 10.5 was expected to be less than or equal to the integer 100", + "The number value 10.5 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The number value 99.9 was expected to be less than or equal to the integer 100", + "The number value 99.9 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_7_real_bounds", + "schema": { + "$schema": "http://json-schema.org/draft-06/schema#", + "items": { "type": "number", "minimum": 0.5, "maximum": 100 } + }, + "instance": [ 1, 50 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 1 was expected to be less than or equal to the integer 100", + "The integer value 1 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 1 was expected to be less than or equal to the integer 100", + "The integer value 1 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "The integer value 50 was expected to be less than or equal to the integer 100", + "The integer value 50 was expected to be greater than or equal to the number 0.5", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } + }, + { + "description": "items_integer_bounded_8_boundary_values", + "schema": { + "$schema": "http://json-schema.org/draft-06/schema#", + "items": { "type": "number", "minimum": 0, "maximum": 100 } + }, + "instance": [ 0, 100 ], + "valid": true, + "fast": { + "pre": [ + [ "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "post": [ + [ true, "LoopItemsIntegerBounded", "/items", "#/items", "" ] + ], + "descriptions": [ + "Every item in the array was expected to be a number within the given range" + ] + }, + "exhaustive": { + "pre": [ + [ "LoopItems", "/items", "#/items", "" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ] + ], + "post": [ + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/0" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/0" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/0" ], + [ true, "AssertionLessEqual", "/items/maximum", "#/items/maximum", "/1" ], + [ true, "AssertionGreaterEqual", "/items/minimum", "#/items/minimum", "/1" ], + [ true, "AssertionTypeStrictAny", "/items/type", "#/items/type", "/1" ], + [ true, "LoopItems", "/items", "#/items", "" ] + ], + "descriptions": [ + "The integer value 0 was expected to be less than or equal to the integer 100", + "The integer value 0 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "The integer value 100 was expected to be less than or equal to the integer 100", + "The integer value 100 was expected to be greater than or equal to the integer 0", + "The value was expected to be of type number", + "Every item in the array value was expected to validate against the given subschema" + ] + } } ]