summaryrefslogtreecommitdiffstats
path: root/src/parser/threaded_json_parser_test.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:48:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:48:59 +0000
commitc484829272cd13a738e35412498e12f2c9a194ac (patch)
treea1f5ec09629ee895bd3963fa8820b45f2f4c574b /src/parser/threaded_json_parser_test.cpp
parentInitial commit. (diff)
downloadliborcus-upstream.tar.xz
liborcus-upstream.zip
Adding upstream version 0.19.2.upstream/0.19.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/parser/threaded_json_parser_test.cpp')
-rw-r--r--src/parser/threaded_json_parser_test.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/src/parser/threaded_json_parser_test.cpp b/src/parser/threaded_json_parser_test.cpp
new file mode 100644
index 0000000..5ac8053
--- /dev/null
+++ b/src/parser/threaded_json_parser_test.cpp
@@ -0,0 +1,187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "test_global.hpp"
+#include <orcus/threaded_json_parser.hpp>
+
+#include <cstring>
+
+using namespace orcus;
+using namespace std;
+
+class handler
+{
+ json::parse_tokens_t m_tokens;
+
+public:
+ void begin_parse()
+ {
+ m_tokens.emplace_back(json::parse_token_t::begin_parse);
+ }
+
+ void end_parse()
+ {
+ m_tokens.emplace_back(json::parse_token_t::end_parse);
+ }
+
+ void begin_array()
+ {
+ m_tokens.emplace_back(json::parse_token_t::begin_array);
+ }
+
+ void end_array()
+ {
+ m_tokens.emplace_back(json::parse_token_t::end_array);
+ }
+
+ void begin_object()
+ {
+ m_tokens.emplace_back(json::parse_token_t::begin_object);
+ }
+
+ void object_key(const char* p, size_t len, bool transient)
+ {
+ assert(!transient); // transient is never true with the threaded parser.
+ m_tokens.emplace_back(json::parse_token_t::object_key, std::string_view{p, len});
+ }
+
+ void end_object()
+ {
+ m_tokens.emplace_back(json::parse_token_t::end_object);
+ }
+
+ void boolean_true()
+ {
+ m_tokens.emplace_back(json::parse_token_t::boolean_true);
+ }
+
+ void boolean_false()
+ {
+ m_tokens.emplace_back(json::parse_token_t::boolean_false);
+ }
+
+ void null()
+ {
+ m_tokens.emplace_back(json::parse_token_t::null);
+ }
+
+ void string(const char* p, size_t len, bool transient)
+ {
+ assert(!transient); // transient is never true with the threaded parser.
+ m_tokens.emplace_back(json::parse_token_t::string, std::string_view{p, len});
+ }
+
+ void number(double val)
+ {
+ m_tokens.emplace_back(val);
+ }
+
+ const json::parse_tokens_t& get_tokens() const
+ {
+ return m_tokens;
+ }
+};
+
+void test_parser(const char* src, const json::parse_tokens_t& expected)
+{
+ cout << "source: " << src << endl;
+
+ handler hdl;
+ threaded_json_parser<handler> parser(src, std::strlen(src), hdl, 5, 5);
+ parser.parse();
+
+ if (hdl.get_tokens() != expected)
+ {
+ cout << "Expected tokens:" << endl;
+ cout << expected;
+ cout << "Actual tokens:" << endl;
+ cout << hdl.get_tokens();
+ abort();
+ }
+}
+
+void test_threaded_json_parser_basic()
+{
+ struct test_case
+ {
+ const char* source;
+ json::parse_tokens_t expected;
+ };
+
+ test_case tcs[] =
+ {
+ {
+ "[1,2,3]",
+ {
+ { json::parse_token_t::begin_parse },
+ { json::parse_token_t::begin_array },
+ { 1.0 },
+ { 2.0 },
+ { 3.0 },
+ { json::parse_token_t::end_array },
+ { json::parse_token_t::end_parse },
+ }
+ },
+ {
+ "{\"foo\": [true, false, null]}",
+ {
+ { json::parse_token_t::begin_parse },
+ { json::parse_token_t::begin_object },
+ { json::parse_token_t::object_key, std::string_view{"foo"} },
+ { json::parse_token_t::begin_array },
+ { json::parse_token_t::boolean_true },
+ { json::parse_token_t::boolean_false },
+ { json::parse_token_t::null },
+ { json::parse_token_t::end_array },
+ { json::parse_token_t::end_object },
+ { json::parse_token_t::end_parse },
+ }
+ }
+ };
+
+ for (size_t i = 0, n = std::size(tcs); i < n; ++i)
+ test_parser(tcs[i].source, tcs[i].expected);
+}
+
+void test_threaded_json_parser_invalid()
+{
+ const char* invalids[] = {
+ "[foo]",
+ "[qwerty]",
+ "[1,2] null",
+ "{\"key\" 1: 12}",
+ "[1,,2]",
+ "\"key\": {\"inner\": 12}"
+ };
+
+ for (size_t i = 0; i < std::size(invalids); ++i)
+ {
+ const char* src = invalids[i];
+
+ try
+ {
+ handler hdl;
+ threaded_json_parser<handler> parser(src, std::strlen(src), hdl, 1);
+ parser.parse();
+ assert(false);
+ }
+ catch (const parse_error&)
+ {
+ // works as expected.
+ cout << "invalid source: " << src << endl;
+ }
+ }
+}
+
+int main()
+{
+ test_threaded_json_parser_basic();
+ test_threaded_json_parser_invalid();
+ return EXIT_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */