[Android] Ignore exceptions when provision attempts to write local props.
[chromium-blink-merge.git] / ppapi / tests / test_var_deprecated.cc
blobdbfa83e21d61af3f82c07dd3d0e9da0d286fb866
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.
5 #include "ppapi/tests/test_var_deprecated.h"
7 #include <string.h>
9 #include <limits>
11 #include "ppapi/c/pp_var.h"
12 #include "ppapi/c/dev/ppb_var_deprecated.h"
13 #include "ppapi/cpp/dev/scriptable_object_deprecated.h"
14 #include "ppapi/cpp/instance.h"
15 #include "ppapi/cpp/module.h"
16 #include "ppapi/cpp/private/var_private.h"
17 #include "ppapi/cpp/var.h"
18 #include "ppapi/tests/testing_instance.h"
20 namespace {
22 uint32_t kInvalidLength = static_cast<uint32_t>(-1);
24 static const char kSetValueFunction[] = "SetValue";
26 // ScriptableObject used by the var tests.
27 class VarScriptableObject : public pp::deprecated::ScriptableObject {
28 public:
29 VarScriptableObject(TestVarDeprecated* v) : test_var_deprecated_(v) {}
31 // pp::deprecated::ScriptableObject overrides.
32 bool HasMethod(const pp::Var& name, pp::Var* exception);
33 pp::Var Call(const pp::Var& name,
34 const std::vector<pp::Var>& args,
35 pp::Var* exception);
37 private:
38 TestVarDeprecated* test_var_deprecated_;
41 bool VarScriptableObject::HasMethod(const pp::Var& name, pp::Var* exception) {
42 if (!name.is_string())
43 return false;
44 return name.AsString() == kSetValueFunction;
47 pp::Var VarScriptableObject::Call(const pp::Var& method_name,
48 const std::vector<pp::Var>& args,
49 pp::Var* exception) {
50 if (!method_name.is_string())
51 return false;
52 std::string name = method_name.AsString();
54 if (name == kSetValueFunction) {
55 if (args.size() != 1)
56 *exception = pp::Var("Bad argument to SetValue(<value>)");
57 else
58 test_var_deprecated_->set_var_from_page(pp::VarPrivate(args[0]));
61 return pp::Var();
64 } // namespace
66 REGISTER_TEST_CASE(VarDeprecated);
68 bool TestVarDeprecated::Init() {
69 var_interface_ = static_cast<const PPB_Var_Deprecated*>(
70 pp::Module::Get()->GetBrowserInterface(PPB_VAR_DEPRECATED_INTERFACE));
71 return var_interface_ && CheckTestingInterface();
74 void TestVarDeprecated::RunTests(const std::string& filter) {
75 RUN_TEST(BasicString, filter);
76 RUN_TEST(InvalidAndEmpty, filter);
77 RUN_TEST(InvalidUtf8, filter);
78 RUN_TEST(NullInputInUtf8Conversion, filter);
79 RUN_TEST(ValidUtf8, filter);
80 RUN_TEST(Utf8WithEmbeddedNulls, filter);
81 RUN_TEST(VarToUtf8ForWrongType, filter);
82 RUN_TEST(HasPropertyAndMethod, filter);
83 RUN_TEST(PassReference, filter);
86 pp::deprecated::ScriptableObject* TestVarDeprecated::CreateTestObject() {
87 return new VarScriptableObject(this);
90 std::string TestVarDeprecated::TestBasicString() {
91 uint32_t before_object = testing_interface_->GetLiveObjectsForInstance(
92 instance_->pp_instance());
94 const char kStr[] = "Hello";
95 const uint32_t kStrLen(sizeof(kStr) - 1);
96 PP_Var str = var_interface_->VarFromUtf8(pp::Module::Get()->pp_module(),
97 kStr, kStrLen);
98 ASSERT_EQ(PP_VARTYPE_STRING, str.type);
100 // Reading back the string should work.
101 uint32_t len = 0;
102 const char* result = var_interface_->VarToUtf8(str, &len);
103 ASSERT_EQ(kStrLen, len);
104 ASSERT_EQ(0, strncmp(kStr, result, kStrLen));
106 // Destroy the string, readback should now fail.
107 var_interface_->Release(str);
108 result = var_interface_->VarToUtf8(str, &len);
109 ASSERT_EQ(0, len);
110 ASSERT_EQ(NULL, result);
113 // Make sure nothing leaked.
114 ASSERT_TRUE(testing_interface_->GetLiveObjectsForInstance(
115 instance_->pp_instance()) == before_object);
117 PASS();
120 std::string TestVarDeprecated::TestInvalidAndEmpty() {
121 PP_Var invalid_string;
122 invalid_string.type = PP_VARTYPE_STRING;
123 invalid_string.value.as_id = 31415926;
125 // Invalid strings should give NULL as the return value.
126 uint32_t len = std::numeric_limits<uint32_t>::max();
127 const char* result = var_interface_->VarToUtf8(invalid_string, &len);
128 ASSERT_EQ(0, len);
129 ASSERT_EQ(NULL, result);
131 // Same with vars that are not strings.
132 len = std::numeric_limits<uint32_t>::max();
133 pp::Var int_var(42);
134 result = var_interface_->VarToUtf8(int_var.pp_var(), &len);
135 ASSERT_EQ(0, len);
136 ASSERT_EQ(NULL, result);
138 // Empty strings should return non-NULL.
139 pp::Var empty_string("");
140 len = std::numeric_limits<uint32_t>::max();
141 result = var_interface_->VarToUtf8(empty_string.pp_var(), &len);
142 ASSERT_EQ(0, len);
143 ASSERT_NE(NULL, result);
145 PASS();
148 std::string TestVarDeprecated::TestInvalidUtf8() {
149 // utf8じゃăȘい (japanese for "is not utf8") in shift-jis encoding.
150 static const char kSjisString[] = "utf8\x82\xb6\x82\xe1\x82\xc8\x82\xa2";
151 pp::Var sjis(kSjisString);
152 if (!sjis.is_null())
153 return "Non-UTF8 string was permitted erroneously.";
155 PASS();
158 std::string TestVarDeprecated::TestNullInputInUtf8Conversion() {
159 // This test talks directly to the C interface to access edge cases that
160 // cannot be exercised via the C++ interface.
161 PP_Var converted_string;
163 // 0-length string should not dereference input string, and should produce
164 // an empty string.
165 converted_string = var_interface_->VarFromUtf8(
166 pp::Module::Get()->pp_module(), NULL, 0);
167 if (converted_string.type != PP_VARTYPE_STRING) {
168 return "Expected 0 length to return empty string.";
171 // Now convert it back.
172 uint32_t length = kInvalidLength;
173 const char* result = NULL;
174 result = var_interface_->VarToUtf8(converted_string, &length);
175 if (length != 0) {
176 return "Expected 0 length string on conversion.";
178 if (result == NULL) {
179 return "Expected a non-null result for 0-lengthed string from VarToUtf8.";
181 var_interface_->Release(converted_string);
183 // Should not crash, and make an empty string.
184 const char* null_string = NULL;
185 pp::Var null_var(null_string);
186 if (!null_var.is_string() || null_var.AsString() != "") {
187 return "Expected NULL input to make an empty string Var.";
190 PASS();
193 std::string TestVarDeprecated::TestValidUtf8() {
194 // From UTF8 string -> PP_Var.
195 // Chinese for "I am utf8."
196 static const char kValidUtf8[] = "\xe6\x88\x91\xe6\x98\xafutf8.";
197 pp::Var converted_string(kValidUtf8);
199 if (converted_string.is_null())
200 return "Unable to convert valid utf8 to var.";
202 // Since we're already here, test PP_Var back to UTF8 string.
203 std::string returned_string = converted_string.AsString();
205 // We need to check against 1 less than sizeof because the resulting string
206 // is technically not NULL terminated by API design.
207 if (returned_string.size() != sizeof(kValidUtf8) - 1) {
208 return "Unable to convert utf8 string back from var.";
210 if (returned_string != kValidUtf8) {
211 return "String mismatches on conversion back from PP_Var.";
214 PASS();
217 std::string TestVarDeprecated::TestUtf8WithEmbeddedNulls() {
218 // From UTF8 string with embedded nulls -> PP_Var.
219 // Chinese for "also utf8."
220 static const char kUtf8WithEmbededNull[] = "\xe6\xb9\x9f\xe6\x98\xaf\0utf8.";
221 std::string orig_string(kUtf8WithEmbededNull,
222 sizeof(kUtf8WithEmbededNull) -1);
223 pp::Var converted_string(orig_string);
225 if (converted_string.is_null())
226 return "Unable to convert utf8 with embedded nulls to var.";
228 // Since we're already here, test PP_Var back to UTF8 string.
229 std::string returned_string = converted_string.AsString();
231 if (returned_string.size() != orig_string.size()) {
232 return "Unable to convert utf8 with embedded nulls back from var.";
234 if (returned_string != orig_string) {
235 return "String mismatches on conversion back from PP_Var.";
238 PASS();
241 std::string TestVarDeprecated::TestVarToUtf8ForWrongType() {
242 uint32_t length = kInvalidLength;
243 const char* result = NULL;
244 result = var_interface_->VarToUtf8(PP_MakeUndefined(), &length);
245 if (length != 0) {
246 return "Expected 0 on string conversion from Void var.";
248 if (result != NULL) {
249 return "Expected NULL on string conversion from Void var.";
252 length = kInvalidLength;
253 result = NULL;
254 result = var_interface_->VarToUtf8(PP_MakeNull(), &length);
255 if (length != 0) {
256 return "Expected 0 on string conversion from Null var.";
258 if (result != NULL) {
259 return "Expected NULL on string conversion from Null var.";
262 length = kInvalidLength;
263 result = NULL;
264 result = var_interface_->VarToUtf8(PP_MakeBool(PP_TRUE), &length);
265 if (length != 0) {
266 return "Expected 0 on string conversion from Bool var.";
268 if (result != NULL) {
269 return "Expected NULL on string conversion from Bool var.";
272 length = kInvalidLength;
273 result = NULL;
274 result = var_interface_->VarToUtf8(PP_MakeInt32(1), &length);
275 if (length != 0) {
276 return "Expected 0 on string conversion from Int32 var.";
278 if (result != NULL) {
279 return "Expected NULL on string conversion from Int32 var.";
282 length = kInvalidLength;
283 result = NULL;
284 result = var_interface_->VarToUtf8(PP_MakeDouble(1.0), &length);
285 if (length != 0) {
286 return "Expected 0 on string conversion from Double var.";
288 if (result != NULL) {
289 return "Expected NULL on string conversion from Double var.";
292 PASS();
295 std::string TestVarDeprecated::TestHasPropertyAndMethod() {
296 pp::VarPrivate window = instance_->GetWindowObject();
297 ASSERT_TRUE(window.is_object());
299 // Regular property.
300 pp::Var exception;
301 ASSERT_TRUE(window.HasProperty("scrollX", &exception));
302 ASSERT_TRUE(exception.is_undefined());
303 ASSERT_FALSE(window.HasMethod("scrollX", &exception));
304 ASSERT_TRUE(exception.is_undefined());
306 // Regular method (also counts as HasProperty).
307 ASSERT_TRUE(window.HasProperty("find", &exception));
308 ASSERT_TRUE(exception.is_undefined());
309 ASSERT_TRUE(window.HasMethod("find", &exception));
310 ASSERT_TRUE(exception.is_undefined());
312 // Nonexistant ones should return false and not set the exception.
313 ASSERT_FALSE(window.HasProperty("superEvilBit", &exception));
314 ASSERT_TRUE(exception.is_undefined());
315 ASSERT_FALSE(window.HasMethod("superEvilBit", &exception));
316 ASSERT_TRUE(exception.is_undefined());
318 // Check exception and return false on invalid property name.
319 ASSERT_FALSE(window.HasProperty(3.14159, &exception));
320 ASSERT_FALSE(exception.is_undefined());
321 exception = pp::Var();
323 exception = pp::Var();
324 ASSERT_FALSE(window.HasMethod(3.14159, &exception));
325 ASSERT_FALSE(exception.is_undefined());
327 // Try to use something not an object.
328 exception = pp::Var();
329 pp::VarPrivate string_object("asdf");
330 ASSERT_FALSE(string_object.HasProperty("find", &exception));
331 ASSERT_FALSE(exception.is_undefined());
332 exception = pp::Var();
333 ASSERT_FALSE(string_object.HasMethod("find", &exception));
334 ASSERT_FALSE(exception.is_undefined());
336 // Try to use an invalid object (need to use the C API).
337 PP_Var invalid_object;
338 invalid_object.type = PP_VARTYPE_OBJECT;
339 invalid_object.value.as_id = static_cast<int64_t>(-1234567);
340 PP_Var exception2 = PP_MakeUndefined();
341 ASSERT_FALSE(var_interface_->HasProperty(invalid_object,
342 pp::Var("find").pp_var(),
343 &exception2));
344 ASSERT_NE(PP_VARTYPE_UNDEFINED, exception2.type);
345 var_interface_->Release(exception2);
347 exception2 = PP_MakeUndefined();
348 ASSERT_FALSE(var_interface_->HasMethod(invalid_object,
349 pp::Var("find").pp_var(),
350 &exception2));
351 ASSERT_NE(PP_VARTYPE_UNDEFINED, exception2.type);
352 var_interface_->Release(exception2);
354 // Getting a valid property/method when the exception is set returns false.
355 exception = pp::Var("Bad something-or-other exception");
356 ASSERT_FALSE(window.HasProperty("find", &exception));
357 ASSERT_FALSE(exception.is_undefined());
358 ASSERT_FALSE(window.HasMethod("find", &exception));
359 ASSERT_FALSE(exception.is_undefined());
361 PASS();
364 // Tests that when the page sends an object to the plugin via a function call,
365 // that the refcounting works properly (bug 79813).
366 std::string TestVarDeprecated::TestPassReference() {
367 var_from_page_ = pp::Var();
369 // Send a JS object from the page to the plugin.
370 pp::Var exception;
371 pp::Var ret = instance_->ExecuteScript(
372 "document.getElementById('plugin').SetValue(function(arg) {"
373 "return 'works' + arg;"
374 "})",
375 &exception);
376 ASSERT_TRUE(exception.is_undefined());
378 // We should have gotten an object set for our var_from_page.
379 ASSERT_TRUE(var_from_page_.is_object());
381 // If the reference counting works, the object should be valid. We can test
382 // this by executing it (it was a function we defined above) and it should
383 // return "works" concatenated with the argument.
384 pp::VarPrivate function(var_from_page_);
385 pp::Var result = var_from_page_.Call(pp::Var(), "nice");
386 ASSERT_TRUE(result.is_string());
387 ASSERT_TRUE(result.AsString() == "worksnice");
389 // Reset var_from_page_ so it doesn't seem like a leak to the var leak
390 // checking code.
391 var_from_page_ = pp::Var();
393 PASS();