Home | History | Annotate | Download | only in memory
      1 // Copyright (c) 2011 The Chromium 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 "base/memory/scoped_ptr.h"
      6 #include "base/memory/scoped_vector.h"
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 
      9 namespace {
     10 
     11 // The LifeCycleObject notifies its Observer upon construction & destruction.
     12 class LifeCycleObject {
     13  public:
     14   class Observer {
     15    public:
     16     virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
     17     virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
     18 
     19    protected:
     20     virtual ~Observer() {}
     21   };
     22 
     23   explicit LifeCycleObject(Observer* observer)
     24       : observer_(observer) {
     25     observer_->OnLifeCycleConstruct(this);
     26   }
     27 
     28   ~LifeCycleObject() {
     29     observer_->OnLifeCycleDestroy(this);
     30   }
     31 
     32  private:
     33   Observer* observer_;
     34 
     35   DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
     36 };
     37 
     38 // The life cycle states we care about for the purposes of testing ScopedVector
     39 // against objects.
     40 enum LifeCycleState {
     41   LC_INITIAL,
     42   LC_CONSTRUCTED,
     43   LC_DESTROYED,
     44 };
     45 
     46 // Because we wish to watch the life cycle of an object being constructed and
     47 // destroyed, and further wish to test expectations against the state of that
     48 // object, we cannot save state in that object itself. Instead, we use this
     49 // pairing of the watcher, which observes the object and notifies of
     50 // construction & destruction. Since we also may be testing assumptions about
     51 // things not getting freed, this class also acts like a scoping object and
     52 // deletes the |constructed_life_cycle_object_|, if any when the
     53 // LifeCycleWatcher is destroyed. To keep this simple, the only expected state
     54 // changes are:
     55 //   INITIAL -> CONSTRUCTED -> DESTROYED.
     56 // Anything more complicated than that should start another test.
     57 class LifeCycleWatcher : public LifeCycleObject::Observer {
     58  public:
     59   LifeCycleWatcher()
     60       : life_cycle_state_(LC_INITIAL),
     61         constructed_life_cycle_object_(NULL) {}
     62   ~LifeCycleWatcher() {
     63   }
     64 
     65   // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
     66   // LifeCycleWatcher.
     67   virtual void OnLifeCycleConstruct(LifeCycleObject* object) {
     68     ASSERT_EQ(LC_INITIAL, life_cycle_state_);
     69     ASSERT_EQ(NULL, constructed_life_cycle_object_.get());
     70     life_cycle_state_ = LC_CONSTRUCTED;
     71     constructed_life_cycle_object_.reset(object);
     72   }
     73 
     74   // Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the
     75   // same one we saw constructed.
     76   virtual void OnLifeCycleDestroy(LifeCycleObject* object) {
     77     ASSERT_EQ(LC_CONSTRUCTED, life_cycle_state_);
     78     LifeCycleObject* constructed_life_cycle_object =
     79         constructed_life_cycle_object_.release();
     80     ASSERT_EQ(constructed_life_cycle_object, object);
     81     life_cycle_state_ = LC_DESTROYED;
     82   }
     83 
     84   LifeCycleState life_cycle_state() const { return life_cycle_state_; }
     85 
     86   // Factory method for creating a new LifeCycleObject tied to this
     87   // LifeCycleWatcher.
     88   LifeCycleObject* NewLifeCycleObject() {
     89     return new LifeCycleObject(this);
     90   }
     91 
     92  private:
     93   LifeCycleState life_cycle_state_;
     94   scoped_ptr<LifeCycleObject> constructed_life_cycle_object_;
     95 
     96   DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher);
     97 };
     98 
     99 TEST(ScopedVectorTest, LifeCycleWatcher) {
    100   LifeCycleWatcher watcher;
    101   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
    102   LifeCycleObject* object = watcher.NewLifeCycleObject();
    103   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
    104   delete object;
    105   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
    106 }
    107 
    108 TEST(ScopedVectorTest, Reset) {
    109   LifeCycleWatcher watcher;
    110   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
    111   ScopedVector<LifeCycleObject> scoped_vector;
    112   scoped_vector.push_back(watcher.NewLifeCycleObject());
    113   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
    114   scoped_vector.reset();
    115   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
    116 }
    117 
    118 TEST(ScopedVectorTest, Scope) {
    119   LifeCycleWatcher watcher;
    120   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
    121   {
    122     ScopedVector<LifeCycleObject> scoped_vector;
    123     scoped_vector.push_back(watcher.NewLifeCycleObject());
    124     EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
    125   }
    126   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
    127 }
    128 
    129 TEST(ScopedVectorTest, InsertRange) {
    130   LifeCycleWatcher watchers[5];
    131 
    132   std::vector<LifeCycleObject*> vec;
    133   for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
    134       ++it) {
    135     EXPECT_EQ(LC_INITIAL, it->life_cycle_state());
    136     vec.push_back(it->NewLifeCycleObject());
    137     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
    138   }
    139   // Start scope for ScopedVector.
    140   {
    141     ScopedVector<LifeCycleObject> scoped_vector;
    142     scoped_vector.insert(scoped_vector.end(), vec.begin() + 1, vec.begin() + 3);
    143     for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
    144         ++it)
    145       EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
    146   }
    147   for(LifeCycleWatcher* it = watchers; it != watchers + 1; ++it)
    148     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
    149   for(LifeCycleWatcher* it = watchers + 1; it != watchers + 3; ++it)
    150     EXPECT_EQ(LC_DESTROYED, it->life_cycle_state());
    151   for(LifeCycleWatcher* it = watchers + 3; it != watchers + arraysize(watchers);
    152       ++it)
    153     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
    154 }
    155 
    156 }  // namespace
    157