value_ptr_test.cxx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //
  2. // copy_ptr.t.h
  3. // pointers
  4. //
  5. // Created by Sam Jaffe on 1/5/17.
  6. //
  7. #include "pointers/value_ptr.hpp"
  8. #include <stdexcept>
  9. #include <gmock/gmock.h>
  10. #include "test_stubs.h"
  11. struct copy_me {};
  12. struct copy_me_throw {};
  13. namespace pointers { namespace detail {
  14. template <> class value_ptr_copy<copy_me_throw> {
  15. protected:
  16. copy_me_throw * Copy(copy_me_throw const * p) const {
  17. if (p == nullptr) { throw std::runtime_error{"NULL"}; }
  18. return new copy_me_throw{*p};
  19. }
  20. };
  21. }}
  22. class base {
  23. public:
  24. virtual ~base() {}
  25. virtual base * clone() const = 0;
  26. virtual int id() const = 0;
  27. };
  28. class derived_0 : public base {
  29. public:
  30. static const constexpr int ID = 0;
  31. virtual base * clone() const override { return new derived_0; }
  32. virtual int id() const override { return ID; }
  33. };
  34. class derived_1 : public base {
  35. public:
  36. static const constexpr int ID = 1;
  37. virtual base * clone() const override { return new derived_1; }
  38. virtual int id() const override { return ID; }
  39. };
  40. using namespace pointers;
  41. TEST(ValuePtrTest, CanCopySimpleObject) {
  42. value_ptr<copy_me> c1{new copy_me};
  43. value_ptr<copy_me> c2{c1};
  44. EXPECT_THAT(c1.get(), testing::Not(c2.get()));
  45. }
  46. TEST(ValuePtrTest, CopyCtorIsNullSafe) {
  47. value_ptr<copy_me> c1{nullptr};
  48. value_ptr<copy_me> c2{c1};
  49. EXPECT_THAT(c1.get(), testing::IsNull());
  50. EXPECT_THAT(c1.get(), c2.get());
  51. }
  52. TEST(ValuePtrCustomTest, CanCopyWithCustomFunction) {
  53. using ptr_t = value_ptr<copy_me_throw>;
  54. value_ptr<copy_me_throw> c1{new copy_me_throw};
  55. value_ptr<copy_me_throw> c2{c1};
  56. EXPECT_THAT(c1.get(), testing::Not(c2.get()));
  57. }
  58. TEST(ValuePtrCustomTest, CustomCopyFunctionCanThrow) {
  59. value_ptr<copy_me_throw> c1{nullptr};
  60. EXPECT_THROW(value_ptr<copy_me_throw>{c1}, std::runtime_error);
  61. }
  62. TEST(ValuePtrTest, CopiedValueDeeplyEqualButNotSameAddress) {
  63. std::vector<int> my_vec = {1, 3, 5, 3, 6, 1, 2, -1, 0};
  64. value_ptr<std::vector<int>> c1{new std::vector<int>{my_vec}};
  65. EXPECT_THAT(*c1, my_vec);
  66. value_ptr<std::vector<int>> c2{c1};
  67. EXPECT_THAT(*c2, *c1);
  68. EXPECT_THAT(c2.get(), testing::Not(c1.get()));
  69. }
  70. TEST(ValuePtrPolymorphicTest, CanConstructPtrToBaseFromDerivedClasses) {
  71. value_ptr<base> c0{new derived_0};
  72. EXPECT_THAT(c0->id(), derived_0::ID);
  73. value_ptr<base> c1{new derived_1};
  74. EXPECT_THAT(c1->id(), derived_1::ID);
  75. }
  76. TEST(ValuePtrPolymorphicTest, CanConstructFromNullptr) {
  77. value_ptr<base> c1{nullptr};
  78. value_ptr<base> c2{c1};
  79. EXPECT_THAT(c1.get(), testing::IsNull());
  80. EXPECT_THAT(c1.get(), c2.get());
  81. }
  82. TEST(ValuePtrTest, OwnsGivenObject) {
  83. bool has_delete{false};
  84. destructor_sentinal * test_struct = new destructor_sentinal{has_delete};
  85. // I cannot actually copy-construct from a pointer for safety
  86. EXPECT_NO_THROW(value_ptr<destructor_sentinal>{std::move(test_struct)});
  87. EXPECT_TRUE(has_delete);
  88. }
  89. TEST(ValuePtrTest, OwnsTemporaryObject) {
  90. bool has_delete{false};
  91. EXPECT_NO_THROW(
  92. value_ptr<destructor_sentinal>{new destructor_sentinal{has_delete}});
  93. EXPECT_TRUE(has_delete);
  94. }
  95. TEST(ValuePtrTest, FactoryMethodProducesCopy) {
  96. int deleted{0};
  97. {
  98. std::unique_ptr<destructor_ctr> test_struct{new destructor_ctr{deleted}};
  99. EXPECT_NO_THROW(value_ptr<destructor_ctr>::copy_of(test_struct.get()));
  100. EXPECT_THAT(deleted, 1);
  101. }
  102. EXPECT_THAT(deleted, 2);
  103. }