15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LifeCycleObject notifies its Observer upon construction & destruction.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LifeCycleObject {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Observer {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Observer() {}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~LifeCycleObject() {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnLifeCycleDestroy(this);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class LifeCycleWatcher;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit LifeCycleObject(Observer* observer)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : observer_(observer) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer_->OnLifeCycleConstruct(this);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Observer* observer_;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The life cycle states we care about for the purposes of testing ScopedVector
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// against objects.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum LifeCycleState {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LC_INITIAL,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LC_CONSTRUCTED,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LC_DESTROYED,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Because we wish to watch the life cycle of an object being constructed and
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed, and further wish to test expectations against the state of that
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object, we cannot save state in that object itself. Instead, we use this
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pairing of the watcher, which observes the object and notifies of
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// construction & destruction. Since we also may be testing assumptions about
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// things not getting freed, this class also acts like a scoping object and
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// deletes the |constructed_life_cycle_object_|, if any when the
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LifeCycleWatcher is destroyed. To keep this simple, the only expected state
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// changes are:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   INITIAL -> CONSTRUCTED -> DESTROYED.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Anything more complicated than that should start another test.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LifeCycleWatcher : public LifeCycleObject::Observer {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  LifeCycleWatcher() : life_cycle_state_(LC_INITIAL) {}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~LifeCycleWatcher() {}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LifeCycleWatcher.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnLifeCycleConstruct(LifeCycleObject* object) OVERRIDE {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(LC_INITIAL, life_cycle_state_);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(NULL, constructed_life_cycle_object_.get());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    life_cycle_state_ = LC_CONSTRUCTED;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    constructed_life_cycle_object_.reset(object);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same one we saw constructed.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnLifeCycleDestroy(LifeCycleObject* object) OVERRIDE {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(LC_CONSTRUCTED, life_cycle_state_);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LifeCycleObject* constructed_life_cycle_object =
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        constructed_life_cycle_object_.release();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(constructed_life_cycle_object, object);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    life_cycle_state_ = LC_DESTROYED;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleState life_cycle_state() const { return life_cycle_state_; }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Factory method for creating a new LifeCycleObject tied to this
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LifeCycleWatcher.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleObject* NewLifeCycleObject() {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new LifeCycleObject(this);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true iff |object| is the same object that this watcher is tracking.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsWatching(LifeCycleObject* object) const {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return object == constructed_life_cycle_object_.get();
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleState life_cycle_state_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<LifeCycleObject> constructed_life_cycle_object_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ScopedVectorTest, LifeCycleWatcher) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleWatcher watcher;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleObject* object = watcher.NewLifeCycleObject();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete object;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST(ScopedVectorTest, PopBack) {
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  LifeCycleWatcher watcher;
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<LifeCycleObject> scoped_vector;
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_vector.push_back(watcher.NewLifeCycleObject());
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_vector.pop_back();
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(scoped_vector.empty());
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ScopedVectorTest, Clear) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleWatcher watcher;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVector<LifeCycleObject> scoped_vector;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_vector.push_back(watcher.NewLifeCycleObject());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_vector.clear();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scoped_vector.empty());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ScopedVectorTest, WeakClear) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleWatcher watcher;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVector<LifeCycleObject> scoped_vector;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_vector.push_back(watcher.NewLifeCycleObject());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_vector.weak_clear();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scoped_vector.empty());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(ScopedVectorTest, ResizeShrink) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LifeCycleWatcher first_watcher;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_INITIAL, first_watcher.life_cycle_state());
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LifeCycleWatcher second_watcher;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<LifeCycleObject> scoped_vector;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_vector.push_back(first_watcher.NewLifeCycleObject());
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(first_watcher.IsWatching(scoped_vector[0]));
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(second_watcher.IsWatching(scoped_vector[0]));
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_vector.push_back(second_watcher.NewLifeCycleObject());
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, second_watcher.life_cycle_state());
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(first_watcher.IsWatching(scoped_vector[1]));
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(second_watcher.IsWatching(scoped_vector[1]));
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test that shrinking a vector deletes elements in the disappearing range.
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_vector.resize(1);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_DESTROYED, second_watcher.life_cycle_state());
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, scoped_vector.size());
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(first_watcher.IsWatching(scoped_vector[0]));
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(ScopedVectorTest, ResizeGrow) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LifeCycleWatcher watcher;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<LifeCycleObject> scoped_vector;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_vector.push_back(watcher.NewLifeCycleObject());
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_vector.resize(5);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(5u, scoped_vector.size());
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(watcher.IsWatching(scoped_vector[0]));
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(watcher.IsWatching(scoped_vector[1]));
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(watcher.IsWatching(scoped_vector[2]));
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(watcher.IsWatching(scoped_vector[3]));
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(watcher.IsWatching(scoped_vector[4]));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ScopedVectorTest, Scope) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleWatcher watcher;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<LifeCycleObject> scoped_vector;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_vector.push_back(watcher.NewLifeCycleObject());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ScopedVectorTest, MoveConstruct) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleWatcher watcher;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<LifeCycleObject> scoped_vector;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_vector.push_back(watcher.NewLifeCycleObject());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(scoped_vector.empty());
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<LifeCycleObject> scoped_vector_copy(scoped_vector.Pass());
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(scoped_vector.empty());
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(scoped_vector_copy.empty());
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(watcher.IsWatching(scoped_vector_copy.back()));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ScopedVectorTest, MoveAssign) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleWatcher watcher;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<LifeCycleObject> scoped_vector;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_vector.push_back(watcher.NewLifeCycleObject());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<LifeCycleObject> scoped_vector_assign;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(scoped_vector.empty());
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_vector_assign = scoped_vector.Pass();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(scoped_vector.empty());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(scoped_vector_assign.empty());
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(watcher.IsWatching(scoped_vector_assign.back()));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeleteCounter {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit DeleteCounter(int* deletes)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : deletes_(deletes) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~DeleteCounter() {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*deletes_)++;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VoidMethod0() {}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int* const deletes_;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteCounter);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T>
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedVector<T> PassThru(ScopedVector<T> scoper) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoper.Pass();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ScopedVectorTest, Passed) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int deletes = 0;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVector<DeleteCounter> deleter_vector;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  deleter_vector.push_back(new DeleteCounter(&deletes));
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, deletes);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Callback<ScopedVector<DeleteCounter>(void)> callback =
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PassThru<DeleteCounter>, base::Passed(&deleter_vector));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, deletes);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVector<DeleteCounter> result = callback.Run();
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, deletes);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.clear();
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, deletes);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ScopedVectorTest, InsertRange) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LifeCycleWatcher watchers[5];
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<LifeCycleObject*> vec;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++it) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(LC_INITIAL, it->life_cycle_state());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vec.push_back(it->NewLifeCycleObject());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start scope for ScopedVector.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<LifeCycleObject> scoped_vector;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_vector.insert(scoped_vector.end(), vec.begin() + 1, vec.begin() + 3);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++it)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(LifeCycleWatcher* it = watchers; it != watchers + 1; ++it)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(LifeCycleWatcher* it = watchers + 1; it != watchers + 3; ++it)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(LC_DESTROYED, it->life_cycle_state());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(LifeCycleWatcher* it = watchers + 3; it != watchers + arraysize(watchers);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++it)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
312