| Index: ppapi/proxy/ppp_instance_proxy_test.cc
|
| diff --git a/ppapi/proxy/ppp_instance_proxy_test.cc b/ppapi/proxy/ppp_instance_proxy_test.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..15cb716713e69458bc990cb5d79274afe8b06406
|
| --- /dev/null
|
| +++ b/ppapi/proxy/ppp_instance_proxy_test.cc
|
| @@ -0,0 +1,319 @@
|
| +// 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/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_4 ppp_instance_0_4 = {
|
| + &DidCreate,
|
| + &DidDestroy,
|
| + &DidChangeView,
|
| + &DidChangeFocus,
|
| + &HandleInputEvent,
|
| + &HandleDocumentLoad,
|
| + &GetInstanceObject
|
| +};
|
| +
|
| +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_4) {
|
| + plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_0_4, &ppp_instance_0_4);
|
| + host().RegisterTestInterface(PPB_FULLSCREEN_DEV_INTERFACE,
|
| + &ppb_fullscreen_dev);
|
| +
|
| + // Try requesting the 0.5 version, like the browser does. This should come
|
| + // back NULL, since we're not registering 0.5. But this ensures that the
|
| + // behavior through the proxy code reflects more closely what happens for a
|
| + // real plug-in.
|
| + const void* interface =
|
| + host().host_dispatcher()->GetProxiedInterface(PPP_INSTANCE_INTERFACE_0_5);
|
| + EXPECT_EQ(NULL, interface);
|
| +
|
| + // Grab the host-side proxy for the 0.4 interface.
|
| + const PPP_Instance_0_4* ppp_instance = static_cast<const PPP_Instance_0_4*>(
|
| + host().host_dispatcher()->GetProxiedInterface(
|
| + PPP_INSTANCE_INTERFACE_0_4));
|
| +
|
| + // 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);
|
| + // If I define operator== for PP_Rect, it has to come before gtest's template
|
| + // definitions in the translation unit, or else it's not found. So instead of
|
| + // defining operator== before the #include that brings in gtest, I compare the
|
| + // individual parts.
|
| + 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.
|
| +
|
| + var_to_return = PP_MakeInt32(100);
|
| + ResetReceived();
|
| + PP_Var result(ppp_instance->GetInstanceObject(expected_instance));
|
| + ASSERT_EQ(var_to_return.type, result.type);
|
| + EXPECT_EQ(var_to_return.value.as_int, result.value.as_int);
|
| + EXPECT_EQ(received_instance, expected_instance);
|
| +}
|
| +
|
| +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
|
| +
|
|
|