OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
bkonyi
2017/04/19 16:37:52
I'll change the copyright date.
zra
2017/04/19 17:46:13
tests should go under the test/ directory.
bkonyi
2017/04/19 21:29:50
Done.
bkonyi
2017/04/19 21:29:50
Done.
| |
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 | |
5 import "dart:isolate"; | |
6 import "dart:io"; | |
7 import "../sync_http.dart"; | |
zra
2017/04/19 17:46:13
This should be a package: import, like:
import "p
bkonyi
2017/04/19 21:29:50
Tried this before, didn't realize I needed to run
| |
8 import "../../../sdk/pkg/expect/lib/expect.dart"; | |
bkonyi
2017/04/19 16:37:52
This needs to be changed to not use an explicit pa
zra
2017/04/19 17:46:13
Use the "test" package. Add it under "dev_dependen
bkonyi
2017/04/19 21:29:50
Done.
| |
9 | |
10 class TestServerMain { | |
11 TestServerMain() | |
12 : _statusPort = new ReceivePort(), | |
13 _serverPort = null; | |
zra
2017/04/19 17:46:13
not needed
bkonyi
2017/04/19 21:29:50
Removed.
| |
14 | |
15 void setServerStartedHandler(void startedCallback(int port)) { | |
16 _startedCallback = startedCallback; | |
17 } | |
18 | |
19 void start([bool chunkedEncoding = false]) { | |
20 ReceivePort receivePort = new ReceivePort(); | |
21 var remote = Isolate.spawn(startTestServer, receivePort.sendPort); | |
zra
2017/04/19 17:46:13
remote is unused
bkonyi
2017/04/19 21:29:50
Removed.
| |
22 receivePort.first.then((port) { | |
23 _serverPort = port; | |
24 | |
25 if (chunkedEncoding) { | |
26 // Send chunked encoding message to the server. | |
27 port.send( | |
28 [new TestServerCommand.chunkedEncoding(), _statusPort.sendPort]); | |
29 } | |
30 | |
31 // Send server start message to the server. | |
32 var command = new TestServerCommand.start(); | |
33 port.send([command, _statusPort.sendPort]); | |
34 }); | |
35 | |
36 // Handle status messages from the server. | |
37 _statusPort.listen((var status) { | |
38 if (status.isStarted) { | |
39 _startedCallback(status.port); | |
40 } | |
41 }); | |
42 } | |
43 | |
44 void close() { | |
45 // Send server stop message to the server. | |
46 _serverPort.send([new TestServerCommand.stop(), _statusPort.sendPort]); | |
47 _statusPort.close(); | |
48 } | |
49 | |
50 ReceivePort _statusPort; // Port for receiving messages from the server. | |
zra
2017/04/19 17:46:13
I think Dart style tends towards putting these at
bkonyi
2017/04/19 21:29:50
Good point. Moved.
| |
51 SendPort _serverPort; // Port for sending messages to the server. | |
52 var _startedCallback; | |
zra
2017/04/19 17:46:13
You can make a typedef for the function type and u
bkonyi
2017/04/19 21:29:50
Done.
| |
53 } | |
54 | |
55 class TestServerCommand { | |
zra
2017/04/19 17:46:13
How about an enum?
bkonyi
2017/04/19 21:29:50
Done.
| |
56 static const START = 0; | |
zra
2017/04/19 17:46:13
Check the Dart style guide fro naming constants. A
bkonyi
2017/04/19 21:29:50
Replaced with enum.
| |
57 static const STOP = 1; | |
58 static const CHUNKED_ENCODING = 2; | |
59 | |
60 TestServerCommand.start() : _command = START; | |
61 TestServerCommand.stop() : _command = STOP; | |
62 TestServerCommand.chunkedEncoding() : _command = CHUNKED_ENCODING; | |
63 | |
64 bool get isStart => _command == START; | |
65 bool get isStop => _command == STOP; | |
66 bool get isChunkedEncoding => _command == CHUNKED_ENCODING; | |
67 | |
68 int _command; | |
69 } | |
70 | |
71 class TestServerStatus { | |
zra
2017/04/19 17:46:13
Maybe split the state off into an enum.
bkonyi
2017/04/19 21:29:50
Done.
| |
72 static const STARTED = 0; | |
73 static const STOPPED = 1; | |
74 static const ERROR = 2; | |
75 | |
76 TestServerStatus.started(this._port) : _state = STARTED; | |
77 TestServerStatus.stopped() : _state = STOPPED; | |
78 TestServerStatus.error() : _state = ERROR; | |
79 | |
80 bool get isStarted => _state == STARTED; | |
81 bool get isStopped => _state == STOPPED; | |
82 bool get isError => _state == ERROR; | |
83 | |
84 int get port => _port; | |
85 | |
86 int _state; | |
87 int _port; | |
88 } | |
89 | |
90 void startTestServer(SendPort replyTo) { | |
91 var server = new TestServer(); | |
92 server.init(); | |
93 replyTo.send(server.dispatchSendPort); | |
94 } | |
95 | |
96 class TestServer { | |
97 // Echo the request content back to the response. | |
98 void _echoHandler(HttpRequest request) { | |
99 var response = request.response; | |
100 Expect.equals("POST", request.method); | |
101 response.contentLength = request.contentLength; | |
102 request.listen((List<int> data) { | |
103 var string = new String.fromCharCodes(data); | |
104 response.write(string); | |
105 response.close(); | |
106 }); | |
107 } | |
108 | |
109 // Echo the request content back to the response. | |
110 void _zeroToTenHandler(HttpRequest request) { | |
111 var response = request.response; | |
112 String msg = "01234567890"; | |
113 Expect.equals("GET", request.method); | |
114 response.contentLength = msg.length; | |
115 response.write(msg); | |
116 response.close(); | |
117 } | |
118 | |
119 // Return a 404. | |
120 void _notFoundHandler(HttpRequest request) { | |
121 var response = request.response; | |
122 response.statusCode = HttpStatus.NOT_FOUND; | |
123 String msg = "Page not found"; | |
124 response.contentLength = msg.length; | |
125 response.headers.set("Content-Type", "text/html; charset=UTF-8"); | |
126 response.write(msg); | |
127 response.close(); | |
128 } | |
129 | |
130 // Return a 301 with a custom reason phrase. | |
131 void _reasonForMovingHandler(HttpRequest request) { | |
132 var response = request.response; | |
133 response.statusCode = HttpStatus.MOVED_PERMANENTLY; | |
134 response.reasonPhrase = "Don't come looking here any more"; | |
135 response.close(); | |
136 } | |
137 | |
138 // Check the "Host" header. | |
139 void _hostHandler(HttpRequest request) { | |
140 var response = request.response; | |
141 Expect.equals(1, request.headers["Host"].length); | |
142 Expect.equals("www.dartlang.org:1234", request.headers["Host"][0]); | |
143 Expect.equals("www.dartlang.org", request.headers.host); | |
144 Expect.equals(1234, request.headers.port); | |
145 response.statusCode = HttpStatus.OK; | |
146 response.close(); | |
147 } | |
148 | |
149 void init() { | |
150 // Setup request handlers. | |
151 _requestHandlers = new Map(); | |
152 _requestHandlers["/echo"] = _echoHandler; | |
153 _requestHandlers["/0123456789"] = _zeroToTenHandler; | |
154 _requestHandlers["/reasonformoving"] = _reasonForMovingHandler; | |
155 _requestHandlers["/host"] = _hostHandler; | |
156 _dispatchPort = new ReceivePort(); | |
157 _dispatchPort.listen(dispatch); | |
158 } | |
159 | |
160 SendPort get dispatchSendPort => _dispatchPort.sendPort; | |
161 | |
162 void dispatch(var message) { | |
163 TestServerCommand command = message[0]; | |
164 SendPort replyTo = message[1]; | |
165 if (command.isStart) { | |
166 try { | |
167 HttpServer.bind("127.0.0.1", 0).then((server) { | |
168 _server = server; | |
169 _server.listen(_requestReceivedHandler); | |
170 replyTo.send(new TestServerStatus.started(_server.port)); | |
171 }); | |
172 } catch (e) { | |
173 replyTo.send(new TestServerStatus.error()); | |
174 } | |
175 } else if (command.isStop) { | |
176 _server.close(); | |
177 _dispatchPort.close(); | |
178 replyTo.send(new TestServerStatus.stopped()); | |
179 } else if (command.isChunkedEncoding) { | |
180 _chunkedEncoding = true; | |
181 } | |
182 } | |
183 | |
184 void _requestReceivedHandler(HttpRequest request) { | |
185 var requestHandler = _requestHandlers[request.uri.path]; | |
186 if (requestHandler != null) { | |
187 requestHandler(request); | |
188 } else { | |
189 _notFoundHandler(request); | |
190 } | |
191 } | |
192 | |
193 HttpServer _server; // HTTP server instance. | |
194 ReceivePort _dispatchPort; | |
195 Map _requestHandlers; | |
196 bool _chunkedEncoding = false; | |
197 } | |
198 | |
199 void testStartStop() { | |
zra
2017/04/19 17:46:13
These tests are asynchronous, and you'll probably
bkonyi
2017/04/19 21:29:50
Done.
| |
200 TestServerMain testServerMain = new TestServerMain(); | |
201 testServerMain.setServerStartedHandler((int port) { | |
202 testServerMain.close(); | |
203 }); | |
204 testServerMain.start(); | |
205 } | |
206 | |
207 void testGET() { | |
208 TestServerMain testServerMain = new TestServerMain(); | |
209 testServerMain.setServerStartedHandler((int port) { | |
210 HttpClientSync httpClient = new HttpClientSync(); | |
211 var request = | |
212 httpClient.getUrl(new Uri.http("127.0.0.1:$port", "/0123456789")); | |
213 var response = request.close(); | |
214 Expect.equals(HttpStatus.OK, response.statusCode); | |
215 Expect.equals(11, response.contentLength); | |
216 Expect.equals("01234567890", response.body); | |
217 testServerMain.close(); | |
218 }); | |
219 testServerMain.start(); | |
220 } | |
221 | |
222 void testPOST(bool chunkedEncoding) { | |
223 String data = "ABCDEFGHIJKLMONPQRSTUVWXYZ"; | |
224 final int kMessageCount = 10; | |
225 | |
226 TestServerMain testServerMain = new TestServerMain(); | |
227 | |
228 void runTest(int port) { | |
229 int count = 0; | |
230 HttpClientSync httpClient = new HttpClientSync(); | |
231 void sendRequest() { | |
232 var request = | |
233 httpClient.postUrl(new Uri.http("127.0.0.1:$port", "/echo")); | |
234 if (chunkedEncoding) { | |
235 request.write(data.substring(0, 10)); | |
236 request.write(data.substring(10, data.length)); | |
237 } else { | |
238 request.write(data); | |
239 } | |
240 var response = request.close(); | |
241 Expect.equals(HttpStatus.OK, response.statusCode); | |
242 Expect.equals(data, response.body); | |
243 count++; | |
244 if (count < kMessageCount) { | |
245 sendRequest(); | |
246 } else { | |
247 testServerMain.close(); | |
248 } | |
249 } | |
250 | |
251 sendRequest(); | |
252 } | |
253 | |
254 testServerMain.setServerStartedHandler(runTest); | |
255 testServerMain.start(chunkedEncoding); | |
256 } | |
257 | |
258 void test404() { | |
259 TestServerMain testServerMain = new TestServerMain(); | |
260 testServerMain.setServerStartedHandler((int port) { | |
261 HttpClientSync httpClient = new HttpClientSync(); | |
262 var request = | |
263 httpClient.getUrl(new Uri.http("127.0.0.1:$port", "/thisisnotfound")); | |
264 var response = request.close(); | |
265 Expect.equals(HttpStatus.NOT_FOUND, response.statusCode); | |
266 Expect.equals("Page not found", response.body); | |
267 testServerMain.close(); | |
268 }); | |
269 testServerMain.start(); | |
270 } | |
271 | |
272 void testReasonPhrase() { | |
273 TestServerMain testServerMain = new TestServerMain(); | |
274 testServerMain.setServerStartedHandler((int port) { | |
275 HttpClientSync httpClient = new HttpClientSync(); | |
276 var request = | |
277 httpClient.getUrl(new Uri.http("127.0.0.1:$port", "/reasonformoving")); | |
278 var response = request.close(); | |
279 Expect.equals(HttpStatus.MOVED_PERMANENTLY, response.statusCode); | |
280 Expect.equals( | |
281 "Don't come looking here any more\r\n", response.reasonPhrase); | |
282 testServerMain.close(); | |
283 }); | |
284 testServerMain.start(); | |
285 } | |
286 | |
287 void main() { | |
288 testStartStop(); | |
289 testGET(); | |
290 testPOST(true); | |
291 testPOST(false); | |
292 test404(); | |
293 testReasonPhrase(); | |
294 } | |
OLD | NEW |