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/cfx_retain_ptr.h"
      6 
      7 #include <utility>
      8 
      9 #include "testing/fx_string_testhelpers.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 namespace {
     13 
     14 class PseudoRetainable {
     15  public:
     16   PseudoRetainable() : retain_count_(0), release_count_(0) {}
     17   void Retain() { ++retain_count_; }
     18   void Release() { ++release_count_; }
     19   int retain_count() const { return retain_count_; }
     20   int release_count() const { return release_count_; }
     21 
     22  private:
     23   int retain_count_;
     24   int release_count_;
     25 };
     26 
     27 }  // namespace
     28 
     29 TEST(fxcrt, RetainPtrNull) {
     30   CFX_RetainPtr<PseudoRetainable> ptr;
     31   EXPECT_EQ(nullptr, ptr.Get());
     32 }
     33 
     34 TEST(fxcrt, RetainPtrNormal) {
     35   PseudoRetainable obj;
     36   {
     37     CFX_RetainPtr<PseudoRetainable> ptr(&obj);
     38     EXPECT_EQ(&obj, ptr.Get());
     39     EXPECT_EQ(1, obj.retain_count());
     40     EXPECT_EQ(0, obj.release_count());
     41   }
     42   EXPECT_EQ(1, obj.retain_count());
     43   EXPECT_EQ(1, obj.release_count());
     44 }
     45 
     46 TEST(fxcrt, RetainPtrCopyCtor) {
     47   PseudoRetainable obj;
     48   {
     49     CFX_RetainPtr<PseudoRetainable> ptr1(&obj);
     50     {
     51       CFX_RetainPtr<PseudoRetainable> ptr2(ptr1);
     52       EXPECT_EQ(2, obj.retain_count());
     53       EXPECT_EQ(0, obj.release_count());
     54     }
     55     EXPECT_EQ(2, obj.retain_count());
     56     EXPECT_EQ(1, obj.release_count());
     57   }
     58   EXPECT_EQ(2, obj.retain_count());
     59   EXPECT_EQ(2, obj.release_count());
     60 }
     61 
     62 TEST(fxcrt, RetainPtrMoveCtor) {
     63   PseudoRetainable obj;
     64   {
     65     CFX_RetainPtr<PseudoRetainable> ptr1(&obj);
     66     {
     67       CFX_RetainPtr<PseudoRetainable> ptr2(std::move(ptr1));
     68       EXPECT_EQ(1, obj.retain_count());
     69       EXPECT_EQ(0, obj.release_count());
     70     }
     71     EXPECT_EQ(1, obj.retain_count());
     72     EXPECT_EQ(1, obj.release_count());
     73   }
     74   EXPECT_EQ(1, obj.retain_count());
     75   EXPECT_EQ(1, obj.release_count());
     76 }
     77 
     78 TEST(fxcrt, RetainPtrResetNull) {
     79   PseudoRetainable obj;
     80   {
     81     CFX_RetainPtr<PseudoRetainable> ptr(&obj);
     82     ptr.Reset();
     83     EXPECT_EQ(1, obj.retain_count());
     84     EXPECT_EQ(1, obj.release_count());
     85   }
     86   EXPECT_EQ(1, obj.retain_count());
     87   EXPECT_EQ(1, obj.release_count());
     88 }
     89 
     90 TEST(fxcrt, RetainPtrReset) {
     91   PseudoRetainable obj1;
     92   PseudoRetainable obj2;
     93   {
     94     CFX_RetainPtr<PseudoRetainable> ptr(&obj1);
     95     ptr.Reset(&obj2);
     96     EXPECT_EQ(1, obj1.retain_count());
     97     EXPECT_EQ(1, obj1.release_count());
     98     EXPECT_EQ(1, obj2.retain_count());
     99     EXPECT_EQ(0, obj2.release_count());
    100   }
    101   EXPECT_EQ(1, obj1.retain_count());
    102   EXPECT_EQ(1, obj1.release_count());
    103   EXPECT_EQ(1, obj2.retain_count());
    104   EXPECT_EQ(1, obj2.release_count());
    105 }
    106 
    107 TEST(fxcrt, RetainPtrSwap) {
    108   PseudoRetainable obj1;
    109   PseudoRetainable obj2;
    110   {
    111     CFX_RetainPtr<PseudoRetainable> ptr1(&obj1);
    112     {
    113       CFX_RetainPtr<PseudoRetainable> ptr2(&obj2);
    114       ptr1.Swap(ptr2);
    115       EXPECT_EQ(1, obj1.retain_count());
    116       EXPECT_EQ(0, obj1.release_count());
    117       EXPECT_EQ(1, obj2.retain_count());
    118       EXPECT_EQ(0, obj2.release_count());
    119     }
    120     EXPECT_EQ(1, obj1.retain_count());
    121     EXPECT_EQ(1, obj1.release_count());
    122     EXPECT_EQ(1, obj2.retain_count());
    123     EXPECT_EQ(0, obj2.release_count());
    124   }
    125   EXPECT_EQ(1, obj1.retain_count());
    126   EXPECT_EQ(1, obj1.release_count());
    127   EXPECT_EQ(1, obj2.retain_count());
    128   EXPECT_EQ(1, obj2.release_count());
    129 }
    130 
    131 TEST(fxcrt, RetainPtrLeak) {
    132   PseudoRetainable obj;
    133   PseudoRetainable* leak;
    134   {
    135     CFX_RetainPtr<PseudoRetainable> ptr(&obj);
    136     leak = ptr.Leak();
    137     EXPECT_EQ(1, obj.retain_count());
    138     EXPECT_EQ(0, obj.release_count());
    139   }
    140   EXPECT_EQ(1, obj.retain_count());
    141   EXPECT_EQ(0, obj.release_count());
    142   {
    143     CFX_RetainPtr<PseudoRetainable> ptr;
    144     ptr.Unleak(leak);
    145     EXPECT_EQ(1, obj.retain_count());
    146     EXPECT_EQ(0, obj.release_count());
    147   }
    148   EXPECT_EQ(1, obj.retain_count());
    149   EXPECT_EQ(1, obj.release_count());
    150 }
    151 
    152 TEST(fxcrt, RetainPtrSwapNull) {
    153   PseudoRetainable obj1;
    154   {
    155     CFX_RetainPtr<PseudoRetainable> ptr1(&obj1);
    156     {
    157       CFX_RetainPtr<PseudoRetainable> ptr2;
    158       ptr1.Swap(ptr2);
    159       EXPECT_FALSE(ptr1);
    160       EXPECT_TRUE(ptr2);
    161       EXPECT_EQ(1, obj1.retain_count());
    162       EXPECT_EQ(0, obj1.release_count());
    163     }
    164     EXPECT_EQ(1, obj1.retain_count());
    165     EXPECT_EQ(1, obj1.release_count());
    166   }
    167   EXPECT_EQ(1, obj1.retain_count());
    168   EXPECT_EQ(1, obj1.release_count());
    169 }
    170 
    171 TEST(fxcrt, RetainPtrAssign) {
    172   PseudoRetainable obj;
    173   {
    174     CFX_RetainPtr<PseudoRetainable> ptr(&obj);
    175     {
    176       CFX_RetainPtr<PseudoRetainable> ptr2;
    177       ptr2 = ptr;
    178       EXPECT_EQ(2, obj.retain_count());
    179       EXPECT_EQ(0, obj.release_count());
    180     }
    181     EXPECT_EQ(2, obj.retain_count());
    182     EXPECT_EQ(1, obj.release_count());
    183   }
    184   EXPECT_EQ(2, obj.retain_count());
    185   EXPECT_EQ(2, obj.release_count());
    186 }
    187 
    188 TEST(fxcrt, RetainPtrEquals) {
    189   PseudoRetainable obj1;
    190   PseudoRetainable obj2;
    191   CFX_RetainPtr<PseudoRetainable> null_ptr1;
    192   CFX_RetainPtr<PseudoRetainable> obj1_ptr1(&obj1);
    193   CFX_RetainPtr<PseudoRetainable> obj2_ptr1(&obj2);
    194   {
    195     CFX_RetainPtr<PseudoRetainable> null_ptr2;
    196     EXPECT_TRUE(null_ptr1 == null_ptr2);
    197 
    198     CFX_RetainPtr<PseudoRetainable> obj1_ptr2(&obj1);
    199     EXPECT_TRUE(obj1_ptr1 == obj1_ptr2);
    200 
    201     CFX_RetainPtr<PseudoRetainable> obj2_ptr2(&obj2);
    202     EXPECT_TRUE(obj2_ptr1 == obj2_ptr2);
    203   }
    204   EXPECT_FALSE(null_ptr1 == obj1_ptr1);
    205   EXPECT_FALSE(null_ptr1 == obj2_ptr1);
    206   EXPECT_FALSE(obj1_ptr1 == obj2_ptr1);
    207 }
    208 
    209 TEST(fxcrt, RetainPtrNotEquals) {
    210   PseudoRetainable obj1;
    211   PseudoRetainable obj2;
    212   CFX_RetainPtr<PseudoRetainable> null_ptr1;
    213   CFX_RetainPtr<PseudoRetainable> obj1_ptr1(&obj1);
    214   CFX_RetainPtr<PseudoRetainable> obj2_ptr1(&obj2);
    215   {
    216     CFX_RetainPtr<PseudoRetainable> null_ptr2;
    217     CFX_RetainPtr<PseudoRetainable> obj1_ptr2(&obj1);
    218     CFX_RetainPtr<PseudoRetainable> obj2_ptr2(&obj2);
    219     EXPECT_FALSE(null_ptr1 != null_ptr2);
    220     EXPECT_FALSE(obj1_ptr1 != obj1_ptr2);
    221     EXPECT_FALSE(obj2_ptr1 != obj2_ptr2);
    222   }
    223   EXPECT_TRUE(null_ptr1 != obj1_ptr1);
    224   EXPECT_TRUE(null_ptr1 != obj2_ptr1);
    225   EXPECT_TRUE(obj1_ptr1 != obj2_ptr1);
    226 }
    227 
    228 TEST(fxcrt, RetainPtrLessThan) {
    229   PseudoRetainable objs[2];
    230   CFX_RetainPtr<PseudoRetainable> obj1_ptr(&objs[0]);
    231   CFX_RetainPtr<PseudoRetainable> obj2_ptr(&objs[1]);
    232   EXPECT_TRUE(obj1_ptr < obj2_ptr);
    233   EXPECT_FALSE(obj2_ptr < obj1_ptr);
    234 }
    235 
    236 TEST(fxcrt, RetainPtrBool) {
    237   PseudoRetainable obj1;
    238   CFX_RetainPtr<PseudoRetainable> null_ptr;
    239   CFX_RetainPtr<PseudoRetainable> obj1_ptr(&obj1);
    240   bool null_bool = !!null_ptr;
    241   bool obj1_bool = !!obj1_ptr;
    242   EXPECT_FALSE(null_bool);
    243   EXPECT_TRUE(obj1_bool);
    244 }
    245 
    246 TEST(fxcrt, RetainPtrMakeRetained) {
    247   auto ptr = pdfium::MakeRetain<CFX_Retainable>();
    248   EXPECT_TRUE(ptr->HasOneRef());
    249   {
    250     CFX_RetainPtr<CFX_Retainable> other = ptr;
    251     EXPECT_FALSE(ptr->HasOneRef());
    252   }
    253   EXPECT_TRUE(ptr->HasOneRef());
    254 }
    255