diff options
Diffstat (limited to 'ppapi/tests')
-rw-r--r-- | ppapi/tests/test_case.cc | 2 | ||||
-rw-r--r-- | ppapi/tests/test_case.h | 20 | ||||
-rw-r--r-- | ppapi/tests/test_post_message.cc | 166 | ||||
-rw-r--r-- | ppapi/tests/test_post_message.h | 53 | ||||
-rw-r--r-- | ppapi/tests/testing_instance.cc | 17 | ||||
-rw-r--r-- | ppapi/tests/testing_instance.h | 13 |
6 files changed, 257 insertions, 14 deletions
diff --git a/ppapi/tests/test_case.cc b/ppapi/tests/test_case.cc index 20e45d1..ab54d51 100644 --- a/ppapi/tests/test_case.cc +++ b/ppapi/tests/test_case.cc @@ -34,6 +34,8 @@ pp::Var TestCase::GetTestObject() { return test_object_; } +void TestCase::HandleMessage(const pp::Var& message_data) {} + pp::deprecated::ScriptableObject* TestCase::CreateTestObject() { return NULL; } diff --git a/ppapi/tests/test_case.h b/ppapi/tests/test_case.h index 35026fe..b06ecb8 100644 --- a/ppapi/tests/test_case.h +++ b/ppapi/tests/test_case.h @@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef PPAPI_TEST_TEST_CASE_H_ -#define PPAPI_TEST_TEST_CASE_H_ +#ifndef PPAPI_TESTS_TEST_CASE_H_ +#define PPAPI_TESTS_TEST_CASE_H_ +#include <cmath> +#include <limits> #include <string> #include "ppapi/c/pp_resource.h" @@ -22,7 +24,7 @@ class ScriptableObject; // Individual classes of tests derive from this generic test case. class TestCase { public: - TestCase(TestingInstance* instance) : instance_(instance) {} + explicit TestCase(TestingInstance* instance) : instance_(instance) {} virtual ~TestCase() {} // Optionally override to do testcase specific initialization. @@ -38,6 +40,12 @@ class TestCase { // Internally, this uses CreateTestObject which each test overrides. pp::Var GetTestObject(); + // A function that is invoked whenever HandleMessage is called on the + // associated TestingInstance. Default implementation does nothing. TestCases + // that want to handle incoming postMessage events should override this + // method. + virtual void HandleMessage(const pp::Var& message_data); + protected: // Overridden by each test to supply a ScriptableObject corresponding to the // test. There can only be one object created for all test in a given class @@ -115,6 +123,10 @@ class TestCaseFactory { #define ASSERT_EQ(a, b) ASSERT_TRUE((a) == (b)) #define ASSERT_NE(a, b) ASSERT_TRUE((a) != (b)) +#define ASSERT_DOUBLE_EQ(a, b) ASSERT_TRUE( \ + std::fabs((a)-(b)) <= std::numeric_limits<double>::epsilon()) + #define PASS() return std::string() -#endif // PPAPI_TEST_TEST_CASE_H_ +#endif // PPAPI_TESTS_TEST_CASE_H_ + diff --git a/ppapi/tests/test_post_message.cc b/ppapi/tests/test_post_message.cc new file mode 100644 index 0000000..b22fb05 --- /dev/null +++ b/ppapi/tests/test_post_message.cc @@ -0,0 +1,166 @@ +// 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_post_message.h" + +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/cpp/dev/scriptable_object_deprecated.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/var.h" +#include "ppapi/tests/testing_instance.h" + +REGISTER_TEST_CASE(PostMessage); + +namespace { + +const PPB_Testing_Dev* GetTestingInterface() { + static const PPB_Testing_Dev* g_testing_interface = + reinterpret_cast<PPB_Testing_Dev const*>( + pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); + return g_testing_interface; +} + +const char kTestString[] = "Hello world!"; +const bool kTestBool = true; +const int32_t kTestInt = 42; +const double kTestDouble = 42.0; +const int32_t kThreadsToRun = 10; + +} // namespace + +bool TestPostMessage::Init() { + testing_interface_ = reinterpret_cast<const PPB_Testing_Dev*>( + pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); + if (!testing_interface_) { + // Give a more helpful error message for the testing interface being gone + // since that needs special enabling in Chrome. + instance_->AppendError("This test needs the testing interface, which is " + "not currently available. In Chrome, use --enable-pepper-testing when " + "launching."); + } + return (testing_interface_ != NULL); +} + +void TestPostMessage::RunTest() { + RUN_TEST(SendingData); + RUN_TEST(MessageEvent); + RUN_TEST(NoHandler); +} + +void TestPostMessage::HandleMessage(const pp::Var& message_data) { + message_data_.push_back(message_data); +} + +bool TestPostMessage::MakeOnMessageEcho(const std::string& expression) { + std::string js_code( + "document.getElementById('plugin').onmessage = function(message_event) {" + " document.getElementById('plugin').postMessage("); + js_code += expression; + js_code += ");}"; + pp::Var exception; + // TODO(dmichael): Move ExecuteScript to the testing interface. + instance_->ExecuteScript(js_code, &exception); + return(exception.is_undefined()); +} + +std::string TestPostMessage::TestSendingData() { + // Set up the JavaScript onmessage handler to echo the data part of the + // message event back to us. + ASSERT_TRUE(MakeOnMessageEcho("message_event.data")); + + // Test sending a message to JavaScript for each supported type. The JS sends + // the data back to us, and we check that they match. + message_data_.clear(); + instance_->PostMessage(pp::Var(kTestString)); + // Note that the trusted in-process version is completely synchronous, so we + // do not need to use 'RunMessageLoop' to wait. + ASSERT_EQ(message_data_.size(), 1); + ASSERT_TRUE(message_data_.back().is_string()); + ASSERT_EQ(message_data_.back().AsString(), kTestString); + + message_data_.clear(); + instance_->PostMessage(pp::Var(kTestBool)); + ASSERT_EQ(message_data_.size(), 1); + ASSERT_TRUE(message_data_.back().is_bool()); + ASSERT_EQ(message_data_.back().AsBool(), kTestBool); + + message_data_.clear(); + instance_->PostMessage(pp::Var(kTestInt)); + ASSERT_EQ(message_data_.size(), 1); + ASSERT_TRUE(message_data_.back().is_number()); + ASSERT_DOUBLE_EQ(message_data_.back().AsDouble(), + static_cast<double>(kTestInt)); + + message_data_.clear(); + instance_->PostMessage(pp::Var(kTestDouble)); + ASSERT_EQ(message_data_.size(), 1); + ASSERT_TRUE(message_data_.back().is_number()); + ASSERT_DOUBLE_EQ(message_data_.back().AsDouble(), kTestDouble); + + message_data_.clear(); + instance_->PostMessage(pp::Var()); + ASSERT_EQ(message_data_.size(), 1); + ASSERT_TRUE(message_data_.back().is_undefined()); + + message_data_.clear(); + instance_->PostMessage(pp::Var(pp::Var::Null())); + ASSERT_EQ(message_data_.size(), 1); + ASSERT_TRUE(message_data_.back().is_null()); + + PASS(); +} + +std::string TestPostMessage::TestMessageEvent() { + // Set up the JavaScript onmessage handler to pass us some values from the + // MessageEvent and make sure they match our expectations. + + // Have onmessage pass back the type of message_event and make sure it's + // "object". + ASSERT_TRUE(MakeOnMessageEcho("typeof(message_event)")); + message_data_.clear(); + instance_->PostMessage(pp::Var(kTestInt)); + ASSERT_EQ(message_data_.size(), 1); + ASSERT_TRUE(message_data_.back().is_string()); + ASSERT_EQ(message_data_.back().AsString(), "object"); + + // Make sure all the non-data properties have the expected values. + bool success = MakeOnMessageEcho("((message_event.origin == '')" + " && (message_event.lastEventId == '')" + " && (message_event.source == null)" + " && (message_event.ports == null)" + " && (message_event.bubbles == false)" + " && (message_event.cancelable == false)" + ")"); + ASSERT_TRUE(success); + message_data_.clear(); + instance_->PostMessage(pp::Var(kTestInt)); + // Note that the trusted in-process version is completely synchronous, so we + // do not need to use 'RunMessageLoop' to wait. + ASSERT_EQ(message_data_.size(), 1); + ASSERT_TRUE(message_data_.back().is_bool()); + ASSERT_TRUE(message_data_.back().AsBool()); + + PASS(); +} + +std::string TestPostMessage::TestNoHandler() { + // Delete the onmessage handler (if it exists) + std::string js_code( + "if (document.getElementById('plugin').onmessage) {" + " delete document.getElementById('plugin').onmessage;" + "}"); + pp::Var exception; + instance_->ExecuteScript(js_code, &exception); + ASSERT_TRUE(exception.is_undefined()); + + // Now send a message and make sure we don't get anything back (and that we + // don't crash). + message_data_.clear(); + instance_->PostMessage(pp::Var()); + ASSERT_EQ(message_data_.size(), 0); + + PASS(); +} + diff --git a/ppapi/tests/test_post_message.h b/ppapi/tests/test_post_message.h new file mode 100644 index 0000000..1b841c8 --- /dev/null +++ b/ppapi/tests/test_post_message.h @@ -0,0 +1,53 @@ +// 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. + +#ifndef PPAPI_TESTS_TEST_POST_MESSAGE_H_ +#define PPAPI_TESTS_TEST_POST_MESSAGE_H_ + +#include <string> +#include <vector> + +#include "ppapi/tests/test_case.h" + +struct PPB_Testing_Dev; + +class TestPostMessage : public TestCase { + public: + explicit TestPostMessage(TestingInstance* instance) + : TestCase(instance), testing_interface_(NULL) {} + + private: + // TestCase implementation. + virtual bool Init(); + virtual void RunTest(); + + // A handler for JS->Native calls to postMessage. Simply pushes + // the given value to the back of message_data_ + virtual void HandleMessage(const pp::Var& message_data); + + // Set the JavaScript onmessage handler to echo back some expression based on + // the message_event by passing it to postMessage. Returns true on success, + // false on failure. + bool MakeOnMessageEcho(const std::string& expression); + + // Test some basic functionality; make sure we can send data successfully + // in both directions. + std::string TestSendingData(); + + // Test the MessageEvent object that JavaScript received to make sure it is + // of the right type and has all the expected fields. + std::string TestMessageEvent(); + + // Test sending a message when no handler exists, make sure nothing happens. + std::string TestNoHandler(); + + const PPB_Testing_Dev* testing_interface_; + + // This is used to store pp::Var objects we receive via a call to + // HandleMessage. + std::vector<pp::Var> message_data_; +}; + +#endif // PPAPI_TESTS_TEST_POST_MESSAGE_H_ + diff --git a/ppapi/tests/testing_instance.cc b/ppapi/tests/testing_instance.cc index 34ec749..ca82b5c 100644 --- a/ppapi/tests/testing_instance.cc +++ b/ppapi/tests/testing_instance.cc @@ -5,7 +5,8 @@ #include "ppapi/tests/testing_instance.h" #include <algorithm> -#include <string.h> +#include <cstring> +#include <vector> #include "ppapi/cpp/module.h" #include "ppapi/cpp/var.h" @@ -27,15 +28,15 @@ bool TestingInstance::Init(uint32_t argc, const char* argn[], const char* argv[]) { for (uint32_t i = 0; i < argc; i++) { - if (strcmp(argn[i], "mode") == 0) { - if (strcmp(argv[i], "nacl") == 0) + if (std::strcmp(argn[i], "mode") == 0) { + if (std::strcmp(argv[i], "nacl") == 0) nacl_mode_ = true; break; } } // Create the proper test case from the argument. for (uint32_t i = 0; i < argc; i++) { - if (strcmp(argn[i], "testcase") == 0) { + if (std::strcmp(argn[i], "testcase") == 0) { if (argv[i][0] == '\0') break; current_case_ = CaseForTestName(argv[i]); @@ -55,6 +56,10 @@ pp::Var TestingInstance::GetInstanceObject() { return current_case_->GetTestObject(); } +void TestingInstance::HandleMessage(const pp::Var& message_data) { + current_case_->HandleMessage(message_data); +} + void TestingInstance::DidChangeView(const pp::Rect& position, const pp::Rect& clip) { if (!executed_tests_) { @@ -66,7 +71,7 @@ void TestingInstance::DidChangeView(const pp::Rect& position, } void TestingInstance::LogTest(const std::string& test_name, - const std::string& error_message) { + const std::string& error_message) { std::string html; html.append("<div class=\"test_line\"><span class=\"test_name\">"); html.append(test_name); @@ -120,7 +125,7 @@ void TestingInstance::ExecuteTests(int32_t unused) { TestCase* TestingInstance::CaseForTestName(const char* name) { TestCaseFactory* iter = TestCaseFactory::head_; while (iter != NULL) { - if (strcmp(name, iter->name_) == 0) + if (std::strcmp(name, iter->name_) == 0) return iter->method_(this); iter = iter->next_; } diff --git a/ppapi/tests/testing_instance.h b/ppapi/tests/testing_instance.h index 5eedf24..5bb95ae 100644 --- a/ppapi/tests/testing_instance.h +++ b/ppapi/tests/testing_instance.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef PPAPI_TEST_TESTING_INSTANCE_H_ -#define PPAPI_TEST_TESTING_INSTANCE_H_ +#ifndef PPAPI_TESTS_TESTING_INSTANCE_H_ +#define PPAPI_TESTS_TESTING_INSTANCE_H_ #include <string> @@ -14,7 +14,7 @@ class TestCase; class TestingInstance : public pp::Instance { public: - TestingInstance(PP_Instance instance); + explicit TestingInstance(PP_Instance instance); // pp::Instance override. virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); @@ -41,6 +41,10 @@ class TestingInstance : public pp::Instance { // Appends an error message to the log. void AppendError(const std::string& message); + // Passes the message_data through to the HandleMessage method on the + // TestClass object that's associated with this instance. + virtual void HandleMessage(const pp::Var& message_data); + private: void ExecuteTests(int32_t unused); @@ -75,4 +79,5 @@ class TestingInstance : public pp::Instance { bool nacl_mode_; }; -#endif // PPAPI_TEST_TESTING_INSTANCE_H_ +#endif // PPAPI_TESTS_TESTING_INSTANCE_H_ + |