From 14471347a07a0f50ba42f427475bbec9fab4c26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Fri, 9 Jul 2021 16:00:03 -0300 Subject: [PATCH] Add failing tests for chunked parser == RATIONALE A chunked parser that failed to consume the next token means either: 1. Insufficient tokens. The user must buffer more and try again. 2. Invalid token. There's nothing polemic about the first case. As for the second one: I. Either the stream is invalid and it'll abort parsing; II. Or we're using a syntactic extension to the JSON stream and want to trigger a fallback mini-parser to consume that part of the stream. If a parser doesn't report invalid token the user will try to buffer the stream forever. However if invalid token is a terminal state then the user can't combine parsers to support an extended JSON syntax. A chunked parser meant to be used combined with other parsers should report all 3 scenarios: * Valid token. * Insufficient tokens. * Invalid token (and invalid token cannot be a terminal state). If we exclude the first event from the notification set the parser isn't useful at all. If we exclude the second event then we don't have a chunked parser. If we exclude the third event the user might buffer forever on invalid tokens. Thus all three events must be part of the notification set. --- test/json/chunk_reader_suite.cpp | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/test/json/chunk_reader_suite.cpp b/test/json/chunk_reader_suite.cpp index 1eaf395..cfdbf4a 100644 --- a/test/json/chunk_reader_suite.cpp +++ b/test/json/chunk_reader_suite.cpp @@ -43,10 +43,20 @@ void string_missing_array_end() TRIAL_PROTOCOL_TEST_EQUAL(reader.code(), token::code::end_array); } +void string_invalid_token() +{ + json::chunk_reader reader; + TRIAL_PROTOCOL_TEST(reader.finish("\"a\"%")); + TRIAL_PROTOCOL_TEST_EQUAL(reader.code(), token::code::string); + TRIAL_PROTOCOL_TEST(!reader.next()); + TRIAL_PROTOCOL_TEST_EQUAL(reader.code(), token::code::error_unexpected_token); +} + void run() { string_missing_quote(); string_missing_array_end(); + string_invalid_token(); } } // namespace string_suite @@ -168,6 +178,48 @@ void run() //----------------------------------------------------------------------------- +namespace array_suite +{ + +void array_invalid_token() +{ + json::chunk_reader reader; + TRIAL_PROTOCOL_TEST(reader.finish("[%")); + TRIAL_PROTOCOL_TEST_EQUAL(reader.code(), token::code::begin_array); + TRIAL_PROTOCOL_TEST(!reader.next()); + TRIAL_PROTOCOL_TEST_EQUAL(reader.code(), token::code::error_unexpected_token); +} + +void run() +{ + array_invalid_token(); +} + +} // namespace array_suite + +//----------------------------------------------------------------------------- + +namespace object_suite +{ + +void object_invalid_token() +{ + json::chunk_reader reader; + TRIAL_PROTOCOL_TEST(reader.finish("{%")); + TRIAL_PROTOCOL_TEST_EQUAL(reader.code(), token::code::begin_object); + TRIAL_PROTOCOL_TEST(!reader.next()); + TRIAL_PROTOCOL_TEST_EQUAL(reader.code(), token::code::error_unexpected_token); +} + +void run() +{ + object_invalid_token(); +} + +} // namespace object_suite + +//----------------------------------------------------------------------------- + namespace whitespace_suite { @@ -228,6 +280,8 @@ int main() { string_suite::run(); number_suite::run(); + array_suite::run(); + object_suite::run(); whitespace_suite::run(); return boost::report_errors();