Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2016 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "core/fxcrt/shared_copy_on_write.h"
      6 
      7 #include <map>
      8 #include <string>
      9 
     10 #include "core/fxcrt/retain_ptr.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 namespace fxcrt {
     14 namespace {
     15 
     16 class Observer {
     17  public:
     18   void OnConstruct(const std::string& name) { construction_counts_[name]++; }
     19   void OnDestruct(const std::string& name) { destruction_counts_[name]++; }
     20   int GetConstructionCount(const std::string& name) {
     21     return construction_counts_[name];
     22   }
     23   int GetDestructionCount(const std::string& name) {
     24     return destruction_counts_[name];
     25   }
     26 
     27  private:
     28   std::map<std::string, int> construction_counts_;
     29   std::map<std::string, int> destruction_counts_;
     30 };
     31 
     32 class Object : public Retainable {
     33  public:
     34   Object(Observer* observer, const std::string& name)
     35       : name_(name), observer_(observer) {
     36     observer->OnConstruct(name_);
     37   }
     38   Object(const Object& that) : name_(that.name_), observer_(that.observer_) {
     39     observer_->OnConstruct(name_);
     40   }
     41   ~Object() override { observer_->OnDestruct(name_); }
     42 
     43  private:
     44   std::string name_;
     45   Observer* observer_;
     46 };
     47 
     48 }  // namespace
     49 
     50 TEST(SharedCopyOnWrite, Null) {
     51   Observer observer;
     52   {
     53     SharedCopyOnWrite<Object> ptr;
     54     EXPECT_EQ(nullptr, ptr.GetObject());
     55   }
     56 }
     57 
     58 TEST(SharedCopyOnWrite, Copy) {
     59   Observer observer;
     60   {
     61     SharedCopyOnWrite<Object> ptr1;
     62     ptr1.Emplace(&observer, std::string("one"));
     63     {
     64       SharedCopyOnWrite<Object> ptr2 = ptr1;
     65       EXPECT_EQ(1, observer.GetConstructionCount("one"));
     66       EXPECT_EQ(0, observer.GetDestructionCount("one"));
     67     }
     68     {
     69       SharedCopyOnWrite<Object> ptr3(ptr1);
     70       EXPECT_EQ(1, observer.GetConstructionCount("one"));
     71       EXPECT_EQ(0, observer.GetDestructionCount("one"));
     72     }
     73     EXPECT_EQ(1, observer.GetConstructionCount("one"));
     74     EXPECT_EQ(0, observer.GetDestructionCount("one"));
     75   }
     76   EXPECT_EQ(1, observer.GetDestructionCount("one"));
     77 }
     78 
     79 TEST(SharedCopyOnWrite, AssignOverOld) {
     80   Observer observer;
     81   {
     82     SharedCopyOnWrite<Object> ptr1;
     83     ptr1.Emplace(&observer, std::string("one"));
     84     ptr1.Emplace(&observer, std::string("two"));
     85     EXPECT_EQ(1, observer.GetConstructionCount("one"));
     86     EXPECT_EQ(1, observer.GetConstructionCount("two"));
     87     EXPECT_EQ(1, observer.GetDestructionCount("one"));
     88     EXPECT_EQ(0, observer.GetDestructionCount("two"));
     89   }
     90   EXPECT_EQ(1, observer.GetDestructionCount("two"));
     91 }
     92 
     93 TEST(SharedCopyOnWrite, AssignOverRetained) {
     94   Observer observer;
     95   {
     96     SharedCopyOnWrite<Object> ptr1;
     97     ptr1.Emplace(&observer, std::string("one"));
     98     SharedCopyOnWrite<Object> ptr2(ptr1);
     99     ptr1.Emplace(&observer, std::string("two"));
    100     EXPECT_EQ(1, observer.GetConstructionCount("one"));
    101     EXPECT_EQ(1, observer.GetConstructionCount("two"));
    102     EXPECT_EQ(0, observer.GetDestructionCount("one"));
    103     EXPECT_EQ(0, observer.GetDestructionCount("two"));
    104   }
    105   EXPECT_EQ(1, observer.GetDestructionCount("one"));
    106   EXPECT_EQ(1, observer.GetDestructionCount("two"));
    107 }
    108 
    109 TEST(SharedCopyOnWrite, GetModify) {
    110   Observer observer;
    111   {
    112     SharedCopyOnWrite<Object> ptr;
    113     EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
    114     EXPECT_EQ(1, observer.GetConstructionCount("one"));
    115     EXPECT_EQ(0, observer.GetDestructionCount("one"));
    116 
    117     EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
    118     EXPECT_EQ(1, observer.GetConstructionCount("one"));
    119     EXPECT_EQ(0, observer.GetDestructionCount("one"));
    120     {
    121       SharedCopyOnWrite<Object> other(ptr);
    122       EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
    123       EXPECT_EQ(2, observer.GetConstructionCount("one"));
    124       EXPECT_EQ(0, observer.GetDestructionCount("one"));
    125     }
    126     EXPECT_EQ(2, observer.GetConstructionCount("one"));
    127     EXPECT_EQ(1, observer.GetDestructionCount("one"));
    128   }
    129   EXPECT_EQ(2, observer.GetDestructionCount("one"));
    130 }
    131 
    132 }  // namespace fxcrt
    133