Chromium Code Reviews| Index: ppapi/tests/test_post_message.cc |
| diff --git a/ppapi/tests/test_post_message.cc b/ppapi/tests/test_post_message.cc |
| index b1e30b23a2c106c8e0a0852f525b9a29ee7728b4..a4f33c6f0c80bd0870eb5b806592c9eaa513983e 100644 |
| --- a/ppapi/tests/test_post_message.cc |
| +++ b/ppapi/tests/test_post_message.cc |
| @@ -4,12 +4,17 @@ |
| #include "ppapi/tests/test_post_message.h" |
| +#include <string.h> |
| #include <algorithm> |
| #include <map> |
| #include <sstream> |
| #include "ppapi/c/dev/ppb_testing_dev.h" |
| #include "ppapi/c/pp_var.h" |
| +#include "ppapi/c/ppb_file_io.h" |
| +#include "ppapi/cpp/file_io.h" |
| +#include "ppapi/cpp/file_ref.h" |
| +#include "ppapi/cpp/file_system.h" |
| #include "ppapi/cpp/instance.h" |
| #include "ppapi/cpp/var.h" |
| #include "ppapi/cpp/var_array.h" |
| @@ -28,6 +33,7 @@ REGISTER_TEST_CASE(PostMessage); |
| namespace { |
| +const char kTestFilename[] = "testfile.txt"; |
| const char kTestString[] = "Hello world!"; |
| const bool kTestBool = true; |
| const int32_t kTestInt = 42; |
| @@ -161,6 +167,18 @@ TestPostMessage::~TestPostMessage() { |
| bool TestPostMessage::Init() { |
| bool success = CheckTestingInterface(); |
| + core_interface_ = static_cast<const PPB_Core*>( |
| + pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE)); |
| + file_system_interface_ = static_cast<const PPB_FileSystem*>( |
| + pp::Module::Get()->GetBrowserInterface(PPB_FILESYSTEM_INTERFACE)); |
| + var_interface_ = static_cast<const PPB_Var*>( |
| + pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE)); |
| + var_resource_interface_ = static_cast<const PPB_VarResource_Dev*>( |
| + pp::Module::Get()->GetBrowserInterface(PPB_VAR_RESOURCE_DEV_INTERFACE)); |
| + if (!core_interface_ || !file_system_interface_ || !var_interface_ || |
| + !var_resource_interface_) |
| + return false; |
| + |
| // Set up a special listener that only responds to a FINISHED_WAITING string. |
| // This is for use by WaitForMessages. |
| std::string js_code; |
| @@ -201,6 +219,7 @@ void TestPostMessage::RunTests(const std::string& filter) { |
| RUN_TEST(SendingArrayBuffer, filter); |
| RUN_TEST(SendingArray, filter); |
| RUN_TEST(SendingDictionary, filter); |
| + RUN_TEST(SendingResource, filter); |
| RUN_TEST(SendingComplexVar, filter); |
| RUN_TEST(MessageEvent, filter); |
| RUN_TEST(NoHandler, filter); |
| @@ -276,6 +295,31 @@ int TestPostMessage::WaitForMessages() { |
| return message_data_.size() - message_size_before; |
| } |
| +int TestPostMessage::PostAsyncMessageFromJavaScriptAndWait( |
| + const std::string& func) { |
| + // After the |func| calls callback, post both the given |message|, as well as |
| + // the special message FINISHED_WAITING_MESSAGE. This ensures that |
| + // WaitForMessagesAsync correctly waits until the callback is called. |
|
raymes
2013/10/27 21:59:34
This comment seems out of date now.
Matt Giuca
2013/10/29 12:21:42
Done.
|
| + std::string js_code; |
| + js_code += "var plugin = document.getElementById('plugin');" |
| + "var callback = function(message) {" |
| + " plugin.postMessage(message);" |
| + " plugin.postMessage('" FINISHED_WAITING_MESSAGE "');" |
| + "};"; |
| + js_code += "(" + func + ")(callback);"; |
| + instance_->EvalScript(js_code); |
| + |
| + size_t message_size_before = message_data_.size(); |
| + // Unlike WaitForMessages, we do not post FINISHED_WAITING_MESSAGE. This is |
| + // because the above JavaScript code will post it for us, when the |
| + // asynchronous operation completes. |
| + testing_interface_->RunMessageLoop(instance_->pp_instance()); |
| + // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know |
| + // that all pending messages have been slurped up. Return the number we |
| + // received (which may be zero). |
| + return message_data_.size() - message_size_before; |
| +} |
| + |
| std::string TestPostMessage::CheckMessageProperties( |
| const pp::Var& test_data, |
| const std::vector<std::string>& properties_to_check) { |
| @@ -533,6 +577,79 @@ std::string TestPostMessage::TestSendingDictionary() { |
| PASS(); |
| } |
| +std::string TestPostMessage::TestSendingResource() { |
| + // Clean up after previous tests. This also swallows the message sent by Init |
| + // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' |
| + // should start with these. |
| + WaitForMessages(); |
| + message_data_.clear(); |
| + ASSERT_TRUE(ClearListeners()); |
| + |
| + // Test sending a DOMFileSystem from JavaScript to the plugin. |
| + // This opens a real (temporary) file using the HTML5 FileSystem API and |
| + // writes to it. |
| + ASSERT_TRUE(AddEchoingListener("message_event.data")); |
| + ASSERT_EQ(message_data_.size(), 0); |
| + std::string js_code = |
| + "function(callback) {" |
| + " window.webkitRequestFileSystem(window.TEMPORARY, 1024," |
| + " function(fileSystem) {" |
| + " fileSystem.root.getFile('"; |
| + js_code += kTestFilename; |
| + js_code += "', {create: true}, function(tempFile) {" |
| + " tempFile.createWriter(function(writer) {" |
| + " writer.onerror = function() { callback(null); };" |
| + " writer.onwriteend = function() { callback(fileSystem); };" |
| + " var blob = new Blob(['"; |
| + js_code += kTestString; |
| + js_code += "'], {'type': 'text/plain'});" |
| + " writer.write(blob);" |
| + " });" |
| + " }, function() { callback(null); });" |
| + " }, function() { callback(null); });" |
| + "}"; |
| + ASSERT_EQ(PostAsyncMessageFromJavaScriptAndWait(js_code), 1); |
| + // TODO(mgiuca): Use the C++ API instead of the C API, when it is available. |
| + PP_Var var = message_data_.back().Detach(); |
| + PP_Resource result = var_resource_interface_->VarToResource(var); |
| + ASSERT_TRUE(file_system_interface_->IsFileSystem(result)); |
| + { |
| + pp::FileSystem file_system(pp::PASS_REF, result); |
| + std::string file_path = "/"; |
|
raymes
2013/10/27 21:59:34
nit: std::string file_path("/");
Matt Giuca
2013/10/29 12:21:42
Done.
|
| + file_path += kTestFilename; |
| + pp::FileRef file_ref(file_system, file_path.c_str()); |
| + ASSERT_NE(0, file_ref.pp_resource()); |
| + ASSERT_EQ(kTestFilename, file_ref.GetName().AsString()); |
|
raymes
2013/10/27 21:59:34
nit: Is this worth having?
Matt Giuca
2013/10/29 12:21:42
Done. (Fair enough; it doesn't test the API we're
|
| + pp::FileIO file_io(instance_); |
| + ASSERT_NE(0, file_io.pp_resource()); |
| + |
| + TestCompletionCallback callback(instance_->pp_instance(), |
| + callback_type()); |
|
raymes
2013/10/27 21:59:34
nit: indentation
Matt Giuca
2013/10/29 12:21:42
Done.
|
| + callback.WaitForResult( |
| + file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback.GetCallback())); |
| + CHECK_CALLBACK_BEHAVIOR(callback); |
| + ASSERT_EQ(PP_OK, callback.result()); |
| + |
| + int length = strlen(kTestString); |
| + char buffer[length]; // Note: Not null-terminated! |
| + callback.WaitForResult( |
| + file_io.Read(0, buffer, length, callback.GetCallback())); |
| + CHECK_CALLBACK_BEHAVIOR(callback); |
| + ASSERT_EQ(length, callback.result()); |
| + ASSERT_EQ(0, memcmp(buffer, kTestString, length)); |
| + } |
| + var_interface_->Release(var); |
| + |
| + WaitForMessages(); |
| + message_data_.clear(); |
| + ASSERT_TRUE(ClearListeners()); |
| + |
| + // TODO(mgiuca): Test roundtrip from plugin to JS and back, when the plugin to |
| + // JS support is available. |
| + |
| + PASS(); |
| +} |
| + |
| std::string TestPostMessage::TestSendingComplexVar() { |
| // Clean up after previous tests. This also swallows the message sent by Init |
| // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' |