| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 | 6 |
| 7 #include "include/dart_tools_api.h" | 7 #include "include/dart_tools_api.h" |
| 8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 } | 65 } |
| 66 | 66 |
| 67 const char* msg() const { return _msg; } | 67 const char* msg() const { return _msg; } |
| 68 | 68 |
| 69 virtual Isolate* isolate() const { return Isolate::Current(); } | 69 virtual Isolate* isolate() const { return Isolate::Current(); } |
| 70 | 70 |
| 71 private: | 71 private: |
| 72 char* _msg; | 72 char* _msg; |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 | |
| 76 static RawArray* Eval(Dart_Handle lib, const char* expr) { | 75 static RawArray* Eval(Dart_Handle lib, const char* expr) { |
| 77 const String& dummy_isolate_id = String::Handle(String::New("isolateId")); | 76 const String& dummy_isolate_id = String::Handle(String::New("isolateId")); |
| 78 Dart_Handle expr_val = Dart_EvaluateExpr(lib, NewString(expr)); | 77 Dart_Handle expr_val = Dart_EvaluateExpr(lib, NewString(expr)); |
| 79 EXPECT_VALID(expr_val); | 78 EXPECT_VALID(expr_val); |
| 80 Zone* zone = Thread::Current()->zone(); | 79 Zone* zone = Thread::Current()->zone(); |
| 81 const GrowableObjectArray& value = | 80 const GrowableObjectArray& value = |
| 82 Api::UnwrapGrowableObjectArrayHandle(zone, expr_val); | 81 Api::UnwrapGrowableObjectArrayHandle(zone, expr_val); |
| 83 const Array& result = Array::Handle(Array::MakeFixedLength(value)); | 82 const Array& result = Array::Handle(Array::MakeFixedLength(value)); |
| 84 GrowableObjectArray& growable = GrowableObjectArray::Handle(); | 83 GrowableObjectArray& growable = GrowableObjectArray::Handle(); |
| 85 growable ^= result.At(4); | 84 growable ^= result.At(4); |
| 86 // Append dummy isolate id to parameter values. | 85 // Append dummy isolate id to parameter values. |
| 87 growable.Add(dummy_isolate_id); | 86 growable.Add(dummy_isolate_id); |
| 88 Array& array = Array::Handle(Array::MakeFixedLength(growable)); | 87 Array& array = Array::Handle(Array::MakeFixedLength(growable)); |
| 89 result.SetAt(4, array); | 88 result.SetAt(4, array); |
| 90 growable ^= result.At(5); | 89 growable ^= result.At(5); |
| 91 // Append dummy isolate id to parameter values. | 90 // Append dummy isolate id to parameter values. |
| 92 growable.Add(dummy_isolate_id); | 91 growable.Add(dummy_isolate_id); |
| 93 array = Array::MakeFixedLength(growable); | 92 array = Array::MakeFixedLength(growable); |
| 94 result.SetAt(5, array); | 93 result.SetAt(5, array); |
| 95 return result.raw(); | 94 return result.raw(); |
| 96 } | 95 } |
| 97 | 96 |
| 98 | |
| 99 static RawArray* EvalF(Dart_Handle lib, const char* fmt, ...) { | 97 static RawArray* EvalF(Dart_Handle lib, const char* fmt, ...) { |
| 100 va_list args; | 98 va_list args; |
| 101 va_start(args, fmt); | 99 va_start(args, fmt); |
| 102 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 100 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
| 103 va_end(args); | 101 va_end(args); |
| 104 | 102 |
| 105 char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1); | 103 char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1); |
| 106 va_list args2; | 104 va_list args2; |
| 107 va_start(args2, fmt); | 105 va_start(args2, fmt); |
| 108 OS::VSNPrint(buffer, (len + 1), fmt, args2); | 106 OS::VSNPrint(buffer, (len + 1), fmt, args2); |
| 109 va_end(args2); | 107 va_end(args2); |
| 110 | 108 |
| 111 return Eval(lib, buffer); | 109 return Eval(lib, buffer); |
| 112 } | 110 } |
| 113 | 111 |
| 114 | |
| 115 static RawFunction* GetFunction(const Class& cls, const char* name) { | 112 static RawFunction* GetFunction(const Class& cls, const char* name) { |
| 116 const Function& result = Function::Handle( | 113 const Function& result = Function::Handle( |
| 117 cls.LookupDynamicFunction(String::Handle(String::New(name)))); | 114 cls.LookupDynamicFunction(String::Handle(String::New(name)))); |
| 118 EXPECT(!result.IsNull()); | 115 EXPECT(!result.IsNull()); |
| 119 return result.raw(); | 116 return result.raw(); |
| 120 } | 117 } |
| 121 | 118 |
| 122 | |
| 123 static RawClass* GetClass(const Library& lib, const char* name) { | 119 static RawClass* GetClass(const Library& lib, const char* name) { |
| 124 const Class& cls = Class::Handle( | 120 const Class& cls = Class::Handle( |
| 125 lib.LookupClass(String::Handle(Symbols::New(Thread::Current(), name)))); | 121 lib.LookupClass(String::Handle(Symbols::New(Thread::Current(), name)))); |
| 126 EXPECT(!cls.IsNull()); // No ambiguity error expected. | 122 EXPECT(!cls.IsNull()); // No ambiguity error expected. |
| 127 return cls.raw(); | 123 return cls.raw(); |
| 128 } | 124 } |
| 129 | 125 |
| 130 | |
| 131 static void HandleIsolateMessage(Isolate* isolate, const Array& msg) { | 126 static void HandleIsolateMessage(Isolate* isolate, const Array& msg) { |
| 132 TransitionNativeToVM transition(Thread::Current()); | 127 TransitionNativeToVM transition(Thread::Current()); |
| 133 Service::HandleIsolateMessage(isolate, msg); | 128 Service::HandleIsolateMessage(isolate, msg); |
| 134 } | 129 } |
| 135 | 130 |
| 136 | |
| 137 static void HandleRootMessage(const Array& message) { | 131 static void HandleRootMessage(const Array& message) { |
| 138 TransitionNativeToVM transition(Thread::Current()); | 132 TransitionNativeToVM transition(Thread::Current()); |
| 139 Service::HandleRootMessage(message); | 133 Service::HandleRootMessage(message); |
| 140 } | 134 } |
| 141 | 135 |
| 142 | |
| 143 TEST_CASE(Service_IsolateStickyError) { | 136 TEST_CASE(Service_IsolateStickyError) { |
| 144 const char* kScript = "main() => throw 'HI THERE STICKY';\n"; | 137 const char* kScript = "main() => throw 'HI THERE STICKY';\n"; |
| 145 | 138 |
| 146 Isolate* isolate = thread->isolate(); | 139 Isolate* isolate = thread->isolate(); |
| 147 isolate->set_is_runnable(true); | 140 isolate->set_is_runnable(true); |
| 148 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | 141 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| 149 EXPECT_VALID(lib); | 142 EXPECT_VALID(lib); |
| 150 Library& vmlib = Library::Handle(); | 143 Library& vmlib = Library::Handle(); |
| 151 vmlib ^= Api::UnwrapHandle(lib); | 144 vmlib ^= Api::UnwrapHandle(lib); |
| 152 EXPECT(!vmlib.IsNull()); | 145 EXPECT(!vmlib.IsNull()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 176 | 169 |
| 177 JSONStream js; | 170 JSONStream js; |
| 178 isolate->PrintJSON(&js, false); | 171 isolate->PrintJSON(&js, false); |
| 179 // Error and PauseExit set. | 172 // Error and PauseExit set. |
| 180 EXPECT_SUBSTRING("\"error\":", js.ToCString()); | 173 EXPECT_SUBSTRING("\"error\":", js.ToCString()); |
| 181 EXPECT_SUBSTRING("HI THERE STICKY", js.ToCString()); | 174 EXPECT_SUBSTRING("HI THERE STICKY", js.ToCString()); |
| 182 EXPECT_SUBSTRING("PauseExit", js.ToCString()); | 175 EXPECT_SUBSTRING("PauseExit", js.ToCString()); |
| 183 } | 176 } |
| 184 } | 177 } |
| 185 | 178 |
| 186 | |
| 187 TEST_CASE(Service_IdZones) { | 179 TEST_CASE(Service_IdZones) { |
| 188 Zone* zone = thread->zone(); | 180 Zone* zone = thread->zone(); |
| 189 Isolate* isolate = thread->isolate(); | 181 Isolate* isolate = thread->isolate(); |
| 190 ObjectIdRing* ring = isolate->object_id_ring(); | 182 ObjectIdRing* ring = isolate->object_id_ring(); |
| 191 | 183 |
| 192 const String& test_a = String::Handle(zone, String::New("a")); | 184 const String& test_a = String::Handle(zone, String::New("a")); |
| 193 const String& test_b = String::Handle(zone, String::New("b")); | 185 const String& test_b = String::Handle(zone, String::New("b")); |
| 194 const String& test_c = String::Handle(zone, String::New("c")); | 186 const String& test_c = String::Handle(zone, String::New("c")); |
| 195 const String& test_d = String::Handle(zone, String::New("d")); | 187 const String& test_d = String::Handle(zone, String::New("d")); |
| 196 | 188 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 211 EXPECT_STREQ("objects/0", reuse_zone.GetServiceId(test_a)); | 203 EXPECT_STREQ("objects/0", reuse_zone.GetServiceId(test_a)); |
| 212 EXPECT_STREQ("objects/0", reuse_zone.GetServiceId(test_a)); | 204 EXPECT_STREQ("objects/0", reuse_zone.GetServiceId(test_a)); |
| 213 EXPECT_STREQ("objects/3", reuse_zone.GetServiceId(test_b)); | 205 EXPECT_STREQ("objects/3", reuse_zone.GetServiceId(test_b)); |
| 214 EXPECT_STREQ("objects/3", reuse_zone.GetServiceId(test_b)); | 206 EXPECT_STREQ("objects/3", reuse_zone.GetServiceId(test_b)); |
| 215 EXPECT_STREQ("objects/4", reuse_zone.GetServiceId(test_c)); | 207 EXPECT_STREQ("objects/4", reuse_zone.GetServiceId(test_c)); |
| 216 EXPECT_STREQ("objects/4", reuse_zone.GetServiceId(test_c)); | 208 EXPECT_STREQ("objects/4", reuse_zone.GetServiceId(test_c)); |
| 217 EXPECT_STREQ("objects/5", reuse_zone.GetServiceId(test_d)); | 209 EXPECT_STREQ("objects/5", reuse_zone.GetServiceId(test_d)); |
| 218 EXPECT_STREQ("objects/5", reuse_zone.GetServiceId(test_d)); | 210 EXPECT_STREQ("objects/5", reuse_zone.GetServiceId(test_d)); |
| 219 } | 211 } |
| 220 | 212 |
| 221 | |
| 222 TEST_CASE(Service_Code) { | 213 TEST_CASE(Service_Code) { |
| 223 const char* kScript = | 214 const char* kScript = |
| 224 "var port;\n" // Set to our mock port by C++. | 215 "var port;\n" // Set to our mock port by C++. |
| 225 "\n" | 216 "\n" |
| 226 "class A {\n" | 217 "class A {\n" |
| 227 " var a;\n" | 218 " var a;\n" |
| 228 " dynamic b() {}\n" | 219 " dynamic b() {}\n" |
| 229 " dynamic c() {\n" | 220 " dynamic c() {\n" |
| 230 " var d = () { b(); };\n" | 221 " var d = () { b(); };\n" |
| 231 " return d;\n" | 222 " return d;\n" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 // Request malformed native code. | 320 // Request malformed native code. |
| 330 service_msg = EvalF(lib, | 321 service_msg = EvalF(lib, |
| 331 "[0, port, '0', 'getObject', ['objectId'], " | 322 "[0, port, '0', 'getObject', ['objectId'], " |
| 332 "['code/native%" Px "']]", | 323 "['code/native%" Px "']]", |
| 333 address); | 324 address); |
| 334 HandleIsolateMessage(isolate, service_msg); | 325 HandleIsolateMessage(isolate, service_msg); |
| 335 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 326 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 336 EXPECT_SUBSTRING("\"error\"", handler.msg()); | 327 EXPECT_SUBSTRING("\"error\"", handler.msg()); |
| 337 } | 328 } |
| 338 | 329 |
| 339 | |
| 340 TEST_CASE(Service_TokenStream) { | 330 TEST_CASE(Service_TokenStream) { |
| 341 const char* kScript = | 331 const char* kScript = |
| 342 "var port;\n" // Set to our mock port by C++. | 332 "var port;\n" // Set to our mock port by C++. |
| 343 "\n" | 333 "\n" |
| 344 "main() {\n" | 334 "main() {\n" |
| 345 "}"; | 335 "}"; |
| 346 | 336 |
| 347 Isolate* isolate = thread->isolate(); | 337 Isolate* isolate = thread->isolate(); |
| 348 isolate->set_is_runnable(true); | 338 isolate->set_is_runnable(true); |
| 349 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | 339 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 379 HandleIsolateMessage(isolate, service_msg); | 369 HandleIsolateMessage(isolate, service_msg); |
| 380 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 370 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 381 | 371 |
| 382 // Check type. | 372 // Check type. |
| 383 EXPECT_SUBSTRING("\"type\":\"Object\"", handler.msg()); | 373 EXPECT_SUBSTRING("\"type\":\"Object\"", handler.msg()); |
| 384 EXPECT_SUBSTRING("\"_vmType\":\"TokenStream\"", handler.msg()); | 374 EXPECT_SUBSTRING("\"_vmType\":\"TokenStream\"", handler.msg()); |
| 385 // Check for members array. | 375 // Check for members array. |
| 386 EXPECT_SUBSTRING("\"members\":[", handler.msg()); | 376 EXPECT_SUBSTRING("\"members\":[", handler.msg()); |
| 387 } | 377 } |
| 388 | 378 |
| 389 | |
| 390 TEST_CASE(Service_PcDescriptors) { | 379 TEST_CASE(Service_PcDescriptors) { |
| 391 const char* kScript = | 380 const char* kScript = |
| 392 "var port;\n" // Set to our mock port by C++. | 381 "var port;\n" // Set to our mock port by C++. |
| 393 "\n" | 382 "\n" |
| 394 "class A {\n" | 383 "class A {\n" |
| 395 " var a;\n" | 384 " var a;\n" |
| 396 " dynamic b() {}\n" | 385 " dynamic b() {}\n" |
| 397 " dynamic c() {\n" | 386 " dynamic c() {\n" |
| 398 " var d = () { b(); };\n" | 387 " var d = () { b(); };\n" |
| 399 " return d;\n" | 388 " return d;\n" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 id); | 432 id); |
| 444 HandleIsolateMessage(isolate, service_msg); | 433 HandleIsolateMessage(isolate, service_msg); |
| 445 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 434 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 446 // Check type. | 435 // Check type. |
| 447 EXPECT_SUBSTRING("\"type\":\"Object\"", handler.msg()); | 436 EXPECT_SUBSTRING("\"type\":\"Object\"", handler.msg()); |
| 448 EXPECT_SUBSTRING("\"_vmType\":\"PcDescriptors\"", handler.msg()); | 437 EXPECT_SUBSTRING("\"_vmType\":\"PcDescriptors\"", handler.msg()); |
| 449 // Check for members array. | 438 // Check for members array. |
| 450 EXPECT_SUBSTRING("\"members\":[", handler.msg()); | 439 EXPECT_SUBSTRING("\"members\":[", handler.msg()); |
| 451 } | 440 } |
| 452 | 441 |
| 453 | |
| 454 TEST_CASE(Service_LocalVarDescriptors) { | 442 TEST_CASE(Service_LocalVarDescriptors) { |
| 455 const char* kScript = | 443 const char* kScript = |
| 456 "var port;\n" // Set to our mock port by C++. | 444 "var port;\n" // Set to our mock port by C++. |
| 457 "\n" | 445 "\n" |
| 458 "class A {\n" | 446 "class A {\n" |
| 459 " var a;\n" | 447 " var a;\n" |
| 460 " dynamic b() {}\n" | 448 " dynamic b() {}\n" |
| 461 " dynamic c() {\n" | 449 " dynamic c() {\n" |
| 462 " var d = () { b(); };\n" | 450 " var d = () { b(); };\n" |
| 463 " return d;\n" | 451 " return d;\n" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 id); | 495 id); |
| 508 HandleIsolateMessage(isolate, service_msg); | 496 HandleIsolateMessage(isolate, service_msg); |
| 509 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 497 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 510 // Check type. | 498 // Check type. |
| 511 EXPECT_SUBSTRING("\"type\":\"Object\"", handler.msg()); | 499 EXPECT_SUBSTRING("\"type\":\"Object\"", handler.msg()); |
| 512 EXPECT_SUBSTRING("\"_vmType\":\"LocalVarDescriptors\"", handler.msg()); | 500 EXPECT_SUBSTRING("\"_vmType\":\"LocalVarDescriptors\"", handler.msg()); |
| 513 // Check for members array. | 501 // Check for members array. |
| 514 EXPECT_SUBSTRING("\"members\":[", handler.msg()); | 502 EXPECT_SUBSTRING("\"members\":[", handler.msg()); |
| 515 } | 503 } |
| 516 | 504 |
| 517 | |
| 518 static void WeakHandleFinalizer(void* isolate_callback_data, | 505 static void WeakHandleFinalizer(void* isolate_callback_data, |
| 519 Dart_WeakPersistentHandle handle, | 506 Dart_WeakPersistentHandle handle, |
| 520 void* peer) {} | 507 void* peer) {} |
| 521 | 508 |
| 522 | |
| 523 TEST_CASE(Service_PersistentHandles) { | 509 TEST_CASE(Service_PersistentHandles) { |
| 524 const char* kScript = | 510 const char* kScript = |
| 525 "var port;\n" // Set to our mock port by C++. | 511 "var port;\n" // Set to our mock port by C++. |
| 526 "\n" | 512 "\n" |
| 527 "class A {\n" | 513 "class A {\n" |
| 528 " var a;\n" | 514 " var a;\n" |
| 529 "}\n" | 515 "}\n" |
| 530 "var global = new A();\n" | 516 "var global = new A();\n" |
| 531 "main() {\n" | 517 "main() {\n" |
| 532 " return global;\n" | 518 " return global;\n" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 service_msg = Eval(lib, "[0, port, '0', '_getPersistentHandles', [], []]"); | 564 service_msg = Eval(lib, "[0, port, '0', '_getPersistentHandles', [], []]"); |
| 579 HandleIsolateMessage(isolate, service_msg); | 565 HandleIsolateMessage(isolate, service_msg); |
| 580 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 566 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 581 EXPECT_SUBSTRING("\"type\":\"_PersistentHandles\"", handler.msg()); | 567 EXPECT_SUBSTRING("\"type\":\"_PersistentHandles\"", handler.msg()); |
| 582 // Verify that old persistent handles are not present. | 568 // Verify that old persistent handles are not present. |
| 583 EXPECT_NOTSUBSTRING("\"peer\":\"0xdeadbeef\"", handler.msg()); | 569 EXPECT_NOTSUBSTRING("\"peer\":\"0xdeadbeef\"", handler.msg()); |
| 584 EXPECT_NOTSUBSTRING("\"name\":\"A\"", handler.msg()); | 570 EXPECT_NOTSUBSTRING("\"name\":\"A\"", handler.msg()); |
| 585 EXPECT_NOTSUBSTRING("\"externalSize\":\"128\"", handler.msg()); | 571 EXPECT_NOTSUBSTRING("\"externalSize\":\"128\"", handler.msg()); |
| 586 } | 572 } |
| 587 | 573 |
| 588 | |
| 589 TEST_CASE(Service_Address) { | 574 TEST_CASE(Service_Address) { |
| 590 const char* kScript = | 575 const char* kScript = |
| 591 "var port;\n" // Set to our mock port by C++. | 576 "var port;\n" // Set to our mock port by C++. |
| 592 "\n" | 577 "\n" |
| 593 "main() {\n" | 578 "main() {\n" |
| 594 "}"; | 579 "}"; |
| 595 | 580 |
| 596 Isolate* isolate = thread->isolate(); | 581 Isolate* isolate = thread->isolate(); |
| 597 isolate->set_is_runnable(true); | 582 isolate->set_is_runnable(true); |
| 598 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | 583 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 "['address'], ['7']]"); | 619 "['address'], ['7']]"); |
| 635 HandleIsolateMessage(isolate, service_msg); | 620 HandleIsolateMessage(isolate, service_msg); |
| 636 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 621 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 637 // TODO(turnidge): Should this be a ServiceException instead? | 622 // TODO(turnidge): Should this be a ServiceException instead? |
| 638 EXPECT_SUBSTRING( | 623 EXPECT_SUBSTRING( |
| 639 "{\"type\":\"Sentinel\",\"kind\":\"Free\"," | 624 "{\"type\":\"Sentinel\",\"kind\":\"Free\"," |
| 640 "\"valueAsString\":\"<free>\"", | 625 "\"valueAsString\":\"<free>\"", |
| 641 handler.msg()); | 626 handler.msg()); |
| 642 } | 627 } |
| 643 | 628 |
| 644 | |
| 645 static bool alpha_callback(const char* name, | 629 static bool alpha_callback(const char* name, |
| 646 const char** option_keys, | 630 const char** option_keys, |
| 647 const char** option_values, | 631 const char** option_values, |
| 648 intptr_t num_options, | 632 intptr_t num_options, |
| 649 void* user_data, | 633 void* user_data, |
| 650 const char** result) { | 634 const char** result) { |
| 651 *result = strdup("alpha"); | 635 *result = strdup("alpha"); |
| 652 return true; | 636 return true; |
| 653 } | 637 } |
| 654 | 638 |
| 655 | |
| 656 static bool beta_callback(const char* name, | 639 static bool beta_callback(const char* name, |
| 657 const char** option_keys, | 640 const char** option_keys, |
| 658 const char** option_values, | 641 const char** option_values, |
| 659 intptr_t num_options, | 642 intptr_t num_options, |
| 660 void* user_data, | 643 void* user_data, |
| 661 const char** result) { | 644 const char** result) { |
| 662 *result = strdup("beta"); | 645 *result = strdup("beta"); |
| 663 return false; | 646 return false; |
| 664 } | 647 } |
| 665 | 648 |
| 666 | |
| 667 TEST_CASE(Service_EmbedderRootHandler) { | 649 TEST_CASE(Service_EmbedderRootHandler) { |
| 668 const char* kScript = | 650 const char* kScript = |
| 669 "var port;\n" // Set to our mock port by C++. | 651 "var port;\n" // Set to our mock port by C++. |
| 670 "\n" | 652 "\n" |
| 671 "var x = 7;\n" | 653 "var x = 7;\n" |
| 672 "main() {\n" | 654 "main() {\n" |
| 673 " x = x * x;\n" | 655 " x = x * x;\n" |
| 674 " x = x / 13;\n" | 656 " x = x / 13;\n" |
| 675 "}"; | 657 "}"; |
| 676 | 658 |
| 677 Dart_RegisterRootServiceRequestCallback("alpha", alpha_callback, NULL); | 659 Dart_RegisterRootServiceRequestCallback("alpha", alpha_callback, NULL); |
| 678 Dart_RegisterRootServiceRequestCallback("beta", beta_callback, NULL); | 660 Dart_RegisterRootServiceRequestCallback("beta", beta_callback, NULL); |
| 679 | 661 |
| 680 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | 662 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| 681 EXPECT_VALID(lib); | 663 EXPECT_VALID(lib); |
| 682 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 664 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 683 EXPECT_VALID(result); | 665 EXPECT_VALID(result); |
| 684 | 666 |
| 685 // Build a mock message handler and wrap it in a dart port. | 667 // Build a mock message handler and wrap it in a dart port. |
| 686 ServiceTestMessageHandler handler; | 668 ServiceTestMessageHandler handler; |
| 687 Dart_Port port_id = PortMap::CreatePort(&handler); | 669 Dart_Port port_id = PortMap::CreatePort(&handler); |
| 688 Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id)); | 670 Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id)); |
| 689 EXPECT_VALID(port); | 671 EXPECT_VALID(port); |
| 690 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | 672 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); |
| 691 | 673 |
| 692 | |
| 693 Array& service_msg = Array::Handle(); | 674 Array& service_msg = Array::Handle(); |
| 694 service_msg = Eval(lib, "[0, port, '\"', 'alpha', [], []]"); | 675 service_msg = Eval(lib, "[0, port, '\"', 'alpha', [], []]"); |
| 695 HandleRootMessage(service_msg); | 676 HandleRootMessage(service_msg); |
| 696 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 677 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 697 EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"result\":alpha,\"id\":\"\\\"\"}", | 678 EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"result\":alpha,\"id\":\"\\\"\"}", |
| 698 handler.msg()); | 679 handler.msg()); |
| 699 service_msg = Eval(lib, "[0, port, 1, 'beta', [], []]"); | 680 service_msg = Eval(lib, "[0, port, 1, 'beta', [], []]"); |
| 700 HandleRootMessage(service_msg); | 681 HandleRootMessage(service_msg); |
| 701 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 682 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 702 EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"error\":beta,\"id\":1}", handler.msg()); | 683 EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"error\":beta,\"id\":1}", handler.msg()); |
| 703 } | 684 } |
| 704 | 685 |
| 705 | |
| 706 TEST_CASE(Service_EmbedderIsolateHandler) { | 686 TEST_CASE(Service_EmbedderIsolateHandler) { |
| 707 const char* kScript = | 687 const char* kScript = |
| 708 "var port;\n" // Set to our mock port by C++. | 688 "var port;\n" // Set to our mock port by C++. |
| 709 "\n" | 689 "\n" |
| 710 "var x = 7;\n" | 690 "var x = 7;\n" |
| 711 "main() {\n" | 691 "main() {\n" |
| 712 " x = x * x;\n" | 692 " x = x * x;\n" |
| 713 " x = x / 13;\n" | 693 " x = x / 13;\n" |
| 714 "}"; | 694 "}"; |
| 715 | 695 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); | 769 EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage()); |
| 790 // Expect error. | 770 // Expect error. |
| 791 EXPECT_SUBSTRING("\"error\"", handler.msg()); | 771 EXPECT_SUBSTRING("\"error\"", handler.msg()); |
| 792 } | 772 } |
| 793 | 773 |
| 794 #endif // !defined(TARGET_ARCH_ARM64) | 774 #endif // !defined(TARGET_ARCH_ARM64) |
| 795 | 775 |
| 796 #endif // !PRODUCT | 776 #endif // !PRODUCT |
| 797 | 777 |
| 798 } // namespace dart | 778 } // namespace dart |
| OLD | NEW |