Skip to content

Commit

Permalink
Allow older JSON Schema dialects (#809)
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti authored Sep 26, 2024
1 parent df1d2e4 commit 831c916
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 25 deletions.
13 changes: 1 addition & 12 deletions src/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,6 @@ auto compile(sourcemeta::jsontoolkit::JSON &schema,
const std::optional<std::string> &default_dialect) -> void {
canonicalize(schema, walker, resolver, default_dialect);

const auto mapper_resolver{make_resolver(resolver)};
const auto base_dialect{sourcemeta::jsontoolkit::base_dialect(
schema, mapper_resolver, default_dialect)
.get()};

// TODO: Use a custom error here
if (!base_dialect.has_value() ||
base_dialect.value() != "https://json-schema.org/draft/2020-12/schema") {
throw std::domain_error("Only JSON Schema 2020-12 is supported");
}

sourcemeta::alterschema::Bundle mapper;

// Enums
Expand All @@ -135,7 +124,7 @@ auto compile(sourcemeta::jsontoolkit::JSON &schema,
// Numbers
mapper.add<NumberArbitrary>();

mapper.apply(schema, walker, mapper_resolver,
mapper.apply(schema, walker, make_resolver(resolver),
sourcemeta::jsontoolkit::empty_pointer, default_dialect);

// The "any" encoding is always the last resort
Expand Down
197 changes: 184 additions & 13 deletions test/compiler/compiler_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,170 @@

#include <stdexcept>

TEST(JSONBinPack_Compiler, unsupported_draft) {
sourcemeta::jsontoolkit::JSON schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "boolean"
TEST(JSONBinPack_Compiler, dialect_2020_12) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema"
})JSON");

EXPECT_THROW(sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver,
"https://json-schema.org/draft/2020-12/schema"),
std::domain_error);
sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, dialect_2019_09) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema"
})JSON");

sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, dialect_draft7) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "http://json-schema.org/draft-07/schema#"
})JSON");

sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, dialect_draft6) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "http://json-schema.org/draft-06/schema#"
})JSON");

sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, unknown_draft_default) {
sourcemeta::jsontoolkit::JSON schema = sourcemeta::jsontoolkit::parse(R"JSON({
TEST(JSONBinPack_Compiler, dialect_draft4) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "http://json-schema.org/draft-04/schema#"
})JSON");

sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, dialect_draft3) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "http://json-schema.org/draft-03/schema#"
})JSON");

sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, dialect_draft2) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "http://json-schema.org/draft-02/schema#"
})JSON");

sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, dialect_draft1) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "http://json-schema.org/draft-01/schema#"
})JSON");

sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, dialect_draft0) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "http://json-schema.org/draft-00/schema#"
})JSON");

sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver);

const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ANY_PACKED_TYPE_TAG_BYTE_PREFIX",
"options": {}
})JSON");

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, unknown_dialect_default) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"type": "integer"
})JSON");

Expand All @@ -28,8 +177,7 @@ TEST(JSONBinPack_Compiler, unknown_draft_default) {
sourcemeta::jsontoolkit::official_resolver,
"https://json-schema.org/draft/2020-12/schema");

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://jsonbinpack.sourcemeta.com/schemas/encoding/v1.json",
"name": "ARBITRARY_MULTIPLE_ZIGZAG_VARINT",
"options": {
Expand All @@ -39,3 +187,26 @@ TEST(JSONBinPack_Compiler, unknown_draft_default) {

EXPECT_EQ(schema, expected);
}

TEST(JSONBinPack_Compiler, unknown_dialect_without_default) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"type": "integer"
})JSON");

EXPECT_THROW(sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver),
sourcemeta::jsontoolkit::SchemaError);
}

TEST(JSONBinPack_Compiler, invalid_dialect) {
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://foo.com",
"type": "integer"
})JSON");

EXPECT_THROW(sourcemeta::jsonbinpack::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver),
sourcemeta::jsontoolkit::SchemaResolutionError);
}

0 comments on commit 831c916

Please sign in to comment.