diff options
Diffstat (limited to 'ppapi/proxy/ppp_instance_proxy_test.cc')
-rw-r--r-- | ppapi/proxy/ppp_instance_proxy_test.cc | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/ppapi/proxy/ppp_instance_proxy_test.cc b/ppapi/proxy/ppp_instance_proxy_test.cc new file mode 100644 index 0000000..00d776b --- /dev/null +++ b/ppapi/proxy/ppp_instance_proxy_test.cc @@ -0,0 +1,208 @@ +// Copyright (c) 2011 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/synchronization/waitable_event.h" +#include "ipc/ipc_message_utils.h" +#include "ppapi/c/dev/ppb_fullscreen_dev.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppapi_proxy_test.h" + +namespace pp { +namespace proxy { + +namespace { +// This is a poor man's mock of PPP_Instance using global variables. Eventually +// we should generalize making PPAPI interface mocks by using IDL or macro/ +// template magic. +PP_Instance received_instance; +uint32_t received_argc; +std::vector<std::string> received_argn; +std::vector<std::string> received_argv; +PP_Bool bool_to_return; +PP_Bool DidCreate(PP_Instance instance, uint32_t argc, const char* argn[], + const char* argv[]) { + received_instance = instance; + received_argc = argc; + received_argn.clear(); + received_argn.insert(received_argn.begin(), argn, argn + argc); + received_argv.clear(); + received_argv.insert(received_argv.begin(), argv, argv + argc); + return bool_to_return; +} + +void DidDestroy(PP_Instance instance) { + received_instance = instance; +} + +PP_Rect received_position; +PP_Rect received_clip; +// DidChangeView is asynchronous. We wait until the call has completed before +// proceeding on to the next test. +base::WaitableEvent did_change_view_called(false, false); +void DidChangeView(PP_Instance instance, const PP_Rect* position, + const PP_Rect* clip) { + received_instance = instance; + received_position = *position; + received_clip = *clip; + did_change_view_called.Signal(); +} + +PP_Bool received_has_focus; +base::WaitableEvent did_change_focus_called(false, false); +void DidChangeFocus(PP_Instance instance, PP_Bool has_focus) { + received_instance = instance; + received_has_focus = has_focus; + did_change_focus_called.Signal(); +} + +PP_InputEvent received_event; +PP_Bool HandleInputEvent(PP_Instance instance, const PP_InputEvent* event) { + received_instance = instance; + memcpy(&received_event, event, sizeof(*event));; + return bool_to_return; +} + +PP_Bool HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) { + // This one requires use of the PPB_URLLoader proxy and PPB_Core, plus a + // resource tracker for the url_loader resource. + // TODO(dmichael): Mock those out and test this function. + NOTREACHED(); + return PP_FALSE; +} + +PP_Var var_to_return; +PP_Var GetInstanceObject(PP_Instance instance) { + received_instance = instance; + return var_to_return; +} + +// Clear all the 'received' values for our mock. Call this before you expect +// one of the functions to be invoked. TODO(dmichael): It would be better to +// have a flag also for each function, so we know the right one got called. +void ResetReceived() { + received_instance = 0; + received_argc = 0; + received_argn.clear(); + received_argv.clear(); + memset(&received_position, 0, sizeof(received_position)); + memset(&received_clip, 0, sizeof(received_clip)); + received_has_focus = PP_FALSE; + memset(&received_event, 0, sizeof(received_event)); +} + +PPP_Instance_0_5 ppp_instance_0_5 = { + &DidCreate, + &DidDestroy, + &DidChangeView, + &DidChangeFocus, + &HandleInputEvent, + &HandleDocumentLoad +}; + +// PPP_Instance_Proxy::DidChangeView relies on PPB_FullscreenDev being +// available with a valid implementation of IsFullScreen, so we mock it. +PP_Bool IsFullscreen(PP_Instance instance) { + return PP_FALSE; +} +PPB_Fullscreen_Dev ppb_fullscreen_dev = { &IsFullscreen }; + +} // namespace + +class PPP_Instance_ProxyTest : public TwoWayTest { + public: + PPP_Instance_ProxyTest() + : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) { + } +}; + +TEST_F(PPP_Instance_ProxyTest, PPPInstance0_5) { + plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_0_5, &ppp_instance_0_5); + host().RegisterTestInterface(PPB_FULLSCREEN_DEV_INTERFACE, + &ppb_fullscreen_dev); + + // Grab the host-side proxy for the 0.5 interface. + const PPP_Instance_0_5* ppp_instance = static_cast<const PPP_Instance_0_5*>( + host().host_dispatcher()->GetProxiedInterface( + PPP_INSTANCE_INTERFACE_0_5)); + + // Call each function in turn, make sure we get the expected values and + // returns. + // + // We don't test DidDestroy, because it has the side-effect of removing the + // PP_Instance from the PluginDispatcher, which will cause a failure later + // when the test is torn down. + PP_Instance expected_instance = pp_instance(); + std::vector<std::string> expected_argn, expected_argv; + expected_argn.push_back("Hello"); + expected_argn.push_back("world."); + expected_argv.push_back("elloHay"); + expected_argv.push_back("orldway."); + std::vector<const char*> argn_to_pass, argv_to_pass; + CHECK(expected_argn.size() == expected_argv.size()); + for (size_t i = 0; i < expected_argn.size(); ++i) { + argn_to_pass.push_back(expected_argn[i].c_str()); + argv_to_pass.push_back(expected_argv[i].c_str()); + } + uint32_t expected_argc = expected_argn.size(); + bool_to_return = PP_TRUE; + ResetReceived(); + EXPECT_EQ(bool_to_return, ppp_instance->DidCreate(expected_instance, + expected_argc, + &argn_to_pass[0], + &argv_to_pass[0])); + EXPECT_EQ(received_instance, expected_instance); + EXPECT_EQ(received_argc, expected_argc); + EXPECT_EQ(received_argn, expected_argn); + EXPECT_EQ(received_argv, expected_argv); + + PP_Rect expected_position = { {1, 2}, {3, 4} }; + PP_Rect expected_clip = { {5, 6}, {7, 8} }; + ResetReceived(); + ppp_instance->DidChangeView(expected_instance, &expected_position, + &expected_clip); + did_change_view_called.Wait(); + EXPECT_EQ(received_instance, expected_instance); + EXPECT_EQ(received_position.point.x, expected_position.point.x); + EXPECT_EQ(received_position.point.y, expected_position.point.y); + EXPECT_EQ(received_position.size.width, expected_position.size.width); + EXPECT_EQ(received_position.size.height, expected_position.size.height); + EXPECT_EQ(received_clip.point.x, expected_clip.point.x); + EXPECT_EQ(received_clip.point.y, expected_clip.point.y); + EXPECT_EQ(received_clip.size.width, expected_clip.size.width); + EXPECT_EQ(received_clip.size.height, expected_clip.size.height); + + PP_Bool expected_has_focus = PP_TRUE; + ResetReceived(); + ppp_instance->DidChangeFocus(expected_instance, expected_has_focus); + did_change_focus_called.Wait(); + EXPECT_EQ(received_instance, expected_instance); + EXPECT_EQ(received_has_focus, expected_has_focus); + + PP_InputEvent expected_event = { PP_INPUTEVENT_TYPE_KEYDOWN, // type + 0, // padding + 1.0, // time_stamp + { { 2, 3 } } }; // u (as PP_InputEvent_Key) + ResetReceived(); + EXPECT_EQ(bool_to_return, + ppp_instance->HandleInputEvent(expected_instance, &expected_event)); + EXPECT_EQ(received_instance, expected_instance); + ASSERT_EQ(received_event.type, expected_event.type); + // Ignore padding; it's okay if it's not serialized. + EXPECT_EQ(received_event.time_stamp, expected_event.time_stamp); + EXPECT_EQ(received_event.u.key.modifier, expected_event.u.key.modifier); + EXPECT_EQ(received_event.u.key.key_code, expected_event.u.key.key_code); + + // TODO(dmichael): Need to mock out a resource Tracker to be able to test + // HandleResourceLoad. It also requires + // PPB_Core.AddRefResource and for PPB_URLLoader to be + // registered. +} + +} // namespace proxy +} // namespace pp + |