Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 | 6 |
| 7 import 'package:async/async.dart'; | 7 import 'package:async/async.dart'; |
| 8 import 'package:test/test.dart'; | 8 import 'package:test/test.dart'; |
| 9 import 'package:vm_service_client/vm_service_client.dart'; | 9 import 'package:vm_service_client/vm_service_client.dart'; |
| 10 | 10 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 try { | 158 try { |
| 159 await other.load(); | 159 await other.load(); |
| 160 } on VMSentinelException catch (_) { | 160 } on VMSentinelException catch (_) { |
| 161 break; | 161 break; |
| 162 } | 162 } |
| 163 } | 163 } |
| 164 | 164 |
| 165 expect(other.onExit, completes); | 165 expect(other.onExit, completes); |
| 166 }); | 166 }); |
| 167 }); | 167 }); |
| 168 | |
| 169 test("onServiceExtensionAdded fires when an extension is added", () async { | |
| 170 client = await runAndConnect(main: """ | |
| 171 registerExtension('ext.test', (_, __) {}); | |
| 172 """, flags: ["--pause-isolates-on-start"]); | |
| 173 | |
| 174 var isolate = await (await client.getVM()).isolates.first.loadRunnable(); | |
| 175 await isolate.waitUntilPaused(); | |
| 176 await isolate.resume(); | |
| 177 | |
| 178 String ext = await isolate.onServiceExtensionAdded.first; | |
| 179 expect(ext, 'ext.test'); | |
| 180 }); | |
| 181 }); | |
| 182 | |
| 183 group("onExtensionEvent", () { | |
| 184 test("emits extension events", () async { | |
|
nweiz
2016/02/17 21:35:41
Nit: this test and the selectExtensionEvents test
yjbanov
2016/02/17 23:51:43
Done.
| |
| 185 client = await runAndConnect(main: """ | |
| 186 postEvent('foo', {'bar': 'baz'}); | |
| 187 """, flags: ["--pause-isolates-on-start"]); | |
| 188 | |
| 189 var isolate = await (await client.getVM()).isolates.first.load(); | |
| 190 await isolate.waitUntilPaused(); | |
| 191 await isolate.resume(); | |
|
nweiz
2016/02/17 21:35:41
There's no point to waiting until the isolate is p
yjbanov
2016/02/17 23:51:43
Done.
| |
| 192 | |
| 193 var event = await isolate.onExtensionEvent.first; | |
|
nweiz
2016/02/17 21:35:41
I'd like to assert that this is the only event emi
yjbanov
2016/02/17 23:51:43
Done, but used a different method. onlyEvent does
nweiz
2016/02/18 00:24:06
How does your approach apply to the streams in the
yjbanov
2016/02/18 01:00:22
Switched to onlyEvent. See below.
| |
| 194 expect(event.kind, 'foo'); | |
| 195 expect(event.data, {'bar': 'baz'}); | |
| 196 }); | |
| 197 }); | |
| 198 | |
| 199 group("selectExtensionEvents", () { | |
| 200 test("chooses by extension kind", () async { | |
| 201 client = await runAndConnect(main: """ | |
| 202 postEvent('foo', {'prefixed': false}); | |
| 203 postEvent('bar.baz', {'prefixed': true}); | |
| 204 postEvent('not.captured', {}); | |
| 205 """, flags: ["--pause-isolates-on-start"]); | |
| 206 | |
| 207 var isolate = await (await client.getVM()).isolates.first.load(); | |
| 208 await isolate.resume(); | |
|
nweiz
2016/02/17 21:35:41
You definitely want a waitUntilPaused here, and yo
yjbanov
2016/02/17 23:51:44
Probably not necessary when pausing on start, but
| |
| 209 | |
| 210 var unprefixedEvent = isolate.selectExtensionEvents('foo').first; | |
| 211 var prefixedEvent = | |
| 212 isolate.selectExtensionEvents('bar.', prefix: true).first; | |
| 213 expect((await unprefixedEvent).kind, 'foo'); | |
| 214 expect((await prefixedEvent).kind, 'bar.baz'); | |
| 215 }); | |
| 216 }); | |
| 217 | |
| 218 group("waitForExtension", () { | |
| 219 test("notifies when the extension is already registered", () async { | |
| 220 client = await runAndConnect(main: """ | |
| 221 registerExtension('ext.test', (_, __) {}); | |
| 222 """); | |
| 223 | |
| 224 var isolate = await (await client.getVM()).isolates.first.load(); | |
|
nweiz
2016/02/17 21:35:41
If we don't wait for some signal that [registerExt
yjbanov
2016/02/17 23:51:43
Seems like an very unlikely scenario, but done.
nweiz
2016/02/18 00:24:06
One thing I've learned from writing a lot of async
| |
| 225 isolate.waitForExtension('ext.test').then(expectAsync((value) { | |
|
nweiz
2016/02/17 21:35:41
You can just write expect(isolate.waitForExtension
yjbanov
2016/02/17 23:51:44
Acknowledged. In this case I'm also checking on th
| |
| 226 expect(value, isNull, | |
| 227 reason: 'we are not expecting a value, just Future completion'); | |
| 228 })); | |
| 229 }); | |
| 230 | |
| 231 test("notifies when the extension is registered later", () async { | |
| 232 client = await runAndConnect(main: """ | |
| 233 registerExtension('ext.one', (_, __) { | |
| 234 registerExtension('ext.two', (_, __) {}); | |
| 235 }); | |
| 236 """); | |
| 237 | |
| 238 var isolate = await (await client.getVM()).isolates.first.load(); | |
| 239 isolate.waitForExtension('ext.two').then(expectAsync((value) { | |
| 240 expect(value, isNull, | |
|
nweiz
2016/02/17 21:35:41
I don't particularly care about asserting that und
yjbanov
2016/02/17 23:51:43
I do, primarily because we're piping futures and s
nweiz
2016/02/18 00:24:06
I am against it. Any void future could theoretical
yjbanov
2016/02/18 01:00:22
Not if you test that it doesn't.
| |
| 241 reason: 'we are not expecting a value, just Future completion'); | |
| 242 })); | |
| 243 | |
| 244 await isolate.waitForExtension('ext.one'); | |
| 245 isolate.invokeExtension('ext.one'); | |
| 246 }); | |
| 247 }); | |
| 248 | |
| 249 group("load", () { | |
| 250 test("loads extensionRPCs", () async { | |
| 251 client = await runAndConnect(main: """ | |
| 252 registerExtension('ext.foo', (_, __) {}); | |
| 253 registerExtension('ext.bar', (_, __) {}); | |
| 254 """); | |
| 255 | |
| 256 var isolate = await (await client.getVM()).isolates.first.load(); | |
| 257 expect(isolate.extensionRPCs, unorderedEquals(['ext.foo', 'ext.bar'])); | |
| 258 }); | |
| 168 }); | 259 }); |
| 169 | 260 |
| 170 group("loadRunnable", () { | 261 group("loadRunnable", () { |
| 171 test("for an unrunnable isolate", () async { | 262 test("for an unrunnable isolate", () async { |
| 172 client = await runAndConnect(flags: ["--pause-isolates-on-start"]); | 263 client = await runAndConnect(flags: ["--pause-isolates-on-start"]); |
| 173 | 264 |
| 174 var isolate = (await client.getVM()).isolates.first; | 265 var isolate = (await client.getVM()).isolates.first; |
| 175 expect(isolate, isNot(new isInstanceOf<VMRunnableIsolate>())); | 266 expect(isolate, isNot(new isInstanceOf<VMRunnableIsolate>())); |
| 176 | 267 |
| 177 isolate = await isolate.loadRunnable(); | 268 isolate = await isolate.loadRunnable(); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 test("works before the isolate is runnable", () async { | 459 test("works before the isolate is runnable", () async { |
| 369 client = await runAndConnect(flags: ['--pause-isolates-on-start']); | 460 client = await runAndConnect(flags: ['--pause-isolates-on-start']); |
| 370 | 461 |
| 371 // We should be able to set a breakpoint before the relevant library is | 462 // We should be able to set a breakpoint before the relevant library is |
| 372 // loaded, although it may fail to resolve if the line number is bogus. | 463 // loaded, although it may fail to resolve if the line number is bogus. |
| 373 var isolate = (await client.getVM()).isolates.first; | 464 var isolate = (await client.getVM()).isolates.first; |
| 374 var breakpoint = await isolate.addBreakpoint('my/script.dart', 0); | 465 var breakpoint = await isolate.addBreakpoint('my/script.dart', 0); |
| 375 expect(breakpoint.number, equals(1)); | 466 expect(breakpoint.number, equals(1)); |
| 376 }); | 467 }); |
| 377 }); | 468 }); |
| 469 | |
| 470 group("invokeExtension", () { | |
| 471 test("enforces ext. prefix", () async { | |
| 472 var client = await runAndConnect(); | |
| 473 var isolate = await (await client.getVM()).isolates.first.loadRunnable(); | |
| 474 expect(() => isolate.invokeExtension('noprefix'), throwsArgumentError); | |
| 475 }); | |
| 476 | |
| 477 test("forwards to scope", () async { | |
| 478 var client = await runAndConnect(main: r""" | |
| 479 registerExtension('ext.ping', (_, __) async { | |
| 480 return new ServiceExtensionResponse.result('{"type": "pong"}'); | |
| 481 }); | |
| 482 """); | |
| 483 | |
| 484 var isolate = await (await client.getVM()).isolates.first.loadRunnable(); | |
| 485 var response = await isolate.invokeExtension('ext.ping'); | |
| 486 expect(response, {'type': 'pong'}); | |
| 487 }); | |
| 488 | |
| 489 test("passes parameters", () async { | |
| 490 var client = await runAndConnect(main: r""" | |
| 491 registerExtension('ext.params', (_, params) async { | |
| 492 return new ServiceExtensionResponse.result('''{ | |
| 493 "foo": "${params['foo']}" | |
| 494 }'''); | |
| 495 }); | |
| 496 """); | |
| 497 | |
| 498 var isolate = await (await client.getVM()).isolates.first.loadRunnable(); | |
| 499 var response = await isolate.invokeExtension('ext.params', { | |
| 500 'foo': 'bar', | |
| 501 }); | |
| 502 expect(response, { | |
| 503 'foo': 'bar', | |
| 504 }); | |
| 505 }); | |
|
nweiz
2016/02/17 21:35:41
I forgot to suggest this earlier, but it would pro
yjbanov
2016/02/17 23:51:43
Good point. Done.
| |
| 506 }); | |
| 378 } | 507 } |
| 379 | 508 |
| 380 /// Starts a client with two unpaused empty isolates. | 509 /// Starts a client with two unpaused empty isolates. |
| 381 Future<List<VMRunnableIsolate>> _twoIsolates() async { | 510 Future<List<VMRunnableIsolate>> _twoIsolates() async { |
| 382 client = await runAndConnect(topLevel: r""" | 511 client = await runAndConnect(topLevel: r""" |
| 383 void otherIsolate(_) {} | 512 void otherIsolate(_) {} |
| 384 """, main: r""" | 513 """, main: r""" |
| 385 Isolate.spawn(otherIsolate, null); | 514 Isolate.spawn(otherIsolate, null); |
| 386 """, flags: ["--pause-isolates-on-start", "--pause-isolates-on-exit"]); | 515 """, flags: ["--pause-isolates-on-start", "--pause-isolates-on-exit"]); |
| 387 | 516 |
| 388 var vm = await client.getVM(); | 517 var vm = await client.getVM(); |
| 389 var main = vm.isolates.first; | 518 var main = vm.isolates.first; |
| 390 | 519 |
| 391 var otherFuture = client.onIsolateRunnable.first; | 520 var otherFuture = client.onIsolateRunnable.first; |
| 392 await main.resume(); | 521 await main.resume(); |
| 393 var other = await otherFuture; | 522 var other = await otherFuture; |
| 394 await other.resume(); | 523 await other.resume(); |
| 395 | 524 |
| 396 return [main, other]; | 525 return [main, other]; |
| 397 } | 526 } |
| OLD | NEW |