Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / recent_tabs_sub_menu_model_unittest.cc
blobdcdeedf7c453ad2acf0dfcda68c075b7b7732fb6
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h"
7 #include <string>
8 #include <vector>
10 #include "base/command_line.h"
11 #include "base/run_loop.h"
12 #include "chrome/app/chrome_command_ids.h"
13 #include "chrome/browser/sessions/persistent_tab_restore_service.h"
14 #include "chrome/browser/sessions/session_service.h"
15 #include "chrome/browser/sessions/session_service_factory.h"
16 #include "chrome/browser/sessions/session_types.h"
17 #include "chrome/browser/sessions/tab_restore_service_factory.h"
18 #include "chrome/browser/sync/glue/synced_session.h"
19 #include "chrome/browser/sync/profile_sync_service_mock.h"
20 #include "chrome/browser/sync/sessions/sessions_sync_manager.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_tabstrip.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/test/base/browser_with_test_window_test.h"
27 #include "chrome/test/base/menu_model_test.h"
28 #include "chrome/test/base/testing_profile.h"
29 #include "components/sessions/serialized_navigation_entry_test_helper.h"
30 #include "components/sync_driver/local_device_info_provider_mock.h"
31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/test/test_utils.h"
33 #include "grit/generated_resources.h"
34 #include "sync/api/fake_sync_change_processor.h"
35 #include "sync/api/sync_error_factory_mock.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
39 namespace {
41 // This copies parts of MenuModelTest::Delegate and combines them with the
42 // RecentTabsSubMenuModel since RecentTabsSubMenuModel is a
43 // SimpleMenuModel::Delegate and not just derived from SimpleMenuModel.
44 class TestRecentTabsSubMenuModel : public RecentTabsSubMenuModel {
45 public:
46 TestRecentTabsSubMenuModel(ui::AcceleratorProvider* provider,
47 Browser* browser,
48 browser_sync::OpenTabsUIDelegate* delegate)
49 : RecentTabsSubMenuModel(provider, browser, delegate),
50 execute_count_(0),
51 enable_count_(0) {
54 // Testing overrides to ui::SimpleMenuModel::Delegate:
55 virtual bool IsCommandIdEnabled(int command_id) const override {
56 bool val = RecentTabsSubMenuModel::IsCommandIdEnabled(command_id);
57 if (val)
58 ++enable_count_;
59 return val;
62 virtual void ExecuteCommand(int command_id, int event_flags) override {
63 ++execute_count_;
66 int execute_count() const { return execute_count_; }
67 int enable_count() const { return enable_count_; }
69 private:
70 int execute_count_;
71 int mutable enable_count_; // Mutable because IsCommandIdEnabledAt is const.
73 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsSubMenuModel);
76 class TestRecentTabsMenuModelDelegate : public ui::MenuModelDelegate {
77 public:
78 explicit TestRecentTabsMenuModelDelegate(ui::MenuModel* model)
79 : model_(model),
80 got_changes_(false) {
81 model_->SetMenuModelDelegate(this);
84 virtual ~TestRecentTabsMenuModelDelegate() {
85 model_->SetMenuModelDelegate(NULL);
88 // ui::MenuModelDelegate implementation:
90 virtual void OnIconChanged(int index) override {
93 virtual void OnMenuStructureChanged() override {
94 got_changes_ = true;
97 bool got_changes() const { return got_changes_; }
99 private:
100 ui::MenuModel* model_;
101 bool got_changes_;
103 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsMenuModelDelegate);
106 class DummyRouter : public browser_sync::LocalSessionEventRouter {
107 public:
108 virtual ~DummyRouter() {}
109 virtual void StartRoutingTo(
110 browser_sync::LocalSessionEventHandler* handler) override {}
111 virtual void Stop() override {}
114 } // namespace
116 class RecentTabsSubMenuModelTest
117 : public BrowserWithTestWindowTest {
118 public:
119 RecentTabsSubMenuModelTest()
120 : sync_service_(&testing_profile_),
121 local_device_(new sync_driver::LocalDeviceInfoProviderMock(
122 "RecentTabsSubMenuModelTest",
123 "Test Machine",
124 "Chromium 10k",
125 "Chrome 10k",
126 sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
127 "device_id")) {
128 manager_.reset(new browser_sync::SessionsSyncManager(
129 &testing_profile_,
130 local_device_.get(),
131 scoped_ptr<browser_sync::LocalSessionEventRouter>(
132 new DummyRouter())));
133 manager_->MergeDataAndStartSyncing(
134 syncer::SESSIONS,
135 syncer::SyncDataList(),
136 scoped_ptr<syncer::SyncChangeProcessor>(
137 new syncer::FakeSyncChangeProcessor),
138 scoped_ptr<syncer::SyncErrorFactory>(
139 new syncer::SyncErrorFactoryMock));
142 void WaitForLoadFromLastSession() {
143 content::RunAllBlockingPoolTasksUntilIdle();
146 static KeyedService* GetTabRestoreService(
147 content::BrowserContext* browser_context) {
148 // Ownership is tranfered to the profile.
149 return new PersistentTabRestoreService(
150 Profile::FromBrowserContext(browser_context), NULL);
153 browser_sync::OpenTabsUIDelegate* GetOpenTabsDelegate() {
154 return manager_.get();
157 void RegisterRecentTabs(RecentTabsBuilderTestHelper* helper) {
158 helper->ExportToSessionsSyncManager(manager_.get());
161 private:
162 TestingProfile testing_profile_;
163 testing::NiceMock<ProfileSyncServiceMock> sync_service_;
165 scoped_ptr<browser_sync::SessionsSyncManager> manager_;
166 scoped_ptr<sync_driver::LocalDeviceInfoProviderMock> local_device_;
169 // Test disabled "Recently closed" header with no foreign tabs.
170 TEST_F(RecentTabsSubMenuModelTest, NoTabs) {
171 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
173 // Expected menu:
174 // Menu index Menu items
175 // ---------------------------------------------
176 // 0 Recently closed header (disabled)
177 // 1 <separator>
178 // 2 No tabs from other Devices
180 int num_items = model.GetItemCount();
181 EXPECT_EQ(3, num_items);
182 EXPECT_FALSE(model.IsEnabledAt(0));
183 EXPECT_FALSE(model.IsEnabledAt(2));
184 EXPECT_EQ(0, model.enable_count());
186 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
187 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
188 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
190 std::string url;
191 base::string16 title;
192 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
193 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
194 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
197 // Test enabled "Recently closed" header with no foreign tabs.
198 TEST_F(RecentTabsSubMenuModelTest, RecentlyClosedTabsFromCurrentSession) {
199 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
200 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
202 // Add 2 tabs and close them.
203 AddTab(browser(), GURL("http://foo/1"));
204 AddTab(browser(), GURL("http://foo/2"));
205 browser()->tab_strip_model()->CloseAllTabs();
207 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
208 // Expected menu:
209 // Menu index Menu items
210 // --------------------------------------
211 // 0 Recently closed header
212 // 1 <tab for http://foo/2>
213 // 2 <tab for http://foo/1>
214 // 3 <separator>
215 // 4 No tabs from other Devices
216 int num_items = model.GetItemCount();
217 EXPECT_EQ(5, num_items);
218 EXPECT_FALSE(model.IsEnabledAt(0));
219 EXPECT_TRUE(model.IsEnabledAt(1));
220 EXPECT_TRUE(model.IsEnabledAt(2));
221 model.ActivatedAt(1);
222 model.ActivatedAt(2);
223 EXPECT_FALSE(model.IsEnabledAt(4));
224 EXPECT_EQ(2, model.enable_count());
225 EXPECT_EQ(2, model.execute_count());
227 EXPECT_TRUE(model.GetLabelFontListAt(0) != NULL);
228 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
229 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
230 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
231 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
233 std::string url;
234 base::string16 title;
235 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
236 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
237 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
238 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
239 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
242 // TODO(sail): enable this test when dynamic model is enabled in
243 // RecentTabsSubMenuModel.
244 #if defined(OS_MACOSX)
245 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
246 DISABLED_RecentlyClosedTabsAndWindowsFromLastSession
247 #else
248 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
249 RecentlyClosedTabsAndWindowsFromLastSession
250 #endif
251 TEST_F(RecentTabsSubMenuModelTest,
252 MAYBE_RecentlyClosedTabsAndWindowsFromLastSession) {
253 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
254 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
256 // Add 2 tabs and close them.
257 AddTab(browser(), GURL("http://wnd/tab0"));
258 AddTab(browser(), GURL("http://wnd/tab1"));
259 browser()->tab_strip_model()->CloseAllTabs();
261 // Create a SessionService for the profile (profile owns the service) and add
262 // a window with a tab to this session.
263 SessionService* session_service = new SessionService(profile());
264 SessionServiceFactory::SetForTestProfile(profile(), session_service);
265 SessionID tab_id;
266 SessionID window_id;
267 session_service->SetWindowType(
268 window_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
269 session_service->SetTabWindow(window_id, tab_id);
270 session_service->SetTabIndexInWindow(window_id, tab_id, 0);
271 session_service->SetSelectedTabInWindow(window_id, 0);
272 session_service->UpdateTabNavigation(
273 window_id, tab_id,
274 sessions::SerializedNavigationEntryTestHelper::CreateNavigation(
275 "http://wnd1/tab0", "title"));
276 // Set this, otherwise previous session won't be loaded.
277 profile()->set_last_session_exited_cleanly(false);
278 // Move this session to the last so that TabRestoreService will load it as the
279 // last session.
280 SessionServiceFactory::GetForProfile(profile())->
281 MoveCurrentSessionToLastSession();
283 // Create a new TabRestoreService so that it'll load the recently closed tabs
284 // and windows afresh.
285 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
286 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
287 // Let the shutdown of previous TabRestoreService run.
288 content::RunAllBlockingPoolTasksUntilIdle();
290 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
291 TestRecentTabsMenuModelDelegate delegate(&model);
292 EXPECT_FALSE(delegate.got_changes());
294 // Expected menu before tabs/windows from last session are loaded:
295 // Menu index Menu items
296 // ----------------------------------------------------------------
297 // 0 Recently closed header
298 // 1 <separator>
299 // 2 No tabs from other Devices
301 int num_items = model.GetItemCount();
302 EXPECT_EQ(3, num_items);
303 EXPECT_FALSE(model.IsEnabledAt(0));
304 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(1));
305 EXPECT_FALSE(model.IsEnabledAt(2));
306 EXPECT_EQ(0, model.enable_count());
308 // Wait for tabs from last session to be loaded.
309 WaitForLoadFromLastSession();
311 // Expected menu after tabs/windows from last session are loaded:
312 // Menu index Menu items
313 // --------------------------------------------------------------
314 // 0 Recently closed header
315 // 1 <window for the tab http://wnd1/tab0>
316 // 2 <tab for http://wnd0/tab1>
317 // 3 <tab for http://wnd0/tab0>
318 // 4 <separator>
319 // 5 No tabs from other Devices
321 EXPECT_TRUE(delegate.got_changes());
323 num_items = model.GetItemCount();
324 EXPECT_EQ(6, num_items);
325 EXPECT_FALSE(model.IsEnabledAt(0));
326 EXPECT_TRUE(model.IsEnabledAt(1));
327 EXPECT_TRUE(model.IsEnabledAt(2));
328 EXPECT_TRUE(model.IsEnabledAt(3));
329 model.ActivatedAt(1);
330 model.ActivatedAt(2);
331 model.ActivatedAt(3);
332 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(4));
333 EXPECT_FALSE(model.IsEnabledAt(5));
334 EXPECT_EQ(3, model.enable_count());
335 EXPECT_EQ(3, model.execute_count());
337 EXPECT_TRUE(model.GetLabelFontListAt(0) != NULL);
338 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
339 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
340 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
341 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
342 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
344 std::string url;
345 base::string16 title;
346 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
347 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
348 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
349 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
350 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
351 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
354 // Test disabled "Recently closed" header with multiple sessions, multiple
355 // windows, and multiple enabled tabs from other devices.
356 TEST_F(RecentTabsSubMenuModelTest, OtherDevices) {
357 // Tabs are populated in decreasing timestamp.
358 base::Time timestamp = base::Time::Now();
359 const base::TimeDelta time_delta = base::TimeDelta::FromMinutes(10);
361 RecentTabsBuilderTestHelper recent_tabs_builder;
363 // Create 1st session : 1 window, 3 tabs
364 recent_tabs_builder.AddSession();
365 recent_tabs_builder.AddWindow(0);
366 for (int i = 0; i < 3; ++i) {
367 timestamp -= time_delta;
368 recent_tabs_builder.AddTabWithInfo(0, 0, timestamp, base::string16());
371 // Create 2nd session : 2 windows, 1 tab in 1st window, 2 tabs in 2nd window
372 recent_tabs_builder.AddSession();
373 recent_tabs_builder.AddWindow(1);
374 recent_tabs_builder.AddWindow(1);
375 timestamp -= time_delta;
376 recent_tabs_builder.AddTabWithInfo(1, 0, timestamp, base::string16());
377 timestamp -= time_delta;
378 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
379 timestamp -= time_delta;
380 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
382 RegisterRecentTabs(&recent_tabs_builder);
384 // Verify that data is populated correctly in RecentTabsSubMenuModel.
385 // Expected menu:
386 // - first inserted tab is most recent and hence is top
387 // Menu index Menu items
388 // -----------------------------------------------------
389 // 0 Recently closed header (disabled)
390 // 1 <separator>
391 // 2 <section header for 1st session>
392 // 3-5 <3 tabs of the only window of session 0>
393 // 6 <separator>
394 // 7 <section header for 2nd session>
395 // 8 <the only tab of window 0 of session 1>
396 // 9-10 <2 tabs of window 1 of session 2>
397 // 11 <separator>
398 // 12 More...
400 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
401 int num_items = model.GetItemCount();
402 EXPECT_EQ(13, num_items);
403 model.ActivatedAt(0);
404 EXPECT_FALSE(model.IsEnabledAt(0));
405 model.ActivatedAt(3);
406 EXPECT_TRUE(model.IsEnabledAt(3));
407 model.ActivatedAt(4);
408 EXPECT_TRUE(model.IsEnabledAt(4));
409 model.ActivatedAt(5);
410 EXPECT_TRUE(model.IsEnabledAt(5));
411 model.ActivatedAt(8);
412 EXPECT_TRUE(model.IsEnabledAt(8));
413 model.ActivatedAt(9);
414 EXPECT_TRUE(model.IsEnabledAt(9));
415 model.ActivatedAt(10);
416 EXPECT_TRUE(model.IsEnabledAt(10));
417 EXPECT_TRUE(model.IsEnabledAt(12));
418 EXPECT_EQ(7, model.enable_count());
419 EXPECT_EQ(7, model.execute_count());
421 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
422 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
423 EXPECT_TRUE(model.GetLabelFontListAt(2) != NULL);
424 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
425 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
426 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
427 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
428 EXPECT_TRUE(model.GetLabelFontListAt(7) != NULL);
429 EXPECT_EQ(NULL, model.GetLabelFontListAt(8));
430 EXPECT_EQ(NULL, model.GetLabelFontListAt(9));
431 EXPECT_EQ(NULL, model.GetLabelFontListAt(10));
432 EXPECT_EQ(NULL, model.GetLabelFontListAt(11));
433 EXPECT_EQ(NULL, model.GetLabelFontListAt(12));
435 std::string url;
436 base::string16 title;
437 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
438 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
439 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
440 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
441 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
442 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
443 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
444 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(7, &url, &title));
445 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(8, &url, &title));
446 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(9, &url, &title));
447 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(10, &url, &title));
448 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(11, &url, &title));
449 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(12, &url, &title));
452 TEST_F(RecentTabsSubMenuModelTest, MaxSessionsAndRecency) {
453 // Create 4 sessions : each session has 1 window with 1 tab each.
454 RecentTabsBuilderTestHelper recent_tabs_builder;
455 for (int s = 0; s < 4; ++s) {
456 recent_tabs_builder.AddSession();
457 recent_tabs_builder.AddWindow(s);
458 recent_tabs_builder.AddTab(s, 0);
460 RegisterRecentTabs(&recent_tabs_builder);
462 // Verify that data is populated correctly in RecentTabsSubMenuModel.
463 // Expected menu:
464 // - max sessions is 3, so only 3 most-recent sessions will show.
465 // Menu index Menu items
466 // ----------------------------------------------------------
467 // 0 Recently closed header (disabled)
468 // 1 <separator>
469 // 2 <section header for 1st session>
470 // 3 <the only tab of the only window of session 3>
471 // 4 <separator>
472 // 5 <section header for 2nd session>
473 // 6 <the only tab of the only window of session 2>
474 // 7 <separator>
475 // 8 <section header for 3rd session>
476 // 9 <the only tab of the only window of session 1>
477 // 10 <separator>
478 // 11 More...
480 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
481 int num_items = model.GetItemCount();
482 EXPECT_EQ(12, num_items);
484 std::vector<base::string16> tab_titles =
485 recent_tabs_builder.GetTabTitlesSortedByRecency();
486 EXPECT_EQ(tab_titles[0], model.GetLabelAt(3));
487 EXPECT_EQ(tab_titles[1], model.GetLabelAt(6));
488 EXPECT_EQ(tab_titles[2], model.GetLabelAt(9));
491 TEST_F(RecentTabsSubMenuModelTest, MaxTabsPerSessionAndRecency) {
492 // Create a session: 2 windows with 5 tabs each.
493 RecentTabsBuilderTestHelper recent_tabs_builder;
494 recent_tabs_builder.AddSession();
495 for (int w = 0; w < 2; ++w) {
496 recent_tabs_builder.AddWindow(0);
497 for (int t = 0; t < 5; ++t)
498 recent_tabs_builder.AddTab(0, w);
500 RegisterRecentTabs(&recent_tabs_builder);
502 // Verify that data is populated correctly in RecentTabsSubMenuModel.
503 // Expected menu:
504 // - max tabs per session is 4, so only 4 most-recent tabs will show,
505 // independent of which window they came from.
506 // Menu index Menu items
507 // ---------------------------------------------
508 // 0 Recently closed header (disabled)
509 // 1 <separator>
510 // 2 <section header for session>
511 // 3-6 <4 most-recent tabs of session>
512 // 7 <separator>
513 // 8 More...
515 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
516 int num_items = model.GetItemCount();
517 EXPECT_EQ(9, num_items);
519 std::vector<base::string16> tab_titles =
520 recent_tabs_builder.GetTabTitlesSortedByRecency();
521 for (int i = 0; i < 4; ++i)
522 EXPECT_EQ(tab_titles[i], model.GetLabelAt(i + 3));
525 TEST_F(RecentTabsSubMenuModelTest, MaxWidth) {
526 // Create 1 session with 1 window and 1 tab.
527 RecentTabsBuilderTestHelper recent_tabs_builder;
528 recent_tabs_builder.AddSession();
529 recent_tabs_builder.AddWindow(0);
530 recent_tabs_builder.AddTab(0, 0);
531 RegisterRecentTabs(&recent_tabs_builder);
533 // Menu index Menu items
534 // ----------------------------------------------------------
535 // 0 Recently closed header (disabled)
536 // 1 <separator>
537 // 2 <section header for 1st session>
538 // 3 <the only tab of the only window of session 1>
539 // 4 <separator>
540 // 5 More...
542 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
543 EXPECT_EQ(6, model.GetItemCount());
544 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(0));
545 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(1));
546 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(2));
547 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(3));
550 TEST_F(RecentTabsSubMenuModelTest, MaxWidthNoDevices) {
551 // Expected menu:
552 // Menu index Menu items
553 // --------------------------------------------
554 // 0 Recently closed heaer (disabled)
555 // 1 <separator>
556 // 2 No tabs from other Devices
558 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
559 EXPECT_EQ(3, model.GetItemCount());
560 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(0));
561 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(1));
562 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(2));