diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9de05405..0c62dd3f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,9 +1,12 @@ project(msft_proxy_tests) add_executable(msft_proxy_tests + proxy_creation_tests.cpp + proxy_invocation_tests.cpp proxy_lifetime_tests.cpp proxy_reflection_tests.cpp proxy_traits_tests.cpp ) +target_include_directories(msft_proxy_tests PRIVATE .) target_compile_features(msft_proxy_tests PRIVATE cxx_std_20) target_link_libraries(msft_proxy_tests PRIVATE msft_proxy) target_link_libraries(msft_proxy_tests PRIVATE gtest_main) diff --git a/tests/proxy_creation_tests.cpp b/tests/proxy_creation_tests.cpp new file mode 100644 index 00000000..936a7a73 --- /dev/null +++ b/tests/proxy_creation_tests.cpp @@ -0,0 +1,204 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include +#include "proxy.h" +#include "utils.h" + +namespace { + +struct TraitsReflection { + public: + template + constexpr explicit TraitsReflection(std::in_place_type_t>) + : sbo_enabled_(true) {} + template + constexpr explicit TraitsReflection(std::in_place_type_t>) + : sbo_enabled_(false) {} + + bool sbo_enabled_; +}; + +struct TestSmallFacade : pro::facade { + using reflection_type = TraitsReflection; + static constexpr std::size_t maximum_size = sizeof(void*); + static constexpr auto minimum_copyability = pro::constraint_level::nontrivial; +}; +struct TestLargeFacade : pro::facade { + using reflection_type = TraitsReflection; + static constexpr auto minimum_copyability = pro::constraint_level::nontrivial; +}; + +} // namespace + +TEST(ProxyCreationTests, TestMakeProxy_WithSBO_FromValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + utils::LifetimeTracker::Session session{ &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + { + auto p = pro::make_proxy(session); + ASSERT_TRUE(p.has_value()); + ASSERT_EQ(p.invoke(), "Session 2"); + ASSERT_TRUE(p.reflect().sbo_enabled_); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kCopyConstruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithSBO_InPlace) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + { + auto p = pro::make_proxy(&tracker); + ASSERT_TRUE(p.has_value()); + ASSERT_EQ(p.invoke(), "Session 1"); + ASSERT_TRUE(p.reflect().sbo_enabled_); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithSBO_InPlaceInitializerList) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + { + auto p = pro::make_proxy({ 1, 2, 3 }, &tracker); + ASSERT_TRUE(p.has_value()); + ASSERT_EQ(p.invoke(), "Session 1"); + ASSERT_TRUE(p.reflect().sbo_enabled_); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kInitializerListConstruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithSBO_Lifetime_Copy) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + { + auto p1 = pro::make_proxy(&tracker); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + auto p2 = p1; + ASSERT_TRUE(p1.has_value()); + ASSERT_EQ(p1.invoke(), "Session 1"); + ASSERT_TRUE(p1.reflect().sbo_enabled_); + ASSERT_TRUE(p2.has_value()); + ASSERT_EQ(p2.invoke(), "Session 2"); + ASSERT_TRUE(p2.reflect().sbo_enabled_); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kCopyConstruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithSBO_Lifetime_Move) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + { + auto p1 = pro::make_proxy(&tracker); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + auto p2 = std::move(p1); + ASSERT_FALSE(p1.has_value()); + ASSERT_TRUE(p2.has_value()); + ASSERT_EQ(p2.invoke(), "Session 2"); + ASSERT_TRUE(p2.reflect().sbo_enabled_); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithoutSBO_FromValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + utils::LifetimeTracker::Session session{ &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + { + auto p = pro::make_proxy(session); + ASSERT_TRUE(p.has_value()); + ASSERT_EQ(p.invoke(), "Session 2"); + ASSERT_FALSE(p.reflect().sbo_enabled_); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kCopyConstruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithoutSBO_InPlace) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + { + auto p = pro::make_proxy(&tracker); + ASSERT_TRUE(p.has_value()); + ASSERT_EQ(p.invoke(), "Session 1"); + ASSERT_FALSE(p.reflect().sbo_enabled_); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithoutSBO_InPlaceInitializerList) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + { + auto p = pro::make_proxy({ 1, 2, 3 }, &tracker); + ASSERT_TRUE(p.has_value()); + ASSERT_EQ(p.invoke(), "Session 1"); + ASSERT_FALSE(p.reflect().sbo_enabled_); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kInitializerListConstruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithoutSBO_Lifetime_Copy) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + { + auto p1 = pro::make_proxy(&tracker); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + auto p2 = p1; + ASSERT_TRUE(p1.has_value()); + ASSERT_EQ(p1.invoke(), "Session 1"); + ASSERT_FALSE(p1.reflect().sbo_enabled_); + ASSERT_TRUE(p2.has_value()); + ASSERT_EQ(p2.invoke(), "Session 2"); + ASSERT_FALSE(p2.reflect().sbo_enabled_); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kCopyConstruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} + +TEST(ProxyCreationTests, TestMakeProxy_WithoutSBO_Lifetime_Move) { + utils::LifetimeTracker tracker; + std::vector expected_ops; + { + auto p1 = pro::make_proxy(&tracker); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + auto p2 = std::move(p1); + ASSERT_FALSE(p1.has_value()); + ASSERT_TRUE(p2.has_value()); + ASSERT_EQ(p2.invoke(), "Session 1"); + ASSERT_FALSE(p2.reflect().sbo_enabled_); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); + } + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + ASSERT_TRUE(tracker.GetOperations() == expected_ops); +} diff --git a/tests/proxy_invocation_tests.cpp b/tests/proxy_invocation_tests.cpp new file mode 100644 index 00000000..bfee24ac --- /dev/null +++ b/tests/proxy_invocation_tests.cpp @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include +#include +#include +#include +#include "proxy.h" + +namespace { + +template struct Call; +template +struct Call : pro::dispatch { + template + R operator()(T& self, Args&&... args) + { return self(std::forward(args)...); } +}; +template +struct CallableFacade : pro::facade> {}; + +struct GetSize : pro::dispatch { + template + std::size_t operator()(const T& self) { return self.size(); } +}; +template +struct ForEach : pro::dispatch>)> { + template + void operator()(U& self, pro::proxy>&& func) { + for (auto& value : self) { + func.invoke(value); + } + } +}; +template +struct IterableFacade : pro::facade, GetSize> {}; + +template struct Append; +template +struct ContainerFacade : pro::facade, GetSize, Append> {}; +template +struct Append : pro::dispatch>(T)> { + template + pro::proxy> operator()(U& self, T&& value) { + self.push_back(std::move(value)); + return &self; + } +}; + +template +concept InvocableWithDispatch = requires(pro::proxy p, Args... args) { + { p.template invoke(std::forward(args)...) }; +}; +template +concept InvocableWithoutDispatch = requires(pro::proxy p, Args... args) { + { p.invoke(std::forward(args)...) }; +}; + +// Static assertions for a facade of a single dispatch +static_assert(InvocableWithDispatch, Call, double>); +static_assert(!InvocableWithDispatch, Call, std::nullptr_t>); // Wrong arguments +static_assert(!InvocableWithoutDispatch, std::nullptr_t>); // Wrong arguments +static_assert(!InvocableWithDispatch, int(double), double>); // Wrong dispatch +static_assert(InvocableWithoutDispatch, float>); // Invoking without specifying a dispatch + +// Static assertions for a facade of multiple dispatches +static_assert(InvocableWithDispatch, GetSize>); +static_assert(!InvocableWithDispatch, ForEach, pro::proxy>>); // Wrong arguments +static_assert(!InvocableWithDispatch, Append>); // Wrong dispatch +static_assert(!InvocableWithoutDispatch>); // Invoking without specifying a dispatch + +} // namespace + +TEST(ProxyInvocationTests, TestArgumentForwarding) { + std::string arg1 = "My string"; + std::vector arg2 = { 1, 2, 3 }; + std::vector arg2_copy = arg2; + std::string arg1_received; + std::vector arg2_received; + int expected_result = 456; + auto f = [&](std::string&& s, std::vector&& v) -> int { + arg1_received = std::move(s); + arg2_received = std::move(v); + return expected_result; + }; + pro::proxy)>> p = &f; + int result = p.invoke(arg1, std::move(arg2)); + ASSERT_TRUE(p.has_value()); + ASSERT_EQ(arg1_received, arg1); + ASSERT_TRUE(arg2.empty()); + ASSERT_EQ(arg2_received, arg2_copy); + ASSERT_EQ(result, expected_result); +} + +TEST(ProxyInvocationTests, TestThrow) { + std::string expected_error_message = "My exception"; + auto f = [&] { throw std::runtime_error{ expected_error_message }; }; + bool exception_thrown = false; + pro::proxy> p = &f; + try { + p.invoke(); + } catch (const std::runtime_error& e) { + exception_thrown = true; + ASSERT_EQ(e.what(), expected_error_message); + } + ASSERT_TRUE(exception_thrown); + ASSERT_TRUE(p.has_value()); +} + +TEST(ProxyInvocationTests, TestMultipleDispatches_Unique) { + std::list l = { 1, 2, 3 }; + pro::proxy> p = &l; + ASSERT_EQ(p.invoke(), 3); + int sum = 0; + auto accumulate_sum = [&](int x) { sum += x; }; + p.invoke>(&accumulate_sum); + ASSERT_EQ(sum, 6); +} + +TEST(ProxyInvocationTests, TestMultipleDispatches_Duplicated) { + using SomeCombination = std::tuple, std::tuple>>; + struct DuplicatedIterableFacade : pro::facade< + ForEach, SomeCombination, ForEach, GetSize, GetSize> {}; + static_assert(sizeof(pro::details::facade_traits::meta_type) == + sizeof(pro::details::facade_traits>::meta_type)); + std::list l = { 1, 2, 3 }; + pro::proxy p = &l; + ASSERT_EQ(p.invoke(), 3); + int sum = 0; + auto accumulate_sum = [&](int x) { sum += x; }; + p.invoke>(&accumulate_sum); + ASSERT_EQ(sum, 6); +} + +TEST(ProxyInvocationTests, TestRecursiveDefinition) { + std::list l = { 1, 2, 3 }; + pro::proxy> p = &l; + ASSERT_EQ(p.invoke(), 3); + int sum = 0; + auto accumulate_sum = [&](int x) { sum += x; }; + p.invoke>(&accumulate_sum); + ASSERT_EQ(sum, 6); + p.invoke>(4).invoke>(5).invoke>(6); + ASSERT_EQ(p.invoke(), 6); + sum = 0; + p.invoke>(&accumulate_sum); + ASSERT_EQ(sum, 21); +} diff --git a/tests/proxy_lifetime_tests.cpp b/tests/proxy_lifetime_tests.cpp index 33cc67c0..0c472bca 100644 --- a/tests/proxy_lifetime_tests.cpp +++ b/tests/proxy_lifetime_tests.cpp @@ -2,94 +2,15 @@ // Licensed under the MIT License. #include -#include -#include #include "proxy.h" +#include "utils.h" namespace { -struct ToString : pro::dispatch { - template - std::string operator()(const T& self) { - using std::to_string; - return to_string(self); - } -}; -struct TestFacade : pro::facade { +struct TestFacade : pro::facade { static constexpr auto minimum_copyability = pro::constraint_level::nontrivial; }; -enum class LifetimeOperationType { - kNone, - kValueConstruction, - kInitializerListConstruction, - kCopyConstruction, - kMoveConstruction, - kDestruction -}; - -struct LifetimeOperation { - LifetimeOperation(int id, LifetimeOperationType type) : id_(id), type_(type) {} - - bool operator==(const LifetimeOperation& rhs) const - { return id_ == rhs.id_ && type_ == rhs.type_; } - - int id_; - LifetimeOperationType type_; -}; - -struct ConstructionFailure : std::exception { - ConstructionFailure(LifetimeOperationType type) : type_(type) {} - - LifetimeOperationType type_; -}; - -class LifetimeTracker { - public: - LifetimeTracker() = default; - LifetimeTracker(const LifetimeTracker&) = delete; - - class Session { - public: - Session(LifetimeTracker* host) - : id_(host->AllocateId(LifetimeOperationType::kValueConstruction)), - host_(host) {} - Session(std::initializer_list, LifetimeTracker* host) - : id_(host->AllocateId(LifetimeOperationType::kInitializerListConstruction)), - host_(host) {} - Session(const Session& rhs) - : id_(rhs.host_->AllocateId(LifetimeOperationType::kCopyConstruction)), - host_(rhs.host_) {} - Session(Session&& rhs) noexcept : - id_(rhs.host_->AllocateId(LifetimeOperationType::kMoveConstruction)), - host_(rhs.host_) {} - ~Session() { host_->ops_.emplace_back(id_, LifetimeOperationType::kDestruction); } - Session& operator*() { return *this; } - friend std::string to_string(const Session& self) { return "Session " + std::to_string(self.id_); } - - private: - int id_; - LifetimeTracker* const host_; - }; - - const std::vector& GetOperations() const { return ops_; } - void ThrowOnNextConstruction() { throw_on_next_construction_ = true; } - - private: - int AllocateId(LifetimeOperationType operation_type) { - if (throw_on_next_construction_) { - throw_on_next_construction_ = false; - throw ConstructionFailure{ operation_type }; - } - ops_.emplace_back(++max_id_, operation_type); - return max_id_; - } - - int max_id_ = 0; - bool throw_on_next_construction_ = false; - std::vector ops_; -}; - } // namespace TEST(ProxyLifetimeTests, TestDefaultConstrction) { @@ -102,68 +23,68 @@ TEST(ProxyLifetimeTests, TestNullConstrction) { ASSERT_FALSE(p.has_value()); } -TEST(ProxyLifetimeTests, TestPolyConstrction) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyConstrction_FromValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p = LifetimeTracker::Session(&tracker); + pro::proxy p = utils::LifetimeTracker::Session(&tracker); ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 2"); - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestPolyConstrction_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyConstrction_FromValue_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - LifetimeTracker::Session another_session{ &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + utils::LifetimeTracker::Session another_session{ &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { pro::proxy p = another_session; - } catch (const ConstructionFailure& e) { + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kCopyConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kCopyConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlacePolyConstrction) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyConstrction_InPlace) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; + pro::proxy p{ std::in_place_type, &tracker }; ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 1"); - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlacePolyConstrction_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyConstrction_InPlace_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { - pro::proxy p{ std::in_place_type, &tracker }; - } catch (const ConstructionFailure& e) { + pro::proxy p{ std::in_place_type, &tracker }; + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kValueConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kValueConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_TRUE(tracker.GetOperations() == expected_ops); @@ -171,31 +92,31 @@ TEST(ProxyLifetimeTests, TestInPlacePolyConstrction_Exception) { ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlaceInitializerListPolyConstrction) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyConstrction_InPlaceInitializerList) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, { 1, 2, 3 }, &tracker }; + pro::proxy p{ std::in_place_type, { 1, 2, 3 }, &tracker }; ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 1"); - expected_ops.emplace_back(1, LifetimeOperationType::kInitializerListConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kInitializerListConstruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlaceInitializerListPolyConstrction_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyConstrction_InPlaceInitializerList_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { - pro::proxy p{ std::in_place_type, { 1, 2, 3 }, &tracker }; - } catch (const ConstructionFailure& e) { + pro::proxy p{ std::in_place_type, { 1, 2, 3 }, &tracker }; + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kInitializerListConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kInitializerListConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_TRUE(tracker.GetOperations() == expected_ops); @@ -204,44 +125,44 @@ TEST(ProxyLifetimeTests, TestInPlaceInitializerListPolyConstrction_Exception) { } TEST(ProxyLifetimeTests, TestCopyConstrction_FromValue) { - LifetimeTracker tracker; - std::vector expected_ops; + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); auto p2 = p1; ASSERT_TRUE(p1.has_value()); ASSERT_EQ(p1.invoke(), "Session 1"); ASSERT_TRUE(p2.has_value()); ASSERT_EQ(p2.invoke(), "Session 2"); - expected_ops.emplace_back(2, LifetimeOperationType::kCopyConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kCopyConstruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } TEST(ProxyLifetimeTests, TestCopyConstrction_FromValue_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { auto p2 = p1; - } catch (const ConstructionFailure& e) { + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kCopyConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kCopyConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_TRUE(p1.has_value()); ASSERT_EQ(p1.invoke(), "Session 1"); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } @@ -253,20 +174,20 @@ TEST(ProxyLifetimeTests, TestCopyConstrction_FromNull) { } TEST(ProxyLifetimeTests, TestMoveConstrction_FromValue) { - LifetimeTracker tracker; - std::vector expected_ops; + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); auto p2 = std::move(p1); ASSERT_FALSE(p1.has_value()); ASSERT_TRUE(p2.has_value()); ASSERT_EQ(p2.invoke(), "Session 2"); - expected_ops.emplace_back(2, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } @@ -278,14 +199,14 @@ TEST(ProxyLifetimeTests, TestMoveConstrction_FromNull) { } TEST(ProxyLifetimeTests, TestNullAssignment_ToValue) { - LifetimeTracker tracker; - std::vector expected_ops; + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); p = nullptr; ASSERT_FALSE(p.has_value()); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } ASSERT_TRUE(tracker.GetOperations() == expected_ops); @@ -298,156 +219,156 @@ TEST(ProxyLifetimeTests, TestNullAssignment_ToNull) { } TEST(ProxyLifetimeTests, TestPolyAssignment_ToValue) { - LifetimeTracker tracker; - std::vector expected_ops; + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - p = LifetimeTracker::Session{ &tracker }; + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + p = utils::LifetimeTracker::Session{ &tracker }; ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 3"); - expected_ops.emplace_back(2, LifetimeOperationType::kValueConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(3, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kValueConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(3, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } TEST(ProxyLifetimeTests, TestPolyAssignment_ToValue_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - LifetimeTracker::Session session{ &tracker }; - expected_ops.emplace_back(2, LifetimeOperationType::kValueConstruction); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + utils::LifetimeTracker::Session session{ &tracker }; + expected_ops.emplace_back(2, utils::LifetimeOperationType::kValueConstruction); tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { p = session; - } catch (const ConstructionFailure& e) { + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kCopyConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kCopyConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 1"); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestPolyAssignment_ToNull) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_FromValue_ToNull) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p; - p = LifetimeTracker::Session{ &tracker }; + p = utils::LifetimeTracker::Session{ &tracker }; ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 2"); - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestPolyAssignment_ToNull_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_FromValue_ToNull_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - LifetimeTracker::Session session{ &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + utils::LifetimeTracker::Session session{ &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); pro::proxy p; tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { p = session; - } catch (const ConstructionFailure& e) { + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kCopyConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kCopyConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_FALSE(p.has_value()); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlacePolyAssignment_ToValue) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_InPlace_ToValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - p.emplace(&tracker); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + p.emplace(&tracker); ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 2"); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(2, LifetimeOperationType::kValueConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kValueConstruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlacePolyAssignment_ToValue_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_InPlace_ToValue_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { - p.emplace(&tracker); - } catch (const ConstructionFailure& e) { + p.emplace(&tracker); + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kValueConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kValueConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_FALSE(p.has_value()); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlacePolyAssignment_ToNull) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_InPlace_ToNull) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p; - p.emplace(&tracker); + p.emplace(&tracker); ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 1"); - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlacePolyAssignment_ToNull_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_InPlace_ToNull_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p; tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { - p.emplace(&tracker); - } catch (const ConstructionFailure& e) { + p.emplace(&tracker); + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kValueConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kValueConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_FALSE(p.has_value()); @@ -456,72 +377,72 @@ TEST(ProxyLifetimeTests, TestInPlacePolyAssignment_ToNull_Exception) { ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlaceInitializerListPolyAssignment_ToValue) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_InPlaceInitializerList_ToValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - p.emplace({ 1, 2, 3 }, &tracker); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + p.emplace({ 1, 2, 3 }, &tracker); ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 2"); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(2, LifetimeOperationType::kInitializerListConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kInitializerListConstruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlaceInitializerListPolyAssignment_ToValue_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_InPlaceInitializerList_ToValue_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { - p.emplace({ 1, 2, 3 }, &tracker); - } catch (const ConstructionFailure& e) { + p.emplace({ 1, 2, 3 }, &tracker); + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kInitializerListConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kInitializerListConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_FALSE(p.has_value()); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlaceInitializerListPolyAssignment_ToNull) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_InPlaceInitializerList_ToNull) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p; - p.emplace({ 1, 2, 3 }, &tracker); + p.emplace({ 1, 2, 3 }, &tracker); ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 1"); - expected_ops.emplace_back(1, LifetimeOperationType::kInitializerListConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kInitializerListConstruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestInPlaceInitializerListPolyAssignment_ToNull_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestPolyAssignment_InPlaceInitializerList_ToNull_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p; tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { - p.emplace({ 1, 2, 3 }, &tracker); - } catch (const ConstructionFailure& e) { + p.emplace({ 1, 2, 3 }, &tracker); + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kInitializerListConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kInitializerListConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_FALSE(p.has_value()); @@ -530,45 +451,45 @@ TEST(ProxyLifetimeTests, TestInPlaceInitializerListPolyAssignment_ToNull_Excepti ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestCopyAssignment_FromValueToValue) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestCopyAssignment_FromValue_ToValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - pro::proxy p2{ std::in_place_type, &tracker }; - expected_ops.emplace_back(2, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + pro::proxy p2{ std::in_place_type, &tracker }; + expected_ops.emplace_back(2, utils::LifetimeOperationType::kValueConstruction); p1 = p2; ASSERT_TRUE(p1.has_value()); ASSERT_EQ(p1.invoke(), "Session 4"); ASSERT_TRUE(p2.has_value()); ASSERT_EQ(p2.invoke(), "Session 2"); - expected_ops.emplace_back(3, LifetimeOperationType::kCopyConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(4, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(3, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kCopyConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(4, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(4, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(4, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestCopyAssignment_FromValueToValue_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestCopyAssignment_FromValue_ToValue_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - pro::proxy p2{ std::in_place_type, &tracker }; - expected_ops.emplace_back(2, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + pro::proxy p2{ std::in_place_type, &tracker }; + expected_ops.emplace_back(2, utils::LifetimeOperationType::kValueConstruction); tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { p1 = p2; - } catch (const ConstructionFailure& e) { + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kCopyConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kCopyConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_TRUE(p1.has_value()); @@ -577,17 +498,17 @@ TEST(ProxyLifetimeTests, TestCopyAssignment_FromValueToValue_Exception) { ASSERT_EQ(p2.invoke(), "Session 2"); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestCopyAssignment_FromValueToSelf) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestCopyAssignment_FromValue_ToSelf) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wself-assign-overloaded" @@ -598,52 +519,52 @@ TEST(ProxyLifetimeTests, TestCopyAssignment_FromValueToSelf) { #endif // __clang__ ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 3"); - expected_ops.emplace_back(2, LifetimeOperationType::kCopyConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(3, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kCopyConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(3, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestCopyAssignment_FromValueToNull) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestCopyAssignment_FromValue_ToNull) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p1; - pro::proxy p2{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p2{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); p1 = p2; ASSERT_TRUE(p1.has_value()); ASSERT_EQ(p1.invoke(), "Session 3"); ASSERT_TRUE(p2.has_value()); ASSERT_EQ(p2.invoke(), "Session 1"); - expected_ops.emplace_back(2, LifetimeOperationType::kCopyConstruction); - expected_ops.emplace_back(3, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kCopyConstruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(3, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestCopyAssignment_FromValueToNull_Exception) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestCopyAssignment_FromValue_ToNull_Exception) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p1; - pro::proxy p2{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p2{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); tracker.ThrowOnNextConstruction(); bool exception_thrown = false; try { p1 = p2; - } catch (const ConstructionFailure& e) { + } catch (const utils::ConstructionFailure& e) { exception_thrown = true; - ASSERT_EQ(e.type_, LifetimeOperationType::kCopyConstruction); + ASSERT_EQ(e.type_, utils::LifetimeOperationType::kCopyConstruction); } ASSERT_TRUE(exception_thrown); ASSERT_FALSE(p1.has_value()); @@ -651,25 +572,25 @@ TEST(ProxyLifetimeTests, TestCopyAssignment_FromValueToNull_Exception) { ASSERT_EQ(p2.invoke(), "Session 1"); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestCopyAssignment_FromNullToValue) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestCopyAssignment_FromNull_ToValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); pro::proxy p2; p1 = p2; - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestCopyAssignment_FromNullToSelf) { +TEST(ProxyLifetimeTests, TestCopyAssignment_FromNull_ToSelf) { pro::proxy p; #ifdef __clang__ #pragma clang diagnostic push @@ -682,7 +603,7 @@ TEST(ProxyLifetimeTests, TestCopyAssignment_FromNullToSelf) { ASSERT_FALSE(p.has_value()); } -TEST(ProxyLifetimeTests, TestCopyAssignment_FromNullToNull) { +TEST(ProxyLifetimeTests, TestCopyAssignment_FromNull_ToNull) { pro::proxy p1; pro::proxy p2; p1 = p2; @@ -690,33 +611,33 @@ TEST(ProxyLifetimeTests, TestCopyAssignment_FromNullToNull) { ASSERT_FALSE(p2.has_value()); } -TEST(ProxyLifetimeTests, TestMoveAssignment_FromValueToValue) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestMoveAssignment_FromValue_ToValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - pro::proxy p2{ std::in_place_type, &tracker }; - expected_ops.emplace_back(2, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + pro::proxy p2{ std::in_place_type, &tracker }; + expected_ops.emplace_back(2, utils::LifetimeOperationType::kValueConstruction); p1 = std::move(p2); ASSERT_TRUE(p1.has_value()); ASSERT_EQ(p1.invoke(), "Session 3"); ASSERT_FALSE(p2.has_value()); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(3, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(3, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestMoveAssignment_FromValueToSelf) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestMoveAssignment_FromValue_ToSelf) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wself-move" @@ -726,48 +647,48 @@ TEST(ProxyLifetimeTests, TestMoveAssignment_FromValueToSelf) { #pragma clang diagnostic pop #endif // __clang__ ASSERT_FALSE(p.has_value()); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(2, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestMoveAssignment_FromValueToNull) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestMoveAssignment_FromValue_ToNull) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p1; - pro::proxy p2{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p2{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); p1 = std::move(p2); ASSERT_TRUE(p1.has_value()); ASSERT_EQ(p1.invoke(), "Session 2"); ASSERT_FALSE(p2.has_value()); - expected_ops.emplace_back(2, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestMoveAssignment_FromNullToValue) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestMoveAssignment_FromNull_ToValue) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); pro::proxy p2; p1 = std::move(p2); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestMoveAssignment_FromNullToSelf) { +TEST(ProxyLifetimeTests, TestMoveAssignment_FromNull_ToSelf) { pro::proxy p; #ifdef __clang__ #pragma clang diagnostic push @@ -780,7 +701,7 @@ TEST(ProxyLifetimeTests, TestMoveAssignment_FromNullToSelf) { ASSERT_FALSE(p.has_value()); } -TEST(ProxyLifetimeTests, TestMoveAssignment_FromNullToNull) { +TEST(ProxyLifetimeTests, TestMoveAssignment_FromNull_ToNull) { pro::proxy p1; pro::proxy p2; p1 = std::move(p2); @@ -798,14 +719,14 @@ TEST(ProxyLifetimeTests, TestHasValue) { } TEST(ProxyLifetimeTests, TestReset_FromValue) { - LifetimeTracker tracker; - std::vector expected_ops; + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); p.reset(); ASSERT_FALSE(p.has_value()); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } ASSERT_TRUE(tracker.GetOperations() == expected_ops); @@ -817,94 +738,94 @@ TEST(ProxyLifetimeTests, TestReset_FromNull) { ASSERT_FALSE(p.has_value()); } -TEST(ProxyLifetimeTests, TestSwap_ValueValue) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestSwap_Value_Value) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); - pro::proxy p2{ std::in_place_type, &tracker }; - expected_ops.emplace_back(2, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); + pro::proxy p2{ std::in_place_type, &tracker }; + expected_ops.emplace_back(2, utils::LifetimeOperationType::kValueConstruction); swap(p1, p2); ASSERT_TRUE(p1.has_value()); ASSERT_EQ(p1.invoke(), "Session 4"); ASSERT_TRUE(p2.has_value()); ASSERT_EQ(p2.invoke(), "Session 5"); - expected_ops.emplace_back(3, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(4, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(5, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(3, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(4, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(5, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(5, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(4, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(5, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(4, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestSwap_ValueSelf) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestSwap_Value_Self) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); swap(p, p); ASSERT_TRUE(p.has_value()); ASSERT_EQ(p.invoke(), "Session 3"); - expected_ops.emplace_back(2, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); - expected_ops.emplace_back(3, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } - expected_ops.emplace_back(3, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(3, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestSwap_ValueNull) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestSwap_Value_Null) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { - pro::proxy p1{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p1{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); pro::proxy p2; swap(p1, p2); ASSERT_FALSE(p1.has_value()); ASSERT_TRUE(p2.has_value()); ASSERT_EQ(p2.invoke(), "Session 2"); - expected_ops.emplace_back(2, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestSwap_NullValue) { - LifetimeTracker tracker; - std::vector expected_ops; +TEST(ProxyLifetimeTests, TestSwap_Null_Value) { + utils::LifetimeTracker tracker; + std::vector expected_ops; { pro::proxy p1; - pro::proxy p2{ std::in_place_type, &tracker }; - expected_ops.emplace_back(1, LifetimeOperationType::kValueConstruction); + pro::proxy p2{ std::in_place_type, &tracker }; + expected_ops.emplace_back(1, utils::LifetimeOperationType::kValueConstruction); swap(p1, p2); ASSERT_TRUE(p1.has_value()); ASSERT_EQ(p1.invoke(), "Session 2"); ASSERT_FALSE(p2.has_value()); - expected_ops.emplace_back(2, LifetimeOperationType::kMoveConstruction); - expected_ops.emplace_back(1, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kMoveConstruction); + expected_ops.emplace_back(1, utils::LifetimeOperationType::kDestruction); } - expected_ops.emplace_back(2, LifetimeOperationType::kDestruction); + expected_ops.emplace_back(2, utils::LifetimeOperationType::kDestruction); ASSERT_TRUE(tracker.GetOperations() == expected_ops); } -TEST(ProxyLifetimeTests, TestSwap_NullSelf) { +TEST(ProxyLifetimeTests, TestSwap_Null_Self) { pro::proxy p; swap(p, p); ASSERT_FALSE(p.has_value()); } -TEST(ProxyLifetimeTests, TestSwap_NullNull) { +TEST(ProxyLifetimeTests, TestSwap_Null_Null) { pro::proxy p1; pro::proxy p2; swap(p1, p2); diff --git a/tests/proxy_reflection_tests.cpp b/tests/proxy_reflection_tests.cpp index 600a1379..971e3126 100644 --- a/tests/proxy_reflection_tests.cpp +++ b/tests/proxy_reflection_tests.cpp @@ -55,18 +55,18 @@ static_assert(ReflectionApplicable); } // namespace -TEST(ProxyReflectionTests, TestRttiReflection_RawPtr) { +TEST(ProxyReflectionTests, TestRtti_RawPtr) { int foo = 123; pro::proxy p = &foo; ASSERT_EQ(p.reflect().GetName(), typeid(int*).name()); } -TEST(ProxyReflectionTests, TestRttiReflection_FancyPtr) { +TEST(ProxyReflectionTests, TestRtti_FancyPtr) { pro::proxy p = std::make_unique(1.23); ASSERT_EQ(p.reflect().GetName(), typeid(std::unique_ptr).name()); } -TEST(ProxyReflectionTests, TestTraitsReflection_RawPtr) { +TEST(ProxyReflectionTests, TestTraits_RawPtr) { int foo = 123; pro::proxy p = &foo; ASSERT_EQ(p.reflect().is_default_constructible_, true); @@ -76,7 +76,7 @@ TEST(ProxyReflectionTests, TestTraitsReflection_RawPtr) { ASSERT_EQ(p.reflect().is_trivial_, true); } -TEST(ProxyReflectionTests, TestTraitsReflection_FancyPtr) { +TEST(ProxyReflectionTests, TestTraits_FancyPtr) { pro::proxy p = std::make_unique(1.23); ASSERT_EQ(p.reflect().is_default_constructible_, true); ASSERT_EQ(p.reflect().is_copy_constructible_, false); diff --git a/tests/proxy_traits_tests.cpp b/tests/proxy_traits_tests.cpp index 988039b6..fe5b6a1c 100644 --- a/tests/proxy_traits_tests.cpp +++ b/tests/proxy_traits_tests.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include #include "proxy.h" namespace { diff --git a/tests/utils.h b/tests/utils.h new file mode 100644 index 00000000..81db6723 --- /dev/null +++ b/tests/utils.h @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifndef _MSFT_PROXY_TEST_UTILS_ +#define _MSFT_PROXY_TEST_UTILS_ + +#include +#include + +namespace utils { + +enum class LifetimeOperationType { + kNone, + kValueConstruction, + kInitializerListConstruction, + kCopyConstruction, + kMoveConstruction, + kDestruction +}; + +struct LifetimeOperation { + LifetimeOperation(int id, LifetimeOperationType type) : id_(id), type_(type) {} + + bool operator==(const LifetimeOperation& rhs) const + { return id_ == rhs.id_ && type_ == rhs.type_; } + + int id_; + LifetimeOperationType type_; +}; + +struct ConstructionFailure : std::exception { + ConstructionFailure(LifetimeOperationType type) : type_(type) {} + + LifetimeOperationType type_; +}; + +class LifetimeTracker { + public: + LifetimeTracker() = default; + LifetimeTracker(const LifetimeTracker&) = delete; + + class Session { + public: + Session(LifetimeTracker* host) + : id_(host->AllocateId(LifetimeOperationType::kValueConstruction)), + host_(host) {} + Session(std::initializer_list, LifetimeTracker* host) + : id_(host->AllocateId(LifetimeOperationType::kInitializerListConstruction)), + host_(host) {} + Session(const Session& rhs) + : id_(rhs.host_->AllocateId(LifetimeOperationType::kCopyConstruction)), + host_(rhs.host_) {} + Session(Session&& rhs) noexcept : + id_(rhs.host_->AllocateId(LifetimeOperationType::kMoveConstruction)), + host_(rhs.host_) {} + ~Session() { host_->ops_.emplace_back(id_, LifetimeOperationType::kDestruction); } + Session& operator*() { return *this; } + friend std::string to_string(const Session& self) { return "Session " + std::to_string(self.id_); } + + private: + int id_; + LifetimeTracker* const host_; + }; + + const std::vector& GetOperations() const { return ops_; } + void ThrowOnNextConstruction() { throw_on_next_construction_ = true; } + + private: + int AllocateId(LifetimeOperationType operation_type) { + if (throw_on_next_construction_) { + throw_on_next_construction_ = false; + throw ConstructionFailure{ operation_type }; + } + ops_.emplace_back(++max_id_, operation_type); + return max_id_; + } + + int max_id_ = 0; + bool throw_on_next_construction_ = false; + std::vector ops_; +}; + +struct ToString : pro::dispatch { + template + std::string operator()(const T& self) { + using std::to_string; + return to_string(self); + } +}; + +} // namespace utils + +#endif // _MSFT_PROXY_TEST_UTILS_