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 /// Test infrastructure for testing pub. Unlike typical unit tests, most pub | 5 /// Test infrastructure for testing pub. Unlike typical unit tests, most pub |
6 /// tests are integration tests that stage some stuff on the file system, run | 6 /// tests are integration tests that stage some stuff on the file system, run |
7 /// pub, and then validate the results. This library provides an API to build | 7 /// pub, and then validate the results. This library provides an API to build |
8 /// tests like that. | 8 /// tests like that. |
9 library test_pub; | 9 library test_pub; |
10 | 10 |
11 import 'dart:async'; | 11 import 'dart:async'; |
12 import 'dart:convert'; | 12 import 'dart:convert'; |
13 import 'dart:io'; | 13 import 'dart:io'; |
14 import 'dart:math'; | 14 import 'dart:math'; |
15 | 15 |
16 import 'package:http/testing.dart'; | 16 import 'package:http/testing.dart'; |
17 import 'package:path/path.dart' as path; | 17 import 'package:path/path.dart' as path; |
18 import 'package:scheduled_test/scheduled_process.dart'; | 18 import 'package:scheduled_test/scheduled_process.dart'; |
19 import 'package:scheduled_test/scheduled_server.dart'; | 19 import 'package:scheduled_test/scheduled_server.dart'; |
20 import 'package:scheduled_test/scheduled_stream.dart'; | 20 import 'package:scheduled_test/scheduled_stream.dart'; |
21 import 'package:scheduled_test/scheduled_test.dart'; | 21 import 'package:scheduled_test/scheduled_test.dart'; |
| 22 import 'package:shelf/shelf.dart' as shelf; |
| 23 import 'package:shelf/shelf_io.dart' as shelf_io; |
22 import 'package:unittest/compact_vm_config.dart'; | 24 import 'package:unittest/compact_vm_config.dart'; |
23 import 'package:yaml/yaml.dart'; | 25 import 'package:yaml/yaml.dart'; |
24 | 26 |
25 import '../lib/src/entrypoint.dart'; | 27 import '../lib/src/entrypoint.dart'; |
26 import '../lib/src/exit_codes.dart' as exit_codes; | 28 import '../lib/src/exit_codes.dart' as exit_codes; |
27 // TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides | 29 // TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides |
28 // with the git descriptor method. Maybe we should try to clean up the top level | 30 // with the git descriptor method. Maybe we should try to clean up the top level |
29 // scope a bit? | 31 // scope a bit? |
30 import '../lib/src/git.dart' as gitlib; | 32 import '../lib/src/git.dart' as gitlib; |
31 import '../lib/src/http.dart'; | 33 import '../lib/src/http.dart'; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 /// exist only for the duration of the pub run. | 99 /// exist only for the duration of the pub run. |
98 /// | 100 /// |
99 /// Subsequent calls to [serve] will replace the previous server. | 101 /// Subsequent calls to [serve] will replace the previous server. |
100 void serve([List<d.Descriptor> contents]) { | 102 void serve([List<d.Descriptor> contents]) { |
101 var baseDir = d.dir("serve-dir", contents); | 103 var baseDir = d.dir("serve-dir", contents); |
102 | 104 |
103 _hasServer = true; | 105 _hasServer = true; |
104 | 106 |
105 schedule(() { | 107 schedule(() { |
106 return _closeServer().then((_) { | 108 return _closeServer().then((_) { |
107 return HttpServer.bind("127.0.0.1", 0).then((server) { | 109 return shelf_io.serve((request) { |
| 110 currentSchedule.heartbeat(); |
| 111 var path = request.pathInfo.replaceFirst("/", ""); |
| 112 _requestedPaths.add(path); |
| 113 |
| 114 return validateStream(baseDir.load(path)) |
| 115 .then((stream) => new shelf.Response.ok(stream)) |
| 116 .catchError((error) { |
| 117 return new shelf.Response.notFound('File "$path" not found.'); |
| 118 }); |
| 119 }, '127.0.0.1', 0).then((server) { |
108 _server = server; | 120 _server = server; |
109 server.listen((request) { | |
110 currentSchedule.heartbeat(); | |
111 var response = request.response; | |
112 try { | |
113 var path = request.uri.path.replaceFirst("/", ""); | |
114 _requestedPaths.add(path); | |
115 | |
116 response.persistentConnection = false; | |
117 var stream = baseDir.load(path); | |
118 | |
119 new ByteStream(stream).toBytes().then((data) { | |
120 currentSchedule.heartbeat(); | |
121 response.statusCode = 200; | |
122 response.contentLength = data.length; | |
123 response.add(data); | |
124 response.close(); | |
125 }).catchError((e) { | |
126 response.statusCode = 404; | |
127 response.contentLength = 0; | |
128 response.close(); | |
129 }); | |
130 } catch (e) { | |
131 currentSchedule.signalError(e); | |
132 response.statusCode = 500; | |
133 response.close(); | |
134 return; | |
135 } | |
136 }); | |
137 _portCompleter.complete(_server.port); | 121 _portCompleter.complete(_server.port); |
138 currentSchedule.onComplete.schedule(_closeServer); | 122 currentSchedule.onComplete.schedule(_closeServer); |
139 return null; | |
140 }); | 123 }); |
141 }); | 124 }); |
142 }, 'starting a server serving:\n${baseDir.describe()}'); | 125 }, 'starting a server serving:\n${baseDir.describe()}'); |
143 } | 126 } |
144 | 127 |
145 /// Closes [_server]. Returns a [Future] that will complete after the [_server] | 128 /// Closes [_server]. Returns a [Future] that will complete after the [_server] |
146 /// is closed. | 129 /// is closed. |
147 Future _closeServer() { | 130 Future _closeServer() { |
148 if (_server == null) return new Future.value(); | 131 if (_server == null) return new Future.value(); |
149 var future = _server.close(); | 132 var future = _server.close(); |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 _lastMatcher.matches(item.last, matchState); | 851 _lastMatcher.matches(item.last, matchState); |
869 } | 852 } |
870 | 853 |
871 Description describe(Description description) { | 854 Description describe(Description description) { |
872 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); | 855 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); |
873 } | 856 } |
874 } | 857 } |
875 | 858 |
876 /// A [StreamMatcher] that matches multiple lines of output. | 859 /// A [StreamMatcher] that matches multiple lines of output. |
877 StreamMatcher emitsLines(String output) => inOrder(output.split("\n")); | 860 StreamMatcher emitsLines(String output) => inOrder(output.split("\n")); |
OLD | NEW |