Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,32 @@ class CustomResolver {
<< " at " << entry.first << "\n"
<< "Are you sure this schema sets any identifiers?\n";
}
} catch (const sourcemeta::core::SchemaKeywordError &error) {
throw FileError<sourcemeta::core::SchemaKeywordError>(
entry.resolution_base, error);
} catch (const sourcemeta::core::SchemaFrameError &error) {
throw FileError<sourcemeta::core::SchemaFrameError>(
entry.resolution_base, std::string{error.identifier()},
error.what());
} catch (const sourcemeta::core::SchemaReferenceError &error) {
throw FileError<sourcemeta::core::SchemaReferenceError>(
entry.resolution_base, std::string{error.identifier()},
error.location(), error.what());
} catch (const sourcemeta::core::SchemaUnknownBaseDialectError &) {
throw FileError<sourcemeta::core::SchemaUnknownBaseDialectError>(
entry.resolution_base);
} catch (const sourcemeta::core::SchemaRelativeMetaschemaResolutionError
&error) {
throw FileError<
sourcemeta::core::SchemaRelativeMetaschemaResolutionError>(
entry.resolution_base, error);
} catch (const sourcemeta::core::SchemaResolutionError &error) {
throw FileError<sourcemeta::core::SchemaResolutionError>(
entry.resolution_base, std::string{error.identifier()},
error.what());
} catch (const sourcemeta::core::SchemaError &error) {
throw FileError<sourcemeta::core::SchemaError>(entry.resolution_base,
error.what());
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ add_jsonschema_test_unix(validate/fail_schema_enoent)
add_jsonschema_test_unix(validate/fail_schema_invalid_json)
add_jsonschema_test_unix(validate/fail_schema_non_schema)
add_jsonschema_test_unix(validate/fail_schema_unknown_dialect)
add_jsonschema_test_unix(validate/fail_resolve_unknown_dialect)
add_jsonschema_test_unix(validate/fail_resolve_invalid_id)
add_jsonschema_test_unix(validate/fail_resolve_invalid_recursive_ref)
add_jsonschema_test_unix(validate/fail_resolve_missing_core_vocabulary)
add_jsonschema_test_unix(validate/fail_resolve_relative_metaschema)
add_jsonschema_test_unix(validate/pass_jsonl_bigint)
add_jsonschema_test_unix(validate/fail_trace)
add_jsonschema_test_unix(validate/fail_trace_fast)
Expand Down
59 changes: 59 additions & 0 deletions test/validate/fail_resolve_invalid_id.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.json"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object"
}
EOF

cat << 'EOF' > "$TMP/resolve.json"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "not a valid uri ::",
"type": "string"
}
EOF

cat << 'EOF' > "$TMP/instance.json"
{ "foo": "bar" }
EOF

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/resolve.json" 2>"$TMP/stderr.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
error: The identifier is not a valid URI
at value not a valid uri ::
at keyword \$id
at file path $(realpath "$TMP")/resolve.json

Are you sure the input is a valid JSON Schema and it is valid according to its meta-schema?
EOF

diff "$TMP/stderr.txt" "$TMP/expected.txt"

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/resolve.json" --json >"$TMP/stdout.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
{
"error": "The identifier is not a valid URI",
"value": "not a valid uri ::",
"keyword": "\$id",
"filePath": "$(realpath "$TMP")/resolve.json"
}
EOF

diff "$TMP/stdout.txt" "$TMP/expected.txt"
57 changes: 57 additions & 0 deletions test/validate/fail_resolve_invalid_recursive_ref.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.json"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object"
}
EOF

cat << 'EOF' > "$TMP/resolve.json"
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "https://example.com/bad-recref",
"$recursiveRef": "not-hash"
}
EOF

cat << 'EOF' > "$TMP/instance.json"
{ "foo": "bar" }
EOF

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/resolve.json" 2>"$TMP/stderr.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
error: Invalid recursive reference
at identifier https://example.com/bad-recref
at file path $(realpath "$TMP")/resolve.json
at location "/\$recursiveRef"
EOF

