1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/id_map.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass IDMapTest : public testing::Test {
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass TestObject {
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass DestructorCounter {
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit DestructorCounter(int* counter) : counter_(counter) {}
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~DestructorCounter() { ++(*counter_); }
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int* counter_;
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(IDMapTest, Basic) {
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  IDMap<TestObject> map;
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(map.IsEmpty());
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, map.size());
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestObject obj1;
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestObject obj2;
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int32 id1 = map.Add(&obj1);
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(map.IsEmpty());
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1U, map.size());
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(&obj1, map.Lookup(id1));
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int32 id2 = map.Add(&obj2);
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(map.IsEmpty());
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2U, map.size());
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(&obj1, map.Lookup(id1));
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(&obj2, map.Lookup(id2));
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  map.Remove(id1);
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(map.IsEmpty());
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1U, map.size());
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  map.Remove(id2);
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(map.IsEmpty());
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, map.size());
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  map.AddWithID(&obj1, 1);
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  map.AddWithID(&obj2, 2);
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(&obj1, map.Lookup(1));
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(&obj2, map.Lookup(2));
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(IDMapTest, IteratorRemainsValidWhenRemovingCurrentElement) {
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  IDMap<TestObject> map;
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestObject obj1;
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestObject obj2;
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestObject obj3;
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  map.Add(&obj1);
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  map.Add(&obj2);
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  map.Add(&obj3);
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDMap<TestObject>::const_iterator iter(&map);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while (!iter.IsAtEnd()) {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      map.Remove(iter.GetCurrentKey());
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      iter.Advance();
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Test that while an iterator is still in scope, we get the map emptiness
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // right (http://crbug.com/35571).
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(map.IsEmpty());
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0U, map.size());
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(map.IsEmpty());
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0U, map.size());
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(IDMapTest, IteratorRemainsValidWhenRemovingOtherElements) {
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  IDMap<TestObject> map;
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kCount = 5;
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestObject obj[kCount];
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int32 ids[kCount];
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kCount; i++)
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ids[i] = map.Add(&obj[i]);
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int counter = 0;
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (IDMap<TestObject>::const_iterator iter(&map);
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       !iter.IsAtEnd(); iter.Advance()) {
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    switch (counter) {
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case 0:
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        EXPECT_EQ(ids[0], iter.GetCurrentKey());
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        EXPECT_EQ(&obj[0], iter.GetCurrentValue());
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        map.Remove(ids[1]);
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        break;
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case 1:
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        EXPECT_EQ(ids[2], iter.GetCurrentKey());
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        EXPECT_EQ(&obj[2], iter.GetCurrentValue());
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        map.Remove(ids[3]);
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        break;
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case 2:
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        EXPECT_EQ(ids[4], iter.GetCurrentKey());
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        EXPECT_EQ(&obj[4], iter.GetCurrentValue());
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        map.Remove(ids[0]);
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        break;
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      default:
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        FAIL() << "should not have that many elements";
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        break;
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    counter++;
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(IDMapTest, OwningPointersDeletesThemOnRemove) {
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kCount = 3;
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int external_del_count = 0;
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DestructorCounter* external_obj[kCount];
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int map_external_ids[kCount];
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int owned_del_count = 0;
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DestructorCounter* owned_obj[kCount];
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int map_owned_ids[kCount];
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  IDMap<DestructorCounter> map_external;
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kCount; ++i) {
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    external_obj[i] = new DestructorCounter(&external_del_count);
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    map_external_ids[i] = map_external.Add(external_obj[i]);
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    owned_obj[i] = new DestructorCounter(&owned_del_count);
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    map_owned_ids[i] = map_owned.Add(owned_obj[i]);
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kCount; ++i) {
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(external_del_count, 0);
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(owned_del_count, i);
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    map_external.Remove(map_external_ids[i]);
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    map_owned.Remove(map_owned_ids[i]);
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kCount; ++i) {
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete external_obj[i];
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(external_del_count, kCount);
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(owned_del_count, kCount);
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(IDMapTest, OwningPointersDeletesThemOnDestruct) {
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kCount = 3;
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int external_del_count = 0;
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DestructorCounter* external_obj[kCount];
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int map_external_ids[kCount];
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int owned_del_count = 0;
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DestructorCounter* owned_obj[kCount];
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int map_owned_ids[kCount];
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    IDMap<DestructorCounter> map_external;
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (int i = 0; i < kCount; ++i) {
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      external_obj[i] = new DestructorCounter(&external_del_count);
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      map_external_ids[i] = map_external.Add(external_obj[i]);
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      owned_obj[i] = new DestructorCounter(&owned_del_count);
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      map_owned_ids[i] = map_owned.Add(owned_obj[i]);
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(external_del_count, 0);
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kCount; ++i) {
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete external_obj[i];
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(external_del_count, kCount);
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(owned_del_count, kCount);
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
198