Skip to content
This repository has been archived by the owner on Apr 29, 2021. It is now read-only.

Commit

Permalink
Add CannedHttp for testing, HTTP headers in response. (#13)
Browse files Browse the repository at this point in the history
* Cleanup web socket API, make more idiomatic.

* Export SeltzerWebSocketProvider

* Bump pubspec to 0.1.0-alpha

* Fix.

* Add a CannedHttp implementation for testing.

* Add response headers.

* Fixes.
  • Loading branch information
matanlurey authored Oct 21, 2016
1 parent 853a5f6 commit 51c697c
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog

## 0.2.0-alpha

- Added `CannedHttpResponse` and the `platform/testing.dart` library.
- Added response headers to `SeltzerHttpResponse`
1 change: 0 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ linter:
- valid_regexps
- always_declare_return_types
- annotate_overrides
- avoid_as
- avoid_init_to_null
- avoid_return_types_on_setters
- await_only_futures
Expand Down
3 changes: 3 additions & 0 deletions lib/platform/browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class _HtmlSeltzerHttpResponse implements SeltzerHttpResponse {

_HtmlSeltzerHttpResponse(this._request);

@override
Map<String, String> get headers => _request.responseHeaders;

@override
String get payload => _request.responseText;
}
Expand Down
13 changes: 11 additions & 2 deletions lib/platform/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,24 @@ class ServerSeltzerHttp extends PlatformSeltzerHttp {
headers.forEach(request.headers.add);
var response = await request.close();
var payload = await UTF8.decodeStream(response);
return new _IOSeltzerHttpResponse(payload);
var responseHeaders = <String, String>{};
response.headers
.forEach((name, value) => responseHeaders[name] = value.join(' '));
return new _IOSeltzerHttpResponse(
payload,
new Map<String, String>.unmodifiable(responseHeaders),
);
}
}

class _IOSeltzerHttpResponse implements SeltzerHttpResponse {
@override
final Map<String, String> headers;

@override
final String payload;

_IOSeltzerHttpResponse(this.payload);
_IOSeltzerHttpResponse(this.payload, this.headers);
}

/// A [SeltzerWebSocket] implementation for the dart vm.
Expand Down
65 changes: 65 additions & 0 deletions lib/platform/testing.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'dart:async';
import 'package:seltzer/src/context.dart';
import 'package:seltzer/src/interface.dart';

/// Initializes `package:seltzer/seltzer.dart` to use an in-memory fake.
///
/// In test environments it's useful to have canned responses.
void useSeltzerForTesting({
CannedSeltzerHttp useHttp,
}) {
if (useHttp != null) {
setHttpPlatform(useHttp, true);
}
}

/// A fake implementation of [SeltzerHttp].
///
/// Use [expect] to add expectations to return canned responses.
class CannedSeltzerHttp extends PlatformSeltzerHttp {
static String _getKey(
String method,
String url,
Map<String, String> headers,
) {
return '$method|$url|$headers';
}

final Map<String, _FakeHttpResponse> _expectations =
<String, _FakeHttpResponse>{};

@override
Future<SeltzerHttpResponse> execute(
String method,
String url, {
Map<String, String> headers,
}) {
var response = _expectations.remove(_getKey(method, url, headers));
if (response == null) {
throw new StateError('No expectation found for $method $url');
}
return new Future<SeltzerHttpResponse>.value(response);
}

/// Adds an expctation for [method] [url] [requestHeaders].
void expect(
String method,
String url, {
Map<String, String> requestHeaders: const {},
String response: '',
Map<String, String> responseHeaders: const {},
}) {
_expectations[_getKey(method, url, requestHeaders)] =
new _FakeHttpResponse(response, responseHeaders);
}
}

class _FakeHttpResponse implements SeltzerHttpResponse {
@override
final Map<String, String> headers;

@override
final String payload;

_FakeHttpResponse(this.payload, this.headers);
}
4 changes: 2 additions & 2 deletions lib/src/context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ const _platformAlreadySetError = 'Platform already initialized. In most` '
'bugs.';

/// Internal method: Initializes the top-level methods to use [platform].
void setHttpPlatform(SeltzerHttp platform) {
void setHttpPlatform(SeltzerHttp platform, [bool allowOverride = false]) {
assert(() {
if (_platform != null) {
if (!allowOverride && _platform != null) {
throw new StateError(_platformAlreadySetError);
}
return true;
Expand Down
3 changes: 3 additions & 0 deletions lib/src/interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ class PlatformSeltzerHttpRequest implements SeltzerHttpRequest {

/// An HTTP response object.
abstract class SeltzerHttpResponse {
/// Response headers.
Map<String, String> get headers;

/// Response payload.
String get payload;
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: seltzer
version: 0.1.0-alpha
version: 0.2.0-alpha
description: An elegant and rich cross-platform HTTP library for Dart.
authors:
- Matan Lurey <[email protected]>
Expand Down
17 changes: 17 additions & 0 deletions test/canned_http_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:seltzer/platform/testing.dart';
import 'package:test/test.dart';

void main() {
test('should fail if an expectation is missing', () {
expect(() => new CannedSeltzerHttp().get('/404').send(), throwsStateError);
});

test('should return the canned response', () async {
var http = new CannedSeltzerHttp();
http.expect('GET', '/fake/url', response: 'Hello World');
expect(
(await http.get('/fake/url').send().first).payload,
'Hello World',
);
});
}

0 comments on commit 51c697c

Please sign in to comment.