diff "$TMP/stderr.txt" "$TMP/expected.txt"

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/resolve.json" --json >"$TMP/stdout.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
{
"error": "Invalid recursive reference",
"identifier": "https://example.com/bad-recref",
"filePath": "$(realpath "$TMP")/resolve.json",
"location": "/\$recursiveRef"
}
EOF

diff "$TMP/stdout.txt" "$TMP/expected.txt"
63 changes: 63 additions & 0 deletions test/validate/fail_resolve_missing_core_vocabulary.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.json"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object"
}
EOF

cat << 'EOF' > "$TMP/meta.json"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/my-meta",
"$vocabulary": {
"https://example.com/fake-vocab": true
}
}
EOF

cat << 'EOF' > "$TMP/resolve.json"
{
"$schema": "https://example.com/my-meta",
"$id": "https://example.com/my-schema",
"type": "string"
}
EOF

cat << 'EOF' > "$TMP/instance.json"
{ "foo": "bar" }
EOF

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/meta.json" --resolve "$TMP/resolve.json" 2>"$TMP/stderr.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
error: The core vocabulary must always be present
at file path $(realpath "$TMP")/resolve.json
EOF

diff "$TMP/stderr.txt" "$TMP/expected.txt"

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/meta.json" --resolve "$TMP/resolve.json" --json >"$TMP/stdout.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
{
"error": "The core vocabulary must always be present",
"filePath": "$(realpath "$TMP")/resolve.json"
}
EOF

diff "$TMP/stdout.txt" "$TMP/expected.txt"
55 changes: 55 additions & 0 deletions test/validate/fail_resolve_relative_metaschema.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.json"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object"
}
EOF

cat << 'EOF' > "$TMP/resolve.json"
{
"$schema": "relative/path",
"$id": "https://example.com/relative-test",
"type": "string"
}
EOF

cat << 'EOF' > "$TMP/instance.json"
{ "foo": "bar" }
EOF

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/resolve.json" 2>"$TMP/stderr.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
error: Relative meta-schema URIs are not valid according to the JSON Schema specification
at identifier relative/path
at file path $(realpath "$TMP")/resolve.json
EOF

diff "$TMP/stderr.txt" "$TMP/expected.txt"

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/resolve.json" --json >"$TMP/stdout.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
{
"error": "Relative meta-schema URIs are not valid according to the JSON Schema specification",
"identifier": "relative/path",
"filePath": "$(realpath "$TMP")/resolve.json"
}
EOF

diff "$TMP/stdout.txt" "$TMP/expected.txt"
57 changes: 57 additions & 0 deletions test/validate/fail_resolve_unknown_dialect.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.json"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object"
}
EOF

cat << 'EOF' > "$TMP/resolve.json"
{
"$schema": "https://example.com/unknown-metaschema",
"$id": "https://example.com/resolve",
"type": "string"
}
EOF

cat << 'EOF' > "$TMP/instance.json"
{ "foo": "bar" }
EOF

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/resolve.json" 2>"$TMP/stderr.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
error: Could not resolve the metaschema of the schema
at identifier https://example.com/unknown-metaschema
at file path $(realpath "$TMP")/resolve.json

This is likely because you forgot to import such schema using \`--resolve/-r\`
EOF

diff "$TMP/stderr.txt" "$TMP/expected.txt"

"$1" validate "$TMP/schema.json" "$TMP/instance.json" \
--resolve "$TMP/resolve.json" --json >"$TMP/stdout.txt" \
&& EXIT_CODE="$?" || EXIT_CODE="$?"
test "$EXIT_CODE" = "1" || exit 1

cat << EOF > "$TMP/expected.txt"
{
"error": "Could not resolve the metaschema of the schema",
"identifier": "https://example.com/unknown-metaschema",
"filePath": "$(realpath "$TMP")/resolve.json"
}
EOF

diff "$TMP/stdout.txt" "$TMP/expected.txt"