Updated test
This commit is contained in:
parent
b7e0d01844
commit
27d739864c
8 changed files with 48 additions and 31 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
# 4.0.2
|
||||||
|
* Resolved static analysis warnings
|
||||||
|
|
||||||
# 4.0.1
|
# 4.0.1
|
||||||
* Updated AUTHORS and LICENSE
|
* Updated AUTHORS and LICENSE
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# angel3_test
|
# angel3_test
|
||||||
[![version](https://img.shields.io/badge/pub-v4.0.1-brightgreen)](https://pub.dartlang.org/packages/angel3_test)
|
[![version](https://img.shields.io/badge/pub-v4.0.2-brightgreen)](https://pub.dartlang.org/packages/angel3_test)
|
||||||
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
|
[![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)
|
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
include: package:pedantic/analysis_options.yaml
|
||||||
analyzer:
|
analyzer:
|
||||||
strong-mode:
|
strong-mode:
|
||||||
implicit-casts: false
|
implicit-casts: false
|
|
@ -34,8 +34,8 @@ void main() {
|
||||||
..get('/gzip', (req, res) async {
|
..get('/gzip', (req, res) async {
|
||||||
res
|
res
|
||||||
..headers['content-encoding'] = 'gzip'
|
..headers['content-encoding'] = 'gzip'
|
||||||
..add(gzip.encode('Poop'.codeUnits))
|
..add(gzip.encode('Poop'.codeUnits));
|
||||||
..close();
|
await res.close();
|
||||||
})
|
})
|
||||||
..use(
|
..use(
|
||||||
'/foo',
|
'/foo',
|
||||||
|
@ -135,7 +135,7 @@ void main() {
|
||||||
test('websocket', () async {
|
test('websocket', () async {
|
||||||
var ws = await client.websocket();
|
var ws = await client.websocket();
|
||||||
var foo = ws.service('foo');
|
var foo = ws.service('foo');
|
||||||
foo.create({});
|
await foo.create({});
|
||||||
var result = await foo.onCreated.first;
|
var result = await foo.onCreated.first;
|
||||||
expect(result.data, equals({'foo': 'bar'}));
|
expect(result.data, equals({'foo': 'bar'}));
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@ import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
import 'package:web_socket_channel/io.dart';
|
import 'package:web_socket_channel/io.dart';
|
||||||
//import 'package:uuid/uuid.dart';
|
//import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
final RegExp _straySlashes = RegExp(r"(^/)|(/+$)");
|
final RegExp _straySlashes = RegExp(r'(^/)|(/+$)');
|
||||||
/*const Map<String, String> _readHeaders = const {'Accept': 'application/json'};
|
/*const Map<String, String> _readHeaders = const {'Accept': 'application/json'};
|
||||||
const Map<String, String> _writeHeaders = const {
|
const Map<String, String> _writeHeaders = const {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
|
@ -25,15 +25,15 @@ final Uuid _uuid = Uuid();*/
|
||||||
/// Shorthand for bootstrapping a [TestClient].
|
/// Shorthand for bootstrapping a [TestClient].
|
||||||
Future<TestClient> connectTo(Angel app,
|
Future<TestClient> connectTo(Angel app,
|
||||||
{Map? initialSession,
|
{Map? initialSession,
|
||||||
bool autoDecodeGzip: true,
|
bool autoDecodeGzip = true,
|
||||||
bool useZone: false}) async {
|
bool useZone = false}) async {
|
||||||
print("Load configuration");
|
print('Load configuration');
|
||||||
if (!app.environment.isProduction) {
|
if (!app.environment.isProduction) {
|
||||||
app.configuration.putIfAbsent('testMode', () => true);
|
app.configuration.putIfAbsent('testMode', () => true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var plugin in app.startupHooks) {
|
for (var plugin in app.startupHooks) {
|
||||||
print("Load plugins");
|
print('Load plugins');
|
||||||
await plugin(app);
|
await plugin(app);
|
||||||
}
|
}
|
||||||
return TestClient(app,
|
return TestClient(app,
|
||||||
|
@ -62,11 +62,12 @@ class TestClient extends client.BaseAngelClient {
|
||||||
|
|
||||||
late AngelHttp _http;
|
late AngelHttp _http;
|
||||||
|
|
||||||
TestClient(this.server, {this.autoDecodeGzip: true, bool useZone: false})
|
TestClient(this.server, {this.autoDecodeGzip = true, bool useZone = false})
|
||||||
: super(http.IOClient(), '/') {
|
: super(http.IOClient(), '/') {
|
||||||
_http = AngelHttp(server, useZone: useZone);
|
_http = AngelHttp(server, useZone: useZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Future close() {
|
Future close() {
|
||||||
this.client!.close();
|
this.client!.close();
|
||||||
return server.close();
|
return server.close();
|
||||||
|
@ -75,7 +76,7 @@ class TestClient extends client.BaseAngelClient {
|
||||||
/// Opens a WebSockets connection to the server. This will automatically bind the server
|
/// Opens a WebSockets connection to the server. This will automatically bind the server
|
||||||
/// over HTTP, if it is not already listening. Unfortunately, WebSockets cannot be mocked (yet!).
|
/// over HTTP, if it is not already listening. Unfortunately, WebSockets cannot be mocked (yet!).
|
||||||
Future<client.WebSockets> websocket(
|
Future<client.WebSockets> websocket(
|
||||||
{String path: '/ws', Duration? timeout}) async {
|
{String path = '/ws', Duration? timeout}) async {
|
||||||
if (_http.server == null) await _http.startServer();
|
if (_http.server == null) await _http.startServer();
|
||||||
var url = _http.uri.replace(scheme: 'ws', path: path);
|
var url = _http.uri.replace(scheme: 'ws', path: path);
|
||||||
var ws = _MockWebSockets(this, url.toString());
|
var ws = _MockWebSockets(this, url.toString());
|
||||||
|
@ -83,6 +84,7 @@ class TestClient extends client.BaseAngelClient {
|
||||||
return ws;
|
return ws;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Future<StreamedResponse> send(http.BaseRequest request) async {
|
Future<StreamedResponse> send(http.BaseRequest request) async {
|
||||||
var rq = MockHttpRequest(request.method, request.url);
|
var rq = MockHttpRequest(request.method, request.url);
|
||||||
request.headers.forEach(rq.headers.add);
|
request.headers.forEach(rq.headers.add);
|
||||||
|
@ -115,7 +117,7 @@ class TestClient extends client.BaseAngelClient {
|
||||||
..clear()
|
..clear()
|
||||||
..addAll(rq.session);
|
..addAll(rq.session);
|
||||||
|
|
||||||
Map<String, String> extractedHeaders = {};
|
var extractedHeaders = <String, String>{};
|
||||||
|
|
||||||
rs.headers.forEach((k, v) {
|
rs.headers.forEach((k, v) {
|
||||||
extractedHeaders[k] = v.join(',');
|
extractedHeaders[k] = v.join(',');
|
||||||
|
@ -128,7 +130,7 @@ class TestClient extends client.BaseAngelClient {
|
||||||
stream = stream.transform(gzip.decoder);
|
stream = stream.transform(gzip.decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Calling persistentConnection causes LateInitialization Exception
|
// Calling persistentConnection causes LateInitialization Exception
|
||||||
//var keepAliveState = rq.headers?.persistentConnection;
|
//var keepAliveState = rq.headers?.persistentConnection;
|
||||||
//if (keepAliveState == null) {
|
//if (keepAliveState == null) {
|
||||||
// keepAliveState = false;
|
// keepAliveState = false;
|
||||||
|
@ -149,7 +151,8 @@ class TestClient extends client.BaseAngelClient {
|
||||||
late String basePath;
|
late String basePath;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<String> authenticateViaPopup(String url, {String eventName: 'token'}) {
|
Stream<String> authenticateViaPopup(String url,
|
||||||
|
{String eventName = 'token'}) {
|
||||||
throw UnsupportedError(
|
throw UnsupportedError(
|
||||||
'MockClient does not support authentication via popup.');
|
'MockClient does not support authentication via popup.');
|
||||||
}
|
}
|
||||||
|
@ -161,7 +164,7 @@ class TestClient extends client.BaseAngelClient {
|
||||||
@override
|
@override
|
||||||
client.Service<Id, Data> service<Id, Data>(String path,
|
client.Service<Id, Data> service<Id, Data>(String path,
|
||||||
{Type? type, client.AngelDeserializer<Data>? deserializer}) {
|
{Type? type, client.AngelDeserializer<Data>? deserializer}) {
|
||||||
String uri = path.toString().replaceAll(_straySlashes, "");
|
var uri = path.toString().replaceAll(_straySlashes, '');
|
||||||
return _services.putIfAbsent(uri,
|
return _services.putIfAbsent(uri,
|
||||||
() => _MockService<Id, Data>(this, uri, deserializer: deserializer))
|
() => _MockService<Id, Data>(this, uri, deserializer: deserializer))
|
||||||
as client.Service<Id, Data>;
|
as client.Service<Id, Data>;
|
||||||
|
@ -192,10 +195,11 @@ class _MockWebSockets extends client.WebSockets {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<WebSocketChannel> getConnectedWebSocket() async {
|
Future<WebSocketChannel> getConnectedWebSocket() async {
|
||||||
Map<String, String> headers = {};
|
var headers = <String, String>{};
|
||||||
|
|
||||||
if (app.authToken?.isNotEmpty == true)
|
if (app.authToken?.isNotEmpty == true) {
|
||||||
headers['authorization'] = 'Bearer ${app.authToken}';
|
headers['authorization'] = 'Bearer ${app.authToken}';
|
||||||
|
}
|
||||||
|
|
||||||
var socket = await WebSocket.connect(baseUrl.toString(), headers: headers);
|
var socket = await WebSocket.connect(baseUrl.toString(), headers: headers);
|
||||||
return IOWebSocketChannel(socket);
|
return IOWebSocketChannel(socket);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import 'package:angel3_validate/angel3_validate.dart';
|
||||||
Matcher isAngelHttpException(
|
Matcher isAngelHttpException(
|
||||||
{String? message,
|
{String? message,
|
||||||
int? statusCode,
|
int? statusCode,
|
||||||
Iterable<String> errors: const []}) =>
|
Iterable<String> errors = const []}) =>
|
||||||
_IsAngelHttpException(
|
_IsAngelHttpException(
|
||||||
message: message, statusCode: statusCode, errors: errors);
|
message: message, statusCode: statusCode, errors: errors);
|
||||||
|
|
||||||
|
@ -71,10 +71,11 @@ class _HasBody extends Matcher {
|
||||||
bool matches(item, Map matchState) {
|
bool matches(item, Map matchState) {
|
||||||
if (item is http.Response) {
|
if (item is http.Response) {
|
||||||
if (body == true) return isNotEmpty.matches(item.bodyBytes, matchState);
|
if (body == true) return isNotEmpty.matches(item.bodyBytes, matchState);
|
||||||
if (body is List<int>)
|
if (body is List<int>) {
|
||||||
return equals(body).matches(item.bodyBytes, matchState);
|
return equals(body).matches(item.bodyBytes, matchState);
|
||||||
else
|
} else {
|
||||||
return equals(body.toString()).matches(item.body, matchState);
|
return equals(body.toString()).matches(item.body, matchState);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -121,10 +122,11 @@ class _HasHeader extends Matcher {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Description describe(Description description) {
|
Description describe(Description description) {
|
||||||
if (value == true)
|
if (value == true) {
|
||||||
return description.add('contains header $key');
|
return description.add('contains header $key');
|
||||||
else
|
} else {
|
||||||
return description.add('contains header $key with value(s) $value');
|
return description.add('contains header $key with value(s) $value');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -135,7 +137,7 @@ class _HasHeader extends Matcher {
|
||||||
.matches(item.headers.keys, matchState);
|
.matches(item.headers.keys, matchState);
|
||||||
} else {
|
} else {
|
||||||
if (!item.headers.containsKey(key.toLowerCase())) return false;
|
if (!item.headers.containsKey(key.toLowerCase())) return false;
|
||||||
Iterable v = value is Iterable ? (value as Iterable) : [value];
|
var v = value is Iterable ? (value as Iterable) : [value];
|
||||||
return v
|
return v
|
||||||
.map((x) => x.toString())
|
.map((x) => x.toString())
|
||||||
.every(item.headers[key.toLowerCase()]!.split(',').contains);
|
.every(item.headers[key.toLowerCase()]!.split(',').contains);
|
||||||
|
@ -189,7 +191,7 @@ class _IsAngelHttpException extends Matcher {
|
||||||
final List<String> errors = [];
|
final List<String> errors = [];
|
||||||
|
|
||||||
_IsAngelHttpException(
|
_IsAngelHttpException(
|
||||||
{this.message, this.statusCode, Iterable<String> errors: const []}) {
|
{this.message, this.statusCode, Iterable<String> errors = const []}) {
|
||||||
this.errors.addAll(errors);
|
this.errors.addAll(errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,11 +239,17 @@ class _IsAngelHttpException extends Matcher {
|
||||||
errors.isEmpty) {
|
errors.isEmpty) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (statusCode != null) if (!equals(statusCode)
|
if (statusCode != null) {
|
||||||
.matches(exc.statusCode, matchState)) return false;
|
if (!equals(statusCode).matches(exc.statusCode, matchState)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (message?.isNotEmpty == true) if (!equals(message)
|
if (message?.isNotEmpty == true) {
|
||||||
.matches(exc.message, matchState)) return false;
|
if (!equals(message).matches(exc.message, matchState)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (errors.isNotEmpty) {
|
if (errors.isNotEmpty) {
|
||||||
if (!errors.every(
|
if (!errors.every(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel3_test
|
name: angel3_test
|
||||||
version: 4.0.1
|
version: 4.0.2
|
||||||
description: Testing utility library for the Angel framework. Use with package:test.
|
description: Testing utility library for the Angel framework. Use with package:test.
|
||||||
homepage: https://github.com/dukefirehawk/angel/tree/angel3/packages/test
|
homepage: https://github.com/dukefirehawk/angel/tree/angel3/packages/test
|
||||||
environment:
|
environment:
|
||||||
|
@ -17,4 +17,5 @@ dependencies:
|
||||||
web_socket_channel: ^2.0.0
|
web_socket_channel: ^2.0.0
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
test: ^1.17.4
|
test: ^1.17.4
|
||||||
|
pedantic: ^1.11.0
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ void main() {
|
||||||
..get('/gzip', (req, res) async {
|
..get('/gzip', (req, res) async {
|
||||||
res
|
res
|
||||||
..headers['content-encoding'] = 'gzip'
|
..headers['content-encoding'] = 'gzip'
|
||||||
..add(gzip.encode('Poop'.codeUnits))
|
..add(gzip.encode('Poop'.codeUnits));
|
||||||
..close();
|
await res.close();
|
||||||
})
|
})
|
||||||
..use(
|
..use(
|
||||||
'/foo',
|
'/foo',
|
||||||
|
|
Loading…
Reference in a new issue