Make codebase consistent with design.md
This commit is contained in:
@@ -78,8 +78,10 @@ find_package(weaseljson REQUIRED)
|
|||||||
find_program(GPERF_EXECUTABLE gperf REQUIRED)
|
find_program(GPERF_EXECUTABLE gperf REQUIRED)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_BINARY_DIR}/json_tokens.cpp
|
OUTPUT ${CMAKE_BINARY_DIR}/json_tokens.cpp
|
||||||
COMMAND ${GPERF_EXECUTABLE} ${CMAKE_SOURCE_DIR}/src/json_tokens.gperf >
|
COMMAND
|
||||||
${CMAKE_BINARY_DIR}/json_tokens.cpp
|
${GPERF_EXECUTABLE} --class-name=PerfectHash
|
||||||
|
${CMAKE_SOURCE_DIR}/src/json_tokens.gperf >
|
||||||
|
${CMAKE_BINARY_DIR}/json_tokens.cpp
|
||||||
DEPENDS ${CMAKE_SOURCE_DIR}/src/json_tokens.gperf
|
DEPENDS ${CMAKE_SOURCE_DIR}/src/json_tokens.gperf
|
||||||
COMMENT "Generating JSON token hash table with gperf")
|
COMMENT "Generating JSON token hash table with gperf")
|
||||||
add_custom_target(generate_json_tokens
|
add_custom_target(generate_json_tokens
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ int main() {
|
|||||||
CommitRequest request;
|
CommitRequest request;
|
||||||
JsonCommitRequestParser parser;
|
JsonCommitRequestParser parser;
|
||||||
std::string mutable_json = SIMPLE_JSON;
|
std::string mutable_json = SIMPLE_JSON;
|
||||||
bool result =
|
auto result =
|
||||||
parser.parse(request, mutable_json.data(), mutable_json.size());
|
parser.parse(request, mutable_json.data(), mutable_json.size());
|
||||||
ankerl::nanobench::doNotOptimizeAway(result);
|
ankerl::nanobench::doNotOptimizeAway(result);
|
||||||
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
||||||
@@ -34,7 +34,7 @@ int main() {
|
|||||||
CommitRequest request;
|
CommitRequest request;
|
||||||
JsonCommitRequestParser parser;
|
JsonCommitRequestParser parser;
|
||||||
std::string mutable_json = MEDIUM_JSON;
|
std::string mutable_json = MEDIUM_JSON;
|
||||||
bool result =
|
auto result =
|
||||||
parser.parse(request, mutable_json.data(), mutable_json.size());
|
parser.parse(request, mutable_json.data(), mutable_json.size());
|
||||||
ankerl::nanobench::doNotOptimizeAway(result);
|
ankerl::nanobench::doNotOptimizeAway(result);
|
||||||
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
||||||
@@ -46,7 +46,7 @@ int main() {
|
|||||||
CommitRequest request;
|
CommitRequest request;
|
||||||
JsonCommitRequestParser parser;
|
JsonCommitRequestParser parser;
|
||||||
std::string mutable_json = COMPLEX_JSON;
|
std::string mutable_json = COMPLEX_JSON;
|
||||||
bool result =
|
auto result =
|
||||||
parser.parse(request, mutable_json.data(), mutable_json.size());
|
parser.parse(request, mutable_json.data(), mutable_json.size());
|
||||||
ankerl::nanobench::doNotOptimizeAway(result);
|
ankerl::nanobench::doNotOptimizeAway(result);
|
||||||
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
||||||
@@ -60,7 +60,7 @@ int main() {
|
|||||||
CommitRequest request;
|
CommitRequest request;
|
||||||
JsonCommitRequestParser parser;
|
JsonCommitRequestParser parser;
|
||||||
std::string mutable_json = large_json;
|
std::string mutable_json = large_json;
|
||||||
bool result =
|
auto result =
|
||||||
parser.parse(request, mutable_json.data(), mutable_json.size());
|
parser.parse(request, mutable_json.data(), mutable_json.size());
|
||||||
ankerl::nanobench::doNotOptimizeAway(result);
|
ankerl::nanobench::doNotOptimizeAway(result);
|
||||||
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ int main() {
|
|||||||
CommitRequest request;
|
CommitRequest request;
|
||||||
JsonCommitRequestParser parser;
|
JsonCommitRequestParser parser;
|
||||||
std::string mutable_json = SIMPLE_JSON;
|
std::string mutable_json = SIMPLE_JSON;
|
||||||
bool result =
|
auto result =
|
||||||
parser.parse(request, mutable_json.data(), mutable_json.size());
|
parser.parse(request, mutable_json.data(), mutable_json.size());
|
||||||
ankerl::nanobench::doNotOptimizeAway(result);
|
ankerl::nanobench::doNotOptimizeAway(result);
|
||||||
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
||||||
@@ -550,7 +550,7 @@ int main() {
|
|||||||
CommitRequest request;
|
CommitRequest request;
|
||||||
JsonCommitRequestParser parser;
|
JsonCommitRequestParser parser;
|
||||||
std::string mutable_json = MEDIUM_JSON;
|
std::string mutable_json = MEDIUM_JSON;
|
||||||
bool result =
|
auto result =
|
||||||
parser.parse(request, mutable_json.data(), mutable_json.size());
|
parser.parse(request, mutable_json.data(), mutable_json.size());
|
||||||
ankerl::nanobench::doNotOptimizeAway(result);
|
ankerl::nanobench::doNotOptimizeAway(result);
|
||||||
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
||||||
@@ -631,7 +631,7 @@ int main() {
|
|||||||
CommitRequest request;
|
CommitRequest request;
|
||||||
JsonCommitRequestParser parser;
|
JsonCommitRequestParser parser;
|
||||||
std::string mutable_json = COMPLEX_JSON;
|
std::string mutable_json = COMPLEX_JSON;
|
||||||
bool result =
|
auto result =
|
||||||
parser.parse(request, mutable_json.data(), mutable_json.size());
|
parser.parse(request, mutable_json.data(), mutable_json.size());
|
||||||
ankerl::nanobench::doNotOptimizeAway(result);
|
ankerl::nanobench::doNotOptimizeAway(result);
|
||||||
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
||||||
@@ -715,7 +715,7 @@ int main() {
|
|||||||
CommitRequest request;
|
CommitRequest request;
|
||||||
JsonCommitRequestParser parser;
|
JsonCommitRequestParser parser;
|
||||||
std::string mutable_json = large_json;
|
std::string mutable_json = large_json;
|
||||||
bool result =
|
auto result =
|
||||||
parser.parse(request, mutable_json.data(), mutable_json.size());
|
parser.parse(request, mutable_json.data(), mutable_json.size());
|
||||||
ankerl::nanobench::doNotOptimizeAway(result);
|
ankerl::nanobench::doNotOptimizeAway(result);
|
||||||
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
ankerl::nanobench::doNotOptimizeAway(request.leader_id());
|
||||||
|
|||||||
@@ -449,16 +449,33 @@ void JsonCommitRequestParser::handle_completed_number(std::string_view s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonCommitRequestParser::parse(CommitRequest &request, char *data,
|
CommitRequestParser::ParseResult
|
||||||
size_t len) {
|
JsonCommitRequestParser::parse(CommitRequest &request, char *data, size_t len) {
|
||||||
if (!begin_streaming_parse(request)) {
|
if (!begin_streaming_parse(request)) {
|
||||||
return false;
|
return ParseResult::OutOfMemory;
|
||||||
}
|
}
|
||||||
parse_chunk(data, len);
|
|
||||||
finish_streaming_parse();
|
|
||||||
|
|
||||||
return !has_parse_error() && !request.leader_id().empty() &&
|
ParseStatus status = parse_chunk(data, len);
|
||||||
parser_context_->has_read_version_been_set;
|
if (status == ParseStatus::Error) {
|
||||||
|
return has_parse_error() ? ParseResult::InvalidJson
|
||||||
|
: ParseResult::InvalidField;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = finish_streaming_parse();
|
||||||
|
if (status == ParseStatus::Error) {
|
||||||
|
return has_parse_error() ? ParseResult::InvalidJson
|
||||||
|
: ParseResult::InvalidField;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.leader_id().empty()) {
|
||||||
|
return ParseResult::MissingField;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parser_context_->has_read_version_been_set) {
|
||||||
|
return ParseResult::MissingField;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonCommitRequestParser::begin_streaming_parse(CommitRequest &request) {
|
bool JsonCommitRequestParser::begin_streaming_parse(CommitRequest &request) {
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public:
|
|||||||
JsonCommitRequestParser &operator=(JsonCommitRequestParser &&other) noexcept;
|
JsonCommitRequestParser &operator=(JsonCommitRequestParser &&other) noexcept;
|
||||||
|
|
||||||
// CommitRequestParser interface implementation
|
// CommitRequestParser interface implementation
|
||||||
bool parse(CommitRequest &request, char *data, size_t len) override;
|
ParseResult parse(CommitRequest &request, char *data, size_t len) override;
|
||||||
bool begin_streaming_parse(CommitRequest &request) override;
|
bool begin_streaming_parse(CommitRequest &request) override;
|
||||||
ParseStatus parse_chunk(char *data, size_t len) override;
|
ParseStatus parse_chunk(char *data, size_t len) override;
|
||||||
ParseStatus finish_streaming_parse() override;
|
ParseStatus finish_streaming_parse() override;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ enum class JsonTokenType {
|
|||||||
*/
|
*/
|
||||||
inline JsonTokenType get_json_token_type(std::string_view str) {
|
inline JsonTokenType get_json_token_type(std::string_view str) {
|
||||||
const JsonToken *token =
|
const JsonToken *token =
|
||||||
Perfect_Hash::lookup_json_token(str.data(), str.size());
|
PerfectHash::lookup_json_token(str.data(), str.size());
|
||||||
if (token) {
|
if (token) {
|
||||||
return static_cast<JsonTokenType>(token->token_id);
|
return static_cast<JsonTokenType>(token->token_id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ struct JsonToken {
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* const JsonToken* token = Perfect_Hash::lookup_json_token("request_id", 10);
|
* const JsonToken* token = PerfectHash::lookup_json_token("request_id", 10);
|
||||||
* if (token) {
|
* if (token) {
|
||||||
* JsonTokenType type = static_cast<JsonTokenType>(token->token_id);
|
* JsonTokenType type = static_cast<JsonTokenType>(token->token_id);
|
||||||
* // Handle known token...
|
* // Handle known token...
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class Perfect_Hash {
|
class PerfectHash {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Look up a JSON token by name using perfect hash.
|
* @brief Look up a JSON token by name using perfect hash.
|
||||||
|
|||||||
22
src/main.cpp
22
src/main.cpp
@@ -87,10 +87,28 @@ int main(int argc, char *argv[]) {
|
|||||||
})";
|
})";
|
||||||
auto copy = sample_json;
|
auto copy = sample_json;
|
||||||
|
|
||||||
if (parser.parse(request, copy.data(), copy.size())) {
|
auto parse_result = parser.parse(request, copy.data(), copy.size());
|
||||||
|
if (parse_result == CommitRequestParser::ParseResult::Success) {
|
||||||
print_stats(request);
|
print_stats(request);
|
||||||
} else {
|
} else {
|
||||||
std::cout << "✗ Failed to parse commit request" << std::endl;
|
std::cout << "✗ Failed to parse commit request: ";
|
||||||
|
switch (parse_result) {
|
||||||
|
case CommitRequestParser::ParseResult::InvalidJson:
|
||||||
|
std::cout << "Invalid JSON format" << std::endl;
|
||||||
|
break;
|
||||||
|
case CommitRequestParser::ParseResult::MissingField:
|
||||||
|
std::cout << "Missing required field" << std::endl;
|
||||||
|
break;
|
||||||
|
case CommitRequestParser::ParseResult::InvalidField:
|
||||||
|
std::cout << "Invalid field value" << std::endl;
|
||||||
|
break;
|
||||||
|
case CommitRequestParser::ParseResult::OutOfMemory:
|
||||||
|
std::cout << "Out of memory" << std::endl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cout << "Unknown error" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Demonstrate streaming parsing
|
// Demonstrate streaming parsing
|
||||||
|
|||||||
@@ -24,6 +24,17 @@ public:
|
|||||||
Error ///< Parse error occurred (check get_parse_error() for details)
|
Error ///< Parse error occurred (check get_parse_error() for details)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Result type for one-shot parsing operations.
|
||||||
|
*/
|
||||||
|
enum class ParseResult {
|
||||||
|
Success, ///< Parsing completed successfully
|
||||||
|
InvalidJson, ///< Invalid JSON format or structure
|
||||||
|
MissingField, ///< Required field missing from input
|
||||||
|
InvalidField, ///< Field value is invalid or malformed
|
||||||
|
OutOfMemory ///< Arena allocation failed
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~CommitRequestParser() = default;
|
virtual ~CommitRequestParser() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,9 +42,9 @@ public:
|
|||||||
* @param request The CommitRequest object to populate
|
* @param request The CommitRequest object to populate
|
||||||
* @param data Pointer to the data buffer
|
* @param data Pointer to the data buffer
|
||||||
* @param len Length of the data in bytes
|
* @param len Length of the data in bytes
|
||||||
* @return true if parsing succeeded, false otherwise
|
* @return ParseResult indicating success or specific error type
|
||||||
*/
|
*/
|
||||||
virtual bool parse(CommitRequest &request, char *data, size_t len) = 0;
|
virtual ParseResult parse(CommitRequest &request, char *data, size_t len) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize streaming parsing.
|
* @brief Initialize streaming parsing.
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
REQUIRE(request.request_id().has_value());
|
REQUIRE(request.request_id().has_value());
|
||||||
REQUIRE(request.request_id().value() == "test123");
|
REQUIRE(request.request_id().value() == "test123");
|
||||||
REQUIRE(request.leader_id() == "leader456");
|
REQUIRE(request.leader_id() == "leader456");
|
||||||
@@ -38,7 +39,8 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
REQUIRE(request.preconditions().size() == 1);
|
REQUIRE(request.preconditions().size() == 1);
|
||||||
REQUIRE(request.preconditions()[0].type == Precondition::Type::PointRead);
|
REQUIRE(request.preconditions()[0].type == Precondition::Type::PointRead);
|
||||||
REQUIRE(request.preconditions()[0].version == 12340);
|
REQUIRE(request.preconditions()[0].version == 12340);
|
||||||
@@ -64,7 +66,8 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
REQUIRE(request.operations().size() == 2);
|
REQUIRE(request.operations().size() == 2);
|
||||||
|
|
||||||
REQUIRE(request.operations()[0].type == Operation::Type::Write);
|
REQUIRE(request.operations()[0].type == Operation::Type::Write);
|
||||||
@@ -82,8 +85,9 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
"read_version": "not_a_number"
|
"read_version": "not_a_number"
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Missing required leader_id") {
|
SUBCASE("Missing required leader_id") {
|
||||||
@@ -92,8 +96,9 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
"read_version": 12345
|
"read_version": 12345
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
// Check completion based on required fields
|
// Check completion based on required fields
|
||||||
REQUIRE(request.leader_id().empty());
|
REQUIRE(request.leader_id().empty());
|
||||||
}
|
}
|
||||||
@@ -104,8 +109,9 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
"leader_id": "leader456"
|
"leader_id": "leader456"
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
// Check completion based on required fields
|
// Check completion based on required fields
|
||||||
REQUIRE(!parser.has_read_version_been_set());
|
REQUIRE(!parser.has_read_version_been_set());
|
||||||
}
|
}
|
||||||
@@ -117,8 +123,9 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
"read_version": 12345
|
"read_version": 12345
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
// Check completion based on required fields
|
// Check completion based on required fields
|
||||||
REQUIRE(request.leader_id().empty());
|
REQUIRE(request.leader_id().empty());
|
||||||
}
|
}
|
||||||
@@ -128,8 +135,9 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
"request_id": "test123"
|
"request_id": "test123"
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
// Check completion based on required fields
|
// Check completion based on required fields
|
||||||
bool missing_leader = request.leader_id().empty();
|
bool missing_leader = request.leader_id().empty();
|
||||||
bool missing_version = !parser.has_read_version_been_set();
|
bool missing_version = !parser.has_read_version_been_set();
|
||||||
@@ -143,7 +151,8 @@ TEST_CASE("CommitRequest basic parsing") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
REQUIRE_FALSE(request.request_id().has_value());
|
REQUIRE_FALSE(request.request_id().has_value());
|
||||||
REQUIRE(request.leader_id() == "leader456");
|
REQUIRE(request.leader_id() == "leader456");
|
||||||
REQUIRE(request.read_version() == 12345);
|
REQUIRE(request.read_version() == 12345);
|
||||||
@@ -167,7 +176,8 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Invalid point_read precondition - missing key") {
|
SUBCASE("Invalid point_read precondition - missing key") {
|
||||||
@@ -181,8 +191,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Valid point_read precondition - empty key") {
|
SUBCASE("Valid point_read precondition - empty key") {
|
||||||
@@ -198,7 +209,8 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Valid range_read precondition") {
|
SUBCASE("Valid range_read precondition") {
|
||||||
@@ -215,9 +227,10 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
bool parse_result =
|
auto parse_result =
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size());
|
parser.parse(request, const_cast<char *>(json.data()), json.size());
|
||||||
INFO("Parse result: " << parse_result);
|
INFO("Parse result: " << (parse_result ==
|
||||||
|
CommitRequestParser::ParseResult::Success));
|
||||||
INFO("Parse error: " << parser.has_parse_error());
|
INFO("Parse error: " << parser.has_parse_error());
|
||||||
const char *error_msg = parser.get_parse_error();
|
const char *error_msg = parser.get_parse_error();
|
||||||
INFO("Parse error message: " << (error_msg ? std::string(error_msg)
|
INFO("Parse error message: " << (error_msg ? std::string(error_msg)
|
||||||
@@ -225,7 +238,7 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
INFO("Leader ID: '" << request.leader_id() << "'");
|
INFO("Leader ID: '" << request.leader_id() << "'");
|
||||||
INFO("Read version: " << request.read_version());
|
INFO("Read version: " << request.read_version());
|
||||||
|
|
||||||
REQUIRE(parse_result);
|
REQUIRE(parse_result == CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Valid range_read precondition - empty begin/end") {
|
SUBCASE("Valid range_read precondition - empty begin/end") {
|
||||||
@@ -242,7 +255,8 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Invalid range_read precondition - missing begin") {
|
SUBCASE("Invalid range_read precondition - missing begin") {
|
||||||
@@ -257,8 +271,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Invalid range_read precondition - missing end") {
|
SUBCASE("Invalid range_read precondition - missing end") {
|
||||||
@@ -273,8 +288,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Valid write operation") {
|
SUBCASE("Valid write operation") {
|
||||||
@@ -291,7 +307,8 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Valid write operation - empty key and value") {
|
SUBCASE("Valid write operation - empty key and value") {
|
||||||
@@ -308,7 +325,8 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Invalid write operation - missing key") {
|
SUBCASE("Invalid write operation - missing key") {
|
||||||
@@ -323,8 +341,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Invalid write operation - missing value") {
|
SUBCASE("Invalid write operation - missing value") {
|
||||||
@@ -339,8 +358,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Valid delete operation") {
|
SUBCASE("Valid delete operation") {
|
||||||
@@ -356,7 +376,8 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Invalid delete operation - missing key") {
|
SUBCASE("Invalid delete operation - missing key") {
|
||||||
@@ -370,8 +391,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Valid range_delete operation") {
|
SUBCASE("Valid range_delete operation") {
|
||||||
@@ -388,7 +410,8 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Invalid range_delete operation - missing begin") {
|
SUBCASE("Invalid range_delete operation - missing begin") {
|
||||||
@@ -403,8 +426,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Invalid range_delete operation - missing end") {
|
SUBCASE("Invalid range_delete operation - missing end") {
|
||||||
@@ -419,8 +443,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("Mixed valid and invalid operations") {
|
SUBCASE("Mixed valid and invalid operations") {
|
||||||
@@ -439,8 +464,9 @@ TEST_CASE("CommitRequest precondition and operation validation") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE_FALSE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) !=
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +487,8 @@ TEST_CASE("CommitRequest memory management") {
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
REQUIRE(parser.parse(request, json.data(), json.size()));
|
REQUIRE(parser.parse(request, json.data(), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
|
|
||||||
// Check that arena allocation worked
|
// Check that arena allocation worked
|
||||||
REQUIRE(request.total_allocated() > 0);
|
REQUIRE(request.total_allocated() > 0);
|
||||||
@@ -669,7 +696,8 @@ TEST_CASE("CommitRequest arena debug dump") {
|
|||||||
std::string json = weaseldb::test_data::COMPLEX_JSON;
|
std::string json = weaseldb::test_data::COMPLEX_JSON;
|
||||||
|
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
|
|
||||||
// Verify the request was parsed correctly
|
// Verify the request was parsed correctly
|
||||||
REQUIRE(request.request_id().has_value());
|
REQUIRE(request.request_id().has_value());
|
||||||
@@ -725,7 +753,8 @@ TEST_CASE("CommitRequest arena debug dump") {
|
|||||||
// Parse complex JSON
|
// Parse complex JSON
|
||||||
std::string json = weaseldb::test_data::COMPLEX_JSON;
|
std::string json = weaseldb::test_data::COMPLEX_JSON;
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
|
|
||||||
// Debug dump after parsing
|
// Debug dump after parsing
|
||||||
std::ostringstream used_output;
|
std::ostringstream used_output;
|
||||||
@@ -746,7 +775,8 @@ TEST_CASE("CommitRequest arena debug dump") {
|
|||||||
// Parse complex JSON first
|
// Parse complex JSON first
|
||||||
std::string json = weaseldb::test_data::COMPLEX_JSON;
|
std::string json = weaseldb::test_data::COMPLEX_JSON;
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
|
|
||||||
size_t allocated_before_reset = request.total_allocated();
|
size_t allocated_before_reset = request.total_allocated();
|
||||||
size_t used_before_reset = request.used_bytes();
|
size_t used_before_reset = request.used_bytes();
|
||||||
@@ -789,7 +819,8 @@ TEST_CASE("CommitRequest arena debug dump") {
|
|||||||
// Parse COMPLEX_JSON to get diverse content in memory
|
// Parse COMPLEX_JSON to get diverse content in memory
|
||||||
std::string json = weaseldb::test_data::COMPLEX_JSON;
|
std::string json = weaseldb::test_data::COMPLEX_JSON;
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
parser.parse(request, const_cast<char *>(json.data()), json.size()));
|
parser.parse(request, const_cast<char *>(json.data()), json.size()) ==
|
||||||
|
CommitRequestParser::ParseResult::Success);
|
||||||
|
|
||||||
// Test different content visualization options
|
// Test different content visualization options
|
||||||
std::ostringstream no_content;
|
std::ostringstream no_content;
|
||||||
|
|||||||
@@ -265,10 +265,10 @@ int main(int argc, char *argv[]) {
|
|||||||
std::vector<char> mutable_json(json_content.begin(), json_content.end());
|
std::vector<char> mutable_json(json_content.begin(), json_content.end());
|
||||||
mutable_json.push_back('\0'); // Null terminate for safety
|
mutable_json.push_back('\0'); // Null terminate for safety
|
||||||
|
|
||||||
bool parse_success = parser.parse(commit_request, mutable_json.data(),
|
auto parse_result = parser.parse(commit_request, mutable_json.data(),
|
||||||
mutable_json.size() - 1);
|
mutable_json.size() - 1);
|
||||||
|
|
||||||
if (!parse_success) {
|
if (parse_result != CommitRequestParser::ParseResult::Success) {
|
||||||
std::cerr << "Error: Failed to parse JSON" << std::endl;
|
std::cerr << "Error: Failed to parse JSON" << std::endl;
|
||||||
if (parser.has_parse_error()) {
|
if (parser.has_parse_error()) {
|
||||||
std::cerr << "Parse error: " << parser.get_parse_error() << std::endl;
|
std::cerr << "Parse error: " << parser.get_parse_error() << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user