Publish test

This commit is contained in:
thomashii 2021-05-15 16:35:27 +08:00
parent cf208bf673
commit 3ac245db46
7 changed files with 79 additions and 93 deletions

View file

@ -1,19 +1,22 @@
# angel_test
[![Pub](https://img.shields.io/pub/v/angel_test.svg)](https://pub.dartlang.org/packages/angel_test)
[![build status](https://travis-ci.org/angel-dart/test.svg)](https://travis-ci.org/angel-dart/test)
# angel3_test
[![version](https://img.shields.io/badge/pub-v4.0.0-brightgreen)](https://pub.dartlang.org/packages/angel3_tet)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
[![License](https://img.shields.io/github/license/dukefirehawk/angel)](https://github.com/dukefirehawk/angel/tree/angel3/packages/test/LICENSE)
Testing utility library for the Angel framework.
# TestClient
The `TestClient` class is a custom `angel_client` that sends mock requests to your server.
The `TestClient` class is a custom `angel3_client` that sends mock requests to your server.
This means that you will not have to bind your server to HTTP to run.
Plus, it is an `angel_client`, and thus supports services and other goodies.
Plus, it is an `angel3_client`, and thus supports services and other goodies.
The `TestClient` also supports WebSockets. WebSockets cannot be mocked (yet!) within this library,
so calling the `websocket()` function will also bind your server to HTTP, if it is not already listening.
The return value is a `WebSockets` client instance
(from [`package:angel_websocket`](https://github.com/angel-dart/websocket));
(from [`package:angel3_websocket`](https://github.com/dukefirehawk/angel/tree/angel3/packages/websocket));
```dart
var ws = await client.websocket('/ws');
@ -52,12 +55,12 @@ test('error', () async {
`hasValidBody` is one of the most powerful `Matcher`s in this library,
because it allows you to validate a JSON body against a
[validation schema](https://github.com/angel-dart/validate).
[validation schema](https://github.com/dukefirehawk/angel/tree/angel3/packages/validate).
Angel provides a comprehensive validation library that integrates tightly
with the very `matcher` package that you already use for testing. :)
with the very `matcher` package that you already use for testing.
[https://github.com/angel-dart/validate](https://github.com/angel-dart/validate)
[`package:angel3_validate`](https://github.com/dukefirehawk/angel/tree/angel3/packages//validate)
```dart
test('validate response', () async {

View file

@ -1,20 +1,20 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_test/angel_test.dart';
import 'package:angel_validate/angel_validate.dart';
import 'package:angel_websocket/server.dart';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_test/angel3_test.dart';
import 'package:angel3_validate/angel3_validate.dart';
import 'package:angel3_websocket/server.dart';
import 'package:test/test.dart';
main() {
void main() {
Angel? app;
late TestClient client;
setUp(() async {
app = new Angel()
app = Angel()
..get('/hello', (req, res) => 'Hello')
..get(
'/error',
(req, res) => throw new AngelHttpException.forbidden(message: 'Test')
(req, res) => throw AngelHttpException.forbidden(message: 'Test')
..errors.addAll(['foo', 'bar']))
..get('/body', (req, res) {
res
@ -39,13 +39,13 @@ main() {
})
..use(
'/foo',
new AnonymousService(
AnonymousService(
index: ([params]) async => [
{'michael': 'jackson'}
],
create: (dynamic data, [params]) async => {'foo': 'bar'}));
var ws = new AngelWebSocket(app);
var ws = AngelWebSocket(app);
await app!.configure(ws.configureServer);
app!.all('/ws', ws.handleRequest);
@ -101,9 +101,9 @@ main() {
expect(res, hasContentType('application/json'));
expect(
res,
hasValidBody(new Validator({
hasValidBody(Validator({
'michael*': [isString, isNotEmpty, equals('jackson')],
'billie': new Validator({
'billie': Validator({
'jean': [isString, isNotEmpty],
'is_my_lover': [isBool, isFalse]
})

View file

@ -1,26 +1,26 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:angel_client/base_angel_client.dart' as client;
import 'package:angel_client/io.dart' as client;
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_framework/http.dart';
import 'package:angel_websocket/io.dart' as client;
import 'package:angel3_client/base_angel_client.dart' as client;
import 'package:angel3_client/io.dart' as client;
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';
import 'package:angel3_websocket/io.dart' as client;
import 'package:http/http.dart' as http hide StreamedResponse;
import 'package:http/io_client.dart' as http;
import 'package:http/src/streamed_response.dart';
import 'package:mock_request/mock_request.dart';
import 'package:angel3_mock_request/angel3_mock_request.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:web_socket_channel/io.dart';
//import 'package:uuid/uuid.dart';
final RegExp _straySlashes = new RegExp(r"(^/)|(/+$)");
final RegExp _straySlashes = RegExp(r"(^/)|(/+$)");
/*const Map<String, String> _readHeaders = const {'Accept': 'application/json'};
const Map<String, String> _writeHeaders = const {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
final Uuid _uuid = new Uuid();*/
final Uuid _uuid = Uuid();*/
/// Shorthand for bootstrapping a [TestClient].
Future<TestClient> connectTo(Angel app,
@ -36,7 +36,7 @@ Future<TestClient> connectTo(Angel app,
print("Load plugins");
await plugin(app);
}
return new TestClient(app,
return TestClient(app,
autoDecodeGzip: autoDecodeGzip != false, useZone: useZone)
..session.addAll(initialSession ?? {});
}
@ -46,7 +46,7 @@ class TestClient extends client.BaseAngelClient {
final Map<String, client.Service> _services = {};
/// Session info to be sent to the server on every request.
final HttpSession session = new MockHttpSession(id: 'angel-test-client');
final HttpSession session = MockHttpSession(id: 'angel-test-client');
/// A list of cookies to be sent to and received from the server.
final List<Cookie> cookies = [];
@ -101,9 +101,9 @@ class TestClient extends client.BaseAngelClient {
rq = newRq;
}
if (authToken?.isNotEmpty == true)
if (authToken?.isNotEmpty == true) {
rq.headers.add('authorization', 'Bearer $authToken');
}
rq..cookies.addAll(cookies)..session.addAll(session);
await request.finalize().pipe(rq);

View file

@ -2,8 +2,8 @@ import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:matcher/matcher.dart';
import 'package:angel_http_exception/angel_http_exception.dart';
import 'package:angel_validate/angel_validate.dart';
import 'package:angel3_http_exception/angel3_http_exception.dart';
import 'package:angel3_validate/angel3_validate.dart';
/// Expects a response to be a JSON representation of an `AngelHttpException`.
///
@ -12,15 +12,15 @@ Matcher isAngelHttpException(
{String? message,
int? statusCode,
Iterable<String> errors: const []}) =>
new _IsAngelHttpException(
_IsAngelHttpException(
message: message, statusCode: statusCode, errors: errors);
/// Expects a given response, when parsed as JSON,
/// to equal a desired value.
Matcher isJson(value) => new _IsJson(value);
Matcher isJson(value) => _IsJson(value);
/// Expects a response to have the given content type, whether a `String` or [ContentType].
Matcher hasContentType(contentType) => new _HasContentType(contentType);
Matcher hasContentType(contentType) => _HasContentType(contentType);
/// Expects a response to have the given body.
///
@ -29,18 +29,18 @@ Matcher hasContentType(contentType) => new _HasContentType(contentType);
///
/// If value is a `List<int>`, then it will be matched against `res.bodyBytes`.
/// Otherwise, the string value will be matched against `res.body`.
Matcher hasBody([value]) => new _HasBody(value ?? true);
Matcher hasBody([value]) => _HasBody(value ?? true);
/// Expects a response to have a header named [key] which contains [value]. [value] can be a `String`, or a List of `String`s.
///
/// If `value` is true (default), then this matcher will simply assert that the header is present.
Matcher hasHeader(String key, [value]) => new _HasHeader(key, value ?? true);
Matcher hasHeader(String key, [value]) => _HasHeader(key, value ?? true);
/// Expects a response to have the given status code.
Matcher hasStatus(int status) => new _HasStatus(status);
Matcher hasStatus(int status) => _HasStatus(status);
/// Expects a response to have a JSON body that is a `Map` and satisfies the given [validator] schema.
Matcher hasValidBody(Validator validator) => new _HasValidBody(validator);
Matcher hasValidBody(Validator validator) => _HasValidBody(validator);
class _IsJson extends Matcher {
var value;
@ -195,26 +195,29 @@ class _IsAngelHttpException extends Matcher {
@override
Description describe(Description description) {
if (message?.isNotEmpty != true && statusCode == null && errors.isEmpty)
if (message?.isNotEmpty != true && statusCode == null && errors.isEmpty) {
return description.add('is an Angel HTTP Exception');
else {
var buf = new StringBuffer('is an Angel HTTP Exception with');
} else {
var buf = StringBuffer('is an Angel HTTP Exception with');
if (statusCode != null) buf.write(' status code $statusCode');
if (message?.isNotEmpty == true) {
if (statusCode != null && errors.isNotEmpty)
if (statusCode != null && errors.isNotEmpty) {
buf.write(',');
else if (statusCode != null && errors.isEmpty) buf.write(' and');
} else if (statusCode != null && errors.isEmpty) {
buf.write(' and');
}
buf.write(' message "$message"');
}
if (errors.isNotEmpty) {
if (statusCode != null || message?.isNotEmpty == true)
if (statusCode != null || message?.isNotEmpty == true) {
buf.write(' and errors $errors');
else
} else {
buf.write(' errors $errors');
}
}
return description.add(buf.toString());
}
@ -226,12 +229,14 @@ class _IsAngelHttpException extends Matcher {
final jsons = json.decode(item.body);
if (jsons is Map && jsons['isError'] == true) {
var exc = new AngelHttpException.fromMap(jsons);
var exc = AngelHttpException.fromMap(jsons);
print(exc.toJson());
if (message?.isNotEmpty != true && statusCode == null && errors.isEmpty)
if (message?.isNotEmpty != true &&
statusCode == null &&
errors.isEmpty) {
return true;
else {
} else {
if (statusCode != null) if (!equals(statusCode)
.matches(exc.statusCode, matchState)) return false;
@ -239,15 +244,17 @@ class _IsAngelHttpException extends Matcher {
.matches(exc.message, matchState)) return false;
if (errors.isNotEmpty) {
if (!errors
.every((err) => contains(err).matches(exc.errors, matchState)))
if (!errors.every(
(err) => contains(err).matches(exc.errors, matchState))) {
return false;
}
}
return true;
}
} else
} else {
return false;
}
} else {
return false;
}

View file

@ -1,44 +1,20 @@
name: angel_test
description: Testing utility library for the Angel framework. Use with package:test.
homepage: https://github.com/dukefirehawk/angel
name: angel3_test
version: 4.0.0
publish_to: none
description: Testing utility library for the Angel framework. Use with package:test.
homepage: https://github.com/dukefirehawk/angel/tree/angel3/packages/test
environment:
sdk: '>=2.12.0 <3.0.0'
dependencies:
angel_client:
git:
url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x_nnbd
path: packages/client
angel_framework:
git:
url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x_nnbd
path: packages/framework
angel_http_exception:
git:
url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x_nnbd
path: packages/http_exception
angel_validate:
git:
url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x_nnbd
path: packages/validate
angel_websocket:
git:
url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x_nnbd
path: packages/websocket
angel3_client: ^4.0.0
angel3_framework: ^4.0.0
angel3_http_exception: ^3.0.0
angel3_validate: ^4.0.0
angel3_websocket: ^4.0.0
angel3_mock_request: ^2.0.0
angel3_container: ^3.0.0
http: ^0.13.1
matcher: ^0.12.10
mock_request:
git:
url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x_nnbd
path: packages/mock_request
web_socket_channel: ^2.0.0
dev_dependencies:
test: ^1.17.3
test: ^1.17.4

View file

@ -1,8 +1,8 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_container/mirrors.dart';
import 'package:angel_test/angel_test.dart';
import 'package:angel_websocket/server.dart';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_container/mirrors.dart';
import 'package:angel3_test/angel3_test.dart';
import 'package:angel3_websocket/server.dart';
import 'package:test/test.dart';
void main() {