From b7280d5ddff75a2b92c19cef743efe9f392c10fb Mon Sep 17 00:00:00 2001 From: Alex Shabalin Date: Wed, 29 May 2024 11:27:33 +0200 Subject: [PATCH] Test XML and streamline output archive --- immer/extra/persist/json/json_immer.hpp | 86 ++++++++++++++++- immer/extra/persist/json/json_with_pool.hpp | 72 +------------- .../persist/json/json_with_pool_auto.hpp | 41 ++------ .../test_circular_dependency_conversion.cpp | 95 ++++++++++++++++--- test/extra/persist/test_conversion.cpp | 21 ++-- test/extra/persist/test_special_pool.cpp | 69 +++----------- test/extra/persist/test_special_pool_auto.cpp | 36 ++++--- 7 files changed, 220 insertions(+), 200 deletions(-) diff --git a/immer/extra/persist/json/json_immer.hpp b/immer/extra/persist/json/json_immer.hpp index 93bc287c..5e010919 100644 --- a/immer/extra/persist/json/json_immer.hpp +++ b/immer/extra/persist/json/json_immer.hpp @@ -2,7 +2,7 @@ #include -#include +#include /** * Special types of archives, working with JSON, that support providing extra @@ -11,6 +11,8 @@ namespace immer::persist { +namespace detail { + struct blackhole_output_archive { void setNextName(const char* name) {} @@ -48,6 +50,37 @@ struct blackhole_output_archive } }; +template +class error_duplicate_pool_name_found; + +inline auto are_type_names_unique(auto type_names) +{ + namespace hana = boost::hana; + auto names_set = + hana::fold_left(type_names, hana::make_set(), [](auto set, auto pair) { + return hana::if_( + hana::contains(set, hana::second(pair)), + [](auto pair) { + return error_duplicate_pool_name_found< + decltype(hana::second(pair))>{}; + }, + [&set](auto pair) { + return hana::insert(set, hana::second(pair)); + })(pair); + }); + return hana::length(type_names) == hana::length(names_set); +} + +template +constexpr bool is_pool_empty() +{ + using Result = + decltype(boost::hana::is_empty(boost::hana::keys(Pools{}.storage()))); + return Result::value; +} + +} // namespace detail + /** * Adapted from cereal/archives/adapters.hpp */ @@ -85,15 +118,26 @@ class json_immer_output_archive { } - void setNextName(const char* name) { previous.setNextName(name); } + ~json_immer_output_archive() { finalize(); } Pools& get_output_pools() & { return pools; } Pools&& get_output_pools() && { return std::move(pools); } void finalize() { + if constexpr (detail::is_pool_empty()) { + return; + } + + if (finalized) { + return; + } + + save_pools_impl(); + auto& self = *this; self(CEREAL_NVP(pools)); + finalized = true; } template @@ -152,10 +196,46 @@ class json_immer_output_archive CEREAL_SAVE_FUNCTION_NAME(ar.previous, v); } +private: + template + friend class json_immer_output_archive; + + // Recursively serializes the pools but not calling finalize + void save_pools_impl() + { + const auto save_pool = [wrap = wrap](auto pools) { + auto ar = + json_immer_output_archive{pools, wrap}; + // Do not try to serialize pools again inside of this temporary + // archive + ar.finalized = true; + ar(pools); + return std::move(ar).get_output_pools(); + }; + + using Names = typename Pools::names_t; + using IsUnique = decltype(detail::are_type_names_unique(Names{})); + static_assert(IsUnique::value, + "Pool names for each type must be unique"); + + auto prev = pools; + while (true) { + // Keep saving pools until everything is saved. + pools = save_pool(std::move(pools)); + if (prev == pools) { + break; + } + prev = pools; + } + } + private: WrapF wrap; Previous previous; Pools pools; + bool finalized{false}; }; template @@ -183,8 +263,6 @@ class json_immer_input_archive { } - void setNextName(const char* name) { previous.setNextName(name); } - Pools& get_input_pools() { return pools; } const Pools& get_input_pools() const { return pools; } diff --git a/immer/extra/persist/json/json_with_pool.hpp b/immer/extra/persist/json/json_with_pool.hpp index 885e83e9..89a54d4e 100644 --- a/immer/extra/persist/json/json_with_pool.hpp +++ b/immer/extra/persist/json/json_with_pool.hpp @@ -25,9 +25,6 @@ namespace hana = boost::hana; template class error_no_pool_for_the_given_type_check_get_pools_types_function; -template -class error_duplicate_pool_name_found; - template class error_missing_pool_for_type; @@ -445,23 +442,6 @@ inline auto generate_output_pools(auto type_names) return output_pools{storage}; } -inline auto are_type_names_unique(auto type_names) -{ - auto names_set = - hana::fold_left(type_names, hana::make_set(), [](auto set, auto pair) { - return hana::if_( - hana::contains(set, hana::second(pair)), - [](auto pair) { - return error_duplicate_pool_name_found< - decltype(hana::second(pair))>{}; - }, - [&set](auto pair) { - return hana::insert(set, hana::second(pair)); - })(pair); - }); - return hana::length(type_names) == hana::length(names_set); -} - inline auto generate_input_pools(auto type_names) { auto storage = @@ -493,72 +473,30 @@ auto get_pools_types(const T&) return boost::hana::make_map(); } -template -constexpr bool is_pool_empty() -{ - using Result = - decltype(boost::hana::is_empty(boost::hana::keys(Pools{}.storage()))); - return Result::value; -} - -// Recursively serializes the pools but not calling finalize -template -void save_pools_impl(json_immer_output_archive& ar, - const SavePoolF& save_pool) -{ - using Names = typename Pools::names_t; - using IsUnique = decltype(detail::are_type_names_unique(Names{})); - static_assert(IsUnique::value, "Pool names for each type must be unique"); - - auto& pools = ar.get_output_pools(); - - auto prev = pools; - while (true) { - // Keep saving pools until everything is saved. - pools = save_pool(std::move(pools)); - if (prev == pools) { - break; - } - prev = pools; - } -} - /** * Type T must provide a callable free function get_pools_types(const T&). */ template auto to_json_with_pool(const T& serializable) { - auto pools = detail::generate_output_pools(get_pools_types(serializable)); - using Pools = std::decay_t; - - const auto save_pool = [](auto pools) { - auto ar2 = - json_immer_output_archive{pools}; - ar2(pools); - return std::move(ar2).get_output_pools(); - }; - auto os = std::ostringstream{}; { + auto pools = + detail::generate_output_pools(get_pools_types(serializable)); + using Pools = std::decay_t; auto ar = immer::persist::json_immer_output_archive{os}; ar(serializable); - if constexpr (!is_pool_empty()) { - save_pools_impl(ar, save_pool); - ar.finalize(); - } - pools = std::move(ar).get_output_pools(); } - return std::make_pair(os.str(), std::move(pools)); + return os.str(); } template auto load_pools(std::istream& is, const ReloadPoolF& reload_pool) { auto pools = Pools{}; - if constexpr (is_pool_empty()) { + if constexpr (detail::is_pool_empty()) { return pools; } diff --git a/immer/extra/persist/json/json_with_pool_auto.hpp b/immer/extra/persist/json/json_with_pool_auto.hpp index e4595feb..ab6624f3 100644 --- a/immer/extra/persist/json/json_with_pool_auto.hpp +++ b/immer/extra/persist/json/json_with_pool_auto.hpp @@ -138,8 +138,6 @@ auto to_json_with_auto_pool(const T& serializable, const PoolsTypes& pools_types, const WrapF& wrap = wrap_for_saving) { - namespace hana = boost::hana; - // In the future, wrap function may ignore certain user-provided types that // should not be persisted. static_assert( @@ -152,32 +150,18 @@ auto to_json_with_auto_pool(const T& serializable, persistable>>, "and a value when it's wrapping"); - auto pools = detail::generate_output_pools(pools_types); - using Pools = std::decay_t; - - const auto save_pool = [wrap](auto pools) { - auto ar = json_immer_output_archive{pools, wrap}; - ar(pools); - return std::move(ar).get_output_pools(); - }; - auto os = std::ostringstream{}; { - auto ar = json_immer_output_archive; + auto ar = json_immer_output_archive{pools, wrap, os}; // value0 because that's now cereal saves the unnamed object by default, // maybe change later. ar(cereal::make_nvp("value0", serializable)); - if constexpr (!is_pool_empty()) { - save_pools_impl(ar, save_pool); - ar.finalize(); - } - pools = std::move(ar).get_output_pools(); } - return std::make_pair(os.str(), std::move(pools)); + return os.str(); } // Same as to_json_with_auto_pool but we don't generate any JSON. @@ -188,8 +172,6 @@ auto get_auto_pool(const T& serializable, const PoolsTypes& pools_types, const WrapF& wrap = wrap_for_saving) { - namespace hana = boost::hana; - // In the future, wrap function may ignore certain user-provided types that // should not be persisted. static_assert( @@ -205,25 +187,14 @@ auto get_auto_pool(const T& serializable, auto pools = detail::generate_output_pools(pools_types); using Pools = std::decay_t; - const auto save_pool = [wrap](auto pools) { - auto ar = json_immer_output_archive{pools, wrap}; - ar(pools); - return std::move(ar).get_output_pools(); - }; - { - auto ar = json_immer_output_archive{pools, wrap}; // value0 because that's now cereal saves the unnamed object by default, // maybe change later. ar(cereal::make_nvp("value0", serializable)); - if constexpr (!is_pool_empty()) { - save_pools_impl(ar, save_pool); - ar.finalize(); - } + ar.finalize(); pools = std::move(ar).get_output_pools(); } return pools; diff --git a/test/extra/persist/test_circular_dependency_conversion.cpp b/test/extra/persist/test_circular_dependency_conversion.cpp index 035398a6..2a33c55a 100644 --- a/test/extra/persist/test_circular_dependency_conversion.cpp +++ b/test/extra/persist/test_circular_dependency_conversion.cpp @@ -8,6 +8,8 @@ #include #include +#include + #define DEFINE_OPERATIONS(name) \ bool operator==(const name& left, const name& right) \ { \ @@ -236,16 +238,25 @@ TEST_CASE("Test exception while circular converting") const auto names = immer::persist::get_pools_for_type(hana::type_c); - const auto [json_str, model_pool] = - immer::persist::to_json_with_auto_pool(value, names); - // REQUIRE(json_str == ""); + const auto model_pool = immer::persist::get_auto_pool(value, names); SECTION("Try to load") { + const auto json_str = + immer::persist::to_json_with_auto_pool(value, names); const auto loaded = immer::persist::from_json_with_auto_pool(json_str, names); REQUIRE(loaded == value); + + SECTION("Loaded value has the same structure as the original") + { + // XXX Currently there is a problem with the box, it gets created + // twice, probably something about recursive type. + const auto json_from_loaded = + immer::persist::to_json_with_auto_pool(loaded, names); + REQUIRE(json_str != json_from_loaded); + } } /** @@ -539,10 +550,10 @@ TEST_CASE("Test circular dependency pools", "[conversion]") SECTION("Compare structure") { - const auto [format_twos_json, ar] = + const auto format_twos_json = immer::persist::to_json_with_auto_pool(format_twos, format_names); - const auto [model_twos_json, ar2] = + const auto model_twos_json = immer::persist::to_json_with_auto_pool(value.twos, names); REQUIRE(model_twos_json == format_twos_json); } @@ -612,10 +623,10 @@ TEST_CASE("Test circular dependency pools", "[conversion]") SECTION("Compare structure") { - const auto [format_twos_json, ar] = + const auto format_twos_json = immer::persist::to_json_with_auto_pool(format_twos, format_names); - const auto [model_twos_json, ar2] = + const auto model_twos_json = immer::persist::to_json_with_auto_pool(value.twos_map, names); REQUIRE(model_twos_json == format_twos_json); } @@ -635,10 +646,10 @@ TEST_CASE("Test circular dependency pools", "[conversion]") SECTION("Compare structure") { - const auto [format_twos_json, ar] = + const auto format_twos_json = immer::persist::to_json_with_auto_pool(format_twos, format_names); - const auto [model_twos_json, ar2] = + const auto model_twos_json = immer::persist::to_json_with_auto_pool(value.twos_set, names); REQUIRE(model_twos_json == format_twos_json); } @@ -657,9 +668,9 @@ TEST_CASE("Test circular dependency pools", "[conversion]") }); return result; }(); - const auto [format_json_str, model_pools] = + const auto format_json_str = immer::persist::to_json_with_auto_pool(format_value, format_names); - const auto [json_str, model_pools_] = + const auto json_str = immer::persist::to_json_with_auto_pool(value, names); REQUIRE(format_json_str == json_str); } @@ -681,4 +692,66 @@ TEST_CASE("Test circular dependency pools", "[conversion]") // The box is actually the same REQUIRE(two1_manually_converted.impl() == two1_from_inside.impl()); } + + SECTION("XML also works") + { + constexpr auto to_xml = + [](const auto& value0, const auto& names, const auto& wrap) { + auto os = std::ostringstream{}; + { + auto pools = + immer::persist::detail::generate_output_pools(names); + using Pools = std::decay_t; + auto ar = immer::persist::json_immer_output_archive< + cereal::XMLOutputArchive, + Pools, + decltype(wrap)>{pools, wrap, os}; + ar(CEREAL_NVP(value0)); + } + return os.str(); + }; + constexpr auto reload_pool_xml = [](auto wrap) { + return [wrap](std::istream& is, + auto pools, + bool ignore_pool_exceptions) { + using Pools = std::decay_t; + auto restore = immer::util::istream_snapshot{is}; + pools.ignore_pool_exceptions = ignore_pool_exceptions; + auto ar = immer::persist::json_immer_input_archive< + cereal::XMLInputArchive, + Pools, + decltype(wrap)>{std::move(pools), wrap, is}; + /** + * NOTE: Critical to clear the pools before loading into it + * again. I hit a bug when pools contained a vector and every + * load would append to it, instead of replacing the contents. + */ + pools = {}; + ar(CEREAL_NVP(pools)); + return pools; + }; + }; + constexpr auto from_xml = [reload_pool_xml](const std::string& str, + auto& value0, + const auto& names, + const auto& wrap) { + auto is = std::istringstream{str}; + using Pools = std::decay_t< + decltype(immer::persist::detail::generate_input_pools(names))>; + auto pools = + immer::persist::load_pools(is, reload_pool_xml(wrap)); + + auto ar = immer::persist::json_immer_input_archive< + cereal::XMLInputArchive, + Pools, + decltype(wrap)>{std::move(pools), wrap, is}; + ar(CEREAL_NVP(value0)); + }; + const auto xml_str = + to_xml(value, names, immer::persist::wrap_for_saving); + auto loaded_value = model::value_one{}; + from_xml( + xml_str, loaded_value, names, immer::persist::wrap_for_loading); + REQUIRE(value == loaded_value); + } } diff --git a/test/extra/persist/test_conversion.cpp b/test/extra/persist/test_conversion.cpp index ca9db3ef..a8bfed1a 100644 --- a/test/extra/persist/test_conversion.cpp +++ b/test/extra/persist/test_conversion.cpp @@ -151,8 +151,7 @@ TEST_CASE("Convert between two hierarchies via JSON compatibility", const auto value = model::make_example_history(); - const auto [json_str, model_pools] = - immer::persist::to_json_with_auto_pool(value, model_names); + const auto model_pools = immer::persist::get_auto_pool(value, model_names); const auto map = hana::make_map( hana::make_pair(hana::type_c>, @@ -177,17 +176,14 @@ TEST_CASE("Convert between two hierarchies via JSON compatibility", const auto format_snapshots = immer::persist::convert_container( model_pools, format_load_pools, value.snapshots); + REQUIRE(test::to_json(format_snapshots) == test::to_json(value.snapshots)); + { - const auto [json_str2, pools] = immer::persist::to_json_with_auto_pool( - format_snapshots, format_names); - (void) json_str2; - REQUIRE(test::to_json(format_snapshots) == - test::to_json(value.snapshots)); - } - { - const auto [json, ar] = immer::persist::to_json_with_auto_pool( + const auto json_format = immer::persist::to_json_with_auto_pool( format::history{.snapshots = format_snapshots}, format_names); - REQUIRE(json == json_str); + const auto json_model = + immer::persist::to_json_with_auto_pool(value, model_names); + REQUIRE(json_format == json_model); } } @@ -206,8 +202,7 @@ TEST_CASE("Not every type is converted", "[conversion]") { const auto names = immer::persist::get_pools_for_type(hana::type_c); - const auto [json_str, pools] = - immer::persist::to_json_with_auto_pool(two_vectors{}, names); + const auto pools = immer::persist::get_auto_pool(two_vectors{}, names); const auto map = hana::make_map(hana::make_pair(hana::type_c>, diff --git a/test/extra/persist/test_special_pool.cpp b/test/extra/persist/test_special_pool.cpp index 621afa87..1347e5e6 100644 --- a/test/extra/persist/test_special_pool.cpp +++ b/test/extra/persist/test_special_pool.cpp @@ -264,8 +264,7 @@ TEST_CASE("Special pool minimal test") }, }; - const auto [json_str, pools] = immer::persist::to_json_with_pool(test1); - + const auto json_str = immer::persist::to_json_with_pool(test1); // REQUIRE(json_str == ""); { @@ -311,46 +310,7 @@ TEST_CASE("Save with a special pool") }, }; - const auto [json_str, pools] = immer::persist::to_json_with_pool(test1); - SECTION("Try to save and load the pool") - { - const auto pools_json = [&pools = pools] { - auto os = std::ostringstream{}; - { - auto ar = immer::persist::json_immer_output_archive< - cereal::JSONOutputArchive, - std::decay_t>{os}; - ar(123); - ar(CEREAL_NVP(pools)); - } - return os.str(); - }(); - // REQUIRE(pools_json == ""); - const auto loaded_pools = [&pools_json] { - using Pools = decltype(immer::persist::detail::generate_input_pools( - get_pools_types(test_data{}))); - auto pools = Pools{}; - - { - auto is = std::istringstream{pools_json}; - auto ar = cereal::JSONInputArchive{is}; - ar(CEREAL_NVP(pools)); - } - - { - auto is = std::istringstream{pools_json}; - auto ar = immer::persist:: - json_immer_input_archive{ - pools, is}; - ar(CEREAL_NVP(pools)); - } - - return pools; - }(); - REQUIRE(loaded_pools.storage()[hana::type_c>] - .pool.leaves.size() == 7); - } - + const auto json_str = immer::persist::to_json_with_pool(test1); // REQUIRE(json_str == ""); { @@ -408,7 +368,7 @@ TEST_CASE("Save with a special pool, special type is enclosed") REQUIRE(test1.flex_ints.container.identity() == test2.flex_ints.container.identity()); - const auto [json_str, pools] = + const auto json_str = immer::persist::to_json_with_pool(std::make_pair(test1, test2)); // REQUIRE(json_str == ""); @@ -440,7 +400,7 @@ TEST_CASE("Special pool must load and save types that have no pool") const auto val2 = test_value{234, "value2"}; const auto value = std::make_pair(val1, val2); - const auto json_pool_str = immer::persist::to_json_with_pool(value).first; + const auto json_pool_str = immer::persist::to_json_with_pool(value); REQUIRE(json_pool_str == test::to_json(value)); { @@ -456,7 +416,7 @@ TEST_CASE("Special pool loads empty test_data") const auto value = test_data{}; // const auto json_pool_str = - // immer::persist::to_json_with_pool(value).first; + // immer::persist::to_json_with_pool(value); // REQUIRE(json_pool_str == ""); const auto json_pool_str = R"({ @@ -524,7 +484,7 @@ TEST_CASE("Special pool throws cereal::Exception") const auto value = test_data{}; // const auto json_pool_str = - // immer::persist::to_json_with_pool(value).first; + // immer::persist::to_json_with_pool(value); // REQUIRE(json_pool_str == ""); const auto json_pool_str = R"({ @@ -631,14 +591,14 @@ TEST_CASE("Test recursive type") immer::box{v2}}, }; - const auto [json_str, pools] = immer::persist::to_json_with_pool(v3); + const auto json_str = immer::persist::to_json_with_pool(v3); // REQUIRE(json_str == ""); { auto full_load = immer::persist::from_json_with_pool(json_str); REQUIRE(full_load == v3); - REQUIRE(immer::persist::to_json_with_pool(full_load).first == json_str); + REQUIRE(immer::persist::to_json_with_pool(full_load) == json_str); } } @@ -670,14 +630,14 @@ TEST_CASE("Test recursive type, saving the box triggers saving the box of the " }, }; - const auto [json_str, pools] = immer::persist::to_json_with_pool(v5); + const auto json_str = immer::persist::to_json_with_pool(v5); // REQUIRE(json_str == ""); { const auto full_load = immer::persist::from_json_with_pool(json_str); REQUIRE(full_load == v5); - REQUIRE(immer::persist::to_json_with_pool(full_load).first == json_str); + REQUIRE(immer::persist::to_json_with_pool(full_load) == json_str); } } @@ -734,14 +694,14 @@ TEST_CASE("Test saving a map that contains the same map") }, }; - const auto [json_str, pools] = immer::persist::to_json_with_pool(value); + const auto json_str = immer::persist::to_json_with_pool(value); // REQUIRE(json_str == ""); { const auto full_load = immer::persist::from_json_with_pool(json_str); REQUIRE(full_load == value); - REQUIRE(immer::persist::to_json_with_pool(full_load).first == json_str); + REQUIRE(immer::persist::to_json_with_pool(full_load) == json_str); } } @@ -890,7 +850,7 @@ TEST_CASE("Test conversion with a special pool") old_type{"_53_", 53}, }, }; - const auto [json_str, pools] = immer::persist::to_json_with_pool(value); + const auto json_str = immer::persist::to_json_with_pool(value); // REQUIRE(json_str == ""); // Describe how to go from the old pool to the desired new pool. @@ -925,8 +885,7 @@ TEST_CASE("Test conversion with a special pool") SECTION( "Demonstrate that the loaded vectors and maps still share structure") { - const auto [json_str, pools] = - immer::persist::to_json_with_pool(full_load); + const auto json_str = immer::persist::to_json_with_pool(full_load); // For example, "x21x" is stored only once. const auto expected = json_t::parse(R"( { diff --git a/test/extra/persist/test_special_pool_auto.cpp b/test/extra/persist/test_special_pool_auto.cpp index 74a17d78..3d1544f9 100644 --- a/test/extra/persist/test_special_pool_auto.cpp +++ b/test/extra/persist/test_special_pool_auto.cpp @@ -172,7 +172,7 @@ TEST_CASE("Auto-persisting") .std_vector_ints = {4, 5, 6, 7}, }; - const auto [json_str, pools] = + const auto json_str = immer::persist::to_json_with_auto_pool(value, pool_types); // REQUIRE(json_str == ""); @@ -191,7 +191,7 @@ TEST_CASE("Auto-pool must load and save types that have no pool") const auto value = std::make_pair(val1, val2); const auto json_pool_str = - immer::persist::to_json_with_auto_pool(value, hana::make_map()).first; + immer::persist::to_json_with_auto_pool(value, hana::make_map()); REQUIRE(json_pool_str == test::to_json(value)); { @@ -239,7 +239,7 @@ TEST_CASE("Test save and load small type") }; const auto pool_types = immer::persist::get_pools_for_type(boost::hana::typeid_(value)); - const auto [json_str, pools] = + const auto json_str = immer::persist::to_json_with_auto_pool(value, pool_types); // REQUIRE(json_str == ""); @@ -340,7 +340,7 @@ TEST_CASE("Test conversion with auto-pool") const auto old_pool_types = immer::persist::get_pools_for_type(hana::type_c); - const auto [json_str, pools] = + const auto json_str = immer::persist::to_json_with_auto_pool(value, old_pool_types); // REQUIRE(json_str == ""); @@ -508,8 +508,7 @@ TEST_CASE("Test table with a funny value") const auto names = immer::persist::get_pools_for_type(hana::type_c); - const auto [json_str, ar] = - immer::persist::to_json_with_auto_pool(value, names); + const auto json_str = immer::persist::to_json_with_auto_pool(value, names); // REQUIRE(json_str == ""); const auto loaded = @@ -550,8 +549,7 @@ TEST_CASE("Test loading broken table") const auto names = immer::persist::get_pools_for_type(hana::type_c); - const auto [json_str, ar] = - immer::persist::to_json_with_auto_pool(value, names); + const auto json_str = immer::persist::to_json_with_auto_pool(value, names); // REQUIRE(json_str == ""); constexpr auto expected_json_str = R"( @@ -620,6 +618,15 @@ TEST_CASE("Test loading broken table") immer::persist::from_json_with_auto_pool( json.dump(), names); REQUIRE(loaded == value); + + SECTION("Loaded value has the same structure as the original") + { + // XXX Currently there is a problem with the box, it gets created + // twice. + const auto json_from_loaded = + immer::persist::to_json_with_auto_pool(loaded, names); + REQUIRE(json_str != json_from_loaded); + } } SECTION("Break the table that's part of the pool itself, not the loaded " @@ -803,7 +810,7 @@ TEST_CASE("Test table with a funny value no auto") .twos_table = t1.insert(two2), }; - const auto [json_str, ar] = immer::persist::to_json_with_pool(value); + const auto json_str = immer::persist::to_json_with_pool(value); // REQUIRE(json_str == ""); const auto loaded = @@ -847,9 +854,7 @@ TEST_CASE("Structure breaks when hash is changed") const auto names = immer::persist::get_pools_for_type(hana::type_c); - const auto [json_str, ar] = - immer::persist::to_json_with_auto_pool(value, names); - // REQUIRE(json_str == ""); + const auto out_pool = immer::persist::get_auto_pool(value, names); constexpr auto convert_pair = [](const std::pair& old) { return std::make_pair(fmt::format("_{}_", old.first), old.second); @@ -866,10 +871,11 @@ TEST_CASE("Structure breaks when hash is changed") ); - auto load_ar = immer::persist::transform_output_pool(ar, map); + auto in_pool = immer::persist::transform_output_pool(out_pool, map); - REQUIRE_THROWS_AS(immer::persist::convert_container(ar, load_ar, value.map), - immer::persist::champ::hash_validation_failed_exception); + REQUIRE_THROWS_AS( + immer::persist::convert_container(out_pool, in_pool, value.map), + immer::persist::champ::hash_validation_failed_exception); } TEST_CASE("Converting between incompatible keys")