| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- //
- // copy_ptr.t.h
- // pointers
- //
- // Created by Sam Jaffe on 1/5/17.
- //
- #include "pointer/value_ptr.hpp"
- #include <stdexcept>
- #include <gmock/gmock.h>
- #include "test_stubs.h"
- struct copy_me {};
- struct copy_me_throw {};
- namespace detail {
- template<> class value_ptr_copy<copy_me_throw> {
- protected:
- copy_me_throw * Copy(copy_me_throw const * p) const {
- if (p == nullptr) { throw std::runtime_error{"NULL"}; }
- return new copy_me_throw{*p};
- }
- };
- }
- class base {
- public:
- virtual ~base() {}
- virtual base* clone() const = 0;
- virtual int id() const = 0;
- };
- class derived_0 : public base {
- public:
- static const constexpr int ID = 0;
- virtual base * clone() const override { return new derived_0; }
- virtual int id() const override { return ID; }
- };
- class derived_1 : public base {
- public:
- static const constexpr int ID = 1;
- virtual base * clone() const override { return new derived_1; }
- virtual int id() const override { return ID; }
- };
- TEST(ValuePtrTest, CanCopySimpleObject) {
- value_ptr<copy_me> c1 {new copy_me};
- value_ptr<copy_me> c2 {c1};
- EXPECT_THAT(c1.get(), testing::Not(c2.get()));
- }
- TEST(ValuePtrTest, CopyCtorIsNullSafe) {
- value_ptr<copy_me> c1{nullptr};
- value_ptr<copy_me> c2{c1};
- EXPECT_THAT(c1.get(), testing::IsNull());
- EXPECT_THAT(c1.get(), c2.get());
- }
- TEST(ValuePtrCustomTest, CanCopyWithCustomFunction) {
- using ptr_t = value_ptr<copy_me_throw>;
- value_ptr<copy_me_throw> c1 {new copy_me_throw};
- value_ptr<copy_me_throw> c2 {c1};
- EXPECT_THAT(c1.get(), testing::Not(c2.get()));
- }
- TEST(ValuePtrCustomTest, CustomCopyFunctionCanThrow) {
- value_ptr<copy_me_throw> c1{nullptr};
- EXPECT_THROW(value_ptr<copy_me_throw>{c1}, std::runtime_error);
- }
- TEST(ValuePtrTest, CopiedValueDeeplyEqualButNotSameAddress) {
- std::vector<int> my_vec = { 1, 3, 5, 3, 6, 1, 2, -1, 0 };
- value_ptr<std::vector<int>> c1{new std::vector<int>{my_vec}};
- EXPECT_THAT(*c1, my_vec);
- value_ptr<std::vector<int>> c2{c1};
- EXPECT_THAT(*c2, *c1);
- EXPECT_THAT(c2.get(), testing::Not(c1.get()));
- }
- TEST(ValuePtrPolymorphicTest, CanConstructPtrToBaseFromDerivedClasses) {
- value_ptr<base> c0{new derived_0};
- EXPECT_THAT(c0->id(), derived_0::ID);
- value_ptr<base> c1{new derived_1};
- EXPECT_THAT(c1->id(), derived_1::ID);
- }
- TEST(ValuePtrPolymorphicTest, CanConstructFromNullptr) {
- value_ptr<base> c1 {nullptr};
- value_ptr<base> c2 {c1};
- EXPECT_THAT(c1.get(), testing::IsNull());
- EXPECT_THAT(c1.get(), c2.get());
- }
- TEST(ValuePtrTest, OwnsGivenObject) {
- bool has_delete{false};
- destructor_sentinal * test_struct = new destructor_sentinal{has_delete};
- // I cannot actually copy-construct from a pointer for safety
- EXPECT_NO_THROW(value_ptr<destructor_sentinal>{std::move(test_struct)});
- EXPECT_TRUE(has_delete);
- }
- TEST(ValuePtrTest, OwnsTemporaryObject) {
- bool has_delete{false};
- EXPECT_NO_THROW(value_ptr<destructor_sentinal>{
- new destructor_sentinal{has_delete}});
- EXPECT_TRUE(has_delete);
- }
- TEST(ValuePtrTest, FactoryMethodProducesCopy) {
- int deleted{0};
- {
- std::unique_ptr<destructor_ctr> test_struct{new destructor_ctr{deleted}};
- EXPECT_NO_THROW(value_ptr<destructor_ctr>::copy_of(test_struct.get()));
- EXPECT_THAT(deleted, 1);
- }
- EXPECT_THAT(deleted, 2);
- }
|