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
11 changes: 11 additions & 0 deletions test/evaluator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,14 @@ target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_unit PRIVATE source
target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_unit PRIVATE sourcemeta::core::jsonschema)
target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_unit PRIVATE sourcemeta::blaze::compiler)
target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_unit PRIVATE sourcemeta::blaze::evaluator)

# Evaluator trace suite with canonicalization (JSON-driven)
sourcemeta_googletest(NAMESPACE sourcemeta PROJECT blaze NAME evaluator_trace_suite_canonical
FOLDER "Blaze/Evaluator" SOURCES tracesuite_canonical.cc)
target_compile_definitions(sourcemeta_blaze_evaluator_trace_suite_canonical_unit
PRIVATE TRACE_SUITE_CANONICAL_PATH="${PROJECT_SOURCE_DIR}/test/evaluator")
target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_canonical_unit PRIVATE sourcemeta::core::json)
target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_canonical_unit PRIVATE sourcemeta::core::jsonschema)
target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_canonical_unit PRIVATE sourcemeta::blaze::compiler)
target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_canonical_unit PRIVATE sourcemeta::blaze::evaluator)
target_link_libraries(sourcemeta_blaze_evaluator_trace_suite_canonical_unit PRIVATE sourcemeta::blaze::alterschema)
118 changes: 118 additions & 0 deletions test/evaluator/tracesuite_canonical.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include <gtest/gtest.h>

#include <sourcemeta/blaze/alterschema.h>
#include <sourcemeta/blaze/compiler.h>
#include <sourcemeta/blaze/evaluator.h>

#include <sourcemeta/core/json.h>
#include <sourcemeta/core/jsonschema.h>

#include "evaluator_utils.h"

#include <cassert> // assert
#include <cstdio> // std::fprintf
#include <filesystem> // std::filesystem::path
#include <string> // std::string
#include <utility> // std::move

class CanonicalizeTest : public testing::Test {
public:
explicit CanonicalizeTest(sourcemeta::core::JSON test_data,
const sourcemeta::blaze::Mode test_mode)
: data{std::move(test_data)}, mode{test_mode} {}

auto TestBody() -> void override {
auto schema{this->data.at("schema")};
const auto &instance{this->data.at("instance")};
const bool expected_valid{this->data.at("valid").to_boolean()};

sourcemeta::blaze::SchemaTransformer bundle;
sourcemeta::blaze::add(bundle,
sourcemeta::blaze::AlterSchemaMode::Canonicalizer);
const auto canonicalize_result{
bundle.apply(schema, sourcemeta::core::schema_walker,
sourcemeta::core::schema_resolver,
[](const auto &, const auto &, const auto &, const auto &,
const auto &) {})};
EXPECT_TRUE(canonicalize_result.first);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test/evaluator/tracesuite_canonical.cc:37: If bundle.apply() reports failure, the test continues to compile/validate anyway, which can hide the root cause behind later failures or exceptions. A fatal failure here would make canonicalisation problems surface more clearly.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


const auto compiled_schema{sourcemeta::blaze::compile(
schema, sourcemeta::core::schema_walker,
sourcemeta::core::schema_resolver,
sourcemeta::blaze::default_schema_compiler, this->mode)};
__ASSERT_TEMPLATE_JSON_SERIALISATION(compiled_schema);

sourcemeta::blaze::Evaluator evaluator;
const auto result{evaluator.validate(compiled_schema, instance)};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test/evaluator/tracesuite_canonical.cc:46: This “trace suite” only asserts the final validate() boolean and never checks the expected trace output (unlike tracesuite.cc which uses EVALUATE_WITH_TRACE/trace expectations). If the goal is to run the trace suite through canonicalisation, this won’t catch regressions where canonicalisation changes the produced trace while preserving validity.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


if (expected_valid) {
EXPECT_TRUE(result);
} else {
EXPECT_FALSE(result);
}
}

private:
const sourcemeta::core::JSON data;
const sourcemeta::blaze::Mode mode;
};

static auto register_tests(const std::filesystem::path &path,
const std::string &suite_name) -> void {
std::fprintf(stderr, "-- Parsing: %s\n", path.string().c_str());
auto suite{sourcemeta::core::read_json(path)};
assert(suite.is_array());

for (const auto &test_case : suite.as_array()) {
assert(test_case.is_object());
assert(test_case.defines("description"));
const auto &description{test_case.at("description").to_string()};

for (const auto &[mode_suffix, mode] :
{std::pair<const char *, sourcemeta::blaze::Mode>{
"_fast", sourcemeta::blaze::Mode::FastValidation},
std::pair<const char *, sourcemeta::blaze::Mode>{
"_exhaustive", sourcemeta::blaze::Mode::Exhaustive}}) {

const auto title{description + mode_suffix};

testing::RegisterTest(suite_name.c_str(), title.c_str(), nullptr, nullptr,
__FILE__, __LINE__, [=]() -> CanonicalizeTest * {
return new CanonicalizeTest(test_case, mode);
});
}
}
}

auto main(int argc, char **argv) -> int {
testing::InitGoogleTest(&argc, argv);

try {
register_tests(std::filesystem::path{TRACE_SUITE_CANONICAL_PATH} /
"evaluator_openapi_3_1.json",
"Canonicalize_OpenAPI_3_1");
register_tests(std::filesystem::path{TRACE_SUITE_CANONICAL_PATH} /
"evaluator_openapi_3_2.json",
"Canonicalize_OpenAPI_3_2");
register_tests(std::filesystem::path{TRACE_SUITE_CANONICAL_PATH} /
"evaluator_draft7.json",
"Canonicalize_draft7");
register_tests(std::filesystem::path{TRACE_SUITE_CANONICAL_PATH} /
"evaluator_2019_09.json",
"Canonicalize_2019_09");
register_tests(std::filesystem::path{TRACE_SUITE_CANONICAL_PATH} /
"evaluator_draft6.json",
"Canonicalize_draft6");
register_tests(std::filesystem::path{TRACE_SUITE_CANONICAL_PATH} /
"evaluator_2020_12.json",
"Canonicalize_2020_12");
register_tests(std::filesystem::path{TRACE_SUITE_CANONICAL_PATH} /
"evaluator_draft4.json",
"Canonicalize_draft4");
} catch (const std::exception &error) {
std::fprintf(stderr, "Error: %s\n", error.what());
return EXIT_FAILURE;
}

return RUN_ALL_TESTS();
}
Loading