diff --git a/.idea/runConfigurations/Simple_Tests.xml b/.idea/runConfigurations/Simple_Tests.xml
new file mode 100644
index 00000000..9f906dc1
--- /dev/null
+++ b/.idea/runConfigurations/Simple_Tests.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..de2210c9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1 @@
+language: dart
\ No newline at end of file
diff --git a/README.md b/README.md
index 96d77d61..40e65277 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,4 @@
# angel_test
Testing utility library for the Angel framework.
-# Todo
-- `ServiceSuite`
-
-etc.
+See the tests for examples.
\ No newline at end of file
diff --git a/lib/src/client.dart b/lib/src/client.dart
index 5dfa49ba..5f270461 100644
--- a/lib/src/client.dart
+++ b/lib/src/client.dart
@@ -1,18 +1,65 @@
import 'dart:async';
+import 'dart:convert';
import 'dart:io';
import 'package:angel_client/io.dart' as client;
-import 'package:angel_framework/angel_framework.dart' as server;
+import 'package:angel_framework/angel_framework.dart';
+import 'package:uuid/uuid.dart';
+
+final Uuid _uuid = new Uuid();
+
+Future connectTo(Angel app,
+ {Map initialSession, bool saveSession: true}) async {
+ TestClient client;
+ var path = '/${_uuid.v1()}/${_uuid.v1()}/${_uuid.v1()}';
+
+ if (saveSession) {
+ app
+ ..get(path, (RequestContext req, res) async {
+ client._session = req.session;
+
+ if (initialSession != null) {
+ req.session.addAll(initialSession);
+ }
+ })
+ ..post(path, (RequestContext req, res) async {
+ client._session = req.session..addAll(req.body);
+ })
+ ..patch(path, (RequestContext req, res) async {
+ req.body['keys'].forEach(req.session.remove);
+ client._session = req.session;
+ });
+ }
-Future connectTo(server.Angel app) async {
final server = await app.startServer();
- return new _TestClient(
- server, 'http://${server.address.address}:${server.port}');
+ final url = 'http://${server.address.address}:${server.port}';
+ client = new TestClient(server, url);
+
+ if (saveSession) {
+ await client.client.get('$url$path');
+ client._sessionPath = path;
+ }
+
+ return client;
}
-class _TestClient extends client.Rest {
+/// Interacts with an Angel server.
+class TestClient extends client.Rest {
final HttpServer server;
+ HttpSession _session;
+ String _sessionPath;
- _TestClient(this.server, String path) : super(path);
+ /// Returns a pointer to the current session.
+ HttpSession get session => _session;
+
+ TestClient(this.server, String path) : super(path);
+
+ /// Adds data to the [session].
+ Future addToSession(Map data) => post(_sessionPath, body: data);
+
+ /// Removes data from the [session].
+ Future removeFromSession(List keys) => patch(_sessionPath,
+ body: JSON.encode({'keys': keys}),
+ headers: {HttpHeaders.CONTENT_TYPE: ContentType.JSON.mimeType});
@override
Future close() async {
diff --git a/lib/src/matchers.dart b/lib/src/matchers.dart
index fbf7cb9a..837d1b74 100644
--- a/lib/src/matchers.dart
+++ b/lib/src/matchers.dart
@@ -3,4 +3,38 @@ import 'package:http/http.dart' as http;
import 'package:matcher/matcher.dart';
/// Expects a given response, when parsed as JSON,
-/// to equal a desired value.
\ No newline at end of file
+/// to equal a desired value.
+Matcher isJson(value) => new _IsJson(value);
+
+/// Expects a response to have the given status code.
+Matcher hasStatus(int status) => new _HasStatus(status);
+
+class _IsJson extends Matcher {
+ var value;
+
+ _IsJson(this.value);
+
+ @override
+ Description describe(Description description) {
+ return description.add(' should equal the desired JSON response: $value');
+ }
+
+ @override
+ bool matches(http.Response item, Map matchState) =>
+ equals(value).matches(JSON.decode(item.body), matchState);
+}
+
+class _HasStatus extends Matcher {
+ int status;
+
+ _HasStatus(this.status);
+
+ @override
+ Description describe(Description description) {
+ return description.add(' should have statuc code $status');
+ }
+
+ @override
+ bool matches(http.Response item, Map matchState) =>
+ equals(status).matches(item.statusCode, matchState);
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index ae8e556d..8c9ad4ab 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -8,6 +8,7 @@ dependencies:
angel_framework: "^1.0.0-dev"
http: "^0.11.3+9"
matcher: "^0.12.0+2"
+ uuid: "^0.5.3"
dev_dependencies:
test: "^0.12.17+2"
environment:
diff --git a/test/simple_test.dart b/test/simple_test.dart
index 46bc63bd..e02020b2 100644
--- a/test/simple_test.dart
+++ b/test/simple_test.dart
@@ -1,17 +1,60 @@
import 'package:angel_framework/angel_framework.dart' as server;
-import 'package:angel_client/angel_client.dart' as client;
import 'package:angel_test/angel_test.dart';
import 'package:test/test.dart';
main() {
server.Angel app;
- client.Angel clientApp;
+ TestClient testClient;
setUp(() async {
- app.get('/hello', 'Hello');
+ app = new server.Angel()
+ ..get('/hello', 'Hello')
+ ..post('/hello', (req, res) async {
+ return {'bar': req.body['foo']};
+ });
- clientApp = await connectTo(app);
+ testClient = await connectTo(app);
});
- tearDown(clientApp.close);
-}
\ No newline at end of file
+ tearDown(() async {
+ await testClient.close();
+ app = null;
+ });
+
+ group('isJson+hasStatus', () {
+ test('get', () async {
+ final response = await testClient.get('/hello');
+ expect(response, isJson('Hello'));
+ });
+
+ test('post', () async {
+ final response = await testClient.post('/hello', body: {'foo': 'baz'});
+ expect(response, allOf(hasStatus(200), isJson({'bar': 'baz'})));
+ });
+ });
+
+ group('session', () {
+ test('initial session', () async {
+ final TestClient client =
+ await connectTo(app, initialSession: {'foo': 'bar'});
+ expect(client.session['foo'], equals('bar'));
+ });
+
+ test('add to session', () async {
+ final TestClient client = await connectTo(app);
+ await client.addToSession({'michael': 'jackson'});
+ expect(client.session['michael'], equals('jackson'));
+ });
+
+ test('remove from session', () async {
+ final TestClient client = await connectTo(app, initialSession: {'angel': 'framework'});
+ await client.removeFromSession(['angel']);
+ expect(client.session.containsKey('angel'), isFalse);
+ });
+
+ test('disable session', () async {
+ final client = await connectTo(app, saveSession: false);
+ expect(client.session, isNull);
+ });
+ });
+}