diff --git a/Common/Cpp/Json/JsonTools.cpp b/Common/Cpp/Json/JsonTools.cpp index 24313a92c7..b1cb5beccc 100644 --- a/Common/Cpp/Json/JsonTools.cpp +++ b/Common/Cpp/Json/JsonTools.cpp @@ -84,7 +84,7 @@ nlohmann::json to_nlohmann(const JsonValue& json){ return ret; } if (json.is_object()){ - nlohmann::json ret; + nlohmann::json::object_t ret; for (const auto& item : *json.to_object()){ ret[item.first] = to_nlohmann(item.second); } diff --git a/Common/Cpp/Json/JsonTools_Tests.cpp b/Common/Cpp/Json/JsonTools_Tests.cpp new file mode 100644 index 0000000000..f548ac8a34 --- /dev/null +++ b/Common/Cpp/Json/JsonTools_Tests.cpp @@ -0,0 +1,77 @@ +/* JSON Tools Tests + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include +#include +#include +#include "Common/Cpp/TestRunners/UnitTestDatabase.h" +#include "JsonValue.h" +#include "JsonTools_Tests.h" + +namespace PokemonAutomation{ +namespace{ + + + +struct DumpInput{ + std::string_view name; + std::string_view text; +}; +struct DumpExpectation{ + std::string_view dumped; +}; +struct DumpCase{ + DumpInput input; + DumpExpectation expectation; +}; + +// Empty containers must keep their type through dump() and parse_json(). +const DumpCase CASES[] = { + {.input = {.name = "Empty object", .text = "{}"}, .expectation = {.dumped = "{}"}}, + {.input = {.name = "Nested empty object", .text = R"({"object":{}})"}, .expectation = {.dumped = R"({"object":{}})"}}, + {.input = {.name = "Nested empty array", .text = R"({"array":[]})"}, .expectation = {.dumped = R"({"array":[]})"}}, +}; + + + +class Test_JsonTools_DumpRoundTrip : public UnitTest{ +public: + explicit Test_JsonTools_DumpRoundTrip(DumpCase test) + : UnitTest(std::format("Common::JsonTools - {} round trip", test.input.name)) + , m_test(test) + {} + + virtual UnitTestResult run(Logger& logger, CancellableScope& scope) const override{ + const std::string dumped = parse_json(std::string(m_test.input.text)).dump(-1); + if (dumped != m_test.expectation.dumped){ + return UnitTestResult(std::format("dump: expected {}, got {}", m_test.expectation.dumped, dumped)); + } + const std::string again = parse_json(dumped).dump(-1); + if (again != dumped){ + return UnitTestResult(std::format("dump after reparse: expected {}, got {}", dumped, again)); + } + return true; + } + +private: + DumpCase m_test; +}; + + + +} // namespace + + + +void add_tests_JsonTools(UnitTestDatabase& database){ + for (const DumpCase& test : CASES){ + database.add(test); + } +} + + + +} // namespace PokemonAutomation diff --git a/Common/Cpp/Json/JsonTools_Tests.h b/Common/Cpp/Json/JsonTools_Tests.h new file mode 100644 index 0000000000..76d61d4b7c --- /dev/null +++ b/Common/Cpp/Json/JsonTools_Tests.h @@ -0,0 +1,22 @@ +/* JSON Tools Tests + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_JsonTools_Tests_H +#define PokemonAutomation_JsonTools_Tests_H + +#include "Common/Cpp/TestRunners/UnitTestDatabase.h" + +namespace PokemonAutomation{ + + + +// Register the JSON dump/parse round-trip tests. +void add_tests_JsonTools(UnitTestDatabase& database); + + + +} // namespace PokemonAutomation +#endif diff --git a/SerialPrograms/Source/ComputerPrograms/ComputerPrograms_UnitTestRunner.cpp b/SerialPrograms/Source/ComputerPrograms/ComputerPrograms_UnitTestRunner.cpp index 15fa65326b..73f475e5e2 100644 --- a/SerialPrograms/Source/ComputerPrograms/ComputerPrograms_UnitTestRunner.cpp +++ b/SerialPrograms/Source/ComputerPrograms/ComputerPrograms_UnitTestRunner.cpp @@ -4,6 +4,7 @@ * */ +#include "Common/Cpp/Json/JsonTools_Tests.h" #include "Common/Cpp/ListenerSet.h" #include "Common/Cpp/MoveOnlyFunction_Tests.h" #include "Common/Cpp/ScopeExit.h" @@ -58,6 +59,7 @@ UnitTestDatabase make_UNIT_TESTS_ALL(){ add_tests_Sockets(ret, GlobalThreadPools::unlimited_normal()); add_tests_BlackBorderDetector(ret); add_tests_ListenerSet(ret); + add_tests_JsonTools(ret); add_tests_MoveOnlyFunction(ret); SysbotBase::add_tests_SysbotBasePing(ret); SysbotBase::add_tests_SysbotBaseReceiveLine(ret); diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 1ef2aaff87..8063bc387c 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -102,6 +102,8 @@ file(GLOB CORE_LIBRARY_SOURCES ../Common/Cpp/Json/JsonObject.h ../Common/Cpp/Json/JsonTools.cpp ../Common/Cpp/Json/JsonTools.h + ../Common/Cpp/Json/JsonTools_Tests.cpp + ../Common/Cpp/Json/JsonTools_Tests.h ../Common/Cpp/Json/JsonValue.cpp ../Common/Cpp/Json/JsonValue.h ../Common/Cpp/LifetimeSanitizer.cpp