Home | History | Annotate | Download | only in plugin
      1 // Copyright (c) 2010 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 "content/test/plugin/plugin_test.h"
      6 
      7 #include "base/strings/string_number_conversions.h"
      8 #include "base/strings/string_util.h"
      9 #include "content/test/plugin/npapi_constants.h"
     10 
     11 namespace NPAPIClient {
     12 
     13 PluginTest::PluginTest(NPP id, NPNetscapeFuncs *host_functions) {
     14   id_ = id;
     15   id_->pdata = this;
     16   host_functions_ = host_functions;
     17   test_completed_ = false;
     18 }
     19 
     20 PluginTest::~PluginTest() {}
     21 
     22 bool PluginTest::IsWindowless() const { return false; }
     23 
     24 NPError PluginTest::New(uint16 mode, int16 argc, const char* argn[],
     25                         const char* argv[], NPSavedData* saved) {
     26   test_name_ = this->GetArgValue("name", argc, argn, argv);
     27   const char* id = this->GetArgValue("id", argc, argn, argv);
     28   if (id)  // NULL for NP_FULL
     29     test_id_ = id;
     30   return NPERR_NO_ERROR;
     31 }
     32 
     33 NPError PluginTest::Destroy() {
     34   return NPERR_NO_ERROR;
     35 }
     36 
     37 NPError PluginTest::SetWindow(NPWindow* pNPWindow) {
     38   return NPERR_NO_ERROR;
     39 }
     40 
     41 // It's a shame I have to implement URLEncode.  But, using webkit's
     42 // or using chrome's means a ball of string of dlls and dependencies that
     43 // is very very long.  After spending far too much time on it,
     44 // I'll just encode it myself.  Too bad Microsoft doesn't implement
     45 // this in a reusable way either.  Both webkit and chrome will
     46 // end up using libicu, which is a string of dependencies we don't
     47 // want.
     48 
     49 inline unsigned char toHex(const unsigned char x) {
     50   return x > 9 ? (x + 'A' - 10) : (x + '0');
     51 }
     52 
     53 std::string URLEncode(const std::string &sIn) {
     54   std::string sOut;
     55 
     56   const size_t length = sIn.length();
     57   for (size_t idx = 0; idx < length;) {
     58     const char ch = sIn.at(idx);
     59     if (isalnum(ch)) {
     60       sOut.append(1, ch);
     61     } else if (isspace(ch) && ((ch != '\n') && (ch != '\r'))) {
     62       sOut.append(1, '+');
     63     } else {
     64       sOut.append(1, '%');
     65       sOut.append(1, toHex(ch>>4));
     66       sOut.append(1, toHex(ch%16));
     67     }
     68     idx++;
     69   }
     70   return sOut;
     71 }
     72 
     73 void PluginTest::SignalTestCompleted() {
     74   NPObject *window_obj = NULL;
     75   host_functions_->getvalue(id_, NPNVWindowNPObject, &window_obj);
     76   if (!window_obj)
     77     return;
     78 
     79   test_completed_ = true;
     80   // To signal test completion, we expect a couple of
     81   // javascript functions to be defined in the webpage
     82   // which hosts this plugin:
     83   //    onSuccess(test_name, test_id)
     84   //    onFailure(test_name, test_id, error_message)
     85   std::string script("javascript:");
     86   if (Succeeded()) {
     87     script.append("onSuccess(\"");
     88     script.append(test_name_);
     89     script.append("\",\"");
     90     script.append(test_id_);
     91     script.append("\");");
     92   } else {
     93     script.append("onFailure(\"");
     94     script.append(test_name_);
     95     script.append("\",\"");
     96     script.append(test_id_);
     97     script.append("\",\"");
     98     script.append(test_status_);
     99     script.append("\");");
    100   }
    101 
    102   NPString script_string;
    103   script_string.UTF8Characters = script.c_str();
    104   script_string.UTF8Length = static_cast<unsigned int>(script.length());
    105 
    106   NPVariant result_var;
    107   host_functions_->evaluate(id_, window_obj, &script_string, &result_var);
    108 }
    109 
    110 const char *PluginTest::GetArgValue(const char *name, const int16 argc,
    111                                     const char *argn[], const char *argv[]) {
    112   for (int idx = 0; idx < argc; idx++)
    113     if (base::strcasecmp(argn[idx], name) == 0)
    114       return argv[idx];
    115   return NULL;
    116 }
    117 
    118 void PluginTest::SetError(const std::string &msg) {
    119   test_status_.append(msg);
    120 }
    121 
    122 void PluginTest::ExpectStringLowerCaseEqual(const std::string &val1,
    123                                             const std::string &val2) {
    124   if (!LowerCaseEqualsASCII(val1, val2.c_str())) {
    125     std::string err;
    126     err = "Expected Equal for '";
    127     err.append(val1);
    128     err.append("' and '");
    129     err.append(val2);
    130     err.append("'");
    131     SetError(err);
    132   }
    133 }
    134 
    135 void PluginTest::ExpectAsciiStringNotEqual(const char *val1, const char *val2) {
    136   if (val1 == val2) {
    137     std::string err;
    138     err = "Expected Not Equal for '";
    139     err.append(val1);
    140     err.append("' and '");
    141     err.append(val2);
    142     err.append("'");
    143     SetError(err);
    144   }
    145 }
    146 
    147 void PluginTest::ExpectIntegerEqual(int val1, int val2) {
    148   if (val1 != val2) {
    149     std::string err;
    150     err = "Expected Equal for '";
    151     err.append(base::IntToString(val1));
    152     err.append("' and '");
    153     err.append(base::IntToString(val2));
    154     err.append("'");
    155     SetError(err);
    156   }
    157 }
    158 
    159 NPError PluginTest::NewStream(NPMIMEType type, NPStream* stream,
    160                               NPBool seekable, uint16* stype) {
    161   // There is no default action here.
    162   return NPERR_NO_ERROR;
    163 }
    164 
    165 int32 PluginTest::WriteReady(NPStream *stream) {
    166   // Take data in small chunks
    167   return 4096;
    168 }
    169 
    170 int32 PluginTest::Write(NPStream *stream, int32 offset, int32 len,
    171                            void *buffer) {
    172   // Pretend that we took all the data.
    173   return len;
    174 }
    175 
    176 NPError PluginTest::DestroyStream(NPStream *stream, NPError reason) {
    177   // There is no default action.
    178   return NPERR_NO_ERROR;
    179 }
    180 
    181 void PluginTest::StreamAsFile(NPStream* stream, const char* fname) {
    182   // There is no default action.
    183 }
    184 
    185 void PluginTest::URLNotify(const char* url, NPReason reason, void* data) {
    186   // There is no default action
    187 }
    188 
    189 int16 PluginTest::HandleEvent(void* event) {
    190   // There is no default action
    191   return 0;
    192 }
    193 
    194 void PluginTest::URLRedirectNotify(const char* url, int32_t status,
    195                                    void* notify_data) {
    196   // There is no default action
    197 }
    198 
    199 } // namespace NPAPIClient
    200