From c9729779aa3ee8ef1c5766d7b8fe5f0ac740355e Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 18:51:43 +0100 Subject: [PATCH 01/11] Booleans --- test/CMakeLists.txt | 1 + test/Jamfile | 1 + test/test_parser.cpp | 149 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 test/test_parser.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d73055a3..1b3a4e9c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -34,6 +34,7 @@ endmacro() # Unit tests make_test(test_low_level) +make_test(test_parser) make_test(test_request) make_test(test_serialization) make_test(test_low_level_sync_sans_io) diff --git a/test/Jamfile b/test/Jamfile index 5ed7d798..93bfd118 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -51,6 +51,7 @@ lib redis_test_common # access to a Redis server, so we only run the ones that don't require a DB server. local tests = test_low_level + test_parser test_request test_serialization test_low_level_sync_sans_io diff --git a/test/test_parser.cpp b/test/test_parser.cpp new file mode 100644 index 00000000..e31eabd5 --- /dev/null +++ b/test/test_parser.cpp @@ -0,0 +1,149 @@ +// +// Copyright (c) 2025 Marcelo Zimbres Silva (mzimbres@gmail.com), +// Ruben Perez Hidalgo (rubenperez038 at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "print_node.hpp" + +#include +#include +#include + +using namespace boost::redis; +using boost::system::error_code; +using resp3::type; + +namespace { + +#define S01a "#11\r\n" +#define S01b "#f\r\n" +#define S01c "#t\r\n" +#define S01d "#\r\n" + +#define S02a "$?\r\n;0\r\n" +#define S02b "$?\r\n;4\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n" +#define S02c "$?\r\n;b\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n" +#define S02d "$?\r\n;d\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n" + +#define S03a "%11\r\n" +#define S03b \ + "%4\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n$4\r\nkey3\r\n$" \ + "6\r\nvalue3\r\n$4\r\nkey3\r\n$6\r\nvalue3\r\n" +#define S03c "%0\r\n" +#define S03d "%rt\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n" + +#define S04a "*1\r\n:11\r\n" +#define S04b "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n" +#define S04c "*1\r\n" S03b +#define S04d "*1\r\n" S09a +#define S04e "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n" +#define S04f "*1\r\n*1\r\n$2\r\nab\r\n" +#define S04g "*1\r\n*1\r\n*1\r\n*1\r\n*1\r\n*1\r\na\r\n" +#define S04h "*0\r\n" +#define S04i "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n" + +#define S05a ":-3\r\n" +#define S05b ":11\r\n" +#define s05c ":3\r\n" +#define S05d ":adf\r\n" +#define S05e ":\r\n" + +#define S06a "_\r\n" + +#define S07a ">4\r\n+pubsub\r\n+message\r\n+some-channel\r\n+some message\r\n" +#define S07b ">0\r\n" + +#define S08a "|1\r\n+key-popularity\r\n%2\r\n$1\r\na\r\n,0.1923\r\n$1\r\nb\r\n,0.0012\r\n" +#define S08b "|0\r\n" + +#define S09a "~6\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n+orange\r\n" +#define S09b "~0\r\n" + +#define S10a "-Error\r\n" +#define S10b "-\r\n" + +#define S11a ",1.23\r\n" +#define S11b ",inf\r\n" +#define S11c ",-inf\r\n" +#define S11d ",1.23\r\n" +#define S11e ",er\r\n" +#define S11f ",\r\n" + +#define S12a "!21\r\nSYNTAX invalid syntax\r\n" +#define S12b "!0\r\n\r\n" +#define S12c "!3\r\nfoo\r\n" + +#define S13a "=15\r\ntxt:Some string\r\n" +#define S13b "=0\r\n\r\n" + +#define S14a "(3492890328409238509324850943850943825024385\r\n" +#define S14b "(\r\n" + +#define S15a "+OK\r\n" +#define S15b "+\r\n" + +#define S16a "s11\r\n" + +#define S17a "$l\r\nhh\r\n" +#define S17b "$2\r\nhh\r\n" +#define S18c "$26\r\nhhaa\aaaa\raaaaa\r\naaaaaaaaaa\r\n" +#define S18d "$0\r\n\r\n" + +void test_success() +{ + const struct { + std::string_view name; + std::string_view input; + std::vector expected; + } test_cases[] = { + // clang-format off + { "boolean_false", "#f\r\n", { + { type::boolean, 1u, 0u, "f" }, + } }, + { "boolean_true", "#t\r\n", { + { type::boolean, 1u, 0u, "t" }, + } }, + // clang-format on + }; + + for (const auto& tc : test_cases) { + std::cerr << "Running test case " << tc.name << std::endl; + + resp3::parser p; + resp3::flat_tree tree; + any_adapter adapter{tree}; + error_code ec; + bool done = resp3::parse(p, tc.input, adapter, ec); + BOOST_TEST(done); + BOOST_TEST(p.done()); + BOOST_TEST_EQ(p.get_consumed(), tc.input.size()); + BOOST_TEST_EQ(ec, error_code()); + BOOST_TEST_ALL_EQ( + tree.get_view().begin(), + tree.get_view().end(), + tc.expected.begin(), + tc.expected.end()); + } +} + +} // namespace + +int main() +{ + test_success(); + + return boost::report_errors(); +} From fc7b01ecd53fb117927daeb336bd3603458918bf Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 18:53:02 +0100 Subject: [PATCH 02/11] simple strings --- test/test_parser.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index e31eabd5..98d2a8f0 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -28,11 +28,6 @@ using resp3::type; namespace { -#define S01a "#11\r\n" -#define S01b "#f\r\n" -#define S01c "#t\r\n" -#define S01d "#\r\n" - #define S02a "$?\r\n;0\r\n" #define S02b "$?\r\n;4\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n" #define S02c "$?\r\n;b\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n" @@ -92,9 +87,6 @@ namespace { #define S14a "(3492890328409238509324850943850943825024385\r\n" #define S14b "(\r\n" -#define S15a "+OK\r\n" -#define S15b "+\r\n" - #define S16a "s11\r\n" #define S17a "$l\r\nhh\r\n" @@ -110,12 +102,20 @@ void test_success() std::vector expected; } test_cases[] = { // clang-format off + { "simple_string", "+OK\r\n", { + { type::simple_string, 1u, 0u, "OK" }, + } }, + { "simple_string_empty", "+\r\n", { + { type::simple_string, 1u, 0u, "" }, + } }, + { "boolean_false", "#f\r\n", { { type::boolean, 1u, 0u, "f" }, } }, { "boolean_true", "#t\r\n", { { type::boolean, 1u, 0u, "t" }, } }, + // clang-format on }; From de290a36be9a1aabdaf0118c756c72d3b4aaa37e Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 18:54:48 +0100 Subject: [PATCH 03/11] simple error --- test/test_parser.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index 98d2a8f0..14a44daa 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -67,9 +67,6 @@ namespace { #define S09a "~6\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n+orange\r\n" #define S09b "~0\r\n" -#define S10a "-Error\r\n" -#define S10b "-\r\n" - #define S11a ",1.23\r\n" #define S11b ",inf\r\n" #define S11c ",-inf\r\n" @@ -102,6 +99,7 @@ void test_success() std::vector expected; } test_cases[] = { // clang-format off + // Simple string { "simple_string", "+OK\r\n", { { type::simple_string, 1u, 0u, "OK" }, } }, @@ -109,6 +107,15 @@ void test_success() { type::simple_string, 1u, 0u, "" }, } }, + // Simple error + { "simple_error", "-Error\r\n", { + { type::simple_error, 1u, 0u, "Error" }, + } }, + { "simple_error_empty", "-\r\n", { + { type::simple_error, 1u, 0u, "" }, + } }, + + // Boolean { "boolean_false", "#f\r\n", { { type::boolean, 1u, 0u, "f" }, } }, From dec37143b36024cf22b80c4b815faa6dea95cccc Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 19:00:35 +0100 Subject: [PATCH 04/11] bulk strings --- test/test_parser.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index 14a44daa..4dc35a38 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -50,12 +50,6 @@ namespace { #define S04h "*0\r\n" #define S04i "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n" -#define S05a ":-3\r\n" -#define S05b ":11\r\n" -#define s05c ":3\r\n" -#define S05d ":adf\r\n" -#define S05e ":\r\n" - #define S06a "_\r\n" #define S07a ">4\r\n+pubsub\r\n+message\r\n+some-channel\r\n+some message\r\n" @@ -115,6 +109,28 @@ void test_success() { type::simple_error, 1u, 0u, "" }, } }, + // Integer + { "integer", ":11\r\n", { + { type::number, 1u, 0u, "11" }, + } }, + { "integer_negative", ":-3\r\n", { + { type::number, 1u, 0u, "-3" }, + } }, + { "integer_zero", ":0\r\n", { + { type::number, 1u, 0u, "0" }, + } }, + + // Bulk strings + { "bulk_string", "$2\r\nhh\r\n", { + { type::blob_string, 1u, 0u, "hh" }, + } }, + { "bulk_string_newlines", "$26\r\nhhaa\aaaa\raaaaa\r\naaaaaaaaaa\r\n", { + { type::blob_string, 1u, 0u, "hhaa\aaaa\raaaaa\r\naaaaaaaaaa" }, + } }, + { "bulk_string_empty", "$0\r\n\r\n", { + { type::blob_string, 1u, 0u, "" }, + } }, + // Boolean { "boolean_false", "#f\r\n", { { type::boolean, 1u, 0u, "f" }, From 64d5d3d9aeb548a5f4f57855c9435000d0480066 Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 19:20:29 +0100 Subject: [PATCH 05/11] arrays --- test/test_parser.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index 4dc35a38..b76abed9 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -139,6 +139,61 @@ void test_success() { type::boolean, 1u, 0u, "t" }, } }, + // Arrays + { "array_1elm", "*1\r\n:11\r\n", { + { type::array, 1u, 0u, "" }, + { type::number, 1u, 1u, "11" }, + } }, + { "array_3elm", "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n", { + { type::array, 3u, 0u, "" }, + { type::blob_string, 1u, 1u, "11" }, + { type::blob_string, 1u, 1u, "22" }, + { type::blob_string, 1u, 1u, "3" }, + } }, + { "array_empty", "*0\r\n", { + { type::array, 0u, 0u, "" }, + } }, + { "array_nested", "*1\r\n*1\r\n$2\r\nab\r\n", { + { type::array, 1u, 0u, "" }, + { type::array, 1u, 1u, "" }, + { type::blob_string, 1u, 2u, "ab" }, + } }, + { "array_nested_different_types_sizes", "*2\r\n+hello\r\n*3\r\n-ERR\r\n%1\r\n+name\r\n+OK\r\n*2\r\n+good\r\n_\r\n", { + { type::array, 2u, 0u, "" }, + { type::simple_string, 1u, 1u, "hello" }, + { type::array, 3u, 1u, "" }, + { type::simple_error, 1u, 2u, "ERR" }, + { type::map, 1u, 2u, "" }, + { type::simple_string, 1u, 3u, "name" }, + { type::simple_string, 1u, 3u, "OK" }, + { type::array, 2u, 2u, "" }, + { type::simple_string, 1u, 3u, "good" }, + { type::null, 1u, 3u, "" }, + } }, + { "array_nested_max", "*1\r\n*1\r\n*1\r\n*1\r\n*1\r\n+OK\r\n", { + { type::array, 1u, 0u, "" }, + { type::array, 1u, 1u, "" }, + { type::array, 1u, 2u, "" }, + { type::array, 1u, 3u, "" }, + { type::array, 1u, 4u, "" }, + { type::simple_string, 1u, 5u, "OK" }, + } }, + { "array_nested_map", "*1\r\n%2\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n", { + { type::array, 1u, 0u, "" }, + { type::map, 2u, 1u, "" }, + { type::blob_string, 1u, 2u, "key1" }, + { type::blob_string, 1u, 2u, "value1" }, + { type::blob_string, 1u, 2u, "key2" }, + { type::blob_string, 1u, 2u, "value2" }, + } }, + { "array_nested_set", "*1\r\n~3\r\n+orange\r\n+apple\r\n+orange\r\n", { + { type::array, 1u, 0u, "" }, + { type::set, 3u, 1u, "" }, + { type::simple_string, 1u, 2u, "orange" }, + { type::simple_string, 1u, 2u, "apple" }, + { type::simple_string, 1u, 2u, "orange" }, + } }, + // clang-format on }; From 39cea3194ee59480364b64527e72c96c00a37989 Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 19:21:24 +0100 Subject: [PATCH 06/11] null --- test/test_parser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index b76abed9..af35e953 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -139,6 +139,12 @@ void test_success() { type::boolean, 1u, 0u, "t" }, } }, + // Null + { "null", "_\r\n", { + { type::null, 1u, 0u, "" }, + } }, + + // Arrays { "array_1elm", "*1\r\n:11\r\n", { { type::array, 1u, 0u, "" }, From dcc7881138b931d9305e07568e298de9e0ec3f08 Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 19:28:50 +0100 Subject: [PATCH 07/11] doubles --- test/test_parser.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index af35e953..a19fd34b 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -109,7 +109,7 @@ void test_success() { type::simple_error, 1u, 0u, "" }, } }, - // Integer + // Integer. Not parsed at this point { "integer", ":11\r\n", { { type::number, 1u, 0u, "11" }, } }, @@ -144,6 +144,31 @@ void test_success() { type::null, 1u, 0u, "" }, } }, + // Double. Not parsed at this point + { "double", ",10.5\r\n", { + { type::doublean, 1u, 0u, "10.5" }, + } }, + { "double_negative", ",-10.5\r\n", { + { type::doublean, 1u, 0u, "-10.5" }, + } }, + { "double_exp", ",1.5e42\r\n", { + { type::doublean, 1u, 0u, "1.5e42" }, + } }, + { "double_exp_capital", ",1.5E42\r\n", { + { type::doublean, 1u, 0u, "1.5E42" }, + } }, + { "double_exp_negative", ",1.5e-42\r\n", { + { type::doublean, 1u, 0u, "1.5e-42" }, + } }, + { "double_inf", ",inf\r\n", { + { type::doublean, 1u, 0u, "inf" }, + } }, + { "double_inf_negative", ",-inf\r\n", { + { type::doublean, 1u, 0u, "-inf" }, + } }, + { "double_nan", ",nan\r\n", { + { type::doublean, 1u, 0u, "nan" }, + } }, // Arrays { "array_1elm", "*1\r\n:11\r\n", { From f1ee1f542e9b53e56b02ef7f50b28478398911db Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 19:29:53 +0100 Subject: [PATCH 08/11] big numbers --- test/test_parser.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index a19fd34b..7541bddc 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -170,6 +170,15 @@ void test_success() { type::doublean, 1u, 0u, "nan" }, } }, + // Big numbers + { "big_number", "(3492890328409238509324850943850943825024385\r\n", { + { type::big_number, 1u, 0u, "3492890328409238509324850943850943825024385" }, + } }, + { "big_number_zero", "(0\r\n", { + { type::big_number, 1u, 0u, "0" }, + } }, + + // Arrays { "array_1elm", "*1\r\n:11\r\n", { { type::array, 1u, 0u, "" }, From b37167b2d8499d6f4b8d892999f05e9da2d49021 Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 19:32:18 +0100 Subject: [PATCH 09/11] bulk errors --- test/test_parser.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index 7541bddc..1814ad31 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -178,6 +178,16 @@ void test_success() { type::big_number, 1u, 0u, "0" }, } }, + // Bulk errors + { "bulk_error", "!21\r\nSYNTAX invalid syntax\r\n", { + { type::blob_error, 1u, 0u, "SYNTAX invalid syntax" }, + } }, + { "bulk_error_newlines", "!23\r\nSYNTAX\r\ninvalid\r\nsyntax\r\n", { + { type::blob_error, 1u, 0u, "SYNTAX\r\ninvalid\r\nsyntax" }, + } }, + { "bulk_error_empty", "!0\r\n\r\n", { + { type::blob_error, 1u, 0u, "" }, + } }, // Arrays { "array_1elm", "*1\r\n:11\r\n", { From 11df5000ac6845b0a41cb9dc9841872e542808d3 Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Tue, 2 Dec 2025 19:36:18 +0100 Subject: [PATCH 10/11] verbatim strings --- test/test_parser.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index 1814ad31..c1eea3e3 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -189,6 +189,20 @@ void test_success() { type::blob_error, 1u, 0u, "" }, } }, + // Verbatim strings + { "verbatim_string", "=15\r\ntxt:Some string\r\n", { + { type::verbatim_string, 1u, 0u, "txt:Some string" }, + } }, + { "verbatim_string_newlines", "=16\r\nt\r\n:Some\r\nstring\r\n", { + { type::verbatim_string, 1u, 0u, "t\r\n:Some\r\nstring" }, + } }, + { "verbatim_string_only_encoding", "=4\r\ntxt:\r\n", { + { type::verbatim_string, 1u, 0u, "txt:" }, + } }, + { "verbatim_string_empty", "=0\r\n\r\n", { + { type::verbatim_string, 1u, 0u, "" }, + } }, + // Arrays { "array_1elm", "*1\r\n:11\r\n", { { type::array, 1u, 0u, "" }, From 30c5cc5f4dc785f6cdd2e6327e4fb743b3d2427f Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Thu, 4 Dec 2025 12:32:14 +0100 Subject: [PATCH 11/11] map tests --- test/test_parser.cpp | 97 +++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 41 deletions(-) diff --git a/test/test_parser.cpp b/test/test_parser.cpp index c1eea3e3..eb8f14bd 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -33,25 +33,6 @@ namespace { #define S02c "$?\r\n;b\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n" #define S02d "$?\r\n;d\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n" -#define S03a "%11\r\n" -#define S03b \ - "%4\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n$4\r\nkey3\r\n$" \ - "6\r\nvalue3\r\n$4\r\nkey3\r\n$6\r\nvalue3\r\n" -#define S03c "%0\r\n" -#define S03d "%rt\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n" - -#define S04a "*1\r\n:11\r\n" -#define S04b "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n" -#define S04c "*1\r\n" S03b -#define S04d "*1\r\n" S09a -#define S04e "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n" -#define S04f "*1\r\n*1\r\n$2\r\nab\r\n" -#define S04g "*1\r\n*1\r\n*1\r\n*1\r\n*1\r\n*1\r\na\r\n" -#define S04h "*0\r\n" -#define S04i "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n" - -#define S06a "_\r\n" - #define S07a ">4\r\n+pubsub\r\n+message\r\n+some-channel\r\n+some message\r\n" #define S07b ">0\r\n" @@ -61,30 +42,8 @@ namespace { #define S09a "~6\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n+orange\r\n" #define S09b "~0\r\n" -#define S11a ",1.23\r\n" -#define S11b ",inf\r\n" -#define S11c ",-inf\r\n" -#define S11d ",1.23\r\n" -#define S11e ",er\r\n" -#define S11f ",\r\n" - -#define S12a "!21\r\nSYNTAX invalid syntax\r\n" -#define S12b "!0\r\n\r\n" -#define S12c "!3\r\nfoo\r\n" - -#define S13a "=15\r\ntxt:Some string\r\n" -#define S13b "=0\r\n\r\n" - -#define S14a "(3492890328409238509324850943850943825024385\r\n" -#define S14b "(\r\n" - #define S16a "s11\r\n" -#define S17a "$l\r\nhh\r\n" -#define S17b "$2\r\nhh\r\n" -#define S18c "$26\r\nhhaa\aaaa\raaaaa\r\naaaaaaaaaa\r\n" -#define S18d "$0\r\n\r\n" - void test_success() { const struct { @@ -258,6 +217,62 @@ void test_success() { type::simple_string, 1u, 2u, "orange" }, } }, + // Map + { "map_1elm", "%1\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n", { + { type::map, 1u, 0u, "" }, + { type::blob_string, 1u, 1u, "key1" }, + { type::blob_string, 1u, 1u, "value1" }, + } }, + { "map_4elm", "%4\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n$4\r\nkey3\r\n$6\r\nvalue3\r\n$4\r\nkey3\r\n$6\r\nvalue3\r\n", { + { type::map, 4u, 0u, "" }, + { type::blob_string, 1u, 1u, "key1" }, + { type::blob_string, 1u, 1u, "value1" }, + { type::blob_string, 1u, 1u, "key2" }, + { type::blob_string, 1u, 1u, "value2" }, + { type::blob_string, 1u, 1u, "key3" }, + { type::blob_string, 1u, 1u, "value3" }, + { type::blob_string, 1u, 1u, "key3" }, + { type::blob_string, 1u, 1u, "value3" }, + } }, + { "map_empty", "%0\r\n", { + { type::map, 0u, 0u, "" }, + } }, + { "map_nested", "%1\r\n+key\r\n%2\r\n+k1\r\n+v1\r\n+k2\r\n+v2\r\n", { + { type::map, 1u, 0u, "" }, + { type::simple_string, 1u, 1u, "key" }, + { type::map, 2u, 1u, "" }, + { type::simple_string, 1u, 2u, "k1" }, + { type::simple_string, 1u, 2u, "v1" }, + { type::simple_string, 1u, 2u, "k2" }, + { type::simple_string, 1u, 2u, "v2" }, + } }, + { "map_nested_max", "%1\r\n+k1\r\n%1\r\n+k2\r\n%1\r\n+k3\r\n%1\r\n+k4\r\n%1\r\n+k5\r\n+v5\r\n", { + { type::map, 1u, 0u, "" }, + { type::simple_string, 1u, 1u, "k1" }, + { type::map, 1u, 1u, "" }, + { type::simple_string, 1u, 2u, "k2" }, + { type::map, 1u, 2u, "" }, + { type::simple_string, 1u, 3u, "k3" }, + { type::map, 1u, 3u, "" }, + { type::simple_string, 1u, 4u, "k4" }, + { type::map, 1u, 4u, "" }, + { type::simple_string, 1u, 5u, "k5" }, + { type::simple_string, 1u, 5u, "v5" }, + } }, + { "map_key_value_types", "%3\r\n_\r\n*0\r\n*2\r\n+a\r\n+b\r\n,3.1\r\n%1\r\n-ERR\r\n(200\r\n:42\r\n", { + { type::map, 3u, 0u, "" }, + { type::null, 1u, 1u, "" }, + { type::array, 0u, 1u, "" }, + { type::array, 2u, 1u, "" }, + { type::simple_string, 1u, 2u, "a" }, + { type::simple_string, 1u, 2u, "b" }, + { type::doublean, 1u, 1u, "3.1" }, + { type::map, 1u, 1u, "" }, + { type::simple_error, 1u, 2u, "ERR" }, + { type::big_number, 1u, 2u, "200" }, + { type::number, 1u, 1u, "42" }, + } }, + // clang-format on };