From 48bdfbeb03319eb21b5e73e69f525ba298af975c Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Sun, 19 Oct 2025 00:08:49 +0200 Subject: json: Add new module Only has methods for writing JSON for now. Will let you create invalid json, but should assert if you do. --- test/json.cc | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 test/json.cc (limited to 'test/json.cc') diff --git a/test/json.cc b/test/json.cc new file mode 100644 index 0000000..2fc7ad2 --- /dev/null +++ b/test/json.cc @@ -0,0 +1,221 @@ +#include "json.hh" + +#include +#include +#include +#include +#include +#include + +namespace { + +enum class Output : uint8_t { + String, + Stream, +}; + +class Writer : public testing::TestWithParam { + protected: + std::unique_ptr make() { + switch (GetParam()) { + case Output::String: + return json::writer(str_); + case Output::Stream: + return json::writer(stream_); + } + std::unreachable(); + } + + std::string str() { + switch (GetParam()) { + case Output::String: + return std::move(str_); + case Output::Stream: + return stream_.str(); + } + std::unreachable(); + } + + private: + std::string str_; + std::stringstream stream_; +}; + +} // namespace + +TEST_P(Writer, example1) { + auto writer = make(); + writer->start_object(); + + writer->key("glossary"); + writer->start_object(); + + writer->key("title"); + writer->value("example glossary"); + + writer->key("GlossDiv"); + writer->start_object(); + + writer->key("title"); + writer->value("S"); + + writer->key("GlossList"); + writer->start_object(); + + writer->key("GlossEntry"); + writer->start_object(); + + writer->key("ID"); + writer->value("SGML"); + writer->key("SortAs"); + writer->value("SGML"); + writer->key("GlossTerm"); + writer->value("Standard Generalized Markup Language"); + writer->key("Acronym"); + writer->value("SGML"); + writer->key("Abbrev"); + writer->value("ISO 8879:1986"); + + writer->key("GlossDef"); + writer->start_object(); + + writer->key("para"); + writer->value( + "A meta-markup language, used to create markup languages such as " + "DocBook."); + + writer->key("GlossSeeAlso"); + writer->start_array(); + writer->value("GML"); + writer->value("XML"); + writer->end_array(); + + writer->end_object(); + + writer->key("GlossSee"); + writer->value("markup"); + + writer->end_object(); + + writer->end_object(); + + writer->end_object(); + + writer->end_object(); + + writer->end_object(); + + EXPECT_EQ( + R"({"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}})", + str()); +} + +TEST_P(Writer, example2) { + auto writer = make(); + writer->start_object(); + + writer->key("widget"); + writer->start_object(); + + writer->key("debug"); + writer->value("on"); + + writer->key("window"); + writer->start_object(); + + writer->key("title"); + writer->value("Sample Konfabulator Widget"); + writer->key("name"); + writer->value("main_window"); + writer->key("width"); + writer->value(500); + writer->key("height"); + writer->value(500); + + writer->end_object(); + + writer->key("image"); + writer->start_object(); + + writer->key("src"); + writer->value("Images/Sun.png"); + writer->key("name"); + writer->value("sun1"); + writer->key("hOffset"); + writer->value(250); + writer->key("vOffset"); + writer->value(250); + writer->key("alignment"); + writer->value("center"); + + writer->end_object(); + + writer->key("text"); + writer->start_object(); + + writer->key("data"); + writer->value("Click Here"); + writer->key("size"); + writer->value(36); + writer->key("style"); + writer->value("bold"); + writer->key("name"); + writer->value("text1"); + writer->key("hOffset"); + writer->value(250); + writer->key("vOffset"); + writer->value(100); + writer->key("alignment"); + writer->value("center"); + writer->key("onMouseUp"); + writer->value("sun1.opacity = (sun1.opacity / 100) * 90;"); + + writer->end_object(); + + writer->end_object(); + + writer->end_object(); + + EXPECT_EQ( + R"({"widget":{"debug":"on","window":{"title":"Sample Konfabulator Widget","name":"main_window","width":500,"height":500},"image":{"src":"Images/Sun.png","name":"sun1","hOffset":250,"vOffset":250,"alignment":"center"},"text":{"data":"Click Here","size":36,"style":"bold","name":"text1","hOffset":250,"vOffset":100,"alignment":"center","onMouseUp":"sun1.opacity = (sun1.opacity / 100) * 90;"}}})", + str()); +} + +TEST_P(Writer, quote1) { + auto writer = make(); + writer->value(R"("Example text")"); + + EXPECT_EQ(R"("\"Example text\"")", str()); +} + +TEST_P(Writer, quote2) { + auto writer = make(); + writer->value(R"(\"Example text\")"); + + EXPECT_EQ(R"("\\\"Example text\\\"")", str()); +} + +TEST_P(Writer, quote3) { + auto writer = make(); + writer->value(R"( +)"); + + EXPECT_EQ(R"("\n")", str()); +} + +TEST_P(Writer, float) { + auto writer = make(); + writer->value(3.14F); + + EXPECT_EQ("3.14", str()); +} + +TEST_P(Writer, double) { + auto writer = make(); + writer->value(3.14); + + EXPECT_EQ("3.14", str()); +} + +INSTANTIATE_TEST_SUITE_P(AllOutputs, Writer, + testing::Values(Output::String, Output::Stream)); -- cgit v1.2.3-70-g09d2