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. 4 5 #include "ui/views/controls/scrollbar/native_scroll_bar.h" 6 #include "ui/views/controls/scrollbar/native_scroll_bar_views.h" 7 #include "ui/views/controls/scrollbar/scroll_bar.h" 8 #include "ui/views/test/views_test_base.h" 9 #include "ui/views/widget/widget.h" 10 11 namespace { 12 13 // The Scrollbar controller. This is the widget that should do the real 14 // scrolling of contents. 15 class TestScrollBarController : public views::ScrollBarController { 16 public: 17 virtual ~TestScrollBarController() {} 18 19 virtual void ScrollToPosition(views::ScrollBar* source, 20 int position) OVERRIDE { 21 last_source = source; 22 last_position = position; 23 } 24 25 virtual int GetScrollIncrement(views::ScrollBar* source, 26 bool is_page, 27 bool is_positive) OVERRIDE { 28 last_source = source; 29 last_is_page = is_page; 30 last_is_positive = is_positive; 31 32 if (is_page) 33 return 20; 34 return 10; 35 } 36 37 // We save the last values in order to assert the corectness of the scroll 38 // operation. 39 views::ScrollBar* last_source; 40 bool last_is_positive; 41 bool last_is_page; 42 int last_position; 43 }; 44 45 } // namespace 46 47 namespace views { 48 49 class NativeScrollBarTest : public ViewsTestBase { 50 public: 51 NativeScrollBarTest() : widget_(NULL), scrollbar_(NULL) {} 52 53 virtual void SetUp() { 54 ViewsTestBase::SetUp(); 55 controller_.reset(new TestScrollBarController()); 56 57 ASSERT_FALSE(scrollbar_); 58 native_scrollbar_ = new NativeScrollBar(true); 59 native_scrollbar_->SetBounds(0, 0, 100, 100); 60 native_scrollbar_->set_controller(controller_.get()); 61 62 widget_ = new Widget; 63 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 64 params.bounds = gfx::Rect(0, 0, 100, 100); 65 widget_->Init(params); 66 View* container = new View(); 67 widget_->SetContentsView(container); 68 container->AddChildView(native_scrollbar_); 69 70 scrollbar_ = 71 static_cast<NativeScrollBarViews*>(native_scrollbar_->native_wrapper_); 72 scrollbar_->SetBounds(0, 0, 100, 100); 73 scrollbar_->Update(100, 200, 0); 74 75 track_size_ = scrollbar_->GetTrackBounds().width(); 76 } 77 78 virtual void TearDown() { 79 widget_->Close(); 80 ViewsTestBase::TearDown(); 81 } 82 83 protected: 84 Widget* widget_; 85 86 // This is the native scrollbar the Views one wraps around. 87 NativeScrollBar* native_scrollbar_; 88 89 // This is the Views scrollbar. 90 BaseScrollBar* scrollbar_; 91 92 // Keep track of the size of the track. This is how we can tell when we 93 // scroll to the middle. 94 int track_size_; 95 96 scoped_ptr<TestScrollBarController> controller_; 97 }; 98 99 // TODO(dnicoara) Can't run the test on Windows since the scrollbar |Part| 100 // isn't handled in NativeTheme. 101 #if defined(OS_WIN) 102 #define MAYBE_Scrolling DISABLED_Scrolling 103 #define MAYBE_ScrollBarFitsToBottom DISABLED_ScrollBarFitsToBottom 104 #else 105 #define MAYBE_Scrolling Scrolling 106 #define MAYBE_ScrollBarFitsToBottom ScrollBarFitsToBottom 107 #endif 108 109 TEST_F(NativeScrollBarTest, MAYBE_Scrolling) { 110 EXPECT_EQ(scrollbar_->GetPosition(), 0); 111 EXPECT_EQ(scrollbar_->GetMaxPosition(), 100); 112 EXPECT_EQ(scrollbar_->GetMinPosition(), 0); 113 114 // Scroll to middle. 115 scrollbar_->ScrollToThumbPosition(track_size_ / 4, false); 116 EXPECT_EQ(controller_->last_position, 50); 117 EXPECT_EQ(controller_->last_source, native_scrollbar_); 118 119 // Scroll to the end. 120 scrollbar_->ScrollToThumbPosition(track_size_ / 2, false); 121 EXPECT_EQ(controller_->last_position, 100); 122 123 // Overscroll. Last position should be the maximum position. 124 scrollbar_->ScrollToThumbPosition(track_size_, false); 125 EXPECT_EQ(controller_->last_position, 100); 126 127 // Underscroll. Last position should be the minimum position. 128 scrollbar_->ScrollToThumbPosition(-10, false); 129 EXPECT_EQ(controller_->last_position, 0); 130 131 // Test the different fixed scrolling amounts. Generally used by buttons, 132 // or click on track. 133 scrollbar_->ScrollToThumbPosition(0, false); 134 scrollbar_->ScrollByAmount(BaseScrollBar::SCROLL_NEXT_LINE); 135 EXPECT_EQ(controller_->last_position, 10); 136 137 scrollbar_->ScrollByAmount(BaseScrollBar::SCROLL_PREV_LINE); 138 EXPECT_EQ(controller_->last_position, 0); 139 140 scrollbar_->ScrollByAmount(BaseScrollBar::SCROLL_NEXT_PAGE); 141 EXPECT_EQ(controller_->last_position, 20); 142 143 scrollbar_->ScrollByAmount(BaseScrollBar::SCROLL_PREV_PAGE); 144 EXPECT_EQ(controller_->last_position, 0); 145 } 146 147 TEST_F(NativeScrollBarTest, MAYBE_ScrollBarFitsToBottom) { 148 scrollbar_->Update(100, 199, 0); 149 EXPECT_EQ(0, scrollbar_->GetPosition()); 150 EXPECT_EQ(99, scrollbar_->GetMaxPosition()); 151 EXPECT_EQ(0, scrollbar_->GetMinPosition()); 152 153 scrollbar_->Update(100, 199, 99); 154 EXPECT_EQ( 155 scrollbar_->GetTrackBounds().width() - scrollbar_->GetThumbSizeForTest(), 156 scrollbar_->GetPosition()); 157 } 158 159 TEST_F(NativeScrollBarTest, ScrollToEndAfterShrinkAndExpand) { 160 // Scroll to the end of the content. 161 scrollbar_->Update(100, 101, 0); 162 EXPECT_TRUE(scrollbar_->ScrollByContentsOffset(-1)); 163 // Shrink and then re-exapnd the content. 164 scrollbar_->Update(100, 100, 0); 165 scrollbar_->Update(100, 101, 0); 166 // Ensure the scrollbar allows scrolling to the end. 167 EXPECT_TRUE(scrollbar_->ScrollByContentsOffset(-1)); 168 } 169 170 } // namespace views 171