Reorganize
Test-only code to tests Rename interface to CommitRequestParser
This commit is contained in:
147
tests/parser_comparison.cpp
Normal file
147
tests/parser_comparison.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "parser_comparison.hpp"
|
||||
#include <sstream>
|
||||
|
||||
std::string ParserComparison::last_error_;
|
||||
|
||||
ParserComparison::ComparisonResult
|
||||
ParserComparison::compare_parsers(const std::string &json_str) {
|
||||
last_error_.clear();
|
||||
|
||||
// Parse with weaseljson parser
|
||||
CommitRequest weasel_request;
|
||||
JsonCommitRequestParser weasel_parser;
|
||||
std::string mutable_json =
|
||||
json_str; // JsonCommitRequestParser needs mutable data
|
||||
auto weasel_result = weasel_parser.parse(weasel_request, mutable_json.data(),
|
||||
mutable_json.size());
|
||||
bool weasel_success =
|
||||
(weasel_result == CommitRequestParser::ParseResult::Success);
|
||||
|
||||
// Parse with nlohmann reference parser
|
||||
CommitRequest nlohmann_request;
|
||||
NlohmannReferenceParser nlohmann_parser;
|
||||
auto nlohmann_result = nlohmann_parser.parse(nlohmann_request, json_str);
|
||||
bool nlohmann_success =
|
||||
(nlohmann_result == NlohmannReferenceParser::ParseResult::Success);
|
||||
|
||||
// Compare results
|
||||
if (weasel_success && nlohmann_success) {
|
||||
// Both succeeded - check if they produce equivalent results
|
||||
if (requests_equal(weasel_request, nlohmann_request)) {
|
||||
return ComparisonResult::BothSuccess;
|
||||
} else {
|
||||
std::ostringstream oss;
|
||||
oss << "Parsers produced different results. ";
|
||||
oss << "Weasel: request_id="
|
||||
<< (weasel_request.request_id().has_value()
|
||||
? weasel_request.request_id().value()
|
||||
: "none");
|
||||
oss << ", leader_id='" << weasel_request.leader_id() << "'";
|
||||
oss << ", read_version=" << weasel_request.read_version();
|
||||
oss << ", preconditions=" << weasel_request.preconditions().size();
|
||||
oss << ", operations=" << weasel_request.operations().size() << ". ";
|
||||
oss << "Nlohmann: request_id="
|
||||
<< (nlohmann_request.request_id().has_value()
|
||||
? nlohmann_request.request_id().value()
|
||||
: "none");
|
||||
oss << ", leader_id='" << nlohmann_request.leader_id() << "'";
|
||||
oss << ", read_version=" << nlohmann_request.read_version();
|
||||
oss << ", preconditions=" << nlohmann_request.preconditions().size();
|
||||
oss << ", operations=" << nlohmann_request.operations().size();
|
||||
last_error_ = oss.str();
|
||||
return ComparisonResult::DifferentResults;
|
||||
}
|
||||
} else if (!weasel_success && !nlohmann_success) {
|
||||
// Both failed - this is expected for invalid JSON
|
||||
return ComparisonResult::BothFailure;
|
||||
} else if (weasel_success && !nlohmann_success) {
|
||||
// Weasel succeeded but nlohmann failed
|
||||
last_error_ = "Weasel parser succeeded but nlohmann failed: " +
|
||||
nlohmann_parser.get_error();
|
||||
return ComparisonResult::WeaselSuccessNlohmannFail;
|
||||
} else {
|
||||
// Nlohmann succeeded but weasel failed
|
||||
last_error_ = "Nlohmann parser succeeded but weasel failed";
|
||||
if (weasel_parser.get_parse_error()) {
|
||||
last_error_ += ": " + std::string(weasel_parser.get_parse_error());
|
||||
}
|
||||
return ComparisonResult::NlohmannSuccessWeaselFail;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ParserComparison::result_to_string(ComparisonResult result) {
|
||||
switch (result) {
|
||||
case ComparisonResult::BothSuccess:
|
||||
return "Both parsers succeeded with equivalent results";
|
||||
case ComparisonResult::BothFailure:
|
||||
return "Both parsers failed (as expected)";
|
||||
case ComparisonResult::WeaselSuccessNlohmannFail:
|
||||
return "Weasel succeeded but nlohmann failed";
|
||||
case ComparisonResult::NlohmannSuccessWeaselFail:
|
||||
return "Nlohmann succeeded but weasel failed";
|
||||
case ComparisonResult::DifferentResults:
|
||||
return "Both succeeded but produced different results";
|
||||
default:
|
||||
return "Unknown result";
|
||||
}
|
||||
}
|
||||
|
||||
bool ParserComparison::requests_equal(const CommitRequest &req1,
|
||||
const CommitRequest &req2) {
|
||||
// Compare request_id
|
||||
if (req1.request_id().has_value() != req2.request_id().has_value()) {
|
||||
return false;
|
||||
}
|
||||
if (req1.request_id().has_value() &&
|
||||
req1.request_id().value() != req2.request_id().value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare leader_id
|
||||
if (req1.leader_id() != req2.leader_id()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare read_version
|
||||
if (req1.read_version() != req2.read_version()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare preconditions
|
||||
auto prec1 = req1.preconditions();
|
||||
auto prec2 = req2.preconditions();
|
||||
if (prec1.size() != prec2.size()) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < prec1.size(); ++i) {
|
||||
if (!preconditions_equal(prec1[i], prec2[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare operations
|
||||
auto ops1 = req1.operations();
|
||||
auto ops2 = req2.operations();
|
||||
if (ops1.size() != ops2.size()) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < ops1.size(); ++i) {
|
||||
if (!operations_equal(ops1[i], ops2[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParserComparison::preconditions_equal(const Precondition &p1,
|
||||
const Precondition &p2) {
|
||||
return p1.type == p2.type && p1.version == p2.version &&
|
||||
p1.begin == p2.begin && p1.end == p2.end;
|
||||
}
|
||||
|
||||
bool ParserComparison::operations_equal(const Operation &op1,
|
||||
const Operation &op2) {
|
||||
return op1.type == op2.type && op1.param1 == op2.param1 &&
|
||||
op1.param2 == op2.param2;
|
||||
}
|
||||
Reference in New Issue
Block a user