| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/ui/tabs/tab_strip_model.h" | 5 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 }; | 260 }; |
| 261 | 261 |
| 262 class MockTabStripModelObserver : public TabStripModelObserver { | 262 class MockTabStripModelObserver : public TabStripModelObserver { |
| 263 public: | 263 public: |
| 264 MockTabStripModelObserver() | 264 MockTabStripModelObserver() |
| 265 : empty_(true), | 265 : empty_(true), |
| 266 model_(NULL) {} | 266 model_(NULL) {} |
| 267 explicit MockTabStripModelObserver(TabStripModel* model) | 267 explicit MockTabStripModelObserver(TabStripModel* model) |
| 268 : empty_(true), | 268 : empty_(true), |
| 269 model_(model) {} | 269 model_(model) {} |
| 270 virtual ~MockTabStripModelObserver() { | 270 virtual ~MockTabStripModelObserver() {} |
| 271 STLDeleteContainerPointers(states_.begin(), states_.end()); | |
| 272 } | |
| 273 | 271 |
| 274 enum TabStripModelObserverAction { | 272 enum TabStripModelObserverAction { |
| 275 INSERT, | 273 INSERT, |
| 276 CLOSE, | 274 CLOSE, |
| 277 DETACH, | 275 DETACH, |
| 278 ACTIVATE, | 276 ACTIVATE, |
| 279 DEACTIVATE, | 277 DEACTIVATE, |
| 280 SELECT, | 278 SELECT, |
| 281 MOVE, | 279 MOVE, |
| 282 CHANGE, | 280 CHANGE, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 303 int dst_index; | 301 int dst_index; |
| 304 bool user_gesture; | 302 bool user_gesture; |
| 305 bool foreground; | 303 bool foreground; |
| 306 TabStripModelObserverAction action; | 304 TabStripModelObserverAction action; |
| 307 }; | 305 }; |
| 308 | 306 |
| 309 int GetStateCount() const { | 307 int GetStateCount() const { |
| 310 return static_cast<int>(states_.size()); | 308 return static_cast<int>(states_.size()); |
| 311 } | 309 } |
| 312 | 310 |
| 313 State* GetStateAt(int index) const { | 311 State GetStateAt(int index) const { |
| 314 DCHECK(index >= 0 && index < GetStateCount()); | 312 DCHECK(index >= 0 && index < GetStateCount()); |
| 315 return states_[index]; | 313 return states_[index]; |
| 316 } | 314 } |
| 317 | 315 |
| 318 bool StateEquals(int index, const State& state) { | 316 bool StateEquals(int index, const State& state) { |
| 319 State* s = GetStateAt(index); | 317 State s = GetStateAt(index); |
| 320 EXPECT_EQ(state.src_contents, s->src_contents); | 318 return (s.src_contents == state.src_contents && |
| 321 EXPECT_EQ(state.dst_contents, s->dst_contents); | 319 s.dst_contents == state.dst_contents && |
| 322 EXPECT_EQ(state.src_index, s->src_index); | 320 s.src_index == state.src_index && |
| 323 EXPECT_EQ(state.dst_index, s->dst_index); | 321 s.dst_index == state.dst_index && |
| 324 EXPECT_EQ(state.user_gesture, s->user_gesture); | 322 s.user_gesture == state.user_gesture && |
| 325 EXPECT_EQ(state.foreground, s->foreground); | 323 s.foreground == state.foreground && |
| 326 EXPECT_EQ(state.action, s->action); | 324 s.action == state.action); |
| 327 return (s->src_contents == state.src_contents && | |
| 328 s->dst_contents == state.dst_contents && | |
| 329 s->src_index == state.src_index && | |
| 330 s->dst_index == state.dst_index && | |
| 331 s->user_gesture == state.user_gesture && | |
| 332 s->foreground == state.foreground && | |
| 333 s->action == state.action); | |
| 334 } | 325 } |
| 335 | 326 |
| 336 // TabStripModelObserver implementation: | 327 // TabStripModelObserver implementation: |
| 337 virtual void TabInsertedAt(TabContents* contents, | 328 virtual void TabInsertedAt(TabContents* contents, |
| 338 int index, | 329 int index, |
| 339 bool foreground) { | 330 bool foreground) { |
| 340 empty_ = false; | 331 empty_ = false; |
| 341 State* s = new State(contents, index, INSERT); | 332 State s(contents, index, INSERT); |
| 342 s->foreground = foreground; | 333 s.foreground = foreground; |
| 343 states_.push_back(s); | 334 states_.push_back(s); |
| 344 } | 335 } |
| 345 virtual void ActiveTabChanged(TabContents* old_contents, | 336 virtual void ActiveTabChanged(TabContents* old_contents, |
| 346 TabContents* new_contents, | 337 TabContents* new_contents, |
| 347 int index, | 338 int index, |
| 348 bool user_gesture) { | 339 bool user_gesture) { |
| 349 State* s = new State(new_contents, index, ACTIVATE); | 340 State s(new_contents, index, ACTIVATE); |
| 350 s->src_contents = old_contents; | 341 s.src_contents = old_contents; |
| 351 s->user_gesture = user_gesture; | 342 s.user_gesture = user_gesture; |
| 352 states_.push_back(s); | 343 states_.push_back(s); |
| 353 } | 344 } |
| 354 virtual void TabSelectionChanged(TabStripModel* tab_strip_model, | 345 virtual void TabSelectionChanged(TabStripModel* tab_strip_model, |
| 355 const TabStripSelectionModel& old_model) { | 346 const TabStripSelectionModel& old_model) { |
| 356 State* s = new State(model()->GetActiveTabContents(), | 347 State s(model()->GetActiveTabContents(), model()->active_index(), SELECT); |
| 357 model()->active_index(), | 348 s.src_contents = model()->GetTabContentsAt(old_model.active()); |
| 358 SELECT); | 349 s.src_index = old_model.active(); |
| 359 s->src_contents = model()->GetTabContentsAt(old_model.active()); | |
| 360 s->src_index = old_model.active(); | |
| 361 states_.push_back(s); | 350 states_.push_back(s); |
| 362 } | 351 } |
| 363 virtual void TabMoved(TabContents* contents, int from_index, int to_index) { | 352 virtual void TabMoved(TabContents* contents, int from_index, int to_index) { |
| 364 State* s = new State(contents, to_index, MOVE); | 353 State s(contents, to_index, MOVE); |
| 365 s->src_index = from_index; | 354 s.src_index = from_index; |
| 366 states_.push_back(s); | 355 states_.push_back(s); |
| 367 } | 356 } |
| 368 | 357 |
| 369 virtual void TabClosingAt(TabStripModel* tab_strip_model, | 358 virtual void TabClosingAt(TabStripModel* tab_strip_model, |
| 370 TabContents* contents, | 359 TabContents* contents, |
| 371 int index) { | 360 int index) { |
| 372 states_.push_back(new State(contents, index, CLOSE)); | 361 states_.push_back(State(contents, index, CLOSE)); |
| 373 } | 362 } |
| 374 virtual void TabDetachedAt(TabContents* contents, int index) { | 363 virtual void TabDetachedAt(TabContents* contents, int index) { |
| 375 states_.push_back(new State(contents, index, DETACH)); | 364 states_.push_back(State(contents, index, DETACH)); |
| 376 } | 365 } |
| 377 virtual void TabDeactivated(TabContents* contents) { | 366 virtual void TabDeactivated(TabContents* contents) { |
| 378 states_.push_back(new State(contents, model()->active_index(), DEACTIVATE)); | 367 states_.push_back(State(contents, model()->active_index(), DEACTIVATE)); |
| 379 } | 368 } |
| 380 virtual void TabChangedAt(TabContents* contents, int index, | 369 virtual void TabChangedAt(TabContents* contents, int index, |
| 381 TabChangeType change_type) { | 370 TabChangeType change_type) { |
| 382 states_.push_back(new State(contents, index, CHANGE)); | 371 states_.push_back(State(contents, index, CHANGE)); |
| 383 } | 372 } |
| 384 virtual void TabReplacedAt(TabStripModel* tab_strip_model, | 373 virtual void TabReplacedAt(TabStripModel* tab_strip_model, |
| 385 TabContents* old_contents, | 374 TabContents* old_contents, |
| 386 TabContents* new_contents, | 375 TabContents* new_contents, |
| 387 int index) { | 376 int index) { |
| 388 State* s = new State(new_contents, index, REPLACED); | 377 State s(new_contents, index, REPLACED); |
| 389 s ->src_contents = old_contents; | 378 s.src_contents = old_contents; |
| 390 states_.push_back(s); | 379 states_.push_back(s); |
| 391 } | 380 } |
| 392 virtual void TabPinnedStateChanged(TabContents* contents, int index) { | 381 virtual void TabPinnedStateChanged(TabContents* contents, int index) { |
| 393 states_.push_back(new State(contents, index, PINNED)); | 382 states_.push_back(State(contents, index, PINNED)); |
| 394 } | 383 } |
| 395 virtual void TabStripEmpty() { | 384 virtual void TabStripEmpty() { |
| 396 empty_ = true; | 385 empty_ = true; |
| 397 } | 386 } |
| 398 | 387 |
| 399 void ClearStates() { | 388 void ClearStates() { |
| 400 STLDeleteContainerPointers(states_.begin(), states_.end()); | |
| 401 states_.clear(); | 389 states_.clear(); |
| 402 } | 390 } |
| 403 | 391 |
| 404 bool empty() const { return empty_; } | 392 bool empty() const { return empty_; } |
| 405 TabStripModel* model() { return model_; } | 393 TabStripModel* model() { return model_; } |
| 406 | 394 |
| 407 private: | 395 private: |
| 408 std::vector<State*> states_; | 396 std::vector<State> states_; |
| 409 | 397 |
| 410 bool empty_; | 398 bool empty_; |
| 411 TabStripModel* model_; | 399 TabStripModel* model_; |
| 412 | 400 |
| 413 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver); | 401 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver); |
| 414 }; | 402 }; |
| 415 | 403 |
| 416 TEST_F(TabStripModelTest, TestBasicAPI) { | 404 TEST_F(TabStripModelTest, TestBasicAPI) { |
| 417 TabStripDummyDelegate delegate(NULL); | 405 TabStripDummyDelegate delegate(NULL); |
| 418 TabStripModel tabstrip(&delegate, profile()); | 406 TabStripModel tabstrip(&delegate, profile()); |
| (...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2319 TabContents* contents3 = CreateTabContents(); | 2307 TabContents* contents3 = CreateTabContents(); |
| 2320 strip.AppendTabContents(contents0, false); | 2308 strip.AppendTabContents(contents0, false); |
| 2321 strip.AppendTabContents(contents1, false); | 2309 strip.AppendTabContents(contents1, false); |
| 2322 strip.AppendTabContents(contents2, false); | 2310 strip.AppendTabContents(contents2, false); |
| 2323 strip.AppendTabContents(contents3, false); | 2311 strip.AppendTabContents(contents3, false); |
| 2324 strip.AddObserver(&observer); | 2312 strip.AddObserver(&observer); |
| 2325 | 2313 |
| 2326 // Selection and active tab change. | 2314 // Selection and active tab change. |
| 2327 strip.ActivateTabAt(3, true); | 2315 strip.ActivateTabAt(3, true); |
| 2328 ASSERT_EQ(2, observer.GetStateCount()); | 2316 ASSERT_EQ(2, observer.GetStateCount()); |
| 2329 ASSERT_EQ(observer.GetStateAt(0)->action, | 2317 ASSERT_EQ(observer.GetStateAt(0).action, |
| 2330 MockTabStripModelObserver::ACTIVATE); | 2318 MockTabStripModelObserver::ACTIVATE); |
| 2331 MockTabStripModelObserver::State s1(contents3, 3, | 2319 MockTabStripModelObserver::State s1(contents3, 3, |
| 2332 MockTabStripModelObserver::SELECT); | 2320 MockTabStripModelObserver::SELECT); |
| 2333 EXPECT_TRUE(observer.StateEquals(1, s1)); | 2321 EXPECT_TRUE(observer.StateEquals(1, s1)); |
| 2334 observer.ClearStates(); | 2322 observer.ClearStates(); |
| 2335 | 2323 |
| 2336 // Adding all tabs to selection, active tab is now at 0. | 2324 // Adding all tabs to selection, active tab is now at 0. |
| 2337 strip.ExtendSelectionTo(0); | 2325 strip.ExtendSelectionTo(0); |
| 2338 ASSERT_EQ(3, observer.GetStateCount()); | 2326 ASSERT_EQ(3, observer.GetStateCount()); |
| 2339 ASSERT_EQ(observer.GetStateAt(0)->action, | 2327 ASSERT_EQ(observer.GetStateAt(0).action, |
| 2340 MockTabStripModelObserver::DEACTIVATE); | 2328 MockTabStripModelObserver::DEACTIVATE); |
| 2341 ASSERT_EQ(observer.GetStateAt(1)->action, | 2329 ASSERT_EQ(observer.GetStateAt(1).action, |
| 2342 MockTabStripModelObserver::ACTIVATE); | 2330 MockTabStripModelObserver::ACTIVATE); |
| 2343 MockTabStripModelObserver::State s2(contents0, 0, | 2331 MockTabStripModelObserver::State s2(contents0, 0, |
| 2344 MockTabStripModelObserver::SELECT); | 2332 MockTabStripModelObserver::SELECT); |
| 2345 s2.src_contents = contents3; | 2333 s2.src_contents = contents3; |
| 2346 s2.src_index = 3; | 2334 s2.src_index = 3; |
| 2347 EXPECT_TRUE(observer.StateEquals(2, s2)); | 2335 EXPECT_TRUE(observer.StateEquals(2, s2)); |
| 2348 observer.ClearStates(); | 2336 observer.ClearStates(); |
| 2349 | 2337 |
| 2350 // Toggle the active tab, should make the next index active. | 2338 // Toggle the active tab, should make the next index active. |
| 2351 strip.ToggleSelectionAt(0); | 2339 strip.ToggleSelectionAt(0); |
| 2352 EXPECT_EQ(1, strip.active_index()); | 2340 EXPECT_EQ(1, strip.active_index()); |
| 2353 EXPECT_EQ(3U, strip.selection_model().size()); | 2341 EXPECT_EQ(3U, strip.selection_model().size()); |
| 2354 EXPECT_EQ(4, strip.count()); | 2342 EXPECT_EQ(4, strip.count()); |
| 2355 ASSERT_EQ(3, observer.GetStateCount()); | 2343 ASSERT_EQ(3, observer.GetStateCount()); |
| 2356 ASSERT_EQ(observer.GetStateAt(0)->action, | 2344 ASSERT_EQ(observer.GetStateAt(0).action, |
| 2357 MockTabStripModelObserver::DEACTIVATE); | 2345 MockTabStripModelObserver::DEACTIVATE); |
| 2358 ASSERT_EQ(observer.GetStateAt(1)->action, | 2346 ASSERT_EQ(observer.GetStateAt(1).action, |
| 2359 MockTabStripModelObserver::ACTIVATE); | 2347 MockTabStripModelObserver::ACTIVATE); |
| 2360 ASSERT_EQ(observer.GetStateAt(2)->action, | 2348 ASSERT_EQ(observer.GetStateAt(2).action, |
| 2361 MockTabStripModelObserver::SELECT); | 2349 MockTabStripModelObserver::SELECT); |
| 2362 observer.ClearStates(); | 2350 observer.ClearStates(); |
| 2363 | 2351 |
| 2364 // Toggle the first tab back to selected and active. | 2352 // Toggle the first tab back to selected and active. |
| 2365 strip.ToggleSelectionAt(0); | 2353 strip.ToggleSelectionAt(0); |
| 2366 EXPECT_EQ(0, strip.active_index()); | 2354 EXPECT_EQ(0, strip.active_index()); |
| 2367 EXPECT_EQ(4U, strip.selection_model().size()); | 2355 EXPECT_EQ(4U, strip.selection_model().size()); |
| 2368 EXPECT_EQ(4, strip.count()); | 2356 EXPECT_EQ(4, strip.count()); |
| 2369 ASSERT_EQ(3, observer.GetStateCount()); | 2357 ASSERT_EQ(3, observer.GetStateCount()); |
| 2370 ASSERT_EQ(observer.GetStateAt(0)->action, | 2358 ASSERT_EQ(observer.GetStateAt(0).action, |
| 2371 MockTabStripModelObserver::DEACTIVATE); | 2359 MockTabStripModelObserver::DEACTIVATE); |
| 2372 ASSERT_EQ(observer.GetStateAt(1)->action, | 2360 ASSERT_EQ(observer.GetStateAt(1).action, |
| 2373 MockTabStripModelObserver::ACTIVATE); | 2361 MockTabStripModelObserver::ACTIVATE); |
| 2374 ASSERT_EQ(observer.GetStateAt(2)->action, | 2362 ASSERT_EQ(observer.GetStateAt(2).action, |
| 2375 MockTabStripModelObserver::SELECT); | 2363 MockTabStripModelObserver::SELECT); |
| 2376 observer.ClearStates(); | 2364 observer.ClearStates(); |
| 2377 | 2365 |
| 2378 // Closing one of the selected tabs, not the active one. | 2366 // Closing one of the selected tabs, not the active one. |
| 2379 strip.CloseTabContentsAt(1, TabStripModel::CLOSE_NONE); | 2367 strip.CloseTabContentsAt(1, TabStripModel::CLOSE_NONE); |
| 2380 EXPECT_EQ(3, strip.count()); | 2368 EXPECT_EQ(3, strip.count()); |
| 2381 ASSERT_EQ(3, observer.GetStateCount()); | 2369 ASSERT_EQ(3, observer.GetStateCount()); |
| 2382 ASSERT_EQ(observer.GetStateAt(0)->action, | 2370 ASSERT_EQ(observer.GetStateAt(0).action, |
| 2383 MockTabStripModelObserver::CLOSE); | 2371 MockTabStripModelObserver::CLOSE); |
| 2384 ASSERT_EQ(observer.GetStateAt(1)->action, | 2372 ASSERT_EQ(observer.GetStateAt(1).action, |
| 2385 MockTabStripModelObserver::DETACH); | 2373 MockTabStripModelObserver::DETACH); |
| 2386 ASSERT_EQ(observer.GetStateAt(2)->action, | 2374 ASSERT_EQ(observer.GetStateAt(2).action, |
| 2387 MockTabStripModelObserver::SELECT); | 2375 MockTabStripModelObserver::SELECT); |
| 2388 observer.ClearStates(); | 2376 observer.ClearStates(); |
| 2389 | 2377 |
| 2390 // Closing the active tab, while there are others tabs selected. | 2378 // Closing the active tab, while there are others tabs selected. |
| 2391 strip.CloseTabContentsAt(0, TabStripModel::CLOSE_NONE); | 2379 strip.CloseTabContentsAt(0, TabStripModel::CLOSE_NONE); |
| 2392 EXPECT_EQ(2, strip.count()); | 2380 EXPECT_EQ(2, strip.count()); |
| 2393 ASSERT_EQ(5, observer.GetStateCount()); | 2381 ASSERT_EQ(5, observer.GetStateCount()); |
| 2394 ASSERT_EQ(observer.GetStateAt(0)->action, | 2382 ASSERT_EQ(observer.GetStateAt(0).action, |
| 2395 MockTabStripModelObserver::CLOSE); | 2383 MockTabStripModelObserver::CLOSE); |
| 2396 ASSERT_EQ(observer.GetStateAt(1)->action, | 2384 ASSERT_EQ(observer.GetStateAt(1).action, |
| 2397 MockTabStripModelObserver::DETACH); | 2385 MockTabStripModelObserver::DETACH); |
| 2398 ASSERT_EQ(observer.GetStateAt(2)->action, | 2386 ASSERT_EQ(observer.GetStateAt(2).action, |
| 2399 MockTabStripModelObserver::DEACTIVATE); | 2387 MockTabStripModelObserver::DEACTIVATE); |
| 2400 ASSERT_EQ(observer.GetStateAt(3)->action, | 2388 ASSERT_EQ(observer.GetStateAt(3).action, |
| 2401 MockTabStripModelObserver::ACTIVATE); | 2389 MockTabStripModelObserver::ACTIVATE); |
| 2402 ASSERT_EQ(observer.GetStateAt(4)->action, | 2390 ASSERT_EQ(observer.GetStateAt(4).action, |
| 2403 MockTabStripModelObserver::SELECT); | 2391 MockTabStripModelObserver::SELECT); |
| 2404 observer.ClearStates(); | 2392 observer.ClearStates(); |
| 2405 | 2393 |
| 2406 // Active tab is at 0, deselecting all but the active tab. | 2394 // Active tab is at 0, deselecting all but the active tab. |
| 2407 strip.ToggleSelectionAt(1); | 2395 strip.ToggleSelectionAt(1); |
| 2408 ASSERT_EQ(1, observer.GetStateCount()); | 2396 ASSERT_EQ(1, observer.GetStateCount()); |
| 2409 ASSERT_EQ(observer.GetStateAt(0)->action, | 2397 ASSERT_EQ(observer.GetStateAt(0).action, |
| 2410 MockTabStripModelObserver::SELECT); | 2398 MockTabStripModelObserver::SELECT); |
| 2411 observer.ClearStates(); | 2399 observer.ClearStates(); |
| 2412 | 2400 |
| 2413 // Attempting to deselect the only selected and therefore active tab, | 2401 // Attempting to deselect the only selected and therefore active tab, |
| 2414 // it is ignored (no notifications being sent) and tab at 0 remains selected | 2402 // it is ignored (no notifications being sent) and tab at 0 remains selected |
| 2415 // and active. | 2403 // and active. |
| 2416 strip.ToggleSelectionAt(0); | 2404 strip.ToggleSelectionAt(0); |
| 2417 ASSERT_EQ(0, observer.GetStateCount()); | 2405 ASSERT_EQ(0, observer.GetStateCount()); |
| 2418 | 2406 |
| 2419 strip.RemoveObserver(&observer); | 2407 strip.RemoveObserver(&observer); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2441 ASSERT_EQ(1, observer.GetStateCount()); | 2429 ASSERT_EQ(1, observer.GetStateCount()); |
| 2442 MockTabStripModelObserver::State s( | 2430 MockTabStripModelObserver::State s( |
| 2443 contents2, 1, MockTabStripModelObserver::SELECT); | 2431 contents2, 1, MockTabStripModelObserver::SELECT); |
| 2444 s.src_contents = contents2; | 2432 s.src_contents = contents2; |
| 2445 s.src_index = 1; | 2433 s.src_index = 1; |
| 2446 s.user_gesture = false; | 2434 s.user_gesture = false; |
| 2447 EXPECT_TRUE(observer.StateEquals(0, s)); | 2435 EXPECT_TRUE(observer.StateEquals(0, s)); |
| 2448 strip.RemoveObserver(&observer); | 2436 strip.RemoveObserver(&observer); |
| 2449 strip.CloseAllTabs(); | 2437 strip.CloseAllTabs(); |
| 2450 } | 2438 } |
| OLD | NEW |