| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/shared/chrome/browser/tabs/web_state_list.h" | 5 #import "ios/shared/chrome/browser/tabs/web_state_list.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/supports_user_data.h" | 9 #include "base/supports_user_data.h" |
| 10 #import "ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h" | 10 #import "ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h" |
| 11 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" | 11 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" |
| 12 #import "ios/shared/chrome/browser/tabs/web_state_opener.h" | 12 #import "ios/shared/chrome/browser/tabs/web_state_opener.h" |
| 13 #import "ios/web/public/test/fakes/test_navigation_manager.h" | 13 #import "ios/web/public/test/fakes/test_navigation_manager.h" |
| 14 #import "ios/web/public/test/fakes/test_web_state.h" | 14 #import "ios/web/public/test/fakes/test_web_state.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "testing/platform_test.h" | 16 #include "testing/platform_test.h" |
| 17 | 17 |
| 18 #if !defined(__has_feature) || !__has_feature(objc_arc) | 18 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 19 #error "This file requires ARC support." | 19 #error "This file requires ARC support." |
| 20 #endif | 20 #endif |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 const char kURL0[] = "https://chromium.org/0"; | 23 const char kURL0[] = "https://chromium.org/0"; |
| 24 const char kURL1[] = "https://chromium.org/1"; | 24 const char kURL1[] = "https://chromium.org/1"; |
| 25 const char kURL2[] = "https://chromium.org/2"; | 25 const char kURL2[] = "https://chromium.org/2"; |
| 26 const char kSupportsUserDataDeathGuardKey = '\0'; | |
| 27 | |
| 28 // A base::SupportsUserData::Data that tracks whether a base::SupportsUserData | |
| 29 // has been deleted (the fact is recorded in a provided pointer as part of the | |
| 30 // object destruction). | |
| 31 class SupportsUserDataDeathGuard : public base::SupportsUserData::Data { | |
| 32 public: | |
| 33 explicit SupportsUserDataDeathGuard(bool* object_was_destroyed) | |
| 34 : object_was_destroyed_(object_was_destroyed) { | |
| 35 *object_was_destroyed_ = false; | |
| 36 } | |
| 37 | |
| 38 ~SupportsUserDataDeathGuard() override { *object_was_destroyed_ = true; } | |
| 39 | |
| 40 private: | |
| 41 bool* object_was_destroyed_; | |
| 42 | |
| 43 DISALLOW_COPY_AND_ASSIGN(SupportsUserDataDeathGuard); | |
| 44 }; | |
| 45 | 26 |
| 46 // WebStateList observer that records which events have been called by the | 27 // WebStateList observer that records which events have been called by the |
| 47 // WebStateList. | 28 // WebStateList. |
| 48 class WebStateListTestObserver : public WebStateListObserver { | 29 class WebStateListTestObserver : public WebStateListObserver { |
| 49 public: | 30 public: |
| 50 WebStateListTestObserver() = default; | 31 WebStateListTestObserver() = default; |
| 51 | 32 |
| 52 // Reset statistics whether events have been called. | 33 // Reset statistics whether events have been called. |
| 53 void ResetStatistics() { | 34 void ResetStatistics() { |
| 54 web_state_inserted_called_ = false; | 35 web_state_inserted_called_ = false; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 117 |
| 137 int last_committed_item_index = 0; | 118 int last_committed_item_index = 0; |
| 138 | 119 |
| 139 DISALLOW_COPY_AND_ASSIGN(FakeNavigationManager); | 120 DISALLOW_COPY_AND_ASSIGN(FakeNavigationManager); |
| 140 }; | 121 }; |
| 141 | 122 |
| 142 } // namespace | 123 } // namespace |
| 143 | 124 |
| 144 class WebStateListTest : public PlatformTest { | 125 class WebStateListTest : public PlatformTest { |
| 145 public: | 126 public: |
| 146 WebStateListTest() | 127 WebStateListTest() : web_state_list_(&web_state_list_delegate_) { |
| 147 : web_state_list_(&web_state_list_delegate_, | |
| 148 WebStateList::WebStateOwned) { | |
| 149 web_state_list_.AddObserver(&observer_); | 128 web_state_list_.AddObserver(&observer_); |
| 150 } | 129 } |
| 151 | 130 |
| 152 ~WebStateListTest() override { web_state_list_.RemoveObserver(&observer_); } | 131 ~WebStateListTest() override { web_state_list_.RemoveObserver(&observer_); } |
| 153 | 132 |
| 154 protected: | 133 protected: |
| 155 FakeWebStateListDelegate web_state_list_delegate_; | 134 FakeWebStateListDelegate web_state_list_delegate_; |
| 156 WebStateList web_state_list_; | 135 WebStateList web_state_list_; |
| 157 WebStateListTestObserver observer_; | 136 WebStateListTestObserver observer_; |
| 158 | 137 |
| 159 // This method should return std::unique_ptr<> however, due to the complex | 138 std::unique_ptr<web::WebState> CreateWebState(const char* url) { |
| 160 // ownership of Tab, WebStateList currently uses raw pointers. Change this | |
| 161 // once Tab ownership is sane, see http://crbug.com/546222 for progress. | |
| 162 web::WebState* CreateWebState(const char* url) { | |
| 163 auto test_web_state = base::MakeUnique<web::TestWebState>(); | 139 auto test_web_state = base::MakeUnique<web::TestWebState>(); |
| 164 test_web_state->SetCurrentURL(GURL(url)); | 140 test_web_state->SetCurrentURL(GURL(url)); |
| 165 test_web_state->SetNavigationManager( | 141 test_web_state->SetNavigationManager( |
| 166 base::MakeUnique<FakeNavigationManager>()); | 142 base::MakeUnique<FakeNavigationManager>()); |
| 167 return test_web_state.release(); | 143 // TODO(crbug.com/703565): remove std::move() once Xcode 9.0+ is required. |
| 144 return std::move(test_web_state); |
| 168 } | 145 } |
| 169 | 146 |
| 170 private: | 147 private: |
| 171 DISALLOW_COPY_AND_ASSIGN(WebStateListTest); | 148 DISALLOW_COPY_AND_ASSIGN(WebStateListTest); |
| 172 }; | 149 }; |
| 173 | 150 |
| 174 TEST_F(WebStateListTest, IsEmpty) { | 151 TEST_F(WebStateListTest, IsEmpty) { |
| 175 EXPECT_EQ(0, web_state_list_.count()); | 152 EXPECT_EQ(0, web_state_list_.count()); |
| 176 EXPECT_TRUE(web_state_list_.empty()); | 153 EXPECT_TRUE(web_state_list_.empty()); |
| 177 | 154 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 web_state_list_.InsertWebState(1, CreateWebState(kURL1)); | 309 web_state_list_.InsertWebState(1, CreateWebState(kURL1)); |
| 333 web_state_list_.InsertWebState(2, CreateWebState(kURL2)); | 310 web_state_list_.InsertWebState(2, CreateWebState(kURL2)); |
| 334 | 311 |
| 335 // Sanity check before closing WebState. | 312 // Sanity check before closing WebState. |
| 336 EXPECT_EQ(3, web_state_list_.count()); | 313 EXPECT_EQ(3, web_state_list_.count()); |
| 337 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); | 314 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); |
| 338 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); | 315 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); |
| 339 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec()); | 316 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec()); |
| 340 | 317 |
| 341 observer_.ResetStatistics(); | 318 observer_.ResetStatistics(); |
| 342 std::unique_ptr<web::WebState> old_web_state( | 319 web_state_list_.DetachWebStateAt(0); |
| 343 web_state_list_.DetachWebStateAt(0)); | |
| 344 | 320 |
| 345 EXPECT_TRUE(observer_.web_state_detached_called()); | 321 EXPECT_TRUE(observer_.web_state_detached_called()); |
| 346 EXPECT_EQ(2, web_state_list_.count()); | 322 EXPECT_EQ(2, web_state_list_.count()); |
| 347 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); | 323 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); |
| 348 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); | 324 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); |
| 349 } | 325 } |
| 350 | 326 |
| 351 TEST_F(WebStateListTest, DetachWebStateAtIndexMiddle) { | 327 TEST_F(WebStateListTest, DetachWebStateAtIndexMiddle) { |
| 352 web_state_list_.InsertWebState(0, CreateWebState(kURL0)); | 328 web_state_list_.InsertWebState(0, CreateWebState(kURL0)); |
| 353 web_state_list_.InsertWebState(1, CreateWebState(kURL1)); | 329 web_state_list_.InsertWebState(1, CreateWebState(kURL1)); |
| 354 web_state_list_.InsertWebState(2, CreateWebState(kURL2)); | 330 web_state_list_.InsertWebState(2, CreateWebState(kURL2)); |
| 355 | 331 |
| 356 // Sanity check before closing WebState. | 332 // Sanity check before closing WebState. |
| 357 EXPECT_EQ(3, web_state_list_.count()); | 333 EXPECT_EQ(3, web_state_list_.count()); |
| 358 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); | 334 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); |
| 359 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); | 335 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); |
| 360 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec()); | 336 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec()); |
| 361 | 337 |
| 362 observer_.ResetStatistics(); | 338 observer_.ResetStatistics(); |
| 363 std::unique_ptr<web::WebState> old_web_state( | 339 web_state_list_.DetachWebStateAt(1); |
| 364 web_state_list_.DetachWebStateAt(1)); | |
| 365 | 340 |
| 366 EXPECT_TRUE(observer_.web_state_detached_called()); | 341 EXPECT_TRUE(observer_.web_state_detached_called()); |
| 367 EXPECT_EQ(2, web_state_list_.count()); | 342 EXPECT_EQ(2, web_state_list_.count()); |
| 368 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); | 343 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); |
| 369 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); | 344 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); |
| 370 } | 345 } |
| 371 | 346 |
| 372 TEST_F(WebStateListTest, DetachWebStateAtIndexLast) { | 347 TEST_F(WebStateListTest, DetachWebStateAtIndexLast) { |
| 373 web_state_list_.InsertWebState(0, CreateWebState(kURL0)); | 348 web_state_list_.InsertWebState(0, CreateWebState(kURL0)); |
| 374 web_state_list_.InsertWebState(1, CreateWebState(kURL1)); | 349 web_state_list_.InsertWebState(1, CreateWebState(kURL1)); |
| 375 web_state_list_.InsertWebState(2, CreateWebState(kURL2)); | 350 web_state_list_.InsertWebState(2, CreateWebState(kURL2)); |
| 376 | 351 |
| 377 // Sanity check before closing WebState. | 352 // Sanity check before closing WebState. |
| 378 EXPECT_EQ(3, web_state_list_.count()); | 353 EXPECT_EQ(3, web_state_list_.count()); |
| 379 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); | 354 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); |
| 380 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); | 355 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); |
| 381 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec()); | 356 EXPECT_EQ(kURL2, web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec()); |
| 382 | 357 |
| 383 observer_.ResetStatistics(); | 358 observer_.ResetStatistics(); |
| 384 std::unique_ptr<web::WebState> old_web_state( | 359 web_state_list_.DetachWebStateAt(2); |
| 385 web_state_list_.DetachWebStateAt(2)); | |
| 386 | 360 |
| 387 EXPECT_TRUE(observer_.web_state_detached_called()); | 361 EXPECT_TRUE(observer_.web_state_detached_called()); |
| 388 EXPECT_EQ(2, web_state_list_.count()); | 362 EXPECT_EQ(2, web_state_list_.count()); |
| 389 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); | 363 EXPECT_EQ(kURL0, web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec()); |
| 390 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); | 364 EXPECT_EQ(kURL1, web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec()); |
| 391 } | 365 } |
| 392 | 366 |
| 393 TEST_F(WebStateListTest, OwnershipBorrowed) { | |
| 394 bool web_state_was_killed = false; | |
| 395 auto test_web_state = base::MakeUnique<web::TestWebState>(); | |
| 396 test_web_state->SetUserData( | |
| 397 &kSupportsUserDataDeathGuardKey, | |
| 398 base::MakeUnique<SupportsUserDataDeathGuard>(&web_state_was_killed)); | |
| 399 | |
| 400 FakeWebStateListDelegate web_state_list_delegate; | |
| 401 auto web_state_list = base::MakeUnique<WebStateList>( | |
| 402 &web_state_list_delegate, WebStateList::WebStateBorrowed); | |
| 403 web_state_list->InsertWebState(0, test_web_state.get()); | |
| 404 EXPECT_FALSE(web_state_was_killed); | |
| 405 | |
| 406 web_state_list.reset(); | |
| 407 EXPECT_FALSE(web_state_was_killed); | |
| 408 } | |
| 409 | |
| 410 TEST_F(WebStateListTest, OwnershipOwned) { | |
| 411 bool web_state_was_killed = false; | |
| 412 auto test_web_state = base::MakeUnique<web::TestWebState>(); | |
| 413 test_web_state->SetUserData( | |
| 414 &kSupportsUserDataDeathGuardKey, | |
| 415 base::MakeUnique<SupportsUserDataDeathGuard>(&web_state_was_killed)); | |
| 416 | |
| 417 FakeWebStateListDelegate web_state_list_delegate; | |
| 418 auto web_state_list = base::MakeUnique<WebStateList>( | |
| 419 &web_state_list_delegate, WebStateList::WebStateOwned); | |
| 420 web_state_list->InsertWebState(0, test_web_state.release()); | |
| 421 EXPECT_FALSE(web_state_was_killed); | |
| 422 | |
| 423 web_state_list.reset(); | |
| 424 EXPECT_TRUE(web_state_was_killed); | |
| 425 } | |
| 426 | |
| 427 TEST_F(WebStateListTest, OpenersEmptyList) { | 367 TEST_F(WebStateListTest, OpenersEmptyList) { |
| 428 EXPECT_TRUE(web_state_list_.empty()); | 368 EXPECT_TRUE(web_state_list_.empty()); |
| 429 | 369 |
| 430 EXPECT_EQ(WebStateList::kInvalidIndex, | 370 EXPECT_EQ(WebStateList::kInvalidIndex, |
| 431 web_state_list_.GetIndexOfNextWebStateOpenedBy( | 371 web_state_list_.GetIndexOfNextWebStateOpenedBy( |
| 432 nullptr, WebStateList::kInvalidIndex, false)); | 372 nullptr, WebStateList::kInvalidIndex, false)); |
| 433 EXPECT_EQ(WebStateList::kInvalidIndex, | 373 EXPECT_EQ(WebStateList::kInvalidIndex, |
| 434 web_state_list_.GetIndexOfLastWebStateOpenedBy( | 374 web_state_list_.GetIndexOfLastWebStateOpenedBy( |
| 435 nullptr, WebStateList::kInvalidIndex, false)); | 375 nullptr, WebStateList::kInvalidIndex, false)); |
| 436 | 376 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 web_state_list_.GetIndexOfLastWebStateOpenedBy(opener, start_index, | 487 web_state_list_.GetIndexOfLastWebStateOpenedBy(opener, start_index, |
| 548 false)); | 488 false)); |
| 549 | 489 |
| 550 EXPECT_EQ(WebStateList::kInvalidIndex, | 490 EXPECT_EQ(WebStateList::kInvalidIndex, |
| 551 web_state_list_.GetIndexOfNextWebStateOpenedBy(opener, start_index, | 491 web_state_list_.GetIndexOfNextWebStateOpenedBy(opener, start_index, |
| 552 true)); | 492 true)); |
| 553 EXPECT_EQ(WebStateList::kInvalidIndex, | 493 EXPECT_EQ(WebStateList::kInvalidIndex, |
| 554 web_state_list_.GetIndexOfLastWebStateOpenedBy(opener, start_index, | 494 web_state_list_.GetIndexOfLastWebStateOpenedBy(opener, start_index, |
| 555 true)); | 495 true)); |
| 556 } | 496 } |
| OLD | NEW |