summaryrefslogtreecommitdiffstats
path: root/ppapi/tests/test_input_event.cc
diff options
context:
space:
mode:
authorbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-20 21:18:07 +0000
committerbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-20 21:18:07 +0000
commited33e2eb202e0efc5bba8f275fd126aebdc91ada (patch)
tree5560e2bd728baaca0c72f4b31f03dc9761090e64 /ppapi/tests/test_input_event.cc
parent52dc84021b685da622a96e0d0c35dbc3f1197ada (diff)
downloadchromium_src-ed33e2eb202e0efc5bba8f275fd126aebdc91ada.zip
chromium_src-ed33e2eb202e0efc5bba8f275fd126aebdc91ada.tar.gz
chromium_src-ed33e2eb202e0efc5bba8f275fd126aebdc91ada.tar.bz2
Add functions to generate input events to PPB_Testing_Dev. These make
it possible to test APIs that require user gestures and other input events. BUG=none TEST=none Review URL: http://codereview.chromium.org/8413021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110865 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/tests/test_input_event.cc')
-rw-r--r--ppapi/tests/test_input_event.cc290
1 files changed, 290 insertions, 0 deletions
diff --git a/ppapi/tests/test_input_event.cc b/ppapi/tests/test_input_event.cc
new file mode 100644
index 0000000..378a677
--- /dev/null
+++ b/ppapi/tests/test_input_event.cc
@@ -0,0 +1,290 @@
+// 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 "ppapi/tests/test_input_event.h"
+
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_input_event.h"
+#include "ppapi/cpp/input_event.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/test_utils.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(InputEvent);
+
+namespace {
+
+const uint32_t kSpaceChar = 0x20;
+const char* kSpaceString = " ";
+
+#define FINISHED_WAITING_MESSAGE "TEST_INPUT_EVENT_FINISHED_WAITING"
+
+pp::Point GetCenter(const pp::Rect& rect) {
+ return pp::Point(
+ rect.x() + rect.width() / 2,
+ rect.y() + rect.height() / 2);
+}
+}
+
+void TestInputEvent::RunTests(const std::string& filter) {
+ RUN_TEST(Events, filter);
+}
+
+TestInputEvent::TestInputEvent(TestingInstance* instance)
+ : TestCase(instance),
+ input_event_interface_(NULL),
+ mouse_input_event_interface_(NULL),
+ wheel_input_event_interface_(NULL),
+ keyboard_input_event_interface_(NULL),
+ view_rect_(),
+ expected_input_event_(0),
+ received_expected_event_(false),
+ received_finish_message_(false) {
+}
+
+TestInputEvent::~TestInputEvent() {
+ // Remove the special listener that only responds to a
+ // FINISHED_WAITING_MESSAGE string. See Init for where it gets added.
+ std::string js_code;
+ js_code += "var plugin = document.getElementById('plugin');"
+ "plugin.removeEventListener('message',"
+ " plugin.wait_for_messages_handler);"
+ "delete plugin.wait_for_messages_handler;";
+ pp::Var exception;
+ instance_->ExecuteScript(js_code, &exception);
+}
+
+bool TestInputEvent::Init() {
+ input_event_interface_ = static_cast<PPB_InputEvent const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_INPUT_EVENT_INTERFACE));
+ mouse_input_event_interface_ = static_cast<PPB_MouseInputEvent const*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_MOUSE_INPUT_EVENT_INTERFACE));
+ wheel_input_event_interface_ = static_cast<PPB_WheelInputEvent const*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_WHEEL_INPUT_EVENT_INTERFACE));
+ keyboard_input_event_interface_ = static_cast<PPB_KeyboardInputEvent const*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_KEYBOARD_INPUT_EVENT_INTERFACE));
+
+ bool success =
+ input_event_interface_ &&
+ mouse_input_event_interface_ &&
+ wheel_input_event_interface_ &&
+ keyboard_input_event_interface_ &&
+ InitTestingInterface();
+
+ // Set up a listener for our message that signals that all input events have
+ // been received.
+ std::string js_code;
+ // Note the following code is dependent on some features of test_case.html.
+ // E.g., it is assumed that the DOM element where the plugin is embedded has
+ // an id of 'plugin', and there is a function 'IsTestingMessage' that allows
+ // us to ignore the messages that are intended for use by the testing
+ // framework itself.
+ js_code += "var plugin = document.getElementById('plugin');"
+ "var wait_for_messages_handler = function(message_event) {"
+ " if (!IsTestingMessage(message_event.data) &&"
+ " message_event.data === '" FINISHED_WAITING_MESSAGE "') {"
+ " plugin.postMessage('" FINISHED_WAITING_MESSAGE "');"
+ " }"
+ "};"
+ "plugin.addEventListener('message', wait_for_messages_handler);"
+ // Stash it on the plugin so we can remove it in the destructor.
+ "plugin.wait_for_messages_handler = wait_for_messages_handler;";
+ pp::Var exception;
+ instance_->ExecuteScript(js_code, &exception);
+ success = success && exception.is_undefined();
+
+ return success;
+}
+
+pp::InputEvent TestInputEvent::CreateMouseEvent(
+ PP_InputEvent_Type type,
+ PP_InputEvent_MouseButton buttons) {
+ return pp::MouseInputEvent(
+ instance_,
+ type,
+ 100, // time_stamp
+ 0, // modifiers
+ buttons,
+ GetCenter(view_rect_),
+ 1, // click count
+ pp::Point()); // movement
+}
+
+pp::InputEvent TestInputEvent::CreateWheelEvent() {
+ return pp::WheelInputEvent(
+ instance_,
+ 100, // time_stamp
+ 0, // modifiers
+ pp::FloatPoint(1, 2),
+ pp::FloatPoint(3, 4),
+ PP_TRUE); // scroll_by_page
+}
+
+pp::InputEvent TestInputEvent::CreateKeyEvent(PP_InputEvent_Type type,
+ uint32_t key_code) {
+ return pp::KeyboardInputEvent(
+ instance_,
+ type,
+ 100, // time_stamp
+ 0, // modifiers
+ key_code,
+ pp::Var());
+}
+
+pp::InputEvent TestInputEvent::CreateCharEvent(const std::string& text) {
+ return pp::KeyboardInputEvent(
+ instance_,
+ PP_INPUTEVENT_TYPE_CHAR,
+ 100, // time_stamp
+ 0, // modifiers
+ 0, // keycode
+ pp::Var(text));
+}
+
+// Simulates the input event and calls PostMessage to let us know when
+// we have received all resulting events from the browser.
+bool TestInputEvent::SimulateInputEvent(
+ const pp::InputEvent& input_event) {
+ expected_input_event_ = pp::InputEvent(input_event.pp_resource());
+ received_expected_event_ = false;
+ received_finish_message_ = false;
+ testing_interface_->SimulateInputEvent(instance_->pp_instance(),
+ input_event.pp_resource());
+ instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE));
+ testing_interface_->RunMessageLoop(instance_->pp_instance());
+ return received_finish_message_ && received_expected_event_;
+}
+
+bool TestInputEvent::AreEquivalentEvents(PP_Resource received,
+ PP_Resource expected) {
+ if (!input_event_interface_->IsInputEvent(received) ||
+ !input_event_interface_->IsInputEvent(expected)) {
+ return false;
+ }
+
+ // Test common fields, except modifiers and time stamp, which may be changed
+ // by the browser.
+ int32_t received_type = input_event_interface_->GetType(received);
+ int32_t expected_type = input_event_interface_->GetType(expected);
+ if (received_type != expected_type) {
+ // Allow key down events to match "raw" key down events.
+ if (expected_type != PP_INPUTEVENT_TYPE_KEYDOWN &&
+ received_type != PP_INPUTEVENT_TYPE_RAWKEYDOWN) {
+ return false;
+ }
+ }
+
+ // Test event type-specific fields.
+ switch (input_event_interface_->GetType(received)) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
+ case PP_INPUTEVENT_TYPE_MOUSELEAVE:
+ // Check mouse fields, except position and movement, which may be
+ // modified by the renderer.
+ return
+ mouse_input_event_interface_->GetButton(received) ==
+ mouse_input_event_interface_->GetButton(expected) &&
+ mouse_input_event_interface_->GetClickCount(received) ==
+ mouse_input_event_interface_->GetClickCount(expected);
+
+ case PP_INPUTEVENT_TYPE_WHEEL:
+ return
+ pp::FloatPoint(wheel_input_event_interface_->GetDelta(received)) ==
+ pp::FloatPoint(wheel_input_event_interface_->GetDelta(expected)) &&
+ pp::FloatPoint(wheel_input_event_interface_->GetTicks(received)) ==
+ pp::FloatPoint(wheel_input_event_interface_->GetTicks(expected)) &&
+ wheel_input_event_interface_->GetScrollByPage(received) ==
+ wheel_input_event_interface_->GetScrollByPage(expected);
+
+ case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
+ case PP_INPUTEVENT_TYPE_KEYDOWN:
+ case PP_INPUTEVENT_TYPE_KEYUP:
+ return
+ keyboard_input_event_interface_->GetKeyCode(received) ==
+ keyboard_input_event_interface_->GetKeyCode(expected);
+
+ case PP_INPUTEVENT_TYPE_CHAR:
+ return
+ keyboard_input_event_interface_->GetKeyCode(received) ==
+ keyboard_input_event_interface_->GetKeyCode(expected) &&
+ pp::Var(pp::Var::PassRef(),
+ keyboard_input_event_interface_->GetCharacterText(received)) ==
+ pp::Var(pp::Var::PassRef(),
+ keyboard_input_event_interface_->GetCharacterText(expected));
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool TestInputEvent::HandleInputEvent(const pp::InputEvent& input_event) {
+ // Some events may cause extra events to be generated, so look for the
+ // first one that matches.
+ if (!received_expected_event_) {
+ received_expected_event_ = AreEquivalentEvents(
+ input_event.pp_resource(),
+ expected_input_event_.pp_resource());
+ }
+ // Handle all input events.
+ return true;
+}
+
+void TestInputEvent::HandleMessage(const pp::Var& message_data) {
+ if (message_data.is_string() &&
+ (message_data.AsString() == FINISHED_WAITING_MESSAGE)) {
+ testing_interface_->QuitMessageLoop(instance_->pp_instance());
+ received_finish_message_ = true;
+ }
+}
+
+void TestInputEvent::DidChangeView(const pp::Rect& position,
+ const pp::Rect& clip) {
+ view_rect_ = position;
+}
+
+std::string TestInputEvent::TestEvents() {
+ // Request all input event classes.
+ input_event_interface_->RequestInputEvents(instance_->pp_instance(),
+ PP_INPUTEVENT_CLASS_MOUSE |
+ PP_INPUTEVENT_CLASS_WHEEL |
+ PP_INPUTEVENT_CLASS_KEYBOARD);
+ // Send the events and check that we received them.
+ ASSERT_TRUE(
+ SimulateInputEvent(CreateMouseEvent(PP_INPUTEVENT_TYPE_MOUSEDOWN,
+ PP_INPUTEVENT_MOUSEBUTTON_LEFT)));
+ ASSERT_TRUE(
+ SimulateInputEvent(CreateWheelEvent()));
+ ASSERT_TRUE(
+ SimulateInputEvent(CreateKeyEvent(PP_INPUTEVENT_TYPE_KEYDOWN,
+ kSpaceChar)));
+ ASSERT_TRUE(
+ SimulateInputEvent(CreateCharEvent(kSpaceString)));
+
+ // Request only mouse events.
+ input_event_interface_->ClearInputEventRequest(instance_->pp_instance(),
+ PP_INPUTEVENT_CLASS_WHEEL |
+ PP_INPUTEVENT_CLASS_KEYBOARD);
+ // Check that we only receive mouse events.
+ ASSERT_TRUE(
+ SimulateInputEvent(CreateMouseEvent(PP_INPUTEVENT_TYPE_MOUSEDOWN,
+ PP_INPUTEVENT_MOUSEBUTTON_LEFT)));
+ ASSERT_FALSE(
+ SimulateInputEvent(CreateWheelEvent()));
+ ASSERT_FALSE(
+ SimulateInputEvent(CreateKeyEvent(PP_INPUTEVENT_TYPE_KEYDOWN,
+ kSpaceChar)));
+ ASSERT_FALSE(
+ SimulateInputEvent(CreateCharEvent(kSpaceString)));
+
+ PASS();
+}
+