Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: sdk/lib/_internal/pub_generated/test/serve/utils.dart

Issue 657673002: Regenerate pub sources. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS d.file
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.
4
1 library pub_tests; 5 library pub_tests;
6
2 import 'dart:async'; 7 import 'dart:async';
3 import 'dart:convert'; 8 import 'dart:convert';
4 import 'dart:io'; 9 import 'dart:io';
10
5 import 'package:http/http.dart' as http; 11 import 'package:http/http.dart' as http;
6 import 'package:scheduled_test/scheduled_process.dart'; 12 import 'package:scheduled_test/scheduled_process.dart';
7 import 'package:scheduled_test/scheduled_stream.dart'; 13 import 'package:scheduled_test/scheduled_stream.dart';
8 import 'package:scheduled_test/scheduled_test.dart'; 14 import 'package:scheduled_test/scheduled_test.dart';
9 import 'package:stack_trace/stack_trace.dart'; 15 import 'package:stack_trace/stack_trace.dart';
16
10 import '../../lib/src/utils.dart'; 17 import '../../lib/src/utils.dart';
11 import '../descriptor.dart' as d; 18 import '../descriptor.dart' as d;
12 import '../test_pub.dart'; 19 import '../test_pub.dart';
20
21 /// The pub process running "pub serve".
13 ScheduledProcess _pubServer; 22 ScheduledProcess _pubServer;
23
24 /// The ephemeral port assign to the running admin server.
14 int _adminPort; 25 int _adminPort;
26
27 /// The ephemeral ports assigned to the running servers, associated with the
28 /// directories they're serving.
15 final _ports = new Map<String, int>(); 29 final _ports = new Map<String, int>();
30
31 /// A completer that completes when the server has been started and the served
32 /// ports are known.
16 Completer _portsCompleter; 33 Completer _portsCompleter;
34
35 /// The web socket connection to the running pub process, or `null` if no
36 /// connection has been made.
17 WebSocket _webSocket; 37 WebSocket _webSocket;
18 Stream _webSocketBroadcastStream; 38 Stream _webSocketBroadcastStream;
39
40 /// The code for a transformer that renames ".txt" files to ".out" and adds a
41 /// ".out" suffix.
19 const REWRITE_TRANSFORMER = """ 42 const REWRITE_TRANSFORMER = """
20 import 'dart:async'; 43 import 'dart:async';
21 44
22 import 'package:barback/barback.dart'; 45 import 'package:barback/barback.dart';
23 46
24 class RewriteTransformer extends Transformer { 47 class RewriteTransformer extends Transformer {
25 RewriteTransformer.asPlugin(); 48 RewriteTransformer.asPlugin();
26 49
27 String get allowedExtensions => '.txt'; 50 String get allowedExtensions => '.txt';
28 51
29 Future apply(Transform transform) { 52 Future apply(Transform transform) {
30 return transform.primaryInput.readAsString().then((contents) { 53 return transform.primaryInput.readAsString().then((contents) {
31 var id = transform.primaryInput.id.changeExtension(".out"); 54 var id = transform.primaryInput.id.changeExtension(".out");
32 transform.addOutput(new Asset.fromString(id, "\$contents.out")); 55 transform.addOutput(new Asset.fromString(id, "\$contents.out"));
33 }); 56 });
34 } 57 }
35 } 58 }
36 """; 59 """;
60
61 /// The code for a lazy version of [REWRITE_TRANSFORMER].
37 const LAZY_TRANSFORMER = """ 62 const LAZY_TRANSFORMER = """
38 import 'dart:async'; 63 import 'dart:async';
39 64
40 import 'package:barback/barback.dart'; 65 import 'package:barback/barback.dart';
41 66
42 class LazyRewriteTransformer extends Transformer implements LazyTransformer { 67 class LazyRewriteTransformer extends Transformer implements LazyTransformer {
43 LazyRewriteTransformer.asPlugin(); 68 LazyRewriteTransformer.asPlugin();
44 69
45 String get allowedExtensions => '.txt'; 70 String get allowedExtensions => '.txt';
46 71
47 Future apply(Transform transform) { 72 Future apply(Transform transform) {
48 transform.logger.info('Rewriting \${transform.primaryInput.id}.'); 73 transform.logger.info('Rewriting \${transform.primaryInput.id}.');
49 return transform.primaryInput.readAsString().then((contents) { 74 return transform.primaryInput.readAsString().then((contents) {
50 var id = transform.primaryInput.id.changeExtension(".out"); 75 var id = transform.primaryInput.id.changeExtension(".out");
51 transform.addOutput(new Asset.fromString(id, "\$contents.out")); 76 transform.addOutput(new Asset.fromString(id, "\$contents.out"));
52 }); 77 });
53 } 78 }
54 79
55 Future declareOutputs(DeclaringTransform transform) { 80 Future declareOutputs(DeclaringTransform transform) {
56 transform.declareOutput(transform.primaryId.changeExtension(".out")); 81 transform.declareOutput(transform.primaryId.changeExtension(".out"));
57 return new Future.value(); 82 return new Future.value();
58 } 83 }
59 } 84 }
60 """; 85 """;
86
87 /// The web socket error code for a directory not being served.
61 const NOT_SERVED = 1; 88 const NOT_SERVED = 1;
89
90 /// Returns the source code for a Dart library defining a Transformer that
91 /// rewrites Dart files.
92 ///
93 /// The transformer defines a constant named TOKEN whose value is [id]. When the
94 /// transformer transforms another Dart file, it will look for a "TOKEN"
95 /// constant definition there and modify it to include *this* transformer's
96 /// TOKEN value as well.
97 ///
98 /// If [import] is passed, it should be the name of a package that defines its
99 /// own TOKEN constant. The primary library of that package will be imported
100 /// here and its TOKEN value will be added to this library's.
101 ///
102 /// This transformer takes one configuration field: "addition". This is
103 /// concatenated to its TOKEN value before adding it to the output library.
62 String dartTransformer(String id, {String import}) { 104 String dartTransformer(String id, {String import}) {
63 if (import != null) { 105 if (import != null) {
64 id = '$id imports \${$import.TOKEN}'; 106 id = '$id imports \${$import.TOKEN}';
65 import = 'import "package:$import/$import.dart" as $import;'; 107 import = 'import "package:$import/$import.dart" as $import;';
66 } else { 108 } else {
67 import = ''; 109 import = '';
68 } 110 }
111
69 return """ 112 return """
70 import 'dart:async'; 113 import 'dart:async';
71 114
72 import 'package:barback/barback.dart'; 115 import 'package:barback/barback.dart';
73 $import 116 $import
74 117
75 import 'dart:io'; 118 import 'dart:io';
76 119
77 const TOKEN = "$id"; 120 const TOKEN = "$id";
78 121
(...skipping 13 matching lines...) Expand all
92 var token = TOKEN; 135 var token = TOKEN;
93 var addition = _settings.configuration["addition"]; 136 var addition = _settings.configuration["addition"];
94 if (addition != null) token += addition; 137 if (addition != null) token += addition;
95 return 'const TOKEN = "(\${match[1]}, \$token)";'; 138 return 'const TOKEN = "(\${match[1]}, \$token)";';
96 }))); 139 })));
97 }); 140 });
98 } 141 }
99 } 142 }
100 """; 143 """;
101 } 144 }
145
146 /// Schedules starting the `pub serve` process.
147 ///
148 /// Unlike [pubServe], this doesn't determine the port number of the server, and
149 /// so may be used to test for errors in the initialization process.
150 ///
151 /// Returns the `pub serve` process.
102 ScheduledProcess startPubServe({Iterable<String> args, bool createWebDir: true}) 152 ScheduledProcess startPubServe({Iterable<String> args, bool createWebDir: true})
103 { 153 {
104 var pubArgs = ["serve", "--port=0", "--force-poll", "--log-admin-url"]; 154 var pubArgs = ["serve", "--port=0", // Use port 0 to get an ephemeral port.
155 "--force-poll", "--log-admin-url"];
156
105 if (args != null) pubArgs.addAll(args); 157 if (args != null) pubArgs.addAll(args);
158
159 // Dart2js can take a long time to compile dart code, so we increase the
160 // timeout to cope with that.
106 currentSchedule.timeout *= 1.5; 161 currentSchedule.timeout *= 1.5;
162
107 if (createWebDir) d.dir(appPath, [d.dir("web")]).create(); 163 if (createWebDir) d.dir(appPath, [d.dir("web")]).create();
108 return startPub(args: pubArgs); 164 return startPub(args: pubArgs);
109 } 165 }
166
167 /// Schedules starting the "pub serve" process and records its port number for
168 /// future requests.
169 ///
170 /// If [shouldGetFirst] is `true`, validates that pub get is run first.
171 ///
172 /// If [createWebDir] is `true`, creates a `web/` directory if one doesn't exist
173 /// so pub doesn't complain about having nothing to serve.
174 ///
175 /// Returns the `pub serve` process.
110 ScheduledProcess pubServe({bool shouldGetFirst: false, bool createWebDir: true, 176 ScheduledProcess pubServe({bool shouldGetFirst: false, bool createWebDir: true,
111 Iterable<String> args}) { 177 Iterable<String> args}) {
112 _pubServer = startPubServe(args: args, createWebDir: createWebDir); 178 _pubServer = startPubServe(args: args, createWebDir: createWebDir);
113 _portsCompleter = new Completer(); 179 _portsCompleter = new Completer();
180
114 currentSchedule.onComplete.schedule(() { 181 currentSchedule.onComplete.schedule(() {
115 _portsCompleter = null; 182 _portsCompleter = null;
116 _ports.clear(); 183 _ports.clear();
184
117 if (_webSocket != null) { 185 if (_webSocket != null) {
118 _webSocket.close(); 186 _webSocket.close();
119 _webSocket = null; 187 _webSocket = null;
120 _webSocketBroadcastStream = null; 188 _webSocketBroadcastStream = null;
121 } 189 }
122 }); 190 });
191
123 if (shouldGetFirst) { 192 if (shouldGetFirst) {
124 _pubServer.stdout.expect( 193 _pubServer.stdout.expect(
125 consumeThrough( 194 consumeThrough(
126 anyOf(["Got dependencies!", matches(new RegExp(r"^Changed \d+ depend enc"))]))); 195 anyOf(["Got dependencies!", matches(new RegExp(r"^Changed \d+ depend enc"))])));
127 } 196 }
197
128 _pubServer.stdout.expect(startsWith("Loading source assets...")); 198 _pubServer.stdout.expect(startsWith("Loading source assets..."));
129 _pubServer.stdout.expect(consumeWhile(matches("Loading .* transformers..."))); 199 _pubServer.stdout.expect(consumeWhile(matches("Loading .* transformers...")));
200
130 _pubServer.stdout.expect(predicate(_parseAdminPort)); 201 _pubServer.stdout.expect(predicate(_parseAdminPort));
202
203 // The server should emit one or more ports.
131 _pubServer.stdout.expect( 204 _pubServer.stdout.expect(
132 consumeWhile(predicate(_parsePort, 'emits server url'))); 205 consumeWhile(predicate(_parsePort, 'emits server url')));
133 schedule(() { 206 schedule(() {
134 expect(_ports, isNot(isEmpty)); 207 expect(_ports, isNot(isEmpty));
135 _portsCompleter.complete(); 208 _portsCompleter.complete();
136 }); 209 });
210
137 return _pubServer; 211 return _pubServer;
138 } 212 }
213
214 /// The regular expression for parsing pub's output line describing the URL for
215 /// the server.
139 final _parsePortRegExp = new RegExp(r"([^ ]+) +on http://localhost:(\d+)"); 216 final _parsePortRegExp = new RegExp(r"([^ ]+) +on http://localhost:(\d+)");
217
218 /// Parses the port number from the "Running admin server on localhost:1234"
219 /// line printed by pub serve.
140 bool _parseAdminPort(String line) { 220 bool _parseAdminPort(String line) {
141 var match = _parsePortRegExp.firstMatch(line); 221 var match = _parsePortRegExp.firstMatch(line);
142 if (match == null) return false; 222 if (match == null) return false;
143 _adminPort = int.parse(match[2]); 223 _adminPort = int.parse(match[2]);
144 return true; 224 return true;
145 } 225 }
226
227 /// Parses the port number from the "Serving blah on localhost:1234" line
228 /// printed by pub serve.
146 bool _parsePort(String line) { 229 bool _parsePort(String line) {
147 var match = _parsePortRegExp.firstMatch(line); 230 var match = _parsePortRegExp.firstMatch(line);
148 if (match == null) return false; 231 if (match == null) return false;
149 _ports[match[1]] = int.parse(match[2]); 232 _ports[match[1]] = int.parse(match[2]);
150 return true; 233 return true;
151 } 234 }
235
152 void endPubServe() { 236 void endPubServe() {
153 _pubServer.kill(); 237 _pubServer.kill();
154 } 238 }
239
240 /// Schedules an HTTP request to the running pub server with [urlPath] and
241 /// invokes [callback] with the response.
242 ///
243 /// [root] indicates which server should be accessed, and defaults to "web".
155 Future<http.Response> scheduleRequest(String urlPath, {String root}) { 244 Future<http.Response> scheduleRequest(String urlPath, {String root}) {
156 return schedule(() { 245 return schedule(() {
157 return http.get(_getServerUrlSync(root, urlPath)); 246 return http.get(_getServerUrlSync(root, urlPath));
158 }, "request $urlPath"); 247 }, "request $urlPath");
159 } 248 }
249
250 /// Schedules an HTTP request to the running pub server with [urlPath] and
251 /// verifies that it responds with a body that matches [expectation].
252 ///
253 /// [expectation] may either be a [Matcher] or a string to match an exact body.
254 /// [root] indicates which server should be accessed, and defaults to "web".
255 /// [headers] may be either a [Matcher] or a map to match an exact headers map.
160 void requestShouldSucceed(String urlPath, expectation, {String root, headers}) { 256 void requestShouldSucceed(String urlPath, expectation, {String root, headers}) {
161 scheduleRequest(urlPath, root: root).then((response) { 257 scheduleRequest(urlPath, root: root).then((response) {
162 if (expectation != null) expect(response.body, expectation); 258 if (expectation != null) expect(response.body, expectation);
163 if (headers != null) expect(response.headers, headers); 259 if (headers != null) expect(response.headers, headers);
164 }); 260 });
165 } 261 }
262
263 /// Schedules an HTTP request to the running pub server with [urlPath] and
264 /// verifies that it responds with a 404.
265 ///
266 /// [root] indicates which server should be accessed, and defaults to "web".
166 void requestShould404(String urlPath, {String root}) { 267 void requestShould404(String urlPath, {String root}) {
167 scheduleRequest(urlPath, root: root).then((response) { 268 scheduleRequest(urlPath, root: root).then((response) {
168 expect(response.statusCode, equals(404)); 269 expect(response.statusCode, equals(404));
169 }); 270 });
170 } 271 }
272
273 /// Schedules an HTTP request to the running pub server with [urlPath] and
274 /// verifies that it responds with a redirect to the given [redirectTarget].
275 ///
276 /// [redirectTarget] may be either a [Matcher] or a string to match an exact
277 /// URL. [root] indicates which server should be accessed, and defaults to
278 /// "web".
171 void requestShouldRedirect(String urlPath, redirectTarget, {String root}) { 279 void requestShouldRedirect(String urlPath, redirectTarget, {String root}) {
172 schedule(() { 280 schedule(() {
173 var request = 281 var request =
174 new http.Request("GET", Uri.parse(_getServerUrlSync(root, urlPath))); 282 new http.Request("GET", Uri.parse(_getServerUrlSync(root, urlPath)));
175 request.followRedirects = false; 283 request.followRedirects = false;
176 return request.send().then((response) { 284 return request.send().then((response) {
177 expect(response.statusCode ~/ 100, equals(3)); 285 expect(response.statusCode ~/ 100, equals(3));
178 expect(response.headers, containsPair('location', redirectTarget)); 286 expect(response.headers, containsPair('location', redirectTarget));
179 }); 287 });
180 }, "request $urlPath"); 288 }, "request $urlPath");
181 } 289 }
290
291 /// Schedules an HTTP POST to the running pub server with [urlPath] and verifies
292 /// that it responds with a 405.
293 ///
294 /// [root] indicates which server should be accessed, and defaults to "web".
182 void postShould405(String urlPath, {String root}) { 295 void postShould405(String urlPath, {String root}) {
183 schedule(() { 296 schedule(() {
184 return http.post(_getServerUrlSync(root, urlPath)).then((response) { 297 return http.post(_getServerUrlSync(root, urlPath)).then((response) {
185 expect(response.statusCode, equals(405)); 298 expect(response.statusCode, equals(405));
186 }); 299 });
187 }, "request $urlPath"); 300 }, "request $urlPath");
188 } 301 }
302
303 /// Schedules an HTTP request to the (theoretically) running pub server with
304 /// [urlPath] and verifies that it cannot be connected to.
305 ///
306 /// [root] indicates which server should be accessed, and defaults to "web".
189 void requestShouldNotConnect(String urlPath, {String root}) { 307 void requestShouldNotConnect(String urlPath, {String root}) {
190 schedule(() { 308 schedule(() {
191 return expect( 309 return expect(
192 http.get(_getServerUrlSync(root, urlPath)), 310 http.get(_getServerUrlSync(root, urlPath)),
193 throwsA(new isInstanceOf<SocketException>())); 311 throwsA(new isInstanceOf<SocketException>()));
194 }, "request $urlPath"); 312 }, "request $urlPath");
195 } 313 }
314
315 /// Reads lines from pub serve's stdout until it prints the build success
316 /// message.
317 ///
318 /// The schedule will not proceed until the output is found. If not found, it
319 /// will eventually time out.
196 void waitForBuildSuccess() => 320 void waitForBuildSuccess() =>
197 _pubServer.stdout.expect(consumeThrough(contains("successfully"))); 321 _pubServer.stdout.expect(consumeThrough(contains("successfully")));
322
323 /// Schedules opening a web socket connection to the currently running pub
324 /// serve.
198 Future _ensureWebSocket() { 325 Future _ensureWebSocket() {
326 // Use the existing one if already connected.
199 if (_webSocket != null) return new Future.value(); 327 if (_webSocket != null) return new Future.value();
328
329 // Server should already be running.
200 expect(_pubServer, isNotNull); 330 expect(_pubServer, isNotNull);
201 expect(_adminPort, isNotNull); 331 expect(_adminPort, isNotNull);
332
202 return WebSocket.connect("ws://localhost:$_adminPort").then((socket) { 333 return WebSocket.connect("ws://localhost:$_adminPort").then((socket) {
203 _webSocket = socket; 334 _webSocket = socket;
335 // TODO(rnystrom): Works around #13913.
204 _webSocketBroadcastStream = _webSocket.map(JSON.decode).asBroadcastStream(); 336 _webSocketBroadcastStream = _webSocket.map(JSON.decode).asBroadcastStream();
205 }); 337 });
206 } 338 }
339
340 /// Schedules closing the web socket connection to the currently-running pub
341 /// serve.
207 void closeWebSocket() { 342 void closeWebSocket() {
208 schedule(() { 343 schedule(() {
209 return _ensureWebSocket().then((_) => _webSocket.close()).then((_) => _webSo cket = 344 return _ensureWebSocket().then((_) => _webSocket.close()).then((_) => _webSo cket =
210 null); 345 null);
211 }, "closing web socket"); 346 }, "closing web socket");
212 } 347 }
348
349 /// Sends a JSON RPC 2.0 request to the running pub serve's web socket
350 /// connection.
351 ///
352 /// This calls a method named [method] with the given [params] (or no
353 /// parameters, if it's not passed). [params] may contain Futures, in which case
354 /// this will wait until they've completed before sending the request.
355 ///
356 /// This schedules the request, but doesn't block the schedule on the response.
357 /// It returns the response as a [Future].
213 Future<Map> webSocketRequest(String method, [Map params]) { 358 Future<Map> webSocketRequest(String method, [Map params]) {
214 var completer = new Completer(); 359 var completer = new Completer();
215 schedule(() { 360 schedule(() {
216 return Future.wait( 361 return Future.wait(
217 [_ensureWebSocket(), awaitObject(params)]).then((results) { 362 [_ensureWebSocket(), awaitObject(params),]).then((results) {
218 var resolvedParams = results[1]; 363 var resolvedParams = results[1];
219 chainToCompleter( 364 chainToCompleter(
220 currentSchedule.wrapFuture(_jsonRpcRequest(method, resolvedParams)), 365 currentSchedule.wrapFuture(_jsonRpcRequest(method, resolvedParams)),
221 completer); 366 completer);
222 }); 367 });
223 }, "send $method with $params to web socket"); 368 }, "send $method with $params to web socket");
224 return completer.future; 369 return completer.future;
225 } 370 }
371
372 /// Sends a JSON RPC 2.0 request to the running pub serve's web socket
373 /// connection, waits for a reply, then verifies the result.
374 ///
375 /// This calls a method named [method] with the given [params]. [params] may
376 /// contain Futures, in which case this will wait until they've completed before
377 /// sending the request.
378 ///
379 /// The result is validated using [result], which may be a [Matcher] or a [Map]
380 /// containing [Matcher]s and [Future]s. This will wait until any futures are
381 /// completed before sending the request.
382 ///
383 /// Returns a [Future] that completes to the call's result.
226 Future<Map> expectWebSocketResult(String method, Map params, result) { 384 Future<Map> expectWebSocketResult(String method, Map params, result) {
227 return schedule(() { 385 return schedule(() {
228 return Future.wait( 386 return Future.wait(
229 [webSocketRequest(method, params), awaitObject(result)]).then((results) { 387 [webSocketRequest(method, params), awaitObject(result)]).then((results) {
230 var response = results[0]; 388 var response = results[0];
231 var resolvedResult = results[1]; 389 var resolvedResult = results[1];
232 expect(response["result"], resolvedResult); 390 expect(response["result"], resolvedResult);
233 return response["result"]; 391 return response["result"];
234 }); 392 });
235 }, "send $method with $params to web socket and expect $result"); 393 }, "send $method with $params to web socket and expect $result");
236 } 394 }
395
396 /// Sends a JSON RPC 2.0 request to the running pub serve's web socket
397 /// connection, waits for a reply, then verifies the error response.
398 ///
399 /// This calls a method named [method] with the given [params]. [params] may
400 /// contain Futures, in which case this will wait until they've completed before
401 /// sending the request.
402 ///
403 /// The error response is validated using [errorCode] and [errorMessage]. Both
404 /// of these must be provided. The error code is checked against [errorCode] and
405 /// the error message is checked against [errorMessage]. Either of these may be
406 /// matchers.
407 ///
408 /// If [data] is provided, it is a JSON value or matcher used to validate the
409 /// "data" value of the error response.
410 ///
411 /// Returns a [Future] that completes to the error's [data] field.
237 Future expectWebSocketError(String method, Map params, errorCode, errorMessage, 412 Future expectWebSocketError(String method, Map params, errorCode, errorMessage,
238 {data}) { 413 {data}) {
239 return schedule(() { 414 return schedule(() {
240 return webSocketRequest(method, params).then((response) { 415 return webSocketRequest(method, params).then((response) {
241 expect(response["error"]["code"], errorCode); 416 expect(response["error"]["code"], errorCode);
242 expect(response["error"]["message"], errorMessage); 417 expect(response["error"]["message"], errorMessage);
418
243 if (data != null) { 419 if (data != null) {
244 expect(response["error"]["data"], data); 420 expect(response["error"]["data"], data);
245 } 421 }
422
246 return response["error"]["data"]; 423 return response["error"]["data"];
247 }); 424 });
248 }, "send $method with $params to web socket and expect error $errorCode"); 425 }, "send $method with $params to web socket and expect error $errorCode");
249 } 426 }
427
428 /// Validates that [root] was not bound to a port when pub serve started.
250 Future expectNotServed(String root) { 429 Future expectNotServed(String root) {
251 return schedule(() { 430 return schedule(() {
252 expect(_ports.containsKey(root), isFalse); 431 expect(_ports.containsKey(root), isFalse);
253 }); 432 });
254 } 433 }
434
435 /// The next id to use for a JSON-RPC 2.0 request.
255 var _rpcId = 0; 436 var _rpcId = 0;
437
438 /// Sends a JSON-RPC 2.0 request calling [method] with [params].
439 ///
440 /// Returns the response object.
256 Future<Map> _jsonRpcRequest(String method, [Map params]) { 441 Future<Map> _jsonRpcRequest(String method, [Map params]) {
257 var id = _rpcId++; 442 var id = _rpcId++;
258 var message = { 443 var message = {
259 "jsonrpc": "2.0", 444 "jsonrpc": "2.0",
260 "method": method, 445 "method": method,
261 "id": id 446 "id": id
262 }; 447 };
263 if (params != null) message["params"] = params; 448 if (params != null) message["params"] = params;
264 _webSocket.add(JSON.encode(message)); 449 _webSocket.add(JSON.encode(message));
450
265 return _webSocketBroadcastStream.firstWhere( 451 return _webSocketBroadcastStream.firstWhere(
266 (response) => response["id"] == id).then((value) { 452 (response) => response["id"] == id).then((value) {
267 currentSchedule.addDebugInfo( 453 currentSchedule.addDebugInfo(
268 "Web Socket request $method with params $params\n" "Result: $value"); 454 "Web Socket request $method with params $params\n" "Result: $value");
455
269 expect(value["id"], equals(id)); 456 expect(value["id"], equals(id));
270 return value; 457 return value;
271 }); 458 });
272 } 459 }
460
461 /// Returns a [Future] that completes to a URL string for the server serving
462 /// [path] from [root].
463 ///
464 /// If [root] is omitted, defaults to "web". If [path] is omitted, no path is
465 /// included. The Future will complete once the server is up and running and
466 /// the bound ports are known.
273 Future<String> getServerUrl([String root, String path]) => 467 Future<String> getServerUrl([String root, String path]) =>
274 _portsCompleter.future.then((_) => _getServerUrlSync(root, path)); 468 _portsCompleter.future.then((_) => _getServerUrlSync(root, path));
469
470 /// Records that [root] has been bound to [port].
471 ///
472 /// Used for testing the Web Socket API for binding new root directories to
473 /// ports after pub serve has been started.
275 registerServerPort(String root, int port) { 474 registerServerPort(String root, int port) {
276 _ports[root] = port; 475 _ports[root] = port;
277 } 476 }
477
478 /// Returns a URL string for the server serving [path] from [root].
479 ///
480 /// If [root] is omitted, defaults to "web". If [path] is omitted, no path is
481 /// included. Unlike [getServerUrl], this should only be called after the ports
482 /// are known.
278 String _getServerUrlSync([String root, String path]) { 483 String _getServerUrlSync([String root, String path]) {
279 if (root == null) root = 'web'; 484 if (root == null) root = 'web';
280 expect(_ports, contains(root)); 485 expect(_ports, contains(root));
281 var url = "http://localhost:${_ports[root]}"; 486 var url = "http://localhost:${_ports[root]}";
282 if (path != null) url = "$url/$path"; 487 if (path != null) url = "$url/$path";
283 return url; 488 return url;
284 } 489 }
490
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698