| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 #include <map> | 5 #include <map> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 std::map<TabContents*, int> foo_; | 263 std::map<TabContents*, int> foo_; |
| 264 | 264 |
| 265 // ProfileManager requires a base::SystemMonitor. | 265 // ProfileManager requires a base::SystemMonitor. |
| 266 base::SystemMonitor system_monitor; | 266 base::SystemMonitor system_monitor; |
| 267 | 267 |
| 268 ProfileManager pm_; | 268 ProfileManager pm_; |
| 269 }; | 269 }; |
| 270 | 270 |
| 271 class MockTabStripModelObserver : public TabStripModelObserver { | 271 class MockTabStripModelObserver : public TabStripModelObserver { |
| 272 public: | 272 public: |
| 273 MockTabStripModelObserver() : empty_(true) {} | 273 MockTabStripModelObserver() : empty_(true), |
| 274 log_tab_selection_changed_(false), |
| 275 model_(NULL) {} |
| 276 explicit MockTabStripModelObserver(TabStripModel* model) |
| 277 : empty_(true), |
| 278 log_tab_selection_changed_(false), |
| 279 model_(model) {} |
| 274 ~MockTabStripModelObserver() { | 280 ~MockTabStripModelObserver() { |
| 275 STLDeleteContainerPointers(states_.begin(), states_.end()); | 281 STLDeleteContainerPointers(states_.begin(), states_.end()); |
| 276 } | 282 } |
| 277 | 283 |
| 278 enum TabStripModelObserverAction { | 284 enum TabStripModelObserverAction { |
| 279 INSERT, | 285 INSERT, |
| 280 CLOSE, | 286 CLOSE, |
| 281 DETACH, | 287 DETACH, |
| 288 ACTIVATE, |
| 282 SELECT, | 289 SELECT, |
| 283 MOVE, | 290 MOVE, |
| 284 CHANGE, | 291 CHANGE, |
| 285 PINNED, | 292 PINNED, |
| 286 REPLACED | 293 REPLACED |
| 287 }; | 294 }; |
| 288 | 295 |
| 289 struct State { | 296 struct State { |
| 290 State(TabContentsWrapper* a_dst_contents, | 297 State(TabContentsWrapper* a_dst_contents, |
| 291 int a_dst_index, | 298 int a_dst_index, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 bool foreground) { | 348 bool foreground) { |
| 342 empty_ = false; | 349 empty_ = false; |
| 343 State* s = new State(contents, index, INSERT); | 350 State* s = new State(contents, index, INSERT); |
| 344 s->foreground = foreground; | 351 s->foreground = foreground; |
| 345 states_.push_back(s); | 352 states_.push_back(s); |
| 346 } | 353 } |
| 347 virtual void ActiveTabChanged(TabContentsWrapper* old_contents, | 354 virtual void ActiveTabChanged(TabContentsWrapper* old_contents, |
| 348 TabContentsWrapper* new_contents, | 355 TabContentsWrapper* new_contents, |
| 349 int index, | 356 int index, |
| 350 bool user_gesture) { | 357 bool user_gesture) { |
| 351 State* s = new State(new_contents, index, SELECT); | 358 State* s = new State(new_contents, index, ACTIVATE); |
| 352 s->src_contents = old_contents; | 359 s->src_contents = old_contents; |
| 353 s->user_gesture = user_gesture; | 360 s->user_gesture = user_gesture; |
| 354 states_.push_back(s); | 361 states_.push_back(s); |
| 355 } | 362 } |
| 363 virtual void TabSelectionChanged(const TabStripSelectionModel& old_model) { |
| 364 if (!log_tab_selection_changed()) |
| 365 return; |
| 366 |
| 367 State* s = new State(model()->GetActiveTabContents(), |
| 368 model()->active_index(), |
| 369 SELECT); |
| 370 s->src_contents = model()->GetTabContentsAt(old_model.active()); |
| 371 s->src_index = old_model.active(); |
| 372 states_.push_back(s); |
| 373 } |
| 356 virtual void TabMoved( | 374 virtual void TabMoved( |
| 357 TabContentsWrapper* contents, int from_index, int to_index) { | 375 TabContentsWrapper* contents, int from_index, int to_index) { |
| 358 State* s = new State(contents, to_index, MOVE); | 376 State* s = new State(contents, to_index, MOVE); |
| 359 s->src_index = from_index; | 377 s->src_index = from_index; |
| 360 states_.push_back(s); | 378 states_.push_back(s); |
| 361 } | 379 } |
| 362 | 380 |
| 363 virtual void TabClosingAt(TabStripModel* tab_strip_model, | 381 virtual void TabClosingAt(TabStripModel* tab_strip_model, |
| 364 TabContentsWrapper* contents, | 382 TabContentsWrapper* contents, |
| 365 int index) { | 383 int index) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 385 } | 403 } |
| 386 virtual void TabStripEmpty() { | 404 virtual void TabStripEmpty() { |
| 387 empty_ = true; | 405 empty_ = true; |
| 388 } | 406 } |
| 389 | 407 |
| 390 void ClearStates() { | 408 void ClearStates() { |
| 391 STLDeleteContainerPointers(states_.begin(), states_.end()); | 409 STLDeleteContainerPointers(states_.begin(), states_.end()); |
| 392 states_.clear(); | 410 states_.clear(); |
| 393 } | 411 } |
| 394 | 412 |
| 413 void set_log_tab_selection_changed(bool flag) { |
| 414 log_tab_selection_changed_ = flag; |
| 415 } |
| 416 |
| 395 bool empty() const { return empty_; } | 417 bool empty() const { return empty_; } |
| 418 bool log_tab_selection_changed() const { return log_tab_selection_changed_; } |
| 419 TabStripModel* model() { return model_; } |
| 396 | 420 |
| 397 private: | 421 private: |
| 398 std::vector<State*> states_; | 422 std::vector<State*> states_; |
| 399 | 423 |
| 400 bool empty_; | 424 bool empty_; |
| 425 // TODO(dpapad): Remove this variable and update TestBasicAPI so that it takes |
| 426 // into account TabSelectionChanged notifications. |
| 427 bool log_tab_selection_changed_; |
| 428 TabStripModel* model_; |
| 401 | 429 |
| 402 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver); | 430 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver); |
| 403 }; | 431 }; |
| 404 | 432 |
| 405 TEST_F(TabStripModelTest, TestBasicAPI) { | 433 TEST_F(TabStripModelTest, TestBasicAPI) { |
| 406 TabStripDummyDelegate delegate(NULL); | 434 TabStripDummyDelegate delegate(NULL); |
| 407 TabStripModel tabstrip(&delegate, profile()); | 435 TabStripModel tabstrip(&delegate, profile()); |
| 408 MockTabStripModelObserver observer; | 436 MockTabStripModelObserver observer; |
| 409 tabstrip.AddObserver(&observer); | 437 tabstrip.AddObserver(&observer); |
| 410 | 438 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 421 // Test AppendTabContents, ContainsIndex | 449 // Test AppendTabContents, ContainsIndex |
| 422 { | 450 { |
| 423 EXPECT_FALSE(tabstrip.ContainsIndex(0)); | 451 EXPECT_FALSE(tabstrip.ContainsIndex(0)); |
| 424 tabstrip.AppendTabContents(contents1, true); | 452 tabstrip.AppendTabContents(contents1, true); |
| 425 EXPECT_TRUE(tabstrip.ContainsIndex(0)); | 453 EXPECT_TRUE(tabstrip.ContainsIndex(0)); |
| 426 EXPECT_EQ(1, tabstrip.count()); | 454 EXPECT_EQ(1, tabstrip.count()); |
| 427 EXPECT_EQ(2, observer.GetStateCount()); | 455 EXPECT_EQ(2, observer.GetStateCount()); |
| 428 State s1(contents1, 0, MockTabStripModelObserver::INSERT); | 456 State s1(contents1, 0, MockTabStripModelObserver::INSERT); |
| 429 s1.foreground = true; | 457 s1.foreground = true; |
| 430 EXPECT_TRUE(observer.StateEquals(0, s1)); | 458 EXPECT_TRUE(observer.StateEquals(0, s1)); |
| 431 State s2(contents1, 0, MockTabStripModelObserver::SELECT); | 459 State s2(contents1, 0, MockTabStripModelObserver::ACTIVATE); |
| 432 s2.src_contents = NULL; | 460 s2.src_contents = NULL; |
| 433 EXPECT_TRUE(observer.StateEquals(1, s2)); | 461 EXPECT_TRUE(observer.StateEquals(1, s2)); |
| 434 observer.ClearStates(); | 462 observer.ClearStates(); |
| 435 } | 463 } |
| 436 | 464 |
| 437 // Test InsertTabContentsAt, foreground tab. | 465 // Test InsertTabContentsAt, foreground tab. |
| 438 TabContentsWrapper* contents2 = CreateTabContents(); | 466 TabContentsWrapper* contents2 = CreateTabContents(); |
| 439 { | 467 { |
| 440 tabstrip.InsertTabContentsAt(1, contents2, TabStripModel::ADD_ACTIVE); | 468 tabstrip.InsertTabContentsAt(1, contents2, TabStripModel::ADD_ACTIVE); |
| 441 | 469 |
| 442 EXPECT_EQ(2, tabstrip.count()); | 470 EXPECT_EQ(2, tabstrip.count()); |
| 443 EXPECT_EQ(2, observer.GetStateCount()); | 471 EXPECT_EQ(2, observer.GetStateCount()); |
| 444 State s1(contents2, 1, MockTabStripModelObserver::INSERT); | 472 State s1(contents2, 1, MockTabStripModelObserver::INSERT); |
| 445 s1.foreground = true; | 473 s1.foreground = true; |
| 446 EXPECT_TRUE(observer.StateEquals(0, s1)); | 474 EXPECT_TRUE(observer.StateEquals(0, s1)); |
| 447 State s2(contents2, 1, MockTabStripModelObserver::SELECT); | 475 State s2(contents2, 1, MockTabStripModelObserver::ACTIVATE); |
| 448 s2.src_contents = contents1; | 476 s2.src_contents = contents1; |
| 449 EXPECT_TRUE(observer.StateEquals(1, s2)); | 477 EXPECT_TRUE(observer.StateEquals(1, s2)); |
| 450 observer.ClearStates(); | 478 observer.ClearStates(); |
| 451 } | 479 } |
| 452 | 480 |
| 453 // Test InsertTabContentsAt, background tab. | 481 // Test InsertTabContentsAt, background tab. |
| 454 TabContentsWrapper* contents3 = CreateTabContents(); | 482 TabContentsWrapper* contents3 = CreateTabContents(); |
| 455 { | 483 { |
| 456 tabstrip.InsertTabContentsAt(2, contents3, TabStripModel::ADD_NONE); | 484 tabstrip.InsertTabContentsAt(2, contents3, TabStripModel::ADD_NONE); |
| 457 | 485 |
| 458 EXPECT_EQ(3, tabstrip.count()); | 486 EXPECT_EQ(3, tabstrip.count()); |
| 459 EXPECT_EQ(1, observer.GetStateCount()); | 487 EXPECT_EQ(1, observer.GetStateCount()); |
| 460 State s1(contents3, 2, MockTabStripModelObserver::INSERT); | 488 State s1(contents3, 2, MockTabStripModelObserver::INSERT); |
| 461 s1.foreground = false; | 489 s1.foreground = false; |
| 462 EXPECT_TRUE(observer.StateEquals(0, s1)); | 490 EXPECT_TRUE(observer.StateEquals(0, s1)); |
| 463 observer.ClearStates(); | 491 observer.ClearStates(); |
| 464 } | 492 } |
| 465 | 493 |
| 466 // Test ActivateTabAt | 494 // Test ActivateTabAt |
| 467 { | 495 { |
| 468 tabstrip.ActivateTabAt(2, true); | 496 tabstrip.ActivateTabAt(2, true); |
| 469 EXPECT_EQ(1, observer.GetStateCount()); | 497 EXPECT_EQ(1, observer.GetStateCount()); |
| 470 State s1(contents3, 2, MockTabStripModelObserver::SELECT); | 498 State s1(contents3, 2, MockTabStripModelObserver::ACTIVATE); |
| 471 s1.src_contents = contents2; | 499 s1.src_contents = contents2; |
| 472 s1.user_gesture = true; | 500 s1.user_gesture = true; |
| 473 EXPECT_TRUE(observer.StateEquals(0, s1)); | 501 EXPECT_TRUE(observer.StateEquals(0, s1)); |
| 474 observer.ClearStates(); | 502 observer.ClearStates(); |
| 475 } | 503 } |
| 476 | 504 |
| 477 // Test DetachTabContentsAt | 505 // Test DetachTabContentsAt |
| 478 { | 506 { |
| 479 // Detach | 507 // Detach |
| 480 TabContentsWrapper* detached = tabstrip.DetachTabContentsAt(2); | 508 TabContentsWrapper* detached = tabstrip.DetachTabContentsAt(2); |
| 481 // ... and append again because we want this for later. | 509 // ... and append again because we want this for later. |
| 482 tabstrip.AppendTabContents(detached, true); | 510 tabstrip.AppendTabContents(detached, true); |
| 483 EXPECT_EQ(4, observer.GetStateCount()); | 511 EXPECT_EQ(4, observer.GetStateCount()); |
| 484 State s1(detached, 2, MockTabStripModelObserver::DETACH); | 512 State s1(detached, 2, MockTabStripModelObserver::DETACH); |
| 485 EXPECT_TRUE(observer.StateEquals(0, s1)); | 513 EXPECT_TRUE(observer.StateEquals(0, s1)); |
| 486 State s2(contents2, 1, MockTabStripModelObserver::SELECT); | 514 State s2(contents2, 1, MockTabStripModelObserver::ACTIVATE); |
| 487 s2.src_contents = contents3; | 515 s2.src_contents = contents3; |
| 488 s2.user_gesture = false; | 516 s2.user_gesture = false; |
| 489 EXPECT_TRUE(observer.StateEquals(1, s2)); | 517 EXPECT_TRUE(observer.StateEquals(1, s2)); |
| 490 State s3(detached, 2, MockTabStripModelObserver::INSERT); | 518 State s3(detached, 2, MockTabStripModelObserver::INSERT); |
| 491 s3.foreground = true; | 519 s3.foreground = true; |
| 492 EXPECT_TRUE(observer.StateEquals(2, s3)); | 520 EXPECT_TRUE(observer.StateEquals(2, s3)); |
| 493 State s4(detached, 2, MockTabStripModelObserver::SELECT); | 521 State s4(detached, 2, MockTabStripModelObserver::ACTIVATE); |
| 494 s4.src_contents = contents2; | 522 s4.src_contents = contents2; |
| 495 s4.user_gesture = false; | 523 s4.user_gesture = false; |
| 496 EXPECT_TRUE(observer.StateEquals(3, s4)); | 524 EXPECT_TRUE(observer.StateEquals(3, s4)); |
| 497 observer.ClearStates(); | 525 observer.ClearStates(); |
| 498 } | 526 } |
| 499 | 527 |
| 500 // Test CloseTabContentsAt | 528 // Test CloseTabContentsAt |
| 501 { | 529 { |
| 502 // Let's test nothing happens when the delegate veto the close. | 530 // Let's test nothing happens when the delegate veto the close. |
| 503 delegate.set_can_close(false); | 531 delegate.set_can_close(false); |
| 504 EXPECT_FALSE(tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE)); | 532 EXPECT_FALSE(tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE)); |
| 505 EXPECT_EQ(3, tabstrip.count()); | 533 EXPECT_EQ(3, tabstrip.count()); |
| 506 EXPECT_EQ(0, observer.GetStateCount()); | 534 EXPECT_EQ(0, observer.GetStateCount()); |
| 507 | 535 |
| 508 // Now let's close for real. | 536 // Now let's close for real. |
| 509 delegate.set_can_close(true); | 537 delegate.set_can_close(true); |
| 510 EXPECT_TRUE(tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE)); | 538 EXPECT_TRUE(tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE)); |
| 511 EXPECT_EQ(2, tabstrip.count()); | 539 EXPECT_EQ(2, tabstrip.count()); |
| 512 | 540 |
| 513 EXPECT_EQ(3, observer.GetStateCount()); | 541 EXPECT_EQ(3, observer.GetStateCount()); |
| 514 State s1(contents3, 2, MockTabStripModelObserver::CLOSE); | 542 State s1(contents3, 2, MockTabStripModelObserver::CLOSE); |
| 515 EXPECT_TRUE(observer.StateEquals(0, s1)); | 543 EXPECT_TRUE(observer.StateEquals(0, s1)); |
| 516 State s2(contents3, 2, MockTabStripModelObserver::DETACH); | 544 State s2(contents3, 2, MockTabStripModelObserver::DETACH); |
| 517 EXPECT_TRUE(observer.StateEquals(1, s2)); | 545 EXPECT_TRUE(observer.StateEquals(1, s2)); |
| 518 State s3(contents2, 1, MockTabStripModelObserver::SELECT); | 546 State s3(contents2, 1, MockTabStripModelObserver::ACTIVATE); |
| 519 s3.src_contents = contents3; | 547 s3.src_contents = contents3; |
| 520 s3.user_gesture = false; | 548 s3.user_gesture = false; |
| 521 EXPECT_TRUE(observer.StateEquals(2, s3)); | 549 EXPECT_TRUE(observer.StateEquals(2, s3)); |
| 522 observer.ClearStates(); | 550 observer.ClearStates(); |
| 523 } | 551 } |
| 524 | 552 |
| 525 // Test MoveTabContentsAt, select_after_move == true | 553 // Test MoveTabContentsAt, select_after_move == true |
| 526 { | 554 { |
| 527 tabstrip.MoveTabContentsAt(1, 0, true); | 555 tabstrip.MoveTabContentsAt(1, 0, true); |
| 528 | 556 |
| (...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2055 delete strip.ReplaceTabContentsAt(0, new_contents); | 2083 delete strip.ReplaceTabContentsAt(0, new_contents); |
| 2056 | 2084 |
| 2057 ASSERT_EQ(2, tabstrip_observer.GetStateCount()); | 2085 ASSERT_EQ(2, tabstrip_observer.GetStateCount()); |
| 2058 | 2086 |
| 2059 // First event should be for replaced. | 2087 // First event should be for replaced. |
| 2060 State state(new_contents, 0, MockTabStripModelObserver::REPLACED); | 2088 State state(new_contents, 0, MockTabStripModelObserver::REPLACED); |
| 2061 state.src_contents = first_contents; | 2089 state.src_contents = first_contents; |
| 2062 EXPECT_TRUE(tabstrip_observer.StateEquals(0, state)); | 2090 EXPECT_TRUE(tabstrip_observer.StateEquals(0, state)); |
| 2063 | 2091 |
| 2064 // And the second for selected. | 2092 // And the second for selected. |
| 2065 state = State(new_contents, 0, MockTabStripModelObserver::SELECT); | 2093 state = State(new_contents, 0, MockTabStripModelObserver::ACTIVATE); |
| 2066 state.src_contents = first_contents; | 2094 state.src_contents = first_contents; |
| 2067 EXPECT_TRUE(tabstrip_observer.StateEquals(1, state)); | 2095 EXPECT_TRUE(tabstrip_observer.StateEquals(1, state)); |
| 2068 | 2096 |
| 2069 // Now add another tab and replace it, making sure we don't get a selected | 2097 // Now add another tab and replace it, making sure we don't get a selected |
| 2070 // event this time. | 2098 // event this time. |
| 2071 TabContentsWrapper* third_contents = CreateTabContents(); | 2099 TabContentsWrapper* third_contents = CreateTabContents(); |
| 2072 strip.AddTabContents(third_contents, 1, PageTransition::TYPED, | 2100 strip.AddTabContents(third_contents, 1, PageTransition::TYPED, |
| 2073 TabStripModel::ADD_NONE); | 2101 TabStripModel::ADD_NONE); |
| 2074 | 2102 |
| 2075 tabstrip_observer.ClearStates(); | 2103 tabstrip_observer.ClearStates(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2174 strip.AppendTabContents(contents1, true); | 2202 strip.AppendTabContents(contents1, true); |
| 2175 strip.AppendTabContents(contents2, true); | 2203 strip.AppendTabContents(contents2, true); |
| 2176 strip.AppendTabContents(contents3, true); | 2204 strip.AppendTabContents(contents3, true); |
| 2177 strip.ToggleSelectionAt(1); | 2205 strip.ToggleSelectionAt(1); |
| 2178 strip.CloseSelectedTabs(); | 2206 strip.CloseSelectedTabs(); |
| 2179 EXPECT_EQ(1, strip.count()); | 2207 EXPECT_EQ(1, strip.count()); |
| 2180 EXPECT_EQ(0, strip.active_index()); | 2208 EXPECT_EQ(0, strip.active_index()); |
| 2181 strip.CloseAllTabs(); | 2209 strip.CloseAllTabs(); |
| 2182 } | 2210 } |
| 2183 | 2211 |
| 2212 TEST_F(TabStripModelTest, MultipleSelection) { |
| 2213 TabStripDummyDelegate delegate(NULL); |
| 2214 TabStripModel strip(&delegate, profile()); |
| 2215 MockTabStripModelObserver observer(&strip); |
| 2216 TabContentsWrapper* contents0 = CreateTabContents(); |
| 2217 TabContentsWrapper* contents1 = CreateTabContents(); |
| 2218 TabContentsWrapper* contents2 = CreateTabContents(); |
| 2219 TabContentsWrapper* contents3 = CreateTabContents(); |
| 2220 strip.AppendTabContents(contents0, false); |
| 2221 strip.AppendTabContents(contents1, false); |
| 2222 strip.AppendTabContents(contents2, false); |
| 2223 strip.AppendTabContents(contents3, false); |
| 2224 observer.set_log_tab_selection_changed(true); |
| 2225 strip.AddObserver(&observer); |
| 2226 |
| 2227 // Selection and active tab change. |
| 2228 strip.ActivateTabAt(3, true); |
| 2229 ASSERT_EQ(2, observer.GetStateCount()); |
| 2230 ASSERT_EQ(observer.GetStateAt(0)->action, |
| 2231 MockTabStripModelObserver::ACTIVATE); |
| 2232 MockTabStripModelObserver::State s1(contents3, 3, |
| 2233 MockTabStripModelObserver::SELECT); |
| 2234 EXPECT_TRUE(observer.StateEquals(1, s1)); |
| 2235 observer.ClearStates(); |
| 2236 |
| 2237 // Adding all tabs to selection, active tab is now at 0. |
| 2238 strip.ExtendSelectionTo(0); |
| 2239 ASSERT_EQ(2, observer.GetStateCount()); |
| 2240 ASSERT_EQ(observer.GetStateAt(0)->action, |
| 2241 MockTabStripModelObserver::ACTIVATE); |
| 2242 MockTabStripModelObserver::State s2(contents0, 0, |
| 2243 MockTabStripModelObserver::SELECT); |
| 2244 s2.src_contents = contents3; |
| 2245 s2.src_index = 3; |
| 2246 EXPECT_TRUE(observer.StateEquals(1, s2)); |
| 2247 observer.ClearStates(); |
| 2248 |
| 2249 // Closing one of the selected tabs, not the active one. |
| 2250 strip.CloseTabContentsAt(1, TabStripModel::CLOSE_NONE); |
| 2251 EXPECT_EQ(3, strip.count()); |
| 2252 ASSERT_EQ(3, observer.GetStateCount()); |
| 2253 ASSERT_EQ(observer.GetStateAt(0)->action, |
| 2254 MockTabStripModelObserver::CLOSE); |
| 2255 ASSERT_EQ(observer.GetStateAt(1)->action, |
| 2256 MockTabStripModelObserver::DETACH); |
| 2257 ASSERT_EQ(observer.GetStateAt(2)->action, |
| 2258 MockTabStripModelObserver::SELECT); |
| 2259 observer.ClearStates(); |
| 2260 |
| 2261 // Closing the active tab, while there are others tabs selected. |
| 2262 strip.CloseTabContentsAt(0, TabStripModel::CLOSE_NONE); |
| 2263 EXPECT_EQ(2, strip.count()); |
| 2264 ASSERT_EQ(4, observer.GetStateCount()); |
| 2265 ASSERT_EQ(observer.GetStateAt(0)->action, |
| 2266 MockTabStripModelObserver::CLOSE); |
| 2267 ASSERT_EQ(observer.GetStateAt(1)->action, |
| 2268 MockTabStripModelObserver::DETACH); |
| 2269 ASSERT_EQ(observer.GetStateAt(2)->action, |
| 2270 MockTabStripModelObserver::ACTIVATE); |
| 2271 ASSERT_EQ(observer.GetStateAt(3)->action, |
| 2272 MockTabStripModelObserver::SELECT); |
| 2273 observer.ClearStates(); |
| 2274 |
| 2275 // Active tab is at 0, deselecting all but the active tab. |
| 2276 strip.ToggleSelectionAt(1); |
| 2277 ASSERT_EQ(1, observer.GetStateCount()); |
| 2278 ASSERT_EQ(observer.GetStateAt(0)->action, |
| 2279 MockTabStripModelObserver::SELECT); |
| 2280 observer.ClearStates(); |
| 2281 |
| 2282 // Attempting to deselect the only selected and therefore active tab, |
| 2283 // it is ignored (no notifications being sent) and tab at 0 remains selected |
| 2284 // and active. |
| 2285 strip.ToggleSelectionAt(0); |
| 2286 ASSERT_EQ(0, observer.GetStateCount()); |
| 2287 |
| 2288 strip.RemoveObserver(&observer); |
| 2289 strip.CloseAllTabs(); |
| 2290 } |
| 2291 |
| 2184 // Verifies that if we change the selection from a multi selection to a single | 2292 // Verifies that if we change the selection from a multi selection to a single |
| 2185 // selection, but not in a way that changes the selected_index that | 2293 // selection, but not in a way that changes the selected_index that |
| 2186 // ActiveTabChanged is still invoked. | 2294 // TabSelectionChanged is invoked. |
| 2187 TEST_F(TabStripModelTest, MultipleToSingle) { | 2295 TEST_F(TabStripModelTest, MultipleToSingle) { |
| 2188 TabStripDummyDelegate delegate(NULL); | 2296 TabStripDummyDelegate delegate(NULL); |
| 2189 TabStripModel strip(&delegate, profile()); | 2297 TabStripModel strip(&delegate, profile()); |
| 2190 TabContentsWrapper* contents1 = CreateTabContents(); | 2298 TabContentsWrapper* contents1 = CreateTabContents(); |
| 2191 TabContentsWrapper* contents2 = CreateTabContents(); | 2299 TabContentsWrapper* contents2 = CreateTabContents(); |
| 2192 strip.AppendTabContents(contents1, false); | 2300 strip.AppendTabContents(contents1, false); |
| 2193 strip.AppendTabContents(contents2, false); | 2301 strip.AppendTabContents(contents2, false); |
| 2194 strip.ToggleSelectionAt(0); | 2302 strip.ToggleSelectionAt(0); |
| 2195 strip.ToggleSelectionAt(1); | 2303 strip.ToggleSelectionAt(1); |
| 2196 | 2304 |
| 2197 MockTabStripModelObserver observer; | 2305 MockTabStripModelObserver observer(&strip); |
| 2306 observer.set_log_tab_selection_changed(true); |
| 2198 strip.AddObserver(&observer); | 2307 strip.AddObserver(&observer); |
| 2199 // This changes the selection (0 is no longer selected) but the selected_index | 2308 // This changes the selection (0 is no longer selected) but the selected_index |
| 2200 // still remains at 1. | 2309 // still remains at 1. |
| 2201 strip.ActivateTabAt(1, true); | 2310 strip.ActivateTabAt(1, true); |
| 2202 ASSERT_EQ(1, observer.GetStateCount()); | 2311 ASSERT_EQ(1, observer.GetStateCount()); |
| 2203 MockTabStripModelObserver::State s( | 2312 MockTabStripModelObserver::State s( |
| 2204 contents2, 1, MockTabStripModelObserver::SELECT); | 2313 contents2, 1, MockTabStripModelObserver::SELECT); |
| 2205 s.src_contents = contents2; | 2314 s.src_contents = contents2; |
| 2206 s.user_gesture = true; | 2315 s.src_index = 1; |
| 2316 s.user_gesture = false; |
| 2207 EXPECT_TRUE(observer.StateEquals(0, s)); | 2317 EXPECT_TRUE(observer.StateEquals(0, s)); |
| 2208 strip.RemoveObserver(&observer); | 2318 strip.RemoveObserver(&observer); |
| 2209 strip.CloseAllTabs(); | 2319 strip.CloseAllTabs(); |
| 2210 } | 2320 } |
| OLD | NEW |