Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(450)

Side by Side Diff: chrome/renderer/render_widget_unittest.cc

Issue 16482: Refactor the render widget unittest so it can be reused to create a render vi... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/render_view_unittest.cc ('k') | chrome/test/unit/unittests.vcproj » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "testing/gtest/include/gtest/gtest.h" 5 #include "testing/gtest/include/gtest/gtest.h"
6 6
7 #include "base/ref_counted.h" 7 #include "base/ref_counted.h"
8 #include "chrome/common/child_process.h" 8 #include "chrome/renderer/mock_render_process.h"
9 #include "chrome/renderer/mock_render_thread.h"
9 #include "chrome/renderer/render_widget.h" 10 #include "chrome/renderer/render_widget.h"
10 #include "chrome/renderer/render_thread.h" 11 #include "chrome/renderer/render_thread.h"
11 12
12 // This class is a trivial mock of the child process singleton. It is necessary 13 namespace {
13 // so we don't trip DCHECKs in ChildProcess::ReleaseProcess() when destroying 14
14 // a render widget instance. 15 const int32 kRouteId = 5;
15 class MockProcess : public ChildProcess { 16 const int32 kOpenerId = 7;
17
18 class RenderWidgetTest : public testing::Test {
16 public: 19 public:
17 explicit MockProcess(const std::wstring& channel_name) {} 20
18 static void GlobalInit() { 21 protected:
19 ChildProcessFactory<MockProcess> factory; 22 MessageLoop msg_loop_;
20 ChildProcess::GlobalInit(L"dummy", &factory); 23 MockRenderThread render_thread_;
24
25 // The widget, each test should verify this is non-NULL before continuing.
26 scoped_refptr<RenderWidget> widget_;
27
28 private:
29 // testing::Test
30 virtual void SetUp() {
31 MockProcess::GlobalInit();
32
33 render_thread_.set_routing_id(kRouteId);
34 widget_ = RenderWidget::Create(kOpenerId, &render_thread_, true);
35 ASSERT_TRUE(widget_);
36 }
37 virtual void TearDown() {
38 widget_ = NULL;
39
40 // There is a delayed task that the child process posts to terminate the
41 // message loop so we need to spin the message loop to delete the task.
42 MockProcess::GlobalCleanup();
43 msg_loop_.Run();
21 } 44 }
22 }; 45 };
23 46
24 // This class is very simple mock of RenderThread. It simulates an IPC channel 47 } // namespace
25 // which supports only two messages:
26 // ViewHostMsg_CreateWidget : sync message sent by the Widget.
27 // ViewMsg_Close : async, send to the Widget.
28 class MockRenderThread : public RenderThreadBase {
29 public:
30 MockRenderThread()
31 : routing_id_(0), opener_id_(0), widget_(NULL),
32 reply_deserializer_(NULL) {
33 }
34 virtual ~MockRenderThread() {
35 }
36 48
37 // Called by the Widget. Not used in the test. 49 TEST_F(RenderWidgetTest, CreateAndCloseWidget) {
38 virtual bool InSend() const {
39 return false;
40 }
41
42 // Called by the Widget. The routing_id must match the routing id assigned
43 // to the Widget in reply to ViewHostMsg_CreateWidget message.
44 virtual void AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
45 EXPECT_EQ(routing_id_, routing_id);
46 widget_ = listener;
47 }
48
49 // Called by the Widget. The routing id must match the routing id of AddRoute.
50 virtual void RemoveRoute(int32 routing_id) {
51 EXPECT_EQ(routing_id_, routing_id);
52 widget_ = NULL;
53 }
54
55 // Called by the Widget. Used to send messages to the browser.
56 // We short-circuit the mechanim and handle the messages right here on this
57 // class.
58 virtual bool Send(IPC::Message* msg) {
59 // We need to simulate a synchronous channel, thus we are going to receive
60 // through this function messages, messages with reply and reply messages.
61 // We can only handle one synchronous message at a time.
62 if (msg->is_reply()) {
63 if (reply_deserializer_)
64 reply_deserializer_->SerializeOutputParameters(*msg);
65 delete reply_deserializer_;
66 reply_deserializer_ = NULL;
67 } else {
68 if (msg->is_sync()) {
69 reply_deserializer_ =
70 static_cast<IPC::SyncMessage*>(msg)->GetReplyDeserializer();
71 }
72 OnMessageReceived(*msg);
73 }
74 delete msg;
75 return true;
76 }
77
78 //////////////////////////////////////////////////////////////////////////
79 // The following functions are called by the test itself.
80
81 void set_routing_id(int32 id) {
82 routing_id_ = id;
83 }
84
85 int32 opener_id() const {
86 return opener_id_;
87 }
88
89 bool has_widget() const {
90 return widget_ ? true : false;
91 }
92
93 // Simulates the Widget receiving a close message. This should result
94 // on releasing the internal reference counts and destroying the internal
95 // state.
96 void SendCloseMessage() {
97 ViewMsg_Close msg(routing_id_);
98 widget_->OnMessageReceived(msg);
99 }
100
101 private:
102
103 // This function operates as a regular IPC listener.
104 void OnMessageReceived(const IPC::Message& msg) {
105 bool handled = true;
106 bool msg_is_ok = true;
107 IPC_BEGIN_MESSAGE_MAP_EX(MockRenderThread, msg, msg_is_ok)
108 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnMsgCreateWidget);
109 IPC_MESSAGE_UNHANDLED(handled = false)
110 IPC_END_MESSAGE_MAP_EX()
111
112 // This test must handle all messages that RenderWidget generates.
113 EXPECT_TRUE(handled);
114 }
115
116 // The Widget expects to be returned valid route_id.
117 void OnMsgCreateWidget(int opener_id,
118 bool focus_on_show,
119 int* route_id) {
120 opener_id_ = opener_id;
121 *route_id = routing_id_;
122 }
123
124 // Routing id what will be assigned to the Widget.
125 int32 routing_id_;
126 // Opener id reported by the Widget.
127 int32 opener_id_;
128 // We only keep track of one Widget, we learn its pointer when it
129 // adds a new route.
130 IPC::Channel::Listener* widget_;
131 // The last known good deserializer for sync messages.
132 IPC::MessageReplyDeserializer* reply_deserializer_;
133 };
134
135 TEST(RenderWidgetTest, CreateAndCloseWidget) {
136 MessageLoop msg_loop;
137 MockRenderThread render_thread;
138 MockProcess::GlobalInit();
139
140 const int32 kRouteId = 5;
141 const int32 kOpenerId = 7;
142 render_thread.set_routing_id(kRouteId);
143
144 {
145 scoped_refptr<RenderWidget> rw =
146 RenderWidget::Create(kOpenerId, &render_thread, true);
147 ASSERT_TRUE(rw != NULL);
148
149 // After the RenderWidget it must have sent a message to the render thread 50 // After the RenderWidget it must have sent a message to the render thread
150 // that sets the opener id. 51 // that sets the opener id.
151 EXPECT_EQ(kOpenerId, render_thread.opener_id()); 52 EXPECT_EQ(kOpenerId, render_thread_.opener_id());
152 ASSERT_TRUE(render_thread.has_widget()); 53 ASSERT_TRUE(render_thread_.has_widget());
153 54
154 // Now simulate a close of the Widget. 55 // Now simulate a close of the Widget.
155 render_thread.SendCloseMessage(); 56 render_thread_.SendCloseMessage();
156 EXPECT_FALSE(render_thread.has_widget()); 57 EXPECT_FALSE(render_thread_.has_widget());
157 58
158 // Run the loop so the release task from the renderwidget executes. 59 // Run the loop so the release task from the renderwidget executes.
159 msg_loop.PostTask(FROM_HERE, new MessageLoop::QuitTask()); 60 msg_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask());
160 msg_loop.Run(); 61 msg_loop_.Run();
161 } 62 }
162
163 // There is a delayed task that the child process posts to terminate the
164 // message loop so we need to spin the message loop to delete the task.
165 MockProcess::GlobalCleanup();
166 msg_loop.Run();
167 }
OLDNEW
« no previous file with comments | « chrome/renderer/render_view_unittest.cc ('k') | chrome/test/unit/unittests.vcproj » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698