Index: pkg/shelf/test/shelf_io_test.dart |
diff --git a/pkg/shelf/test/shelf_io_test.dart b/pkg/shelf/test/shelf_io_test.dart |
deleted file mode 100644 |
index c1b4a410cd5fa9c5a0688de38d2a7f2b7dd8b5f1..0000000000000000000000000000000000000000 |
--- a/pkg/shelf/test/shelf_io_test.dart |
+++ /dev/null |
@@ -1,373 +0,0 @@ |
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-library shelf_io_test; |
- |
-import 'dart:async'; |
-import 'dart:convert'; |
-import 'dart:io'; |
- |
-import 'package:http/http.dart' as http; |
-import 'package:http_parser/http_parser.dart' as parser; |
-import 'package:scheduled_test/scheduled_test.dart'; |
-import 'package:shelf/shelf.dart'; |
-import 'package:shelf/shelf_io.dart' as shelf_io; |
- |
-import 'test_util.dart'; |
- |
-void main() { |
- test('sync handler returns a value to the client', () { |
- _scheduleServer(syncHandler); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.body, 'Hello from /'); |
- }); |
- }); |
- |
- test('async handler returns a value to the client', () { |
- _scheduleServer(asyncHandler); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.body, 'Hello from /'); |
- }); |
- }); |
- |
- test('sync null response leads to a 500', () { |
- _scheduleServer((request) => null); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, HttpStatus.INTERNAL_SERVER_ERROR); |
- expect(response.body, 'Internal Server Error'); |
- }); |
- }); |
- |
- test('async null response leads to a 500', () { |
- _scheduleServer((request) => new Future.value(null)); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, HttpStatus.INTERNAL_SERVER_ERROR); |
- expect(response.body, 'Internal Server Error'); |
- }); |
- }); |
- |
- test('thrown error leads to a 500', () { |
- _scheduleServer((request) { |
- throw new UnsupportedError('test'); |
- }); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, HttpStatus.INTERNAL_SERVER_ERROR); |
- expect(response.body, 'Internal Server Error'); |
- }); |
- }); |
- |
- test('async error leads to a 500', () { |
- _scheduleServer((request) { |
- return new Future.error('test'); |
- }); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, HttpStatus.INTERNAL_SERVER_ERROR); |
- expect(response.body, 'Internal Server Error'); |
- }); |
- }); |
- |
- test('Request is populated correctly', () { |
- var path = '/foo/bar?qs=value'; |
- |
- _scheduleServer((request) { |
- expect(request.contentLength, 0); |
- expect(request.method, 'GET'); |
- |
- var expectedUrl = 'http://localhost:$_serverPort$path'; |
- expect(request.requestedUri, Uri.parse(expectedUrl)); |
- |
- expect(request.url.path, '/foo/bar'); |
- expect(request.url.pathSegments, ['foo', 'bar']); |
- expect(request.protocolVersion, '1.1'); |
- expect(request.url.query, 'qs=value'); |
- expect(request.scriptName, ''); |
- |
- return syncHandler(request); |
- }); |
- |
- return schedule(() => http.get('http://localhost:$_serverPort$path')) |
- .then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.body, 'Hello from /foo/bar'); |
- }); |
- }); |
- |
- test('custom response headers are received by the client', () { |
- _scheduleServer((request) { |
- return new Response.ok('Hello from /', headers: { |
- 'test-header': 'test-value', |
- 'test-list': 'a, b, c' |
- }); |
- }); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.headers['test-header'], 'test-value'); |
- expect(response.body, 'Hello from /'); |
- }); |
- }); |
- |
- test('custom status code is received by the client', () { |
- _scheduleServer((request) { |
- return new Response(299, body: 'Hello from /'); |
- }); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, 299); |
- expect(response.body, 'Hello from /'); |
- }); |
- }); |
- |
- test('custom request headers are received by the handler', () { |
- _scheduleServer((request) { |
- expect(request.headers, containsPair('custom-header', 'client value')); |
- |
- // dart:io HttpServer splits multi-value headers into an array |
- // validate that they are combined correctly |
- expect(request.headers, containsPair('multi-header', 'foo,bar,baz')); |
- return syncHandler(request); |
- }); |
- |
- var headers = { |
- 'custom-header': 'client value', |
- 'multi-header': 'foo,bar,baz' |
- }; |
- |
- return _scheduleGet(headers: headers).then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.body, 'Hello from /'); |
- }); |
- }); |
- |
- test('post with empty content', () { |
- _scheduleServer((request) { |
- expect(request.mimeType, isNull); |
- expect(request.encoding, isNull); |
- expect(request.method, 'POST'); |
- expect(request.contentLength, 0); |
- |
- return request.readAsString().then((body) { |
- expect(body, ''); |
- return syncHandler(request); |
- }); |
- }); |
- |
- return _schedulePost().then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.stream.bytesToString(), completion('Hello from /')); |
- }); |
- }); |
- |
- test('post with request content', () { |
- _scheduleServer((request) { |
- expect(request.mimeType, 'text/plain'); |
- expect(request.encoding, UTF8); |
- expect(request.method, 'POST'); |
- expect(request.contentLength, 9); |
- |
- return request.readAsString().then((body) { |
- expect(body, 'test body'); |
- return syncHandler(request); |
- }); |
- }); |
- |
- return _schedulePost(body: 'test body').then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.stream.bytesToString(), completion('Hello from /')); |
- }); |
- }); |
- |
- test('supports request hijacking', () { |
- _scheduleServer((request) { |
- expect(request.method, 'POST'); |
- |
- request.hijack(expectAsync((stream, sink) { |
- expect(stream.first, completion(equals("Hello".codeUnits))); |
- |
- sink.add(( |
- "HTTP/1.1 404 Not Found\r\n" |
- "Date: Mon, 23 May 2005 22:38:34 GMT\r\n" |
- "Content-Length: 13\r\n" |
- "\r\n" |
- "Hello, world!").codeUnits); |
- sink.close(); |
- })); |
- }); |
- |
- return _schedulePost(body: "Hello").then((response) { |
- expect(response.statusCode, HttpStatus.NOT_FOUND); |
- expect(response.headers["date"], "Mon, 23 May 2005 22:38:34 GMT"); |
- expect(response.stream.bytesToString(), |
- completion(equals("Hello, world!"))); |
- }); |
- }); |
- |
- test('reports an error if a HijackException is thrown without hijacking', () { |
- _scheduleServer((request) => throw const HijackException()); |
- |
- return _scheduleGet().then((response) { |
- expect(response.statusCode, HttpStatus.INTERNAL_SERVER_ERROR); |
- }); |
- }); |
- |
- test('passes asynchronous exceptions to the parent error zone', () { |
- return runZoned(() { |
- return shelf_io.serve((request) { |
- new Future(() => throw 'oh no'); |
- return syncHandler(request); |
- }, 'localhost', 0).then((server) { |
- return http.get('http://localhost:${server.port}').then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.body, 'Hello from /'); |
- server.close(); |
- }); |
- }); |
- }, onError: expectAsync((error) { |
- expect(error, equals('oh no')); |
- })); |
- }); |
- |
- test("doesn't pass asynchronous exceptions to the root error zone", () { |
- return Zone.ROOT.run(() { |
- return shelf_io.serve((request) { |
- new Future(() => throw 'oh no'); |
- return syncHandler(request); |
- }, 'localhost', 0).then((server) { |
- return http.get('http://localhost:${server.port}').then((response) { |
- expect(response.statusCode, HttpStatus.OK); |
- expect(response.body, 'Hello from /'); |
- server.close(); |
- }); |
- }); |
- }); |
- }); |
- |
- test('a bad HTTP request results in a 500 response', () { |
- var socket; |
- |
- _scheduleServer(syncHandler); |
- |
- schedule(() { |
- return Socket.connect('localhost', _serverPort).then((value) { |
- socket = value; |
- |
- currentSchedule.onComplete.schedule(() { |
- return socket.close(); |
- }, 'close the socket'); |
- }); |
- }); |
- |
- schedule(() { |
- socket.write('GET / HTTP/1.1\r\n'); |
- socket.write('Host: ^^super bad !@#host\r\n'); |
- socket.write('\r\n'); |
- return socket.close(); |
- }); |
- |
- schedule(() { |
- return UTF8.decodeStream(socket).then((value) { |
- expect(value, contains('500 Internal Server Error')); |
- }); |
- }); |
- }); |
- |
- group('date header', () { |
- test('is sent by default', () { |
- _scheduleServer(syncHandler); |
- |
- // Update beforeRequest to be one second earlier. HTTP dates only have |
- // second-level granularity and the request will likely take less than a |
- // second. |
- var beforeRequest = new DateTime.now().subtract(new Duration(seconds: 1)); |
- |
- return _scheduleGet().then((response) { |
- expect(response.headers, contains('date')); |
- var responseDate = parser.parseHttpDate(response.headers['date']); |
- |
- expect(responseDate.isAfter(beforeRequest), isTrue); |
- expect(responseDate.isBefore(new DateTime.now()), isTrue); |
- }); |
- }); |
- |
- test('defers to header in response', () { |
- var date = new DateTime.utc(1981, 6, 5); |
- _scheduleServer((request) { |
- return new Response.ok('test', headers: { |
- HttpHeaders.DATE: parser.formatHttpDate(date) |
- }); |
- }); |
- |
- return _scheduleGet().then((response) { |
- expect(response.headers, contains('date')); |
- var responseDate = parser.parseHttpDate(response.headers['date']); |
- expect(responseDate, date); |
- }); |
- }); |
- }); |
- |
- group('server header', () { |
- test('defaults to "dart:io with Shelf"', () { |
- _scheduleServer(syncHandler); |
- |
- return _scheduleGet().then((response) { |
- expect(response.headers, |
- containsPair(HttpHeaders.SERVER, 'dart:io with Shelf')); |
- }); |
- }); |
- |
- test('defers to header in response', () { |
- _scheduleServer((request) { |
- return new Response.ok('test', |
- headers: {HttpHeaders.SERVER: 'myServer'}); |
- }); |
- |
- return _scheduleGet().then((response) { |
- expect(response.headers, containsPair(HttpHeaders.SERVER, 'myServer')); |
- }); |
- }); |
- }); |
-} |
- |
-int _serverPort; |
- |
-Future _scheduleServer(Handler handler) { |
- return schedule(() => shelf_io.serve(handler, 'localhost', 0).then((server) { |
- currentSchedule.onComplete.schedule(() { |
- _serverPort = null; |
- return server.close(force: true); |
- }); |
- |
- _serverPort = server.port; |
- })); |
-} |
- |
-Future<http.Response> _scheduleGet({Map<String, String> headers}) { |
- if (headers == null) headers = {}; |
- |
- return schedule(() => |
- http.get('http://localhost:$_serverPort/', headers: headers)); |
-} |
- |
-Future<http.StreamedResponse> _schedulePost({Map<String, String> headers, |
- String body}) { |
- |
- return schedule(() { |
- |
- var request = new http.Request('POST', |
- Uri.parse('http://localhost:$_serverPort/')); |
- |
- if (headers != null) request.headers.addAll(headers); |
- if (body != null) request.body = body; |
- |
- return request.send(); |
- }); |
-} |