| OLD | NEW |
| (Empty) |
| 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 "chromeos/dbus/ibus/ibus_client.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/message_loop/message_loop.h" | |
| 9 #include "base/values.h" | |
| 10 #include "chromeos/dbus/ibus/ibus_constants.h" | |
| 11 #include "dbus/message.h" | |
| 12 #include "dbus/mock_bus.h" | |
| 13 #include "dbus/mock_object_proxy.h" | |
| 14 #include "dbus/object_path.h" | |
| 15 #include "dbus/values_util.h" | |
| 16 #include "testing/gmock/include/gmock/gmock.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | |
| 18 | |
| 19 using testing::Invoke; | |
| 20 using testing::Return; | |
| 21 using testing::_; | |
| 22 | |
| 23 namespace chromeos { | |
| 24 | |
| 25 namespace { | |
| 26 const char kClientName[] = "chrome"; | |
| 27 const char kEngineName[] = "engine"; | |
| 28 const bool kRestartFlag = true; | |
| 29 } // namespace | |
| 30 | |
| 31 class MockCreateInputContextCallback { | |
| 32 public: | |
| 33 MOCK_METHOD1(Run, void(const dbus::ObjectPath& object_path)); | |
| 34 }; | |
| 35 | |
| 36 class MockErrorCallback { | |
| 37 public: | |
| 38 MOCK_METHOD0(Run, void()); | |
| 39 }; | |
| 40 | |
| 41 class IBusClientTest : public testing::Test { | |
| 42 public: | |
| 43 IBusClientTest() : response_(NULL) {} | |
| 44 | |
| 45 // Handles CreateInputContext method call. | |
| 46 void OnCreateInputContext( | |
| 47 dbus::MethodCall* method_call, | |
| 48 int timeout_ms, | |
| 49 const dbus::ObjectProxy::ResponseCallback& callback, | |
| 50 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
| 51 dbus::MessageReader reader(method_call); | |
| 52 std::string client_name; | |
| 53 EXPECT_TRUE(reader.PopString(&client_name)); | |
| 54 EXPECT_EQ(kClientName, client_name); | |
| 55 EXPECT_FALSE(reader.HasMoreData()); | |
| 56 | |
| 57 message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_)); | |
| 58 } | |
| 59 | |
| 60 // Handles fail case of CreateInputContext method call. | |
| 61 void OnCreateInputContextFail( | |
| 62 dbus::MethodCall* method_call, | |
| 63 int timeout_ms, | |
| 64 const dbus::ObjectProxy::ResponseCallback& callback, | |
| 65 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
| 66 dbus::MessageReader reader(method_call); | |
| 67 std::string client_name; | |
| 68 EXPECT_TRUE(reader.PopString(&client_name)); | |
| 69 EXPECT_EQ(kClientName, client_name); | |
| 70 EXPECT_FALSE(reader.HasMoreData()); | |
| 71 | |
| 72 message_loop_.PostTask(FROM_HERE, base::Bind(error_callback, | |
| 73 error_response_)); | |
| 74 } | |
| 75 | |
| 76 // Handles SetGlobalEngine method call. | |
| 77 void OnSetGlobalEngine( | |
| 78 dbus::MethodCall* method_call, | |
| 79 int timeout_ms, | |
| 80 const dbus::ObjectProxy::ResponseCallback& callback, | |
| 81 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
| 82 dbus::MessageReader reader(method_call); | |
| 83 std::string engine_name; | |
| 84 EXPECT_TRUE(reader.PopString(&engine_name)); | |
| 85 EXPECT_EQ(kEngineName, engine_name); | |
| 86 EXPECT_FALSE(reader.HasMoreData()); | |
| 87 message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_)); | |
| 88 } | |
| 89 | |
| 90 // Handles fail case of SetGlobalEngine method call. | |
| 91 void OnSetGlobalEngineFail( | |
| 92 dbus::MethodCall* method_call, | |
| 93 int timeout_ms, | |
| 94 const dbus::ObjectProxy::ResponseCallback& callback, | |
| 95 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
| 96 dbus::MessageReader reader(method_call); | |
| 97 std::string engine_name; | |
| 98 EXPECT_TRUE(reader.PopString(&engine_name)); | |
| 99 EXPECT_EQ(kEngineName, engine_name); | |
| 100 EXPECT_FALSE(reader.HasMoreData()); | |
| 101 message_loop_.PostTask(FROM_HERE, base::Bind(error_callback, | |
| 102 error_response_)); | |
| 103 } | |
| 104 | |
| 105 // Handles Exit method call. | |
| 106 void OnExit(dbus::MethodCall* method_call, | |
| 107 int timeout_ms, | |
| 108 const dbus::ObjectProxy::ResponseCallback& callback, | |
| 109 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
| 110 dbus::MessageReader reader(method_call); | |
| 111 bool restart = false; | |
| 112 EXPECT_TRUE(reader.PopBool(&restart)); | |
| 113 EXPECT_EQ(kRestartFlag, restart); | |
| 114 EXPECT_FALSE(reader.HasMoreData()); | |
| 115 message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_)); | |
| 116 } | |
| 117 | |
| 118 // Handles fail case of Exit method call. | |
| 119 void OnExitFail(dbus::MethodCall* method_call, | |
| 120 int timeout_ms, | |
| 121 const dbus::ObjectProxy::ResponseCallback& callback, | |
| 122 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
| 123 dbus::MessageReader reader(method_call); | |
| 124 bool restart = false; | |
| 125 EXPECT_TRUE(reader.PopBool(&restart)); | |
| 126 EXPECT_EQ(kRestartFlag, restart); | |
| 127 EXPECT_FALSE(reader.HasMoreData()); | |
| 128 message_loop_.PostTask(FROM_HERE, base::Bind(error_callback, | |
| 129 error_response_)); | |
| 130 } | |
| 131 | |
| 132 protected: | |
| 133 virtual void SetUp() OVERRIDE { | |
| 134 dbus::Bus::Options options; | |
| 135 mock_bus_ = new dbus::MockBus(options); | |
| 136 mock_proxy_ = new dbus::MockObjectProxy(mock_bus_.get(), | |
| 137 ibus::kServiceName, | |
| 138 dbus::ObjectPath( | |
| 139 ibus::bus::kServicePath)); | |
| 140 EXPECT_CALL(*mock_bus_.get(), | |
| 141 GetObjectProxy(ibus::kServiceName, | |
| 142 dbus::ObjectPath(ibus::bus::kServicePath))) | |
| 143 .WillOnce(Return(mock_proxy_.get())); | |
| 144 | |
| 145 EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()); | |
| 146 client_.reset( | |
| 147 IBusClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION, mock_bus_.get())); | |
| 148 } | |
| 149 | |
| 150 virtual void TearDown() OVERRIDE { | |
| 151 mock_bus_->ShutdownAndBlock(); | |
| 152 } | |
| 153 | |
| 154 // The IBus client to be tested. | |
| 155 scoped_ptr<IBusClient> client_; | |
| 156 | |
| 157 // A message loop to emulate asynchronous behavior. | |
| 158 base::MessageLoop message_loop_; | |
| 159 scoped_refptr<dbus::MockBus> mock_bus_; | |
| 160 scoped_refptr<dbus::MockObjectProxy> mock_proxy_; | |
| 161 | |
| 162 // Response returned by mock methods. | |
| 163 dbus::Response* response_; | |
| 164 dbus::ErrorResponse* error_response_; | |
| 165 }; | |
| 166 | |
| 167 TEST_F(IBusClientTest, CreateInputContextTest) { | |
| 168 // Set expectations. | |
| 169 const dbus::ObjectPath kInputContextObjectPath = | |
| 170 dbus::ObjectPath("/some/object/path"); | |
| 171 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 172 .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext)); | |
| 173 MockCreateInputContextCallback callback; | |
| 174 EXPECT_CALL(callback, Run(kInputContextObjectPath)); | |
| 175 MockErrorCallback error_callback; | |
| 176 EXPECT_CALL(error_callback, Run()).Times(0); | |
| 177 | |
| 178 // Create response. | |
| 179 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
| 180 dbus::MessageWriter writer(response.get()); | |
| 181 writer.AppendObjectPath(kInputContextObjectPath); | |
| 182 response_ = response.get(); | |
| 183 | |
| 184 // Call CreateInputContext. | |
| 185 client_->CreateInputContext( | |
| 186 kClientName, | |
| 187 base::Bind(&MockCreateInputContextCallback::Run, | |
| 188 base::Unretained(&callback)), | |
| 189 base::Bind(&MockErrorCallback::Run, | |
| 190 base::Unretained(&error_callback))); | |
| 191 | |
| 192 // Run the message loop. | |
| 193 message_loop_.RunUntilIdle(); | |
| 194 } | |
| 195 | |
| 196 TEST_F(IBusClientTest, CreateInputContext_NullResponseFail) { | |
| 197 // Set expectations. | |
| 198 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 199 .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext)); | |
| 200 MockCreateInputContextCallback callback; | |
| 201 EXPECT_CALL(callback, Run(_)).Times(0); | |
| 202 MockErrorCallback error_callback; | |
| 203 EXPECT_CALL(error_callback, Run()); | |
| 204 | |
| 205 // Set NULL response. | |
| 206 response_ = NULL; | |
| 207 | |
| 208 // Call CreateInputContext. | |
| 209 client_->CreateInputContext( | |
| 210 kClientName, | |
| 211 base::Bind(&MockCreateInputContextCallback::Run, | |
| 212 base::Unretained(&callback)), | |
| 213 base::Bind(&MockErrorCallback::Run, | |
| 214 base::Unretained(&error_callback))); | |
| 215 | |
| 216 // Run the message loop. | |
| 217 message_loop_.RunUntilIdle(); | |
| 218 } | |
| 219 | |
| 220 TEST_F(IBusClientTest, CreateInputContext_InvalidResponseFail) { | |
| 221 // Set expectations. | |
| 222 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 223 .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext)); | |
| 224 MockCreateInputContextCallback callback; | |
| 225 EXPECT_CALL(callback, Run(_)).Times(0); | |
| 226 MockErrorCallback error_callback; | |
| 227 EXPECT_CALL(error_callback, Run()); | |
| 228 | |
| 229 // Create invalid(empty) response. | |
| 230 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
| 231 response_ = response.get(); | |
| 232 | |
| 233 // Call CreateInputContext. | |
| 234 client_->CreateInputContext( | |
| 235 kClientName, | |
| 236 base::Bind(&MockCreateInputContextCallback::Run, | |
| 237 base::Unretained(&callback)), | |
| 238 base::Bind(&MockErrorCallback::Run, | |
| 239 base::Unretained(&error_callback))); | |
| 240 | |
| 241 // Run the message loop. | |
| 242 message_loop_.RunUntilIdle(); | |
| 243 } | |
| 244 | |
| 245 TEST_F(IBusClientTest, CreateInputContext_MethodCallFail) { | |
| 246 // Set expectations | |
| 247 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 248 .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContextFail)); | |
| 249 MockCreateInputContextCallback callback; | |
| 250 EXPECT_CALL(callback, Run(_)).Times(0); | |
| 251 MockErrorCallback error_callback; | |
| 252 EXPECT_CALL(error_callback, Run()); | |
| 253 | |
| 254 // The error response is not used in CreateInputContext. | |
| 255 error_response_ = NULL; | |
| 256 | |
| 257 // Call CreateInputContext. | |
| 258 client_->CreateInputContext( | |
| 259 kClientName, | |
| 260 base::Bind(&MockCreateInputContextCallback::Run, | |
| 261 base::Unretained(&callback)), | |
| 262 base::Bind(&MockErrorCallback::Run, | |
| 263 base::Unretained(&error_callback))); | |
| 264 | |
| 265 // Run the message loop. | |
| 266 message_loop_.RunUntilIdle(); | |
| 267 } | |
| 268 | |
| 269 TEST_F(IBusClientTest, SetGlobalEngineTest) { | |
| 270 // Set expectations | |
| 271 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 272 .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngine)); | |
| 273 MockErrorCallback error_callback; | |
| 274 EXPECT_CALL(error_callback, Run()).Times(0); | |
| 275 | |
| 276 // Create empty response. | |
| 277 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
| 278 response_ = response.get(); | |
| 279 | |
| 280 // The error response is not used in SetGLobalEngine. | |
| 281 error_response_ = NULL; | |
| 282 | |
| 283 // Call CreateInputContext. | |
| 284 client_->SetGlobalEngine( | |
| 285 kEngineName, | |
| 286 base::Bind(&MockErrorCallback::Run, | |
| 287 base::Unretained(&error_callback))); | |
| 288 | |
| 289 // Run the message loop. | |
| 290 message_loop_.RunUntilIdle(); | |
| 291 } | |
| 292 | |
| 293 TEST_F(IBusClientTest, SetGlobalEngineTest_InvalidResponse) { | |
| 294 // Set expectations | |
| 295 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 296 .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngineFail)); | |
| 297 MockErrorCallback error_callback; | |
| 298 EXPECT_CALL(error_callback, Run()); | |
| 299 | |
| 300 // Set invalid response. | |
| 301 response_ = NULL; | |
| 302 | |
| 303 // The error response is not used in SetGLobalEngine. | |
| 304 error_response_ = NULL; | |
| 305 | |
| 306 // Call CreateInputContext. | |
| 307 client_->SetGlobalEngine( | |
| 308 kEngineName, | |
| 309 base::Bind(&MockErrorCallback::Run, | |
| 310 base::Unretained(&error_callback))); | |
| 311 | |
| 312 // Run the message loop. | |
| 313 message_loop_.RunUntilIdle(); | |
| 314 } | |
| 315 | |
| 316 TEST_F(IBusClientTest, SetGlobalEngineTest_MethodCallFail) { | |
| 317 // Set expectations | |
| 318 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 319 .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngineFail)); | |
| 320 MockErrorCallback error_callback; | |
| 321 EXPECT_CALL(error_callback, Run()); | |
| 322 | |
| 323 // Create empty response. | |
| 324 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
| 325 response_ = response.get(); | |
| 326 | |
| 327 // The error response is not used in SetGLobalEngine. | |
| 328 error_response_ = NULL; | |
| 329 | |
| 330 // Call CreateInputContext. | |
| 331 client_->SetGlobalEngine( | |
| 332 kEngineName, | |
| 333 base::Bind(&MockErrorCallback::Run, | |
| 334 base::Unretained(&error_callback))); | |
| 335 | |
| 336 // Run the message loop. | |
| 337 message_loop_.RunUntilIdle(); | |
| 338 } | |
| 339 | |
| 340 TEST_F(IBusClientTest, ExitTest) { | |
| 341 // Set expectations | |
| 342 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 343 .WillOnce(Invoke(this, &IBusClientTest::OnExit)); | |
| 344 MockErrorCallback error_callback; | |
| 345 EXPECT_CALL(error_callback, Run()).Times(0); | |
| 346 | |
| 347 // Create empty response. | |
| 348 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
| 349 response_ = response.get(); | |
| 350 | |
| 351 // The error response is not used in SetGLobalEngine. | |
| 352 error_response_ = NULL; | |
| 353 | |
| 354 // Call CreateInputContext. | |
| 355 client_->Exit( | |
| 356 IBusClient::RESTART_IBUS_DAEMON, | |
| 357 base::Bind(&MockErrorCallback::Run, | |
| 358 base::Unretained(&error_callback))); | |
| 359 | |
| 360 // Run the message loop. | |
| 361 message_loop_.RunUntilIdle(); | |
| 362 } | |
| 363 | |
| 364 TEST_F(IBusClientTest, ExitTest_InvalidResponse) { | |
| 365 // Set expectations | |
| 366 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 367 .WillOnce(Invoke(this, &IBusClientTest::OnExit)); | |
| 368 MockErrorCallback error_callback; | |
| 369 EXPECT_CALL(error_callback, Run()); | |
| 370 | |
| 371 // Set invalid response. | |
| 372 response_ = NULL; | |
| 373 | |
| 374 // The error response is not used in SetGLobalEngine. | |
| 375 error_response_ = NULL; | |
| 376 | |
| 377 // Call CreateInputContext. | |
| 378 client_->Exit( | |
| 379 IBusClient::RESTART_IBUS_DAEMON, | |
| 380 base::Bind(&MockErrorCallback::Run, | |
| 381 base::Unretained(&error_callback))); | |
| 382 | |
| 383 // Run the message loop. | |
| 384 message_loop_.RunUntilIdle(); | |
| 385 } | |
| 386 | |
| 387 TEST_F(IBusClientTest, ExitTest_MethodCallFail) { | |
| 388 // Set expectations | |
| 389 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
| 390 .WillOnce(Invoke(this, &IBusClientTest::OnExitFail)); | |
| 391 MockErrorCallback error_callback; | |
| 392 EXPECT_CALL(error_callback, Run()); | |
| 393 | |
| 394 // Create empty response. | |
| 395 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
| 396 response_ = response.get(); | |
| 397 | |
| 398 // The error response is not used in SetGLobalEngine. | |
| 399 error_response_ = NULL; | |
| 400 | |
| 401 // Call CreateInputContext. | |
| 402 client_->Exit( | |
| 403 IBusClient::RESTART_IBUS_DAEMON, | |
| 404 base::Bind(&MockErrorCallback::Run, | |
| 405 base::Unretained(&error_callback))); | |
| 406 | |
| 407 // Run the message loop. | |
| 408 message_loop_.RunUntilIdle(); | |
| 409 } | |
| 410 | |
| 411 } // namespace chromeos | |
| OLD | NEW |