| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library test.integration.analysis; | 5 library test.integration.analysis; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 import 'dart:io'; | 10 import 'dart:io'; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 * received from the server with 'analyzing' set to false. | 81 * received from the server with 'analyzing' set to false. |
| 82 * | 82 * |
| 83 * The future will only be completed by 'server.status' notifications that are | 83 * The future will only be completed by 'server.status' notifications that are |
| 84 * received after this function call. So it is safe to use this getter | 84 * received after this function call. So it is safe to use this getter |
| 85 * multiple times in one test; each time it is used it will wait afresh for | 85 * multiple times in one test; each time it is used it will wait afresh for |
| 86 * analysis to finish. | 86 * analysis to finish. |
| 87 */ | 87 */ |
| 88 Future get analysisFinished { | 88 Future get analysisFinished { |
| 89 Completer completer = new Completer(); | 89 Completer completer = new Completer(); |
| 90 StreamSubscription subscription; | 90 StreamSubscription subscription; |
| 91 subscription = server.onNotification(SERVER_STATUS).listen((params) { | 91 subscription = server.onNotification(SERVER_STATUS).listen(wrapAsync( |
| 92 (params) { |
| 92 bool analysisComplete = false; | 93 bool analysisComplete = false; |
| 93 try { | 94 try { |
| 94 analysisComplete = !params['analysis']['analyzing']; | 95 analysisComplete = !params['analysis']['analyzing']; |
| 95 } catch (_) { | 96 } catch (_) { |
| 96 // Status message was mal-formed or missing optional parameters. That's | 97 // Status message was mal-formed or missing optional parameters. That's |
| 97 // fine, since we'll detect a mal-formed status message below. | 98 // fine, since we'll detect a mal-formed status message below. |
| 98 } | 99 } |
| 99 if (analysisComplete) { | 100 if (analysisComplete) { |
| 100 completer.complete(params); | 101 completer.complete(params); |
| 101 subscription.cancel(); | 102 subscription.cancel(); |
| 102 } | 103 } |
| 103 expect(params, isServerStatusParams); | 104 expect(params, isServerStatusParams); |
| 104 }); | 105 })); |
| 105 return completer.future; | 106 return completer.future; |
| 106 } | 107 } |
| 107 | 108 |
| 108 /** | 109 /** |
| 109 * Print out any messages exchanged with the server. If some messages have | 110 * Print out any messages exchanged with the server. If some messages have |
| 110 * already been exchanged with the server, they are printed out immediately. | 111 * already been exchanged with the server, they are printed out immediately. |
| 111 */ | 112 */ |
| 112 void debugStdio() { | 113 void debugStdio() { |
| 113 server.debugStdio(); | 114 server.debugStdio(); |
| 114 } | 115 } |
| 115 | 116 |
| 116 /** | 117 /** |
| 117 * The server is automatically started before every test, and a temporary | 118 * The server is automatically started before every test, and a temporary |
| 118 * [sourceDirectory] is created. | 119 * [sourceDirectory] is created. |
| 119 */ | 120 */ |
| 120 Future setUp() { | 121 Future setUp() { |
| 121 sourceDirectory = Directory.systemTemp.createTempSync('analysisServer'); | 122 sourceDirectory = Directory.systemTemp.createTempSync('analysisServer'); |
| 122 return Server.start().then((Server server) { | 123 return Server.start().then((Server server) { |
| 123 this.server = server; | 124 this.server = server; |
| 124 server.onNotification(ANALYSIS_ERRORS).listen((params) { | 125 server.onNotification(ANALYSIS_ERRORS).listen(wrapAsync((params) { |
| 125 expect(params, isMap); | 126 expect(params, isMap); |
| 126 expect(params['file'], isString); | 127 expect(params['file'], isString); |
| 127 currentAnalysisErrors[params['file']] = params['errors']; | 128 currentAnalysisErrors[params['file']] = params['errors']; |
| 128 }); | 129 })); |
| 129 }); | 130 }); |
| 130 } | 131 } |
| 131 | 132 |
| 132 /** | 133 /** |
| 133 * After every test, the server stopped and [sourceDirectory] is deleted. | 134 * After every test, the server stopped and [sourceDirectory] is deleted. |
| 134 */ | 135 */ |
| 135 Future tearDown() { | 136 Future tearDown() { |
| 136 return server.kill().then((_) { | 137 return server.kill().then((_) { |
| 137 sourceDirectory.deleteSync(recursive: true); | 138 sourceDirectory.deleteSync(recursive: true); |
| 138 }); | 139 }); |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 String serverPath = normalize(join(dirname(Platform.script.path), '..', | 504 String serverPath = normalize(join(dirname(Platform.script.path), '..', |
| 504 '..', 'bin', 'server.dart')); | 505 '..', 'bin', 'server.dart')); |
| 505 List<String> arguments = []; | 506 List<String> arguments = []; |
| 506 if (debugServer) { | 507 if (debugServer) { |
| 507 arguments.add('--debug'); | 508 arguments.add('--debug'); |
| 508 } | 509 } |
| 509 arguments.add(serverPath); | 510 arguments.add(serverPath); |
| 510 return Process.start(dartBinary, arguments).then((Process process) { | 511 return Process.start(dartBinary, arguments).then((Process process) { |
| 511 Server server = new Server._(process); | 512 Server server = new Server._(process); |
| 512 process.stdout.transform((new Utf8Codec()).decoder).transform( | 513 process.stdout.transform((new Utf8Codec()).decoder).transform( |
| 513 new LineSplitter()).listen((String line) { | 514 new LineSplitter()).listen(wrapAsync((String line) { |
| 514 String trimmedLine = line.trim(); | 515 String trimmedLine = line.trim(); |
| 515 server._recordStdio('RECV: $trimmedLine'); | 516 server._recordStdio('RECV: $trimmedLine'); |
| 516 var message = JSON.decoder.convert(trimmedLine); | 517 var message = JSON.decoder.convert(trimmedLine); |
| 517 expect(message, isMap); | 518 expect(message, isMap); |
| 518 Map messageAsMap = message; | 519 Map messageAsMap = message; |
| 519 if (messageAsMap.containsKey('id')) { | 520 if (messageAsMap.containsKey('id')) { |
| 520 expect(messageAsMap['id'], isString); | 521 expect(messageAsMap['id'], isString); |
| 521 String id = message['id']; | 522 String id = message['id']; |
| 522 Completer completer = server._pendingCommands[id]; | 523 Completer completer = server._pendingCommands[id]; |
| 523 if (completer == null) { | 524 if (completer == null) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 549 StreamController notificationController = | 550 StreamController notificationController = |
| 550 server._notificationControllers[event]; | 551 server._notificationControllers[event]; |
| 551 if (notificationController != null) { | 552 if (notificationController != null) { |
| 552 notificationController.add(messageAsMap['params']); | 553 notificationController.add(messageAsMap['params']); |
| 553 } | 554 } |
| 554 // Check that the message is well-formed. We do this after calling | 555 // Check that the message is well-formed. We do this after calling |
| 555 // notificationController.add() so that we don't stall the test in the | 556 // notificationController.add() so that we don't stall the test in the |
| 556 // event of an error. | 557 // event of an error. |
| 557 expect(message, isNotification); | 558 expect(message, isNotification); |
| 558 } | 559 } |
| 559 }); | 560 })); |
| 560 process.stderr.listen((List<int> data) { | 561 process.stderr.listen(wrapAsync((List<int> data) { |
| 561 fail('Unexpected output from stderr'); | 562 fail('Unexpected output from stderr'); |
| 562 }); | 563 })); |
| 563 return server; | 564 return server; |
| 564 }); | 565 }); |
| 565 } | 566 } |
| 566 | 567 |
| 567 /** | 568 /** |
| 568 * Stop the server. | 569 * Stop the server. |
| 569 */ | 570 */ |
| 570 Future kill() { | 571 Future kill() { |
| 571 _process.kill(); | 572 _process.kill(); |
| 572 return _process.exitCode; | 573 return _process.exitCode; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 * Record a message that was exchanged with the server, and print it out if | 616 * Record a message that was exchanged with the server, and print it out if |
| 616 * [debugStdio] has been called. | 617 * [debugStdio] has been called. |
| 617 */ | 618 */ |
| 618 void _recordStdio(String line) { | 619 void _recordStdio(String line) { |
| 619 if (_debuggingStdio) { | 620 if (_debuggingStdio) { |
| 620 print(line); | 621 print(line); |
| 621 } | 622 } |
| 622 _recordedStdio.add(line); | 623 _recordedStdio.add(line); |
| 623 } | 624 } |
| 624 } | 625 } |
| 626 |
| 627 /** |
| 628 * Wrap a callback function that will be called an unknown number of times. |
| 629 * This won't prevent the integration test from completing, but it will ensure |
| 630 * that any exceptions thrown from the callback are properly reported as unit |
| 631 * test failures. |
| 632 */ |
| 633 Function wrapAsync(Function callback) => expectAsync(callback, count: 0, max: -1 |
| 634 ); |
| OLD | NEW |