From e6b1bd50191cbcfc8d38deebc1e920048b7ca514 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Thu, 30 May 2024 13:21:02 +0100 Subject: [PATCH] Handle unsupported vocabularies in `test` and `validate` (#14) Signed-off-by: Juan Cruz Viotti --- DEPENDENCIES | 2 +- src/command_test.cc | 2 + src/command_validate.cc | 4 ++ test/CMakeLists.txt | 2 + test/test_single_unsupported.sh | 39 +++++++++++++++++++ test/validate_non_supported.sh | 36 +++++++++++++++++ .../jsontoolkit/src/jsonschema/CMakeLists.txt | 1 - .../src/jsonschema/default_compiler.cc | 25 ++++++++---- .../src/jsonschema/default_compiler_2020_12.h | 18 --------- 9 files changed, 101 insertions(+), 28 deletions(-) create mode 100755 test/test_single_unsupported.sh create mode 100755 test/validate_non_supported.sh delete mode 100644 vendor/jsontoolkit/src/jsonschema/default_compiler_2020_12.h diff --git a/DEPENDENCIES b/DEPENDENCIES index 7291b73c..bccc1e97 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,4 +1,4 @@ vendorpull https://github.com/sourcemeta/vendorpull dea311b5bfb53b6926a4140267959ae334d3ecf4 noa https://github.com/sourcemeta/noa 5ff4024902642afc9cc2f9a9e02ae9dff9d15d4f -jsontoolkit https://github.com/sourcemeta/jsontoolkit 466493636bdc27725ad5b171141410ec072919bc +jsontoolkit https://github.com/sourcemeta/jsontoolkit 503146c9412c040bcbcdb9a09a6da42c300d3435 hydra https://github.com/sourcemeta/hydra d5e0c314dae88b0bf2ac4eeff2c7395910e2c7e9 diff --git a/src/command_test.cc b/src/command_test.cc index 19a2f443..8dd60755 100644 --- a/src/command_test.cc +++ b/src/command_test.cc @@ -7,6 +7,8 @@ #include "command.h" #include "utils.h" +// TODO: Add a flag to first validate schema against its metaschema +// TODO: Add a flag to prevent the use of HTTP resolution auto intelligence::jsonschema::cli::test( const std::span &arguments) -> int { const auto options{parse_options(arguments, {})}; diff --git a/src/command_validate.cc b/src/command_validate.cc index 81f50bae..0ac7a013 100644 --- a/src/command_validate.cc +++ b/src/command_validate.cc @@ -3,11 +3,15 @@ #include // EXIT_SUCCESS, EXIT_FAILURE #include // std::cerr +#include // std::set +#include // std::string #include "command.h" #include "utils.h" // TODO: Add a flag to first validate schema against its metaschema +// TODO: Add a flag to emit output using the standard JSON Schema output format +// TODO: Add a flag to prevent the use of HTTP resolution auto intelligence::jsonschema::cli::validate( const std::span &arguments) -> int { const auto options{parse_options(arguments, {})}; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3f6dfa5b..bc857144 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,7 +14,9 @@ add_jsonschema_test_unix(format_cwd) add_jsonschema_test_unix(frame) add_jsonschema_test_unix(validate_pass) add_jsonschema_test_unix(validate_fail) +add_jsonschema_test_unix(validate_non_supported) add_jsonschema_test_unix(bundle_non_remote) add_jsonschema_test_unix(bundle_remote_single_schema) add_jsonschema_test_unix(test_single_pass) add_jsonschema_test_unix(test_single_fail) +add_jsonschema_test_unix(test_single_unsupported) diff --git a/test/test_single_unsupported.sh b/test/test_single_unsupported.sh new file mode 100755 index 00000000..65389958 --- /dev/null +++ b/test/test_single_unsupported.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +set -o errexit +set -o nounset + +TMP="$(mktemp -d)" +# shellcheck disable=SC2317 +clean() { rm -rf "$TMP"; } +trap clean EXIT + +cat << 'EOF' > "$TMP/test.json" +{ + "description": "My sample suite", + "schema": "https://json-schema.org/draft/2020-12/schema", + "tests": [ + { + "description": "First test", + "valid": true, + "data": {} + }, + { + "description": "Invalid type, expected to fail", + "valid": true, + "data": { "type": 1 } + } + ] +} +EOF + +"$1" test "$TMP/test.json" && CODE="$?" || CODE="$?" + +if [ "$CODE" = "0" ] +then + echo "FAIL" 1>&2 + exit 1 +else + echo "PASS" 1>&2 + exit 0 +fi diff --git a/test/validate_non_supported.sh b/test/validate_non_supported.sh new file mode 100755 index 00000000..3efd5fb7 --- /dev/null +++ b/test/validate_non_supported.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +set -o errexit +set -o nounset + +TMP="$(mktemp -d)" +# shellcheck disable=SC2317 +clean() { rm -rf "$TMP"; } +trap clean EXIT + +cat << 'EOF' > "$TMP/schema.json" +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } +} +EOF + +cat << 'EOF' > "$TMP/instance.json" +{ "foo": 1 } +EOF + +"$1" validate "$TMP/schema.json" "$TMP/instance.json" && CODE="$?" || CODE="$?" + +if [ "$CODE" = "0" ] +then + echo "FAIL" 1>&2 + exit 1 +else + echo "PASS" 1>&2 + exit 0 +fi diff --git a/vendor/jsontoolkit/src/jsonschema/CMakeLists.txt b/vendor/jsontoolkit/src/jsonschema/CMakeLists.txt index 412f8d1e..bd0d47ec 100644 --- a/vendor/jsontoolkit/src/jsonschema/CMakeLists.txt +++ b/vendor/jsontoolkit/src/jsonschema/CMakeLists.txt @@ -10,7 +10,6 @@ noa_library(NAMESPACE sourcemeta PROJECT jsontoolkit NAME jsonschema walker.cc bundle.cc transformer.cc transform_rule.cc transform_bundle.cc compile.cc compile_evaluate.cc compile_json.cc compile_describe.cc compile_helpers.h default_compiler.cc - default_compiler_2020_12.h default_compiler_draft6.h default_compiler_draft4.h "${CMAKE_CURRENT_BINARY_DIR}/official_resolver.cc") diff --git a/vendor/jsontoolkit/src/jsonschema/default_compiler.cc b/vendor/jsontoolkit/src/jsonschema/default_compiler.cc index 0acec250..56a5b688 100644 --- a/vendor/jsontoolkit/src/jsonschema/default_compiler.cc +++ b/vendor/jsontoolkit/src/jsonschema/default_compiler.cc @@ -1,16 +1,32 @@ #include +#include -#include "default_compiler_2020_12.h" #include "default_compiler_draft4.h" #include "default_compiler_draft6.h" #include // assert +#include // std::set +#include // std::ostringstream +#include // std::string // TODO: Support every keyword auto sourcemeta::jsontoolkit::default_schema_compiler( const sourcemeta::jsontoolkit::SchemaCompilerContext &context) -> sourcemeta::jsontoolkit::SchemaCompilerTemplate { assert(!context.keyword.empty()); + + static std::set SUPPORTED_VOCABULARIES{ + "http://json-schema.org/draft-06/schema#", + "http://json-schema.org/draft-04/schema#"}; + for (const auto &vocabulary : context.vocabularies) { + if (!SUPPORTED_VOCABULARIES.contains(vocabulary.first) && + vocabulary.second) { + std::ostringstream error; + error << "Cannot compile unsupported vocabulary: " << vocabulary.first; + throw SchemaError(error.str()); + } + } + using namespace sourcemeta::jsontoolkit; #define COMPILE(vocabulary, _keyword, handler) \ @@ -25,13 +41,6 @@ auto sourcemeta::jsontoolkit::default_schema_compiler( return {}; \ } - // ******************************************** - // 2020-12 - // ******************************************** - - COMPILE("https://json-schema.org/draft/2020-12/vocab/validation", "type", - compiler_2020_12_validation_type); - // ******************************************** // DRAFT 6 // ******************************************** diff --git a/vendor/jsontoolkit/src/jsonschema/default_compiler_2020_12.h b/vendor/jsontoolkit/src/jsonschema/default_compiler_2020_12.h deleted file mode 100644 index 38b3e874..00000000 --- a/vendor/jsontoolkit/src/jsonschema/default_compiler_2020_12.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef SOURCEMETA_JSONTOOLKIT_JSONSCHEMA_DEFAULT_COMPILER_2020_12_H_ -#define SOURCEMETA_JSONTOOLKIT_JSONSCHEMA_DEFAULT_COMPILER_2020_12_H_ - -#include - -#include "default_compiler_draft4.h" - -namespace internal { -using namespace sourcemeta::jsontoolkit; - -auto compiler_2020_12_validation_type(const SchemaCompilerContext &context) - -> SchemaCompilerTemplate { - return compiler_draft4_validation_type(context); -} - -} // namespace internal - -#endif