Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: ios/shared/chrome/browser/tabs/web_state_list_unittest.mm

Issue 2680403005: Introduce WebStateList to manage a list of web::WebState. (Closed)
Patch Set: Rebase. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ios/shared/chrome/browser/tabs/web_state_list_observer_bridge.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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 #import "ios/shared/chrome/browser/tabs/web_state_list.h"
6
7 #include "base/macros.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/supports_user_data.h"
10 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
11 #import "ios/web/public/test/fakes/test_web_state.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "testing/platform_test.h"
14
15 namespace {
16 const char kURL0[] = "https://chromium.org/0";
17 const char kURL1[] = "https://chromium.org/1";
18 const char kURL2[] = "https://chromium.org/2";
19 const char kSupportsUserDataDeathGuardKey = '\0';
20
21 // A base::SupportsUserData::Data that tracks whether a base::SupportsUserData
22 // has been deleted (the fact is recorded in a provided pointer as part of the
23 // object destruction).
24 class SupportsUserDataDeathGuard : public base::SupportsUserData::Data {
25 public:
26 explicit SupportsUserDataDeathGuard(bool* object_was_destroyed)
27 : object_was_destroyed_(object_was_destroyed) {
28 *object_was_destroyed_ = false;
29 }
30
31 ~SupportsUserDataDeathGuard() override { *object_was_destroyed_ = true; }
32
33 private:
34 bool* object_was_destroyed_;
35
36 DISALLOW_COPY_AND_ASSIGN(SupportsUserDataDeathGuard);
37 };
38
39 // WebStateList observer that records which events have been called by the
40 // WebStateList.
41 class WebStateListTestObserver : public WebStateListObserver {
42 public:
43 WebStateListTestObserver() = default;
44
45 // Reset statistics whether events have been called.
46 void ResetStatistics() {
47 web_state_inserted_called_ = false;
48 web_state_moved_called_ = false;
49 web_state_replaced_called_ = false;
50 web_state_detached_called_ = false;
51 }
52
53 // Returns whether WebStateInsertedAt was invoked.
54 bool web_state_inserted_called() const { return web_state_inserted_called_; }
55
56 // Returns whether WebStateMoved was invoked.
57 bool web_state_moved_called() const { return web_state_moved_called_; }
58
59 // Returns whether WebStateReplacedAt was invoked.
60 bool web_state_replaced_called() const { return web_state_replaced_called_; }
61
62 // Returns whether WebStateDetachedAt was invoked.
63 bool web_state_detached_called() const { return web_state_detached_called_; }
64
65 // WebStateListObserver implementation.
66 void WebStateInsertedAt(WebStateList* web_state_list,
67 web::WebState* web_state,
68 int index) override {
69 web_state_inserted_called_ = true;
70 }
71
72 void WebStateMoved(WebStateList* web_state_list,
73 web::WebState* web_state,
74 int from_index,
75 int to_index) override {
76 web_state_moved_called_ = true;
77 }
78
79 void WebStateReplacedAt(WebStateList* web_state_list,
80 web::WebState* old_web_state,
81 web::WebState* new_web_state,
82 int index) override {
83 web_state_replaced_called_ = true;
84 }
85
86 void WebStateDetachedAt(WebStateList* web_state_list,
87 web::WebState* web_state,
88 int index) override {
89 web_state_detached_called_ = true;
90 }
91
92 private:
93 bool web_state_inserted_called_ = false;
94 bool web_state_moved_called_ = false;
95 bool web_state_replaced_called_ = false;
96 bool web_state_detached_called_ = false;
97
98 DISALLOW_COPY_AND_ASSIGN(WebStateListTestObserver);
99 };
100 } // namespace
101
102 class WebStateListTest : public PlatformTest {
103 public:
104 WebStateListTest() : web_state_list_(WebStateList::WebStateOwned) {
105 web_state_list_.AddObserver(&observer_);
106 }
107
108 ~WebStateListTest() override { web_state_list_.RemoveObserver(&observer_); }
109
110 protected:
111 WebStateList web_state_list_;
112 WebStateListTestObserver observer_;
113
114 // This method should return std::unique_ptr<> however, due to the complex
115 // ownership of Tab, WebStateList currently uses raw pointers. Change this
116 // once Tab ownership is sane, see http://crbug.com/546222 for progress.
117 web::WebState* CreateWebState(const char* url) {
118 auto test_web_state = base::MakeUnique<web::TestWebState>();
119 test_web_state->SetCurrentURL(GURL(url));
120 return test_web_state.release();
121 }
122
123 private:
124 DISALLOW_COPY_AND_ASSIGN(WebStateListTest);
125 };
126
127 TEST_F(WebStateListTest, IsEmpty) {
128 EXPECT_EQ(0, web_state_list_.count());
129 EXPECT_TRUE(web_state_list_.empty());
130
131 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
132
133 EXPECT_TRUE(observer_.web_state_inserted_called());
134 EXPECT_EQ(1, web_state_list_.count());
135 EXPECT_FALSE(web_state_list_.empty());
136 }
137
138 TEST_F(WebStateListTest, InsertUrlSingle) {
139 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
140
141 EXPECT_TRUE(observer_.web_state_inserted_called());
142 EXPECT_EQ(1, web_state_list_.count());
143 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
144 }
145
146 TEST_F(WebStateListTest, InsertUrlMultiple) {
147 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
148 web_state_list_.InsertWebState(0, CreateWebState(kURL1));
149 web_state_list_.InsertWebState(1, CreateWebState(kURL2));
150
151 EXPECT_TRUE(observer_.web_state_inserted_called());
152 EXPECT_EQ(3, web_state_list_.count());
153 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
154 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
155 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
156 }
157
158 TEST_F(WebStateListTest, MoveWebStateAtRightByOne) {
159 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
160 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
161 web_state_list_.InsertWebState(2, CreateWebState(kURL2));
162
163 // Sanity check before closing WebState.
164 EXPECT_EQ(3, web_state_list_.count());
165 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
166 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
167 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
168
169 observer_.ResetStatistics();
170 web_state_list_.MoveWebStateAt(0, 1);
171
172 EXPECT_TRUE(observer_.web_state_moved_called());
173 EXPECT_EQ(3, web_state_list_.count());
174 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
175 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
176 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
177 }
178
179 TEST_F(WebStateListTest, MoveWebStateAtRightByMoreThanOne) {
180 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
181 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
182 web_state_list_.InsertWebState(2, CreateWebState(kURL2));
183
184 // Sanity check before closing WebState.
185 EXPECT_EQ(3, web_state_list_.count());
186 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
187 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
188 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
189
190 observer_.ResetStatistics();
191 web_state_list_.MoveWebStateAt(0, 2);
192
193 EXPECT_TRUE(observer_.web_state_moved_called());
194 EXPECT_EQ(3, web_state_list_.count());
195 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
196 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
197 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
198 }
199
200 TEST_F(WebStateListTest, MoveWebStateAtLeftByOne) {
201 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
202 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
203 web_state_list_.InsertWebState(2, CreateWebState(kURL2));
204
205 // Sanity check before closing WebState.
206 EXPECT_EQ(3, web_state_list_.count());
207 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
208 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
209 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
210
211 observer_.ResetStatistics();
212 web_state_list_.MoveWebStateAt(2, 1);
213
214 EXPECT_TRUE(observer_.web_state_moved_called());
215 EXPECT_EQ(3, web_state_list_.count());
216 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
217 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
218 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
219 }
220
221 TEST_F(WebStateListTest, MoveWebStateAtLeftByMoreThanOne) {
222 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
223 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
224 web_state_list_.InsertWebState(2, CreateWebState(kURL2));
225
226 // Sanity check before closing WebState.
227 EXPECT_EQ(3, web_state_list_.count());
228 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
229 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
230 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
231
232 observer_.ResetStatistics();
233 web_state_list_.MoveWebStateAt(2, 0);
234
235 EXPECT_TRUE(observer_.web_state_moved_called());
236 EXPECT_EQ(3, web_state_list_.count());
237 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
238 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
239 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
240 }
241
242 TEST_F(WebStateListTest, MoveWebStateAtSameIndex) {
243 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
244 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
245 web_state_list_.InsertWebState(2, CreateWebState(kURL2));
246
247 // Sanity check before closing WebState.
248 EXPECT_EQ(3, web_state_list_.count());
249 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
250 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
251 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
252
253 observer_.ResetStatistics();
254 web_state_list_.MoveWebStateAt(2, 2);
255
256 EXPECT_FALSE(observer_.web_state_moved_called());
257 EXPECT_EQ(3, web_state_list_.count());
258 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
259 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
260 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
261 }
262
263 TEST_F(WebStateListTest, ReplaceWebStateAt) {
264 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
265 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
266
267 // Sanity check before replacing WebState.
268 EXPECT_EQ(2, web_state_list_.count());
269 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
270 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
271
272 observer_.ResetStatistics();
273 std::unique_ptr<web::WebState> old_web_state(
274 web_state_list_.ReplaceWebStateAt(1, CreateWebState(kURL2)));
275
276 EXPECT_TRUE(observer_.web_state_replaced_called());
277 EXPECT_EQ(2, web_state_list_.count());
278 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
279 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
280 EXPECT_EQ(kURL1, old_web_state->GetVisibleURL().spec());
281 }
282
283 TEST_F(WebStateListTest, DetachWebStateAtIndexBegining) {
284 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
285 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
286 web_state_list_.InsertWebState(2, CreateWebState(kURL2));
287
288 // Sanity check before closing WebState.
289 EXPECT_EQ(3, web_state_list_.count());
290 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
291 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
292 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
293
294 observer_.ResetStatistics();
295 web_state_list_.DetachWebStateAt(0);
296
297 EXPECT_TRUE(observer_.web_state_detached_called());
298 EXPECT_EQ(2, web_state_list_.count());
299 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
300 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
301 }
302
303 TEST_F(WebStateListTest, DetachWebStateAtIndexMiddle) {
304 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
305 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
306 web_state_list_.InsertWebState(2, CreateWebState(kURL2));
307
308 // Sanity check before closing WebState.
309 EXPECT_EQ(3, web_state_list_.count());
310 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
311 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
312 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
313
314 observer_.ResetStatistics();
315 web_state_list_.DetachWebStateAt(1);
316
317 EXPECT_TRUE(observer_.web_state_detached_called());
318 EXPECT_EQ(2, web_state_list_.count());
319 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
320 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
321 }
322
323 TEST_F(WebStateListTest, DetachWebStateAtIndexLast) {
324 web_state_list_.InsertWebState(0, CreateWebState(kURL0));
325 web_state_list_.InsertWebState(1, CreateWebState(kURL1));
326 web_state_list_.InsertWebState(2, CreateWebState(kURL2));
327
328 // Sanity check before closing WebState.
329 EXPECT_EQ(3, web_state_list_.count());
330 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
331 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
332 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec());
333
334 observer_.ResetStatistics();
335 web_state_list_.DetachWebStateAt(2);
336
337 EXPECT_TRUE(observer_.web_state_detached_called());
338 EXPECT_EQ(2, web_state_list_.count());
339 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec());
340 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec());
341 }
342
343 TEST_F(WebStateListTest, OwnershipBorrowed) {
344 bool web_state_was_killed = false;
345 auto test_web_state = base::MakeUnique<web::TestWebState>();
346 test_web_state->SetUserData(
347 &kSupportsUserDataDeathGuardKey,
348 base::MakeUnique<SupportsUserDataDeathGuard>(&web_state_was_killed));
349
350 auto web_state_list =
351 base::MakeUnique<WebStateList>(WebStateList::WebStateBorrowed);
352 web_state_list->InsertWebState(0, test_web_state.get());
353 EXPECT_FALSE(web_state_was_killed);
354
355 web_state_list.reset();
356 EXPECT_FALSE(web_state_was_killed);
357 }
358
359 TEST_F(WebStateListTest, OwnershipOwned) {
360 bool web_state_was_killed = false;
361 auto test_web_state = base::MakeUnique<web::TestWebState>();
362 test_web_state->SetUserData(
363 &kSupportsUserDataDeathGuardKey,
364 base::MakeUnique<SupportsUserDataDeathGuard>(&web_state_was_killed));
365
366 auto web_state_list =
367 base::MakeUnique<WebStateList>(WebStateList::WebStateOwned);
368 web_state_list->InsertWebState(0, test_web_state.release());
369 EXPECT_FALSE(web_state_was_killed);
370
371 web_state_list.reset();
372 EXPECT_TRUE(web_state_was_killed);
373 }
OLDNEW
« no previous file with comments | « ios/shared/chrome/browser/tabs/web_state_list_observer_bridge.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698