Chromium Code Reviews| Index: pkg/http_server/test/http_mock.dart |
| diff --git a/pkg/http_server/test/http_mock.dart b/pkg/http_server/test/http_mock.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..aa20ffb57bfa1323ea962d94160e4c6b529da1fc |
| --- /dev/null |
| +++ b/pkg/http_server/test/http_mock.dart |
| @@ -0,0 +1,199 @@ |
| +library http_mock; |
|
sethladd
2014/01/10 18:19:36
Can you pull this out and put it into its own pack
kevmoo
2014/01/10 18:51:24
Tracked for a separate CL https://code.google.com/
|
| + |
| +import 'dart:async'; |
| +import 'dart:collection'; |
| +import 'dart:convert'; |
| +import 'dart:io'; |
| + |
| +class MockHttpHeaders implements HttpHeaders { |
| + final Map<String, List<String>> _headers = |
| + new HashMap<String, List<String>>(); |
| + |
| + |
| + DateTime get ifModifiedSince { |
| + List<String> values = _headers[HttpHeaders.IF_MODIFIED_SINCE]; |
| + if (values != null) { |
| + try { |
| + return HttpDate.parse(values[0]); |
| + } on Exception catch (e) { |
| + return null; |
| + } |
| + } |
| + return null; |
| + } |
| + |
| + void set ifModifiedSince(DateTime ifModifiedSince) { |
| + // Format "ifModifiedSince" header with date in Greenwich Mean Time (GMT). |
| + String formatted = HttpDate.format(ifModifiedSince.toUtc()); |
| + _set(HttpHeaders.IF_MODIFIED_SINCE, formatted); |
| + } |
| + |
| + ContentType contentType; |
| + |
| + void set(String name, Object value) { |
| + name = name.toLowerCase(); |
| + _headers.remove(name); |
| + _addAll(name, value); |
| + } |
| + |
| + String value(String name) { |
| + name = name.toLowerCase(); |
| + List<String> values = _headers[name]; |
| + if (values == null) return null; |
| + if (values.length > 1) { |
| + throw new HttpException("More than one value for header $name"); |
| + } |
| + return values[0]; |
| + } |
| + |
| + String toString() => '$runtimeType : $_headers'; |
| + |
| + // [name] must be a lower-case version of the name. |
| + void _add(String name, value) { |
| + if (name == HttpHeaders.IF_MODIFIED_SINCE) { |
| + if (value is DateTime) { |
| + ifModifiedSince = value; |
| + } else if (value is String) { |
| + _set(HttpHeaders.IF_MODIFIED_SINCE, value); |
| + } else { |
| + throw new HttpException("Unexpected type for header named $name"); |
| + } |
| + } else { |
| + _addValue(name, value); |
| + } |
| + } |
| + |
| + void _addAll(String name, value) { |
| + if (value is List) { |
| + for (int i = 0; i < value.length; i++) { |
| + _add(name, value[i]); |
| + } |
| + } else { |
| + _add(name, value); |
| + } |
| + } |
| + |
| + void _addValue(String name, Object value) { |
| + List<String> values = _headers[name]; |
| + if (values == null) { |
| + values = new List<String>(); |
| + _headers[name] = values; |
| + } |
| + if (value is DateTime) { |
| + values.add(HttpDate.format(value)); |
| + } else { |
| + values.add(value.toString()); |
| + } |
| + } |
| + |
| + void _set(String name, String value) { |
| + assert(name == name.toLowerCase()); |
| + List<String> values = new List<String>(); |
| + _headers[name] = values; |
| + values.add(value); |
| + } |
| + |
| + /* |
| + * Implemented to remove editor warnings |
| + */ |
| + dynamic noSuchMethod(Invocation invocation) { |
| + print([invocation.memberName, invocation.isGetter, invocation.isSetter, invocation.isMethod, invocation.isAccessor]); |
| + return super.noSuchMethod(invocation); |
| + } |
| +} |
| + |
| +class MockHttpRequest implements HttpRequest { |
| + final Uri uri; |
| + final MockHttpResponse response = new MockHttpResponse(); |
| + final HttpHeaders headers = new MockHttpHeaders(); |
| + final String method = 'GET'; |
| + final bool followRedirects; |
| + |
| + MockHttpRequest(this.uri, {this.followRedirects: true, |
| + DateTime ifModifiedSince}) { |
| + if(ifModifiedSince != null) { |
| + headers.ifModifiedSince = ifModifiedSince; |
| + } |
| + } |
| + |
| + /* |
| + * Implemented to remove editor warnings |
| + */ |
| + dynamic noSuchMethod(Invocation invocation) => |
| + super.noSuchMethod(invocation); |
| +} |
| + |
| +class MockHttpResponse implements HttpResponse { |
| + final HttpHeaders headers = new MockHttpHeaders(); |
| + final Completer _completer = new Completer(); |
| + final List<int> _buffer = new List<int>(); |
| + String _reasonPhrase; |
| + Future _doneFuture; |
| + |
| + MockHttpResponse() { |
| + _doneFuture = _completer.future |
| + .whenComplete(() { |
| + assert(!_isDone); |
| + _isDone = true; |
| + }); |
| + } |
| + |
| + bool _isDone = false; |
| + |
| + int statusCode = HttpStatus.OK; |
| + |
| + String get reasonPhrase => _findReasonPhrase(statusCode); |
| + |
| + void set reasonPhrase(String value) { |
| + _reasonPhrase = value; |
| + } |
| + |
| + Future get done => _doneFuture; |
| + |
| + Future close() { |
| + _completer.complete(); |
| + return _doneFuture; |
| + } |
| + |
| + void add(List<int> data) { |
| + _buffer.addAll(data); |
| + } |
| + |
| + void addError(error, [StackTrace stackTrace]) { |
| + // doesn't seem to be hit...hmm... |
| + } |
| + |
| + Future redirect(Uri location, {int status: HttpStatus.MOVED_TEMPORARILY}) { |
| + this.statusCode = status; |
| + headers.set(HttpHeaders.LOCATION, location.toString()); |
| + return close(); |
| + } |
| + |
| + void write(Object obj) { |
| + var str = obj.toString(); |
| + add(UTF8.encode(str)); |
| + } |
| + |
| + /* |
| + * Implemented to remove editor warnings |
| + */ |
| + dynamic noSuchMethod(Invocation invocation) => |
| + super.noSuchMethod(invocation); |
| + |
| + String get mockContent => UTF8.decode(_buffer); |
| + |
| + bool get mockDone => _isDone; |
| + |
| + // Copied from SDK http_impl.dart @ 845 on 2014-01-05 |
| + // TODO: file an SDK bug to expose this on HttpStatus in some way |
| + String _findReasonPhrase(int statusCode) { |
| + if (_reasonPhrase != null) { |
| + return _reasonPhrase; |
| + } |
| + |
| + switch (statusCode) { |
| + case HttpStatus.NOT_FOUND: return "Not Found"; |
| + default: return "Status $statusCode"; |
| + } |
| + } |
| +} |