Home | History | Annotate | Download | only in tests
      1 // Copyright (c) 2011 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_var.h"
      6 
      7 #include <string.h>
      8 
      9 #include <limits>
     10 
     11 #include "ppapi/c/pp_var.h"
     12 #include "ppapi/c/ppb_var.h"
     13 #include "ppapi/cpp/instance.h"
     14 #include "ppapi/cpp/module.h"
     15 #include "ppapi/cpp/var.h"
     16 #include "ppapi/tests/testing_instance.h"
     17 
     18 namespace {
     19 
     20 uint32_t kInvalidLength = static_cast<uint32_t>(-1);
     21 
     22 }  // namespace
     23 
     24 REGISTER_TEST_CASE(Var);
     25 
     26 bool TestVar::Init() {
     27   var_interface_ = static_cast<const PPB_Var*>(
     28       pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
     29   return var_interface_ && CheckTestingInterface();
     30 }
     31 
     32 void TestVar::RunTests(const std::string& filter) {
     33   RUN_TEST(BasicString, filter);
     34   RUN_TEST(InvalidAndEmpty, filter);
     35   RUN_TEST(InvalidUtf8, filter);
     36   RUN_TEST(NullInputInUtf8Conversion, filter);
     37   RUN_TEST(ValidUtf8, filter);
     38   RUN_TEST(Utf8WithEmbeddedNulls, filter);
     39   RUN_TEST(VarToUtf8ForWrongType, filter);
     40 }
     41 
     42 std::string TestVar::TestBasicString() {
     43   uint32_t before_object = testing_interface_->GetLiveObjectsForInstance(
     44       instance_->pp_instance());
     45   {
     46     const char kStr[] = "Hello";
     47     const uint32_t kStrLen(sizeof(kStr) - 1);
     48     PP_Var str = var_interface_->VarFromUtf8(kStr, kStrLen);
     49     ASSERT_EQ(PP_VARTYPE_STRING, str.type);
     50 
     51     // Reading back the string should work.
     52     uint32_t len = 0;
     53     const char* result = var_interface_->VarToUtf8(str, &len);
     54     ASSERT_EQ(kStrLen, len);
     55     ASSERT_EQ(0, strncmp(kStr, result, kStrLen));
     56 
     57     // Destroy the string, readback should now fail.
     58     var_interface_->Release(str);
     59     result = var_interface_->VarToUtf8(str, &len);
     60     ASSERT_EQ(0, len);
     61     ASSERT_EQ(NULL, result);
     62   }
     63 
     64   // Make sure we can assign a C++ object to itself and it stays alive.
     65   {
     66     pp::Var a("test");
     67     a = a;
     68     ASSERT_TRUE(a.AsString() == "test");
     69   }
     70 
     71   // Make sure nothing leaked.
     72   ASSERT_TRUE(testing_interface_->GetLiveObjectsForInstance(
     73       instance_->pp_instance()) == before_object);
     74 
     75   PASS();
     76 }
     77 
     78 std::string TestVar::TestInvalidAndEmpty() {
     79   PP_Var invalid_string;
     80   invalid_string.type = PP_VARTYPE_STRING;
     81   invalid_string.value.as_id = 31415926;
     82 
     83   // Invalid strings should give NULL as the return value.
     84   uint32_t len = std::numeric_limits<uint32_t>::max();
     85   const char* result = var_interface_->VarToUtf8(invalid_string, &len);
     86   ASSERT_EQ(0, len);
     87   ASSERT_EQ(NULL, result);
     88 
     89   // Same with vars that are not strings.
     90   len = std::numeric_limits<uint32_t>::max();
     91   pp::Var int_var(42);
     92   result = var_interface_->VarToUtf8(int_var.pp_var(), &len);
     93   ASSERT_EQ(0, len);
     94   ASSERT_EQ(NULL, result);
     95 
     96   // Empty strings should return non-NULL.
     97   pp::Var empty_string("");
     98   len = std::numeric_limits<uint32_t>::max();
     99   result = var_interface_->VarToUtf8(empty_string.pp_var(), &len);
    100   ASSERT_EQ(0, len);
    101   ASSERT_NE(NULL, result);
    102 
    103   PASS();
    104 }
    105 
    106 std::string TestVar::TestInvalidUtf8() {
    107   // utf8 (japanese for "is not utf8") in shift-jis encoding.
    108   static const char kSjisString[] = "utf8\x82\xb6\x82\xe1\x82\xc8\x82\xa2";
    109   pp::Var sjis(kSjisString);
    110   if (!sjis.is_null())
    111     return "Non-UTF8 string was permitted erroneously.";
    112 
    113   PASS();
    114 }
    115 
    116 std::string TestVar::TestNullInputInUtf8Conversion() {
    117   // This test talks directly to the C interface to access edge cases that
    118   // cannot be exercised via the C++ interface.
    119   PP_Var converted_string;
    120 
    121   // 0-length string should not dereference input string, and should produce
    122   // an empty string.
    123   converted_string = var_interface_->VarFromUtf8(NULL, 0);
    124   if (converted_string.type != PP_VARTYPE_STRING) {
    125     return "Expected 0 length to return empty string.";
    126   }
    127 
    128   // Now convert it back.
    129   uint32_t length = kInvalidLength;
    130   const char* result = NULL;
    131   result = var_interface_->VarToUtf8(converted_string, &length);
    132   if (length != 0) {
    133     return "Expected 0 length string on conversion.";
    134   }
    135   if (result == NULL) {
    136     return "Expected a non-null result for 0-lengthed string from VarToUtf8.";
    137   }
    138   var_interface_->Release(converted_string);
    139 
    140   // Should not crash, and make an empty string.
    141   const char* null_string = NULL;
    142   pp::Var null_var(null_string);
    143   if (!null_var.is_string() || null_var.AsString() != "") {
    144     return "Expected NULL input to make an empty string Var.";
    145   }
    146 
    147   PASS();
    148 }
    149 
    150 std::string TestVar::TestValidUtf8() {
    151   // From UTF8 string -> PP_Var.
    152   // Chinese for "I am utf8."
    153   static const char kValidUtf8[] = "\xe6\x88\x91\xe6\x98\xafutf8.";
    154   pp::Var converted_string(kValidUtf8);
    155 
    156   if (converted_string.is_null())
    157     return "Unable to convert valid utf8 to var.";
    158 
    159   // Since we're already here, test PP_Var back to UTF8 string.
    160   std::string returned_string = converted_string.AsString();
    161 
    162   // We need to check against 1 less than sizeof because the resulting string
    163   // is technically not NULL terminated by API design.
    164   if (returned_string.size() != sizeof(kValidUtf8) - 1) {
    165     return "Unable to convert utf8 string back from var.";
    166   }
    167   if (returned_string != kValidUtf8) {
    168     return "String mismatches on conversion back from PP_Var.";
    169   }
    170 
    171   PASS();
    172 }
    173 
    174 std::string TestVar::TestUtf8WithEmbeddedNulls() {
    175   // From UTF8 string with embedded nulls -> PP_Var.
    176   // Chinese for "also utf8."
    177   static const char kUtf8WithEmbededNull[] = "\xe6\xb9\x9f\xe6\x98\xaf\0utf8.";
    178   std::string orig_string(kUtf8WithEmbededNull,
    179                           sizeof(kUtf8WithEmbededNull) -1);
    180   pp::Var converted_string(orig_string);
    181 
    182   if (converted_string.is_null())
    183     return "Unable to convert utf8 with embedded nulls to var.";
    184 
    185   // Since we're already here, test PP_Var back to UTF8 string.
    186   std::string returned_string = converted_string.AsString();
    187 
    188   if (returned_string.size() != orig_string.size()) {
    189     return "Unable to convert utf8 with embedded nulls back from var.";
    190   }
    191   if (returned_string != orig_string) {
    192     return "String mismatches on conversion back from PP_Var.";
    193   }
    194 
    195   PASS();
    196 }
    197 
    198 std::string TestVar::TestVarToUtf8ForWrongType() {
    199   uint32_t length = kInvalidLength;
    200   const char* result = NULL;
    201   result = var_interface_->VarToUtf8(PP_MakeUndefined(), &length);
    202   if (length != 0) {
    203     return "Expected 0 on string conversion from Void var.";
    204   }
    205   if (result != NULL) {
    206     return "Expected NULL on string conversion from Void var.";
    207   }
    208 
    209   length = kInvalidLength;
    210   result = NULL;
    211   result = var_interface_->VarToUtf8(PP_MakeNull(), &length);
    212   if (length != 0) {
    213     return "Expected 0 on string conversion from Null var.";
    214   }
    215   if (result != NULL) {
    216     return "Expected NULL on string conversion from Null var.";
    217   }
    218 
    219   length = kInvalidLength;
    220   result = NULL;
    221   result = var_interface_->VarToUtf8(PP_MakeBool(PP_TRUE), &length);
    222   if (length != 0) {
    223     return "Expected 0 on string conversion from Bool var.";
    224   }
    225   if (result != NULL) {
    226     return "Expected NULL on string conversion from Bool var.";
    227   }
    228 
    229   length = kInvalidLength;
    230   result = NULL;
    231   result = var_interface_->VarToUtf8(PP_MakeInt32(1), &length);
    232   if (length != 0) {
    233     return "Expected 0 on string conversion from Int32 var.";
    234   }
    235   if (result != NULL) {
    236     return "Expected NULL on string conversion from Int32 var.";
    237   }
    238 
    239   length = kInvalidLength;
    240   result = NULL;
    241   result = var_interface_->VarToUtf8(PP_MakeDouble(1.0), &length);
    242   if (length != 0) {
    243     return "Expected 0 on string conversion from Double var.";
    244   }
    245   if (result != NULL) {
    246     return "Expected NULL on string conversion from Double var.";
    247   }
    248 
    249   PASS();
    250 }
    251 
    252