• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/cfx_shared_copy_on_write.h"
6 
7 #include <map>
8 #include <string>
9 
10 #include "testing/fx_string_testhelpers.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 namespace {
14 
15 class Observer {
16  public:
OnConstruct(const std::string & name)17   void OnConstruct(const std::string& name) { construction_counts_[name]++; }
OnDestruct(const std::string & name)18   void OnDestruct(const std::string& name) { destruction_counts_[name]++; }
GetConstructionCount(const std::string & name)19   int GetConstructionCount(const std::string& name) {
20     return construction_counts_[name];
21   }
GetDestructionCount(const std::string & name)22   int GetDestructionCount(const std::string& name) {
23     return destruction_counts_[name];
24   }
25 
26  private:
27   std::map<std::string, int> construction_counts_;
28   std::map<std::string, int> destruction_counts_;
29 };
30 
31 class Object {
32  public:
Object(Observer * observer,const std::string & name)33   Object(Observer* observer, const std::string& name)
34       : name_(name), observer_(observer) {
35     observer->OnConstruct(name_);
36   }
Object(const Object & that)37   Object(const Object& that) : name_(that.name_), observer_(that.observer_) {
38     observer_->OnConstruct(name_);
39   }
~Object()40   ~Object() { observer_->OnDestruct(name_); }
41 
42  private:
43   std::string name_;
44   Observer* observer_;
45 };
46 
47 }  // namespace
48 
TEST(fxcrt,SharedCopyOnWriteNull)49 TEST(fxcrt, SharedCopyOnWriteNull) {
50   Observer observer;
51   {
52     CFX_SharedCopyOnWrite<Object> ptr;
53     EXPECT_EQ(nullptr, ptr.GetObject());
54   }
55 }
56 
TEST(fxcrt,SharedCopyOnWriteCopy)57 TEST(fxcrt, SharedCopyOnWriteCopy) {
58   Observer observer;
59   {
60     CFX_SharedCopyOnWrite<Object> ptr1;
61     ptr1.Emplace(&observer, std::string("one"));
62     {
63       CFX_SharedCopyOnWrite<Object> ptr2 = ptr1;
64       EXPECT_EQ(1, observer.GetConstructionCount("one"));
65       EXPECT_EQ(0, observer.GetDestructionCount("one"));
66     }
67     {
68       CFX_SharedCopyOnWrite<Object> ptr3(ptr1);
69       EXPECT_EQ(1, observer.GetConstructionCount("one"));
70       EXPECT_EQ(0, observer.GetDestructionCount("one"));
71     }
72     EXPECT_EQ(1, observer.GetConstructionCount("one"));
73     EXPECT_EQ(0, observer.GetDestructionCount("one"));
74   }
75   EXPECT_EQ(1, observer.GetDestructionCount("one"));
76 }
77 
TEST(fxcrt,SharedCopyOnWriteAssignOverOld)78 TEST(fxcrt, SharedCopyOnWriteAssignOverOld) {
79   Observer observer;
80   {
81     CFX_SharedCopyOnWrite<Object> ptr1;
82     ptr1.Emplace(&observer, std::string("one"));
83     ptr1.Emplace(&observer, std::string("two"));
84     EXPECT_EQ(1, observer.GetConstructionCount("one"));
85     EXPECT_EQ(1, observer.GetConstructionCount("two"));
86     EXPECT_EQ(1, observer.GetDestructionCount("one"));
87     EXPECT_EQ(0, observer.GetDestructionCount("two"));
88   }
89   EXPECT_EQ(1, observer.GetDestructionCount("two"));
90 }
91 
TEST(fxcrt,SharedCopyOnWriteAssignOverRetained)92 TEST(fxcrt, SharedCopyOnWriteAssignOverRetained) {
93   Observer observer;
94   {
95     CFX_SharedCopyOnWrite<Object> ptr1;
96     ptr1.Emplace(&observer, std::string("one"));
97     CFX_SharedCopyOnWrite<Object> ptr2(ptr1);
98     ptr1.Emplace(&observer, std::string("two"));
99     EXPECT_EQ(1, observer.GetConstructionCount("one"));
100     EXPECT_EQ(1, observer.GetConstructionCount("two"));
101     EXPECT_EQ(0, observer.GetDestructionCount("one"));
102     EXPECT_EQ(0, observer.GetDestructionCount("two"));
103   }
104   EXPECT_EQ(1, observer.GetDestructionCount("one"));
105   EXPECT_EQ(1, observer.GetDestructionCount("two"));
106 }
107 
TEST(fxcrt,SharedCopyOnWriteGetModify)108 TEST(fxcrt, SharedCopyOnWriteGetModify) {
109   Observer observer;
110   {
111     CFX_SharedCopyOnWrite<Object> ptr;
112     EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
113     EXPECT_EQ(1, observer.GetConstructionCount("one"));
114     EXPECT_EQ(0, observer.GetDestructionCount("one"));
115 
116     EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
117     EXPECT_EQ(1, observer.GetConstructionCount("one"));
118     EXPECT_EQ(0, observer.GetDestructionCount("one"));
119     {
120       CFX_SharedCopyOnWrite<Object> other(ptr);
121       EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
122       EXPECT_EQ(2, observer.GetConstructionCount("one"));
123       EXPECT_EQ(0, observer.GetDestructionCount("one"));
124     }
125     EXPECT_EQ(2, observer.GetConstructionCount("one"));
126     EXPECT_EQ(1, observer.GetDestructionCount("one"));
127   }
128   EXPECT_EQ(2, observer.GetDestructionCount("one"));
129 }
130