Home | History | Annotate | Download | only in tests
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ppapi/tests/test_flash_clipboard.h"
      6 
      7 #include <algorithm>
      8 #include <vector>
      9 
     10 #include "ppapi/cpp/instance.h"
     11 #include "ppapi/cpp/module.h"
     12 #include "ppapi/cpp/point.h"
     13 #include "ppapi/cpp/private/flash_clipboard.h"
     14 #include "ppapi/cpp/var.h"
     15 #include "ppapi/cpp/var_array_buffer.h"
     16 #include "ppapi/tests/testing_instance.h"
     17 
     18 // http://crbug.com/176822
     19 #if !defined(OS_WIN)
     20 REGISTER_TEST_CASE(FlashClipboard);
     21 #endif
     22 
     23 // WriteData() sends an async request to the browser process. As a result, the
     24 // string written may not be reflected by IsFormatAvailable() or ReadPlainText()
     25 // immediately. We need to wait and retry.
     26 const int kIntervalMs = 250;
     27 const int kMaxIntervals = kActionTimeoutMs / kIntervalMs;
     28 
     29 TestFlashClipboard::TestFlashClipboard(TestingInstance* instance)
     30     : TestCase(instance) {
     31 }
     32 
     33 void TestFlashClipboard::RunTests(const std::string& filter) {
     34   RUN_TEST(ReadWritePlainText, filter);
     35   RUN_TEST(ReadWriteHTML, filter);
     36   RUN_TEST(ReadWriteRTF, filter);
     37   RUN_TEST(ReadWriteCustomData, filter);
     38   RUN_TEST(ReadWriteMultipleFormats, filter);
     39   RUN_TEST(Clear, filter);
     40   RUN_TEST(InvalidFormat, filter);
     41   RUN_TEST(RegisterCustomFormat, filter);
     42 }
     43 
     44 bool TestFlashClipboard::ReadStringVar(uint32_t format, std::string* result) {
     45   pp::Var text;
     46   bool success = pp::flash::Clipboard::ReadData(
     47       instance_,
     48       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
     49       format,
     50       &text);
     51   if (success && text.is_string()) {
     52     *result = text.AsString();
     53     return true;
     54   }
     55   return false;
     56 }
     57 
     58 bool TestFlashClipboard::WriteStringVar(uint32_t format,
     59                                         const std::string& text) {
     60   std::vector<uint32_t> formats_vector(1, format);
     61   std::vector<pp::Var> data_vector(1, pp::Var(text));
     62   bool success = pp::flash::Clipboard::WriteData(
     63       instance_,
     64       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
     65       formats_vector,
     66       data_vector);
     67   return success;
     68 }
     69 
     70 bool TestFlashClipboard::IsFormatAvailableMatches(uint32_t format,
     71                                                   bool expected) {
     72   for (int i = 0; i < kMaxIntervals; ++i) {
     73     bool is_available = pp::flash::Clipboard::IsFormatAvailable(
     74         instance_,
     75         PP_FLASH_CLIPBOARD_TYPE_STANDARD,
     76         format);
     77     if (is_available == expected)
     78       return true;
     79 
     80     PlatformSleep(kIntervalMs);
     81   }
     82   return false;
     83 }
     84 
     85 bool TestFlashClipboard::ReadPlainTextMatches(const std::string& expected) {
     86   for (int i = 0; i < kMaxIntervals; ++i) {
     87     std::string result;
     88     bool success = ReadStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, &result);
     89     if (success && result == expected)
     90       return true;
     91 
     92     PlatformSleep(kIntervalMs);
     93   }
     94   return false;
     95 }
     96 
     97 bool TestFlashClipboard::ReadHTMLMatches(const std::string& expected) {
     98   for (int i = 0; i < kMaxIntervals; ++i) {
     99     std::string result;
    100     bool success = ReadStringVar(PP_FLASH_CLIPBOARD_FORMAT_HTML, &result);
    101     // Harmless markup may be inserted around the copied html on some
    102     // platforms, so just check that the pasted string contains the
    103     // copied string. Also check that we only paste the copied fragment, see
    104     // http://code.google.com/p/chromium/issues/detail?id=130827.
    105     if (success && result.find(expected) != std::string::npos &&
    106         result.find("<!--StartFragment-->") == std::string::npos &&
    107         result.find("<!--EndFragment-->") == std::string::npos) {
    108       return true;
    109     }
    110 
    111     PlatformSleep(kIntervalMs);
    112   }
    113   return false;
    114 }
    115 
    116 std::string TestFlashClipboard::TestReadWritePlainText() {
    117   std::string input = "Hello world plain text!";
    118   ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, input));
    119   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
    120                                        true));
    121   ASSERT_TRUE(ReadPlainTextMatches(input));
    122 
    123   PASS();
    124 }
    125 
    126 std::string TestFlashClipboard::TestReadWriteHTML() {
    127   std::string input = "Hello world html!";
    128   ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_HTML, input));
    129   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_HTML, true));
    130   ASSERT_TRUE(ReadHTMLMatches(input));
    131 
    132   PASS();
    133 }
    134 
    135 std::string TestFlashClipboard::TestReadWriteRTF() {
    136   std::string rtf_string =
    137         "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\n"
    138         "This is some {\\b bold} text.\\par\n"
    139         "}";
    140   pp::VarArrayBuffer array_buffer(rtf_string.size());
    141   char* bytes = static_cast<char*>(array_buffer.Map());
    142   std::copy(rtf_string.data(), rtf_string.data() + rtf_string.size(), bytes);
    143   std::vector<uint32_t> formats_vector(1, PP_FLASH_CLIPBOARD_FORMAT_RTF);
    144   std::vector<pp::Var> data_vector(1, array_buffer);
    145   ASSERT_TRUE(pp::flash::Clipboard::WriteData(
    146       instance_,
    147       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
    148       formats_vector,
    149       data_vector));
    150 
    151   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_RTF, true));
    152 
    153   pp::Var rtf_result;
    154   ASSERT_TRUE(pp::flash::Clipboard::ReadData(
    155         instance_,
    156         PP_FLASH_CLIPBOARD_TYPE_STANDARD,
    157         PP_FLASH_CLIPBOARD_FORMAT_RTF,
    158         &rtf_result));
    159   ASSERT_TRUE(rtf_result.is_array_buffer());
    160   pp::VarArrayBuffer array_buffer_result(rtf_result);
    161   ASSERT_TRUE(array_buffer_result.ByteLength() == array_buffer.ByteLength());
    162   char* bytes_result = static_cast<char*>(array_buffer_result.Map());
    163   ASSERT_TRUE(std::equal(bytes, bytes + array_buffer.ByteLength(),
    164       bytes_result));
    165 
    166   PASS();
    167 }
    168 
    169 std::string TestFlashClipboard::TestReadWriteCustomData() {
    170   std::string custom_data = "custom_data";
    171   pp::VarArrayBuffer array_buffer(custom_data.size());
    172   char* bytes = static_cast<char*>(array_buffer.Map());
    173   std::copy(custom_data.begin(), custom_data.end(), bytes);
    174   uint32_t format_id =
    175       pp::flash::Clipboard::RegisterCustomFormat(instance_, "my-format");
    176   ASSERT_NE(format_id, PP_FLASH_CLIPBOARD_FORMAT_INVALID);
    177 
    178   std::vector<uint32_t> formats_vector(1, format_id);
    179   std::vector<pp::Var> data_vector(1, array_buffer);
    180   ASSERT_TRUE(pp::flash::Clipboard::WriteData(
    181       instance_,
    182       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
    183       formats_vector,
    184       data_vector));
    185 
    186   ASSERT_TRUE(IsFormatAvailableMatches(format_id, true));
    187 
    188   pp::Var custom_data_result;
    189   ASSERT_TRUE(pp::flash::Clipboard::ReadData(
    190       instance_,
    191       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
    192       format_id,
    193       &custom_data_result));
    194   ASSERT_TRUE(custom_data_result.is_array_buffer());
    195   pp::VarArrayBuffer array_buffer_result(custom_data_result);
    196   ASSERT_EQ(array_buffer_result.ByteLength(), array_buffer.ByteLength());
    197   char* bytes_result = static_cast<char*>(array_buffer_result.Map());
    198   ASSERT_TRUE(std::equal(bytes, bytes + array_buffer.ByteLength(),
    199       bytes_result));
    200 
    201   PASS();
    202 }
    203 
    204 std::string TestFlashClipboard::TestReadWriteMultipleFormats() {
    205   std::vector<uint32_t> formats;
    206   std::vector<pp::Var> data;
    207   formats.push_back(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT);
    208   data.push_back(pp::Var("plain text"));
    209   formats.push_back(PP_FLASH_CLIPBOARD_FORMAT_HTML);
    210   data.push_back(pp::Var("html"));
    211   bool success = pp::flash::Clipboard::WriteData(
    212       instance_,
    213       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
    214       formats,
    215       data);
    216   ASSERT_TRUE(success);
    217   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
    218                                        true));
    219   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_HTML, true));
    220   ASSERT_TRUE(ReadPlainTextMatches(data[0].AsString()));
    221   ASSERT_TRUE(ReadHTMLMatches(data[1].AsString()));
    222 
    223   PASS();
    224 }
    225 
    226 std::string TestFlashClipboard::TestClear() {
    227   std::string input = "Hello world plain text!";
    228   ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, input));
    229   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
    230                                        true));
    231   bool success = pp::flash::Clipboard::WriteData(
    232       instance_,
    233       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
    234       std::vector<uint32_t>(),
    235       std::vector<pp::Var>());
    236   ASSERT_TRUE(success);
    237   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
    238                                        false));
    239 
    240   PASS();
    241 }
    242 
    243 std::string TestFlashClipboard::TestInvalidFormat() {
    244   uint32_t invalid_format = 999;
    245   ASSERT_FALSE(WriteStringVar(invalid_format, "text"));
    246   ASSERT_TRUE(IsFormatAvailableMatches(invalid_format, false));
    247   std::string unused;
    248   ASSERT_FALSE(ReadStringVar(invalid_format, &unused));
    249 
    250   PASS();
    251 }
    252 
    253 std::string TestFlashClipboard::TestRegisterCustomFormat() {
    254   // Test an empty name is rejected.
    255   uint32_t format_id =
    256       pp::flash::Clipboard::RegisterCustomFormat(instance_, std::string());
    257   ASSERT_EQ(format_id, PP_FLASH_CLIPBOARD_FORMAT_INVALID);
    258 
    259   // Test a valid format name.
    260   format_id = pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b");
    261   ASSERT_NE(format_id, PP_FLASH_CLIPBOARD_FORMAT_INVALID);
    262   // Make sure the format doesn't collide with predefined formats.
    263   ASSERT_NE(format_id, PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT);
    264   ASSERT_NE(format_id, PP_FLASH_CLIPBOARD_FORMAT_HTML);
    265   ASSERT_NE(format_id, PP_FLASH_CLIPBOARD_FORMAT_RTF);
    266 
    267   // Check that if the same name is registered, the same id comes out.
    268   uint32_t format_id2 =
    269       pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b");
    270   ASSERT_EQ(format_id, format_id2);
    271 
    272   // Check that the second format registered has a different id.
    273   uint32_t format_id3 =
    274       pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b-c");
    275   ASSERT_NE(format_id, format_id3);
    276 
    277   PASS();
    278 }
    279