value_ptr_test.cxx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //
  2. // copy_ptr.t.h
  3. // pointers
  4. //
  5. // Created by Sam Jaffe on 1/5/17.
  6. //
  7. #include "pointer/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 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. TEST(ValuePtrTest, CanCopySimpleObject) {
  41. value_ptr<copy_me> c1 {new copy_me};
  42. value_ptr<copy_me> c2 {c1};
  43. EXPECT_THAT(c1.get(), testing::Not(c2.get()));
  44. }
  45. TEST(ValuePtrTest, CopyCtorIsNullSafe) {
  46. value_ptr<copy_me> c1{nullptr};
  47. value_ptr<copy_me> c2{c1};
  48. EXPECT_THAT(c1.get(), testing::IsNull());
  49. EXPECT_THAT(c1.get(), c2.get());
  50. }
  51. TEST(ValuePtrCustomTest, CanCopyWithCustomFunction) {
  52. using ptr_t = value_ptr<copy_me_throw>;
  53. value_ptr<copy_me_throw> c1 {new copy_me_throw};
  54. value_ptr<copy_me_throw> c2 {c1};
  55. EXPECT_THAT(c1.get(), testing::Not(c2.get()));
  56. }
  57. TEST(ValuePtrCustomTest, CustomCopyFunctionCanThrow) {
  58. value_ptr<copy_me_throw> c1{nullptr};
  59. EXPECT_THROW(value_ptr<copy_me_throw>{c1}, std::runtime_error);
  60. }
  61. TEST(ValuePtrTest, CopiedValueDeeplyEqualButNotSameAddress) {
  62. std::vector<int> my_vec = { 1, 3, 5, 3, 6, 1, 2, -1, 0 };
  63. value_ptr<std::vector<int>> c1{new std::vector<int>{my_vec}};
  64. EXPECT_THAT(*c1, my_vec);
  65. value_ptr<std::vector<int>> c2{c1};
  66. EXPECT_THAT(*c2, *c1);
  67. EXPECT_THAT(c2.get(), testing::Not(c1.get()));
  68. }
  69. TEST(ValuePtrPolymorphicTest, CanConstructPtrToBaseFromDerivedClasses) {
  70. value_ptr<base> c0{new derived_0};
  71. EXPECT_THAT(c0->id(), derived_0::ID);
  72. value_ptr<base> c1{new derived_1};
  73. EXPECT_THAT(c1->id(), derived_1::ID);
  74. }
  75. TEST(ValuePtrPolymorphicTest, CanConstructFromNullptr) {
  76. value_ptr<base> c1 {nullptr};
  77. value_ptr<base> c2 {c1};
  78. EXPECT_THAT(c1.get(), testing::IsNull());
  79. EXPECT_THAT(c1.get(), c2.get());
  80. }
  81. TEST(ValuePtrTest, OwnsGivenObject) {
  82. bool has_delete{false};
  83. destructor_sentinal * test_struct = new destructor_sentinal{has_delete};
  84. // I cannot actually copy-construct from a pointer for safety
  85. EXPECT_NO_THROW(value_ptr<destructor_sentinal>{std::move(test_struct)});
  86. EXPECT_TRUE(has_delete);
  87. }
  88. TEST(ValuePtrTest, OwnsTemporaryObject) {
  89. bool has_delete{false};
  90. EXPECT_NO_THROW(value_ptr<destructor_sentinal>{
  91. new destructor_sentinal{has_delete}});
  92. EXPECT_TRUE(has_delete);
  93. }
  94. TEST(ValuePtrTest, FactoryMethodProducesCopy) {
  95. int deleted{0};
  96. {
  97. std::unique_ptr<destructor_ctr> test_struct{new destructor_ctr{deleted}};
  98. EXPECT_NO_THROW(value_ptr<destructor_ctr>::copy_of(test_struct.get()));
  99. EXPECT_THAT(deleted, 1);
  100. }
  101. EXPECT_THAT(deleted, 2);
  102. }