@@ -26,6 +26,14 @@ struct TestTrivialFacade
2626 ::support_destruction<pro::constraint_level::trivial> //
2727 ::build {};
2828
29+ struct TestThrowingDestructionFacade
30+ : pro::facade_builder //
31+ ::add_convention<utils::spec::FreeToString, std::string()> //
32+ ::support_copy<pro::constraint_level::nontrivial> //
33+ ::support_relocation<pro::constraint_level::nontrivial> //
34+ ::support_destruction<pro::constraint_level::nontrivial> //
35+ ::build {};
36+
2937struct TestRttiFacade : pro::facade_builder //
3038 ::add_direct_reflection<utils::RttiReflector> //
3139 ::add_facade_with_substitution<TestFacade> //
@@ -278,6 +286,21 @@ TEST(ProxyLifetimeTests, TestMoveConstrction_FromNull) {
278286 ASSERT_FALSE (p2.has_value ());
279287}
280288
289+ TEST (ProxyLifetimeTests, TestDestruction_Exception) {
290+ utils::LifetimeTracker tracker;
291+ std::vector<utils::LifetimeOperation> expected_ops;
292+ auto destroy = [&] {
293+ pro::proxy<detail::TestThrowingDestructionFacade> p{
294+ std::in_place_type<utils::LifetimeTracker::ThrowingDestructionSession>,
295+ &tracker};
296+ };
297+ ASSERT_THROW (destroy (), utils::DestructionFailure);
298+ expected_ops.emplace_back (1 ,
299+ utils::LifetimeOperationType::kValueConstruction );
300+ expected_ops.emplace_back (1 , utils::LifetimeOperationType::kDestruction );
301+ ASSERT_TRUE (tracker.GetOperations () == expected_ops);
302+ }
303+
281304TEST (ProxyLifetimeTests, TestNullAssignment_FromNullptr_ToValue) {
282305 utils::LifetimeTracker tracker;
283306 std::vector<utils::LifetimeOperation> expected_ops;
@@ -362,6 +385,30 @@ TEST(ProxyLifetimeTests, TestPolyAssignment_ToValue_Exception) {
362385 ASSERT_TRUE (tracker.GetOperations () == expected_ops);
363386}
364387
388+ TEST (ProxyLifetimeTests, TestPolyAssignment_ToValue_DestructionException) {
389+ utils::LifetimeTracker tracker;
390+ std::vector<utils::LifetimeOperation> expected_ops;
391+ {
392+ pro::proxy<detail::TestThrowingDestructionFacade> p{
393+ std::in_place_type<utils::LifetimeTracker::ThrowingDestructionSession>,
394+ &tracker};
395+ expected_ops.emplace_back (1 ,
396+ utils::LifetimeOperationType::kValueConstruction );
397+ utils::LifetimeTracker::Session session{&tracker};
398+ expected_ops.emplace_back (2 ,
399+ utils::LifetimeOperationType::kValueConstruction );
400+ ASSERT_THROW (p = session, utils::DestructionFailure);
401+ ASSERT_FALSE (p.has_value ());
402+ expected_ops.emplace_back (3 ,
403+ utils::LifetimeOperationType::kCopyConstruction );
404+ expected_ops.emplace_back (1 , utils::LifetimeOperationType::kDestruction );
405+ expected_ops.emplace_back (3 , utils::LifetimeOperationType::kDestruction );
406+ ASSERT_TRUE (tracker.GetOperations () == expected_ops);
407+ }
408+ expected_ops.emplace_back (2 , utils::LifetimeOperationType::kDestruction );
409+ ASSERT_TRUE (tracker.GetOperations () == expected_ops);
410+ }
411+
365412TEST (ProxyLifetimeTests, TestPolyAssignment_FromValue_ToNull) {
366413 utils::LifetimeTracker tracker;
367414 std::vector<utils::LifetimeOperation> expected_ops;
@@ -634,6 +681,34 @@ TEST(ProxyLifetimeTests, TestCopyAssignment_FromValue_ToValue_Exception) {
634681 ASSERT_TRUE (tracker.GetOperations () == expected_ops);
635682}
636683
684+ TEST (ProxyLifetimeTests,
685+ TestCopyAssignment_FromValue_ToValue_DestructionException) {
686+ utils::LifetimeTracker tracker;
687+ std::vector<utils::LifetimeOperation> expected_ops;
688+ {
689+ pro::proxy<detail::TestThrowingDestructionFacade> p1{
690+ std::in_place_type<utils::LifetimeTracker::ThrowingDestructionSession>,
691+ &tracker};
692+ expected_ops.emplace_back (1 ,
693+ utils::LifetimeOperationType::kValueConstruction );
694+ pro::proxy<detail::TestThrowingDestructionFacade> p2{
695+ std::in_place_type<utils::LifetimeTracker::Session>, &tracker};
696+ expected_ops.emplace_back (2 ,
697+ utils::LifetimeOperationType::kValueConstruction );
698+ ASSERT_THROW (p1 = p2, utils::DestructionFailure);
699+ ASSERT_FALSE (p1.has_value ());
700+ ASSERT_TRUE (p2.has_value ());
701+ ASSERT_EQ (ToString (*p2), " Session 2" );
702+ expected_ops.emplace_back (3 ,
703+ utils::LifetimeOperationType::kCopyConstruction );
704+ expected_ops.emplace_back (1 , utils::LifetimeOperationType::kDestruction );
705+ expected_ops.emplace_back (3 , utils::LifetimeOperationType::kDestruction );
706+ ASSERT_TRUE (tracker.GetOperations () == expected_ops);
707+ }
708+ expected_ops.emplace_back (2 , utils::LifetimeOperationType::kDestruction );
709+ ASSERT_TRUE (tracker.GetOperations () == expected_ops);
710+ }
711+
637712TEST (ProxyLifetimeTests, TestCopyAssignment_FromValue_ToSelf) {
638713 utils::LifetimeTracker tracker;
639714 std::vector<utils::LifetimeOperation> expected_ops;
0 commit comments