OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/tests/test_post_message.h" | 5 #include "ppapi/tests/test_post_message.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | |
8 #include <sstream> | 9 #include <sstream> |
9 | 10 |
10 #include "ppapi/c/dev/ppb_testing_dev.h" | 11 #include "ppapi/c/dev/ppb_testing_dev.h" |
11 #include "ppapi/c/pp_var.h" | 12 #include "ppapi/c/pp_var.h" |
12 #include "ppapi/cpp/instance.h" | 13 #include "ppapi/cpp/instance.h" |
13 #include "ppapi/cpp/var.h" | 14 #include "ppapi/cpp/var.h" |
14 #include "ppapi/cpp/var_array_buffer.h" | 15 #include "ppapi/cpp/var_array_buffer.h" |
15 #include "ppapi/tests/pp_thread.h" | 16 #include "ppapi/tests/pp_thread.h" |
16 #include "ppapi/tests/test_utils.h" | 17 #include "ppapi/tests/test_utils.h" |
17 #include "ppapi/tests/testing_instance.h" | 18 #include "ppapi/tests/testing_instance.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 }; | 52 }; |
52 | 53 |
53 void InvokePostMessageThreadFunc(void* user_data) { | 54 void InvokePostMessageThreadFunc(void* user_data) { |
54 InvokePostMessageThreadArg* arg = | 55 InvokePostMessageThreadArg* arg = |
55 static_cast<InvokePostMessageThreadArg*>(user_data); | 56 static_cast<InvokePostMessageThreadArg*>(user_data); |
56 for (int32_t i = 0; i < kMessagesToSendPerThread; ++i) | 57 for (int32_t i = 0; i < kMessagesToSendPerThread; ++i) |
57 arg->instance->PostMessage(arg->value_to_send); | 58 arg->instance->PostMessage(arg->value_to_send); |
58 delete arg; | 59 delete arg; |
59 } | 60 } |
60 | 61 |
62 // TODO(raymes): Consider putting something like this into pp::Var. | |
63 bool VarsEqual(const pp::Var& expected, | |
64 const pp::Var& actual, | |
65 std::map<int64_t, int64_t>* visited_ids) { | |
66 if (expected.pp_var().type != actual.pp_var().type) { | |
67 if (!expected.is_number() && !actual.is_number()) | |
68 return false; | |
69 } | |
70 // TODO(raymes): Implement a pp::Var::IsRefCounted() function. | |
71 if (expected.pp_var().type > PP_VARTYPE_DOUBLE) { | |
72 std::map<int64_t, int64_t>::const_iterator it = | |
73 visited_ids->find(expected.pp_var().value.as_id); | |
74 if (it != visited_ids->end()) { | |
75 if (it->second == actual.pp_var().value.as_id) | |
76 return true; | |
77 return false; | |
78 } | |
79 (*visited_ids)[expected.pp_var().value.as_id] = actual.pp_var().value.as_id; | |
dmichael (off chromium)
2013/05/09 20:21:12
random trivia: You can do this with one lookup usi
raymes
2013/05/13 17:09:43
Cool thanks - yeah I didn't know (or I knew and fo
| |
80 } | |
81 | |
82 if (expected.is_number()) { | |
83 return fabs(expected.AsDouble() - actual.AsDouble()) < 1.0e-4; | |
84 } else if (expected.is_array()) { | |
85 pp::VarArray_Dev expected_array(expected); | |
86 pp::VarArray_Dev actual_array(actual); | |
87 if (expected_array.GetLength() != actual_array.GetLength()) | |
88 return false; | |
89 for (uint32_t i = 0; i < expected_array.GetLength(); ++i) { | |
90 if (!VarsEqual(expected_array.Get(i), actual_array.Get(i), visited_ids)) | |
91 return false; | |
92 } | |
93 return true; | |
94 } else if (expected.is_dictionary()) { | |
95 pp::VarDictionary_Dev expected_dict(expected); | |
96 pp::VarDictionary_Dev actual_dict(actual); | |
97 if (expected_dict.GetKeys().GetLength() != | |
98 actual_dict.GetKeys().GetLength()) { | |
99 return false; | |
100 } | |
101 for (uint32_t i = 0; i < expected_dict.GetKeys().GetLength(); ++i) { | |
102 pp::Var key = expected_dict.GetKeys().Get(i); | |
dmichael (off chromium)
2013/05/09 20:21:12
Don't you also need to compare the value of the ke
raymes
2013/05/13 17:09:43
Well it's not iterating through the values here, b
dmichael (off chromium)
2013/05/13 18:02:26
Sorry, I was misreading, as if you were using the
| |
103 if (!VarsEqual(expected_dict.Get(key), actual_dict.Get(key), visited_ids)) | |
104 return false; | |
105 } | |
106 return true; | |
107 } else { | |
108 return expected == actual; | |
109 } | |
110 } | |
111 | |
112 bool VarsEqual(const pp::Var& expected, | |
113 const pp::Var& actual) { | |
114 std::map<int64_t, int64_t> visited_ids; | |
115 return VarsEqual(expected, actual, &visited_ids); | |
116 } | |
117 | |
61 class ScopedArrayBufferSizeSetter { | 118 class ScopedArrayBufferSizeSetter { |
62 public: | 119 public: |
63 ScopedArrayBufferSizeSetter(const PPB_Testing_Dev* interface, | 120 ScopedArrayBufferSizeSetter(const PPB_Testing_Dev* interface, |
64 PP_Instance instance, | 121 PP_Instance instance, |
65 uint32_t threshold) | 122 uint32_t threshold) |
66 : interface_(interface), | 123 : interface_(interface), |
67 instance_(instance) { | 124 instance_(instance) { |
68 interface_->SetMinimumArrayBufferSizeForShmem(instance_, threshold); | 125 interface_->SetMinimumArrayBufferSizeForShmem(instance_, threshold); |
69 } | 126 } |
70 ~ScopedArrayBufferSizeSetter() { | 127 ~ScopedArrayBufferSizeSetter() { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 | 185 |
129 return success; | 186 return success; |
130 } | 187 } |
131 | 188 |
132 void TestPostMessage::RunTests(const std::string& filter) { | 189 void TestPostMessage::RunTests(const std::string& filter) { |
133 // Note: SendInInit must be first, because it expects to receive a message | 190 // Note: SendInInit must be first, because it expects to receive a message |
134 // that was sent in Init above. | 191 // that was sent in Init above. |
135 RUN_TEST(SendInInit, filter); | 192 RUN_TEST(SendInInit, filter); |
136 RUN_TEST(SendingData, filter); | 193 RUN_TEST(SendingData, filter); |
137 RUN_TEST(SendingArrayBuffer, filter); | 194 RUN_TEST(SendingArrayBuffer, filter); |
195 RUN_TEST(SendingArray, filter); | |
196 RUN_TEST(SendingDictionary, filter); | |
197 RUN_TEST(SendingComplexVar, filter); | |
138 RUN_TEST(MessageEvent, filter); | 198 RUN_TEST(MessageEvent, filter); |
139 RUN_TEST(NoHandler, filter); | 199 RUN_TEST(NoHandler, filter); |
140 RUN_TEST(ExtraParam, filter); | 200 RUN_TEST(ExtraParam, filter); |
141 if (testing_interface_->IsOutOfProcess()) | 201 if (testing_interface_->IsOutOfProcess()) |
142 RUN_TEST(NonMainThread, filter); | 202 RUN_TEST(NonMainThread, filter); |
143 } | 203 } |
144 | 204 |
145 void TestPostMessage::HandleMessage(const pp::Var& message_data) { | 205 void TestPostMessage::HandleMessage(const pp::Var& message_data) { |
146 if (message_data.is_string() && | 206 if (message_data.is_string() && |
147 (message_data.AsString() == FINISHED_WAITING_MESSAGE)) | 207 (message_data.AsString() == FINISHED_WAITING_MESSAGE)) |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
353 for (size_t i = 0; i < test_data.ByteLength(); ++i) | 413 for (size_t i = 0; i < test_data.ByteLength(); ++i) |
354 ASSERT_EQ(buff[i], received_buff[i]); | 414 ASSERT_EQ(buff[i], received_buff[i]); |
355 | 415 |
356 message_data_.clear(); | 416 message_data_.clear(); |
357 ASSERT_TRUE(ClearListeners()); | 417 ASSERT_TRUE(ClearListeners()); |
358 } | 418 } |
359 | 419 |
360 PASS(); | 420 PASS(); |
361 } | 421 } |
362 | 422 |
423 std::string TestPostMessage::TestSendingArray() { | |
424 // Clean up after previous tests. This also swallows the message sent by Init | |
425 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' | |
426 // should start with these. | |
427 WaitForMessages(); | |
428 ASSERT_TRUE(ClearListeners()); | |
429 | |
430 pp::VarArray_Dev array; | |
431 array.Set(0, pp::Var(kTestBool)); | |
432 array.Set(1, pp::Var(kTestString)); | |
433 // Purposely leave index 2 empty. | |
434 array.Set(3, pp::Var(kTestInt)); | |
435 array.Set(4, pp::Var(kTestDouble)); | |
436 | |
437 std::stringstream ss; | |
438 ss << array.GetLength(); | |
dmichael (off chromium)
2013/05/09 20:21:12
How about:
std::string length_as_string(ss.str());
raymes
2013/05/13 17:09:43
Done.
| |
439 | |
440 // Have the listener test some properties of the Array. | |
441 std::vector<std::string> properties_to_check; | |
442 properties_to_check.push_back( | |
443 "message_event.data.constructor.name === 'Array'"); | |
444 properties_to_check.push_back( | |
445 std::string("message_event.data.length === ") + ss.str()); | |
446 for (std::vector<std::string>::iterator iter = properties_to_check.begin(); | |
447 iter != properties_to_check.end(); | |
448 ++iter) { | |
449 ASSERT_TRUE(AddEchoingListener(*iter)); | |
450 message_data_.clear(); | |
451 instance_->PostMessage(array); | |
452 ASSERT_EQ(message_data_.size(), 0); | |
453 ASSERT_EQ(WaitForMessages(), 1); | |
454 ASSERT_TRUE(message_data_.back().is_bool()); | |
455 if (!message_data_.back().AsBool()) | |
456 return std::string("Failed: ") + *iter + ", size: " + ss.str(); | |
457 ASSERT_TRUE(message_data_.back().AsBool()); | |
458 ASSERT_TRUE(ClearListeners()); | |
dmichael (off chromium)
2013/05/09 20:21:12
I wonder how hard it would be to wrap this propert
raymes
2013/05/13 17:09:43
Done.
| |
459 } | |
460 | |
461 // Set up the JavaScript message event listener to echo the data part of the | |
462 // message event back to us. | |
463 ASSERT_TRUE(AddEchoingListener("message_event.data")); | |
464 message_data_.clear(); | |
465 instance_->PostMessage(array); | |
466 // PostMessage is asynchronous, so we should not receive a response yet. | |
467 ASSERT_EQ(message_data_.size(), 0); | |
468 ASSERT_EQ(WaitForMessages(), 1); | |
469 ASSERT_TRUE(message_data_.back().is_array()); | |
470 ASSERT_TRUE(VarsEqual(array, message_data_.back())); | |
471 | |
472 message_data_.clear(); | |
473 ASSERT_TRUE(ClearListeners()); | |
474 | |
475 PASS(); | |
476 } | |
477 | |
478 std::string TestPostMessage::TestSendingDictionary() { | |
479 // Clean up after previous tests. This also swallows the message sent by Init | |
480 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' | |
481 // should start with these. | |
482 WaitForMessages(); | |
483 ASSERT_TRUE(ClearListeners()); | |
484 | |
485 pp::VarDictionary_Dev dictionary; | |
486 dictionary.Set(pp::Var("foo"), pp::Var(kTestBool)); | |
487 dictionary.Set(pp::Var("bar"), pp::Var(kTestString)); | |
488 dictionary.Set(pp::Var("abc"), pp::Var(kTestInt)); | |
489 dictionary.Set(pp::Var("def"), pp::Var()); | |
490 | |
491 std::stringstream ss; | |
492 ss << dictionary.GetKeys().GetLength(); | |
493 | |
494 // Have the listener test some properties of the Dictionary. | |
495 std::vector<std::string> properties_to_check; | |
496 properties_to_check.push_back( | |
497 "message_event.data.constructor.name === 'Object'"); | |
498 properties_to_check.push_back( | |
499 std::string("Object.keys(message_event.data).length === ") + ss.str()); | |
500 for (std::vector<std::string>::iterator iter = properties_to_check.begin(); | |
501 iter != properties_to_check.end(); | |
502 ++iter) { | |
503 ASSERT_TRUE(AddEchoingListener(*iter)); | |
504 message_data_.clear(); | |
505 instance_->PostMessage(dictionary); | |
506 ASSERT_EQ(message_data_.size(), 0); | |
507 ASSERT_EQ(WaitForMessages(), 1); | |
508 ASSERT_TRUE(message_data_.back().is_bool()); | |
509 if (!message_data_.back().AsBool()) | |
510 return std::string("Failed: ") + *iter + ", size: " + ss.str(); | |
511 ASSERT_TRUE(message_data_.back().AsBool()); | |
512 ASSERT_TRUE(ClearListeners()); | |
513 } | |
514 | |
515 // Set up the JavaScript message event listener to echo the data part of the | |
516 // message event back to us. | |
517 ASSERT_TRUE(AddEchoingListener("message_event.data")); | |
518 message_data_.clear(); | |
519 instance_->PostMessage(dictionary); | |
520 // PostMessage is asynchronous, so we should not receive a response yet. | |
521 ASSERT_EQ(message_data_.size(), 0); | |
522 ASSERT_EQ(WaitForMessages(), 1); | |
523 ASSERT_TRUE(message_data_.back().is_dictionary()); | |
524 ASSERT_TRUE(VarsEqual(dictionary, message_data_.back())); | |
525 | |
526 message_data_.clear(); | |
527 ASSERT_TRUE(ClearListeners()); | |
528 | |
529 PASS(); | |
530 } | |
531 | |
532 std::string TestPostMessage::TestSendingComplexVar() { | |
533 // Clean up after previous tests. This also swallows the message sent by Init | |
534 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' | |
535 // should start with these. | |
536 WaitForMessages(); | |
537 ASSERT_TRUE(ClearListeners()); | |
538 | |
539 pp::VarDictionary_Dev dictionary; | |
540 dictionary.Set(pp::Var("foo"), pp::Var(kTestBool)); | |
541 dictionary.Set(pp::Var("bar"), pp::Var(kTestString)); | |
542 dictionary.Set(pp::Var("abc"), pp::Var(kTestInt)); | |
543 dictionary.Set(pp::Var("def"), pp::Var()); | |
544 dictionary.Set(pp::Var("dictionary"), dictionary); // Self-reference. | |
545 | |
546 // Reference to array. | |
547 pp::VarArray_Dev array; | |
548 array.Set(0, pp::Var(kTestBool)); | |
549 array.Set(1, pp::Var(kTestString)); | |
550 // Purposely leave index 2 empty. | |
dmichael (off chromium)
2013/05/09 20:21:12
This doesn't actually leave index 2 empty in our i
raymes
2013/05/13 17:09:43
Right - I updated the comment to clarify.
| |
551 array.Set(3, pp::Var(kTestInt)); | |
552 array.Set(4, pp::Var(kTestDouble)); | |
553 | |
554 dictionary.Set(pp::Var("array1"), array); | |
555 dictionary.Set(pp::Var("array2"), array); | |
556 | |
557 // Set up a (dictionary -> dictionary2 -> dictionary) cycle. | |
558 pp::VarDictionary_Dev dictionary2; | |
559 dictionary2.Set(pp::Var("dictionary"), dictionary); | |
560 dictionary.Set(pp::Var("dictionary2"), dictionary2); | |
dmichael (off chromium)
2013/05/09 20:21:12
Can we involve an array in a cycle too? And maybe
raymes
2013/05/13 17:09:43
Done - I modified it to add these 2 cases. I didn'
| |
561 | |
562 // Set up the JavaScript message event listener to echo the data part of the | |
563 // message event back to us. | |
564 ASSERT_TRUE(AddEchoingListener("message_event.data")); | |
565 message_data_.clear(); | |
566 instance_->PostMessage(dictionary); | |
567 // PostMessage is asynchronous, so we should not receive a response yet. | |
568 ASSERT_EQ(message_data_.size(), 0); | |
569 ASSERT_EQ(WaitForMessages(), 1); | |
570 ASSERT_TRUE(message_data_.back().is_dictionary()); | |
571 pp::VarDictionary_Dev result(message_data_.back()); | |
572 ASSERT_TRUE(VarsEqual(dictionary, message_data_.back())); | |
573 | |
574 // Break the cycles. | |
575 dictionary.Delete(pp::Var("dictionary")); | |
576 dictionary.Delete(pp::Var("dictionary2")); | |
577 result.Delete(pp::Var("dictionary")); | |
578 result.Delete(pp::Var("dictionary2")); | |
579 | |
580 message_data_.clear(); | |
581 ASSERT_TRUE(ClearListeners()); | |
582 | |
583 PASS(); | |
584 } | |
585 | |
363 std::string TestPostMessage::TestMessageEvent() { | 586 std::string TestPostMessage::TestMessageEvent() { |
364 // Set up the JavaScript message event listener to pass us some values from | 587 // Set up the JavaScript message event listener to pass us some values from |
365 // the MessageEvent and make sure they match our expectations. | 588 // the MessageEvent and make sure they match our expectations. |
366 | 589 |
367 WaitForMessages(); | 590 WaitForMessages(); |
368 ASSERT_TRUE(ClearListeners()); | 591 ASSERT_TRUE(ClearListeners()); |
369 // Have the listener pass back the class name of message_event and make sure | 592 // Have the listener pass back the class name of message_event and make sure |
370 // it's "MessageEvent". | 593 // it's "MessageEvent". |
371 ASSERT_TRUE(AddEchoingListener("message_event.constructor.name")); | 594 ASSERT_TRUE(AddEchoingListener("message_event.constructor.name")); |
372 message_data_.clear(); | 595 message_data_.clear(); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 ASSERT_TRUE(received_value <= kThreadsToRun); | 733 ASSERT_TRUE(received_value <= kThreadsToRun); |
511 ++received_counts[received_value]; | 734 ++received_counts[received_value]; |
512 } | 735 } |
513 ASSERT_EQ(received_counts, expected_counts); | 736 ASSERT_EQ(received_counts, expected_counts); |
514 | 737 |
515 message_data_.clear(); | 738 message_data_.clear(); |
516 ASSERT_TRUE(ClearListeners()); | 739 ASSERT_TRUE(ClearListeners()); |
517 | 740 |
518 PASS(); | 741 PASS(); |
519 } | 742 } |
OLD | NEW |