1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/time.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/smooth_scroll_gesture_controller.h"
#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_widget_host_view_port.h"
#include "content/port/browser/smooth_scroll_gesture.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(USE_AURA)
#include "ui/aura/env.h"
#include "ui/aura/test/test_screen.h"
#endif
using base::TimeDelta;
namespace content {
namespace {
class MockSmoothScrollGesture : public SmoothScrollGesture {
public:
MockSmoothScrollGesture() :
called_(0) {
}
// SmoothScrollGesture implementation:
virtual bool ForwardInputEvents(base::TimeTicks now,
RenderWidgetHost* host) OVERRIDE {
++called_;
return true;
}
int called_;
protected:
virtual ~MockSmoothScrollGesture() {
}
};
class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
public:
MockRenderWidgetHostDelegate() {
}
virtual ~MockRenderWidgetHostDelegate() {}
};
class MockRenderWidgetHost : public RenderWidgetHostImpl {
public:
MockRenderWidgetHost(
RenderWidgetHostDelegate* delegate,
RenderProcessHost* process,
int routing_id)
: RenderWidgetHostImpl(delegate, process, routing_id) {
}
virtual ~MockRenderWidgetHost() {}
};
class TestView : public TestRenderWidgetHostView {
public:
explicit TestView(RenderWidgetHostImpl* rwh)
: TestRenderWidgetHostView(rwh),
mock_gesture_(NULL) {
}
virtual ~TestView() {}
// TestRenderWidgetHostView implementation:
virtual SmoothScrollGesture* CreateSmoothScrollGesture(
bool scroll_down, int pixels_to_scroll, int mouse_event_x,
int mouse_event_y) OVERRIDE {
mock_gesture_ = new MockSmoothScrollGesture();
return mock_gesture_;
}
virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE {
return rwh_;
}
MockSmoothScrollGesture* mock_gesture_;
};
class SmoothScrollGestureControllerTest : public testing::Test {
public:
SmoothScrollGestureControllerTest() : process_(NULL) {
}
virtual ~SmoothScrollGestureControllerTest() {}
protected:
// testing::Test implementation:
virtual void SetUp() OVERRIDE {
browser_context_.reset(new TestBrowserContext());
delegate_.reset(new MockRenderWidgetHostDelegate());
process_ = new MockRenderProcessHost(browser_context_.get());
#if defined(USE_AURA)
screen_.reset(aura::TestScreen::Create());
gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
#endif
host_.reset(
new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
view_.reset(new TestView(host_.get()));
host_->SetView(view_.get());
host_->Init();
}
virtual void TearDown() OVERRIDE {
view_.reset();
host_.reset();
delegate_.reset();
process_ = NULL;
browser_context_.reset();
#if defined(USE_AURA)
aura::Env::DeleteInstance();
screen_.reset();
#endif
// Process all pending tasks to avoid leaks.
MessageLoop::current()->RunUntilIdle();
}
void PostQuitMessageAndRun() {
// Allow the message loop to process pending synthetic scrolls, then quit.
MessageLoop::current()->PostDelayedTask(
FROM_HERE, MessageLoop::QuitClosure(),
TimeDelta::FromMilliseconds(
controller_.GetSyntheticScrollMessageInterval().InMilliseconds() *
3));
MessageLoop::current()->Run();
}
MessageLoopForUI message_loop_;
scoped_ptr<TestBrowserContext> browser_context_;
MockRenderProcessHost* process_; // Deleted automatically by the widget.
scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
scoped_ptr<MockRenderWidgetHost> host_;
scoped_ptr<TestView> view_;
#if defined(USE_AURA)
scoped_ptr<gfx::Screen> screen_;
#endif
SmoothScrollGestureController controller_;
};
TEST_F(SmoothScrollGestureControllerTest, Tick) {
ViewHostMsg_BeginSmoothScroll_Params params;
params.scroll_down = true;
params.pixels_to_scroll = 10;
params.mouse_event_x = 20;
params.mouse_event_y = 30;
// Begin a smooth scroll, |mock_gesture_| won't be |called| until we post
// message.
controller_.BeginSmoothScroll(view_.get(), params);
EXPECT_TRUE(view_->mock_gesture_ != NULL);
EXPECT_EQ(0, view_->mock_gesture_->called_);
PostQuitMessageAndRun();
const int current_ticks = view_->mock_gesture_->called_;
EXPECT_LT(0, current_ticks);
// Ensure it won't start another smooth scroll.
MockSmoothScrollGesture* original_gesture = view_->mock_gesture_;
controller_.BeginSmoothScroll(view_.get(), params);
PostQuitMessageAndRun();
EXPECT_EQ(original_gesture, view_->mock_gesture_);
// Ensure the smooth scroll is ticked.
PostQuitMessageAndRun();
EXPECT_LT(current_ticks, view_->mock_gesture_->called_);
}
} // namespace
} // namespace content
|