2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-09-22 01:59:10 +00:00
qpdf/libtests/json_handler.cc
Jay Berkenbilt ce3406e93f JSONHandler: pass JSON object to dict start function
If some keys depend on others, we have to check up front since there
is no control of what order key handlers will be called. Anyway, keys
are unordered in json, so we don't want to depend on ordering.
2022-01-31 15:57:45 -05:00

144 lines
3.9 KiB
C++

#include <qpdf/JSONHandler.hh>
#include <qpdf/QUtil.hh>
#include <qpdf/QPDFUsage.hh>
#include <iostream>
#include <cassert>
static void print_null(std::string const& path)
{
std::cout << path << ": null" << std::endl;
}
static void print_string(std::string const& path, std::string const& value)
{
std::cout << path << ": string: " << value << std::endl;
}
static void print_number(std::string const& path, std::string const& value)
{
std::cout << path << ": number: " << value << std::endl;
}
static void print_bool(std::string const& path, bool value)
{
std::cout << path << ": bool: " << (value ? "true" : "false") << std::endl;
}
static void print_json(std::string const& path, JSON value)
{
std::cout << path << ": json: " << value.unparse() << std::endl;
}
static JSONHandler::void_handler_t make_print_message(std::string msg)
{
return [msg](std::string const& path) {
std::cout << path << ": json: " << msg << std::endl;
};
}
static void test_scalar()
{
std::cout << "-- scalar --" << std::endl;
JSONHandler h;
h.addStringHandler(print_string);
JSON j = JSON::parse("\"potato\"");
h.handle(".", j);
}
static std::shared_ptr<JSONHandler> make_all_handler()
{
auto h = std::make_shared<JSONHandler>();
h->addDictHandlers(
print_json, make_print_message("dict end"));
auto h1 = std::make_shared<JSONHandler>();
h1->addStringHandler(print_string);
h->addDictKeyHandler("one", h1);
auto h2 = std::make_shared<JSONHandler>();
h2->addNumberHandler(print_number);
h->addDictKeyHandler("two", h2);
auto h3 = std::make_shared<JSONHandler>();
h3->addBoolHandler(print_bool);
h->addDictKeyHandler("three", h3);
auto h4 = std::make_shared<JSONHandler>();
h4->addAnyHandler(print_json);
h->addDictKeyHandler("four", h4);
h->addDictKeyHandler("phour", h4); // share h4
auto h5 = std::make_shared<JSONHandler>();
// Allow to be either string or bool
h5->addBoolHandler(print_bool);
h5->addStringHandler(print_string);
h5->addNullHandler(print_null);
auto h5s = std::make_shared<JSONHandler>();
h->addDictKeyHandler("five", h5s);
h5s->addArrayHandlers(
make_print_message("array begin"),
make_print_message("array end"),
h5);
auto h6 = std::make_shared<JSONHandler>();
h6->addDictHandlers(
print_json, make_print_message("dict end"));
auto h6a = std::make_shared<JSONHandler>();
h6->addDictKeyHandler("a", h6a);
h6a->addDictHandlers(
print_json, make_print_message("dict end"));
auto h6ab = std::make_shared<JSONHandler>();
h6a->addDictKeyHandler("b", h6ab);
auto h6ax = std::make_shared<JSONHandler>();
h6ax->addAnyHandler(print_json);
h6a->addFallbackDictHandler(h6ax);
h6->addDictKeyHandler("b", h6ab); // share
h6ab->addStringHandler(print_string);
h->addDictKeyHandler("six", h6);
return h;
}
static void test_all()
{
std::cout << "-- all --" << std::endl;
auto h = make_all_handler();
/* cSpell: ignore phour */
JSON j = JSON::parse(R"({
"one": "potato",
"two": 3.14,
"three": true,
"four": ["a", 1],
"five": ["x", false, "y", null, true],
"phour": null,
"six": {"a": {"b": "quack", "Q": "baaa"}, "b": "moo"}
})");
h->handle(".", j);
}
static void test_errors()
{
std::cout << "-- errors --" << std::endl;
auto h = make_all_handler();
auto t = [h](std::string const& msg, std::function<void()> fn) {
try
{
fn();
assert(false);
}
catch (QPDFUsage& e)
{
std::cout << msg << ": " << e.what() << std::endl;
}
};
t("bad type at top", [&h](){
h->handle(".", JSON::makeString("oops"));
});
t("unexpected key", [&h](){
JSON j = JSON::parse(R"({"x": "y"})");
h->handle(".", j);
});
}
int main(int argc, char* argv[])
{
test_scalar();
test_all();
test_errors();
return 0;
}