| 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;
|
| +
|
| +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";
|
| + }
|
| + }
|
| +}
|
|
|