From 31e32c95946f7ee352c25e3452fd86c0a5cba3bb Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Fri, 5 Jul 2024 08:49:36 +0200 Subject: [PATCH 01/14] feat: added test for dio --- packages/alice_dio/pubspec.yaml | 4 +- packages/alice_dio/test/alice_core_mock.dart | 6 +++ .../test/alice_dio_adapter_test.dart | 51 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 packages/alice_dio/test/alice_core_mock.dart create mode 100644 packages/alice_dio/test/alice_dio_adapter_test.dart diff --git a/packages/alice_dio/pubspec.yaml b/packages/alice_dio/pubspec.yaml index 24c5d5be..539860cc 100644 --- a/packages/alice_dio/pubspec.yaml +++ b/packages/alice_dio/pubspec.yaml @@ -21,4 +21,6 @@ dependencies: sdk: flutter dev_dependencies: - flutter_lints: ^4.0.0 \ No newline at end of file + flutter_lints: ^4.0.0 + test: ^1.25.2 + mocktail: ^1.0.4 \ No newline at end of file diff --git a/packages/alice_dio/test/alice_core_mock.dart b/packages/alice_dio/test/alice_core_mock.dart new file mode 100644 index 00000000..955b7b07 --- /dev/null +++ b/packages/alice_dio/test/alice_core_mock.dart @@ -0,0 +1,6 @@ +import 'package:alice/core/alice_core.dart'; +import 'package:mocktail/mocktail.dart'; + +class AliceCoreMock extends Mock implements AliceCore{ + +} \ No newline at end of file diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart new file mode 100644 index 00000000..c2291564 --- /dev/null +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -0,0 +1,51 @@ +import 'package:alice/alice.dart'; +import 'package:alice/core/alice_core.dart'; +import 'package:alice/model/alice_http_call.dart'; +import 'package:alice/model/alice_http_response.dart'; +import 'package:alice_dio/alice_dio_adapter.dart'; +import 'package:dio/dio.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:test/test.dart'; + +import 'alice_core_mock.dart'; + +void main() { + late AliceCore aliceCore; + late AliceDioAdapter aliceDioAdapter; + late Dio dio; + setUp(() { + registerFallbackValue(AliceHttpCall(0)); + registerFallbackValue(AliceHttpResponse()); + aliceCore = AliceCoreMock(); + when(() => aliceCore.addCall(any())).thenAnswer((_) => {}); + when(() => aliceCore.addResponse(any(), any())).thenAnswer((_) => {}); + aliceDioAdapter = AliceDioAdapter(); + aliceDioAdapter.injectCore(aliceCore); + + dio = Dio(BaseOptions(followRedirects: false)) + ..interceptors.add(aliceDioAdapter); + }); + + group("AliceDioAdapter", () { + test("should handle GET call with json response", () async { + await dio.get( + 'https://httpbin.org/json', + ); + final callMatcher = TypeMatcher() + .having((call) => call.id, "Id is set", greaterThan(0)) + .having((call) => call.createdTime.millisecondsSinceEpoch, + "Created time is set", greaterThan(0)) + .having((call) => call.secure, "Is secured", equals(true)) + .having((call) => call.loading, "Is loading", equals(true)) + .having((call) => call.client, "Client is set", equals("Dio")) + .having((call) => call.method, "Method is set", equals("GET")) + .having((call) => call.endpoint, "Endpoint is set", equals("/json")) + .having((call) => call.server, "Server is set", equals("httpbin.org")) + .having((call) => call.uri, "Uri is set", + equals("https://httpbin.org/json")); + + // verify(() => aliceCore.addCall(AliceHttpCall(0))); + verify(() => aliceCore.addCall(any(that: callMatcher))); + }); + }); +} From cc5bd7b0ea2f83c286d2d44a9d86c2f767f43ee5 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Fri, 5 Jul 2024 08:52:02 +0200 Subject: [PATCH 02/14] feat: added test for dio --- packages/alice_dio/test/alice_core_mock.dart | 4 +--- packages/alice_dio/test/alice_dio_adapter_test.dart | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/alice_dio/test/alice_core_mock.dart b/packages/alice_dio/test/alice_core_mock.dart index 955b7b07..f2130c15 100644 --- a/packages/alice_dio/test/alice_core_mock.dart +++ b/packages/alice_dio/test/alice_core_mock.dart @@ -1,6 +1,4 @@ import 'package:alice/core/alice_core.dart'; import 'package:mocktail/mocktail.dart'; -class AliceCoreMock extends Mock implements AliceCore{ - -} \ No newline at end of file +class AliceCoreMock extends Mock implements AliceCore {} diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index c2291564..414bf66b 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -1,4 +1,3 @@ -import 'package:alice/alice.dart'; import 'package:alice/core/alice_core.dart'; import 'package:alice/model/alice_http_call.dart'; import 'package:alice/model/alice_http_response.dart'; @@ -31,7 +30,7 @@ void main() { await dio.get( 'https://httpbin.org/json', ); - final callMatcher = TypeMatcher() + final callMatcher = const TypeMatcher() .having((call) => call.id, "Id is set", greaterThan(0)) .having((call) => call.createdTime.millisecondsSinceEpoch, "Created time is set", greaterThan(0)) From aa7004b11d6f99a3947c04e30c50d4015783e462 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Fri, 5 Jul 2024 09:08:45 +0200 Subject: [PATCH 03/14] feat: added test for dio --- .../test/alice_dio_adapter_test.dart | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index 414bf66b..6c85fffb 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -1,5 +1,6 @@ import 'package:alice/core/alice_core.dart'; import 'package:alice/model/alice_http_call.dart'; +import 'package:alice/model/alice_http_request.dart'; import 'package:alice/model/alice_http_response.dart'; import 'package:alice_dio/alice_dio_adapter.dart'; import 'package:dio/dio.dart'; @@ -27,9 +28,33 @@ void main() { group("AliceDioAdapter", () { test("should handle GET call with json response", () async { - await dio.get( - 'https://httpbin.org/json', - ); + await dio.get('https://httpbin.org/json', + options: Options(headers: {"Content-Type": "application/json"})); + + final requestMatcher = const TypeMatcher() + .having((call) => call.time.millisecondsSinceEpoch, "Time is set", + greaterThan(0)) + .having( + (call) => call.headers, + "Headers are set", + {"Content-Type": "application/json"}, + ) + .having( + (call) => call.contentType, + "Content type is set", + "application/json", + ) + .having( + (call) => call.queryParameters, + "Query params are not set", + {}, + ); + + final responseMatcher = const TypeMatcher().having( + (call) => call.time.millisecondsSinceEpoch, + "Time is set", + greaterThan(0)); + final callMatcher = const TypeMatcher() .having((call) => call.id, "Id is set", greaterThan(0)) .having((call) => call.createdTime.millisecondsSinceEpoch, @@ -41,7 +66,10 @@ void main() { .having((call) => call.endpoint, "Endpoint is set", equals("/json")) .having((call) => call.server, "Server is set", equals("httpbin.org")) .having((call) => call.uri, "Uri is set", - equals("https://httpbin.org/json")); + equals("https://httpbin.org/json")) + .having((call) => call.duration, "Duration is 0", equals(0)) + .having((call) => call.request, "Request matcher", requestMatcher) + .having((call) => call.response, "Response matcher", responseMatcher); // verify(() => aliceCore.addCall(AliceHttpCall(0))); verify(() => aliceCore.addCall(any(that: callMatcher))); From 7acbb5adbcb2a5e66936d43a31df16bf27d9c53e Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Fri, 5 Jul 2024 21:54:20 +0200 Subject: [PATCH 04/14] feat: added test for dio --- .../test/alice_dio_adapter_test.dart | 233 +++++++++++++++--- 1 file changed, 192 insertions(+), 41 deletions(-) diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index 6c85fffb..f703c109 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -31,48 +31,199 @@ void main() { await dio.get('https://httpbin.org/json', options: Options(headers: {"Content-Type": "application/json"})); - final requestMatcher = const TypeMatcher() - .having((call) => call.time.millisecondsSinceEpoch, "Time is set", - greaterThan(0)) - .having( - (call) => call.headers, - "Headers are set", - {"Content-Type": "application/json"}, - ) - .having( - (call) => call.contentType, - "Content type is set", - "application/json", - ) - .having( - (call) => call.queryParameters, - "Query params are not set", - {}, - ); - - final responseMatcher = const TypeMatcher().having( - (call) => call.time.millisecondsSinceEpoch, - "Time is set", - greaterThan(0)); - - final callMatcher = const TypeMatcher() - .having((call) => call.id, "Id is set", greaterThan(0)) - .having((call) => call.createdTime.millisecondsSinceEpoch, - "Created time is set", greaterThan(0)) - .having((call) => call.secure, "Is secured", equals(true)) - .having((call) => call.loading, "Is loading", equals(true)) - .having((call) => call.client, "Client is set", equals("Dio")) - .having((call) => call.method, "Method is set", equals("GET")) - .having((call) => call.endpoint, "Endpoint is set", equals("/json")) - .having((call) => call.server, "Server is set", equals("httpbin.org")) - .having((call) => call.uri, "Uri is set", - equals("https://httpbin.org/json")) - .having((call) => call.duration, "Duration is 0", equals(0)) - .having((call) => call.request, "Request matcher", requestMatcher) - .having((call) => call.response, "Response matcher", responseMatcher); - - // verify(() => aliceCore.addCall(AliceHttpCall(0))); + final requestMatcher = buildRequestMatcher( + checkTime: true, + headers: {"Content-Type": "application/json"}, + contentType: "application/json", + queryParameters: {}, + ); + + final responseMatcher = buildResponseMatcher(checkTime: true); + + final callMatcher = buildCallMatcher( + checkId: true, + checkTime: true, + secured: true, + loading: true, + client: 'Dio', + method: 'GET', + endpoint: '/json', + server: 'httpbin.org', + uri: 'https://httpbin.org/json', + duration: 0, + request: requestMatcher, + response: responseMatcher); + verify(() => aliceCore.addCall(any(that: callMatcher))); + + final nextResponseMatcher = buildResponseMatcher( + status: 200, + size: 254, + checkTime: true, + body: + '{slideshow: {author: Yours Truly, date: date of publication, slides: [{title: Wake up to WonderWidgets!, type: all}, {items: [Why WonderWidgets are great, Who buys WonderWidgets], title: Overview, type: all}], title: Sample Slide Show}}', + headers: { + 'connection': '[keep-alive]', + 'access-control-allow-credentials': '[true]', + 'access-control-allow-origin': '[*]', + 'content-length': '[429]', + 'content-type': '[application/json]' + }, + ); + + verify( + () => aliceCore.addResponse(any(that: nextResponseMatcher), any())); }); }); } + +TypeMatcher buildCallMatcher({ + bool? checkId, + bool? checkTime, + bool? secured, + bool? loading, + String? client, + String? method, + String? endpoint, + String? server, + String? uri, + int? duration, + TypeMatcher? request, + TypeMatcher? response, +}) { + var matcher = const TypeMatcher(); + if (checkId == true) { + matcher = matcher.having((call) => call.id, "id", greaterThan(0)); + } + if (checkTime == true) { + matcher = matcher.having((call) => call.createdTime.millisecondsSinceEpoch, + "createdTime", greaterThan(0)); + } + if (secured != null) { + matcher = matcher.having((call) => call.secure, "secure", equals(secured)); + } + if (loading != null) { + matcher = + matcher.having((call) => call.loading, "loading", equals(loading)); + } + if (client != null) { + matcher = matcher.having((call) => call.client, "client", equals(client)); + } + if (method != null) { + matcher = matcher.having((call) => call.method, "method", equals(method)); + } + if (endpoint != null) { + matcher = + matcher.having((call) => call.endpoint, "endpoint", equals(endpoint)); + } + if (server != null) { + matcher = matcher.having((call) => call.server, "server", equals(server)); + } + if (uri != null) { + matcher = matcher.having((call) => call.uri, "uri", equals(uri)); + } + if (duration != null) { + matcher = + matcher.having((call) => call.duration, "duration", equals(duration)); + } + if (request != null) { + matcher = + matcher.having((call) => call.request, "request", equals(request)); + } + if (response != null) { + matcher = + matcher.having((call) => call.response, "response", equals(response)); + } + return matcher; +} + +TypeMatcher buildRequestMatcher({ + bool? checkTime, + Map? headers, + String? contentType, + Map? queryParameters, +}) { + var matcher = const TypeMatcher(); + if (checkTime == true) { + matcher = matcher.having((request) => request.time.millisecondsSinceEpoch, + "time", greaterThan(0)); + } + if (headers != null) { + for (var header in headers.entries) { + matcher = matcher.having((request) { + return request.headers; + }, "header", ContainsHeader(header)); + } + } + if (contentType != null) { + matcher = matcher.having( + (request) => request.contentType, "contentType", equals(contentType)); + } + if (queryParameters != null) { + matcher = matcher.having((request) => request.queryParameters, + "queryParameters", equals(queryParameters)); + } + + return matcher; +} + +TypeMatcher buildResponseMatcher({ + int? status, + int? size, + bool? checkTime, + String? body, + Map? headers, +}) { + var matcher = const TypeMatcher(); + if (status != null) { + matcher = + matcher.having((response) => response.status, "status", equals(status)); + } + if (size != null) { + matcher = matcher.having((response) => response.size, "size", equals(size)); + } + if (checkTime == true) { + matcher = matcher.having((response) => response.time.millisecondsSinceEpoch, + "time", greaterThan(0)); + } + if (body != null) { + matcher = matcher.having( + (response) => response.body.toString(), "body", equals(body)); + } + if (headers != null) { + for (var header in headers.entries) { + matcher = matcher.having((response) { + return response.headers; + }, "header", ContainsHeader(header)); + } + } + return matcher; +} + +class ContainsHeader extends Matcher { + final MapEntry? _expected; + + const ContainsHeader(this._expected); + + @override + bool matches(Object? item, Map matchState) { + if (item is Map) { + final mapItem = item[_expected?.key]; + return mapItem == _expected?.value; + } + return false; + } + + @override + Description describe(Description description) => + description.add('contains header').addDescriptionOf(_expected); + + @override + Description describeMismatch(Object? item, Description mismatchDescription, + Map matchState, bool verbose) { + mismatchDescription + .add('does not contain header') + .addDescriptionOf(_expected); + return mismatchDescription; + } +} From e98bb48bbdbec284c6a4bbcbb2812ea7511643f0 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 10:20:59 +0200 Subject: [PATCH 05/14] feat: added mocked http adapter --- packages/alice_dio/pubspec.yaml | 3 +- .../test/alice_dio_adapter_test.dart | 38 +++++++++++++------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/packages/alice_dio/pubspec.yaml b/packages/alice_dio/pubspec.yaml index 539860cc..e208f365 100644 --- a/packages/alice_dio/pubspec.yaml +++ b/packages/alice_dio/pubspec.yaml @@ -23,4 +23,5 @@ dependencies: dev_dependencies: flutter_lints: ^4.0.0 test: ^1.25.2 - mocktail: ^1.0.4 \ No newline at end of file + mocktail: ^1.0.4 + http_mock_adapter: ^0.6.1 \ No newline at end of file diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index f703c109..66a81415 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -4,6 +4,7 @@ import 'package:alice/model/alice_http_request.dart'; import 'package:alice/model/alice_http_response.dart'; import 'package:alice_dio/alice_dio_adapter.dart'; import 'package:dio/dio.dart'; +import 'package:http_mock_adapter/http_mock_adapter.dart' as http_mock_adapter; import 'package:mocktail/mocktail.dart'; import 'package:test/test.dart'; @@ -13,6 +14,7 @@ void main() { late AliceCore aliceCore; late AliceDioAdapter aliceDioAdapter; late Dio dio; + late http_mock_adapter.DioAdapter dioAdapter; setUp(() { registerFallbackValue(AliceHttpCall(0)); registerFallbackValue(AliceHttpResponse()); @@ -24,16 +26,33 @@ void main() { dio = Dio(BaseOptions(followRedirects: false)) ..interceptors.add(aliceDioAdapter); + dioAdapter = http_mock_adapter.DioAdapter(dio: dio); }); group("AliceDioAdapter", () { test("should handle GET call with json response", () async { - await dio.get('https://httpbin.org/json', - options: Options(headers: {"Content-Type": "application/json"})); + dioAdapter.onGet( + 'https://test.com/json', + (server) => server.reply( + 200, + '{"result": "ok"}', + headers: { + "content-type": ["application/json"] + }, + ), + headers: {"content-type": "application/json"}, + ); + + await dio.get( + 'https://test.com/json', + options: Options( + headers: {"content-type": "application/json"}, + ), + ); final requestMatcher = buildRequestMatcher( checkTime: true, - headers: {"Content-Type": "application/json"}, + headers: {"content-type": "application/json"}, contentType: "application/json", queryParameters: {}, ); @@ -48,8 +67,8 @@ void main() { client: 'Dio', method: 'GET', endpoint: '/json', - server: 'httpbin.org', - uri: 'https://httpbin.org/json', + server: 'test.com', + uri: 'https://test.com/json', duration: 0, request: requestMatcher, response: responseMatcher); @@ -58,15 +77,10 @@ void main() { final nextResponseMatcher = buildResponseMatcher( status: 200, - size: 254, + size: 16, checkTime: true, - body: - '{slideshow: {author: Yours Truly, date: date of publication, slides: [{title: Wake up to WonderWidgets!, type: all}, {items: [Why WonderWidgets are great, Who buys WonderWidgets], title: Overview, type: all}], title: Sample Slide Show}}', + body: '{"result": "ok"}', headers: { - 'connection': '[keep-alive]', - 'access-control-allow-credentials': '[true]', - 'access-control-allow-origin': '[*]', - 'content-length': '[429]', 'content-type': '[application/json]' }, ); From bc3977df863cebdabc42ae1e0382e449fb58e638 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 10:40:32 +0200 Subject: [PATCH 06/14] feat: added alice_test, updated alice_dio tests --- packages/alice_dio/pubspec.yaml | 3 +- .../test/alice_dio_adapter_test.dart | 157 +------------- packages/alice_test/.gitignore | 29 +++ packages/alice_test/.metadata | 10 + packages/alice_test/LICENSE | 201 ++++++++++++++++++ packages/alice_test/README.md | 3 + packages/alice_test/analysis_options.yaml | 10 + packages/alice_test/lib/alice_test.dart | 4 + .../lib/matcher/alice_call_matcher.dart | 64 ++++++ .../lib/matcher/alice_request_matcher.dart | 33 +++ .../lib/matcher/alice_response_matcher.dart | 36 ++++ .../lib/matcher/header_matcher.dart | 29 +++ packages/alice_test/pubspec.yaml | 18 ++ 13 files changed, 441 insertions(+), 156 deletions(-) create mode 100644 packages/alice_test/.gitignore create mode 100644 packages/alice_test/.metadata create mode 100644 packages/alice_test/LICENSE create mode 100644 packages/alice_test/README.md create mode 100644 packages/alice_test/analysis_options.yaml create mode 100644 packages/alice_test/lib/alice_test.dart create mode 100644 packages/alice_test/lib/matcher/alice_call_matcher.dart create mode 100644 packages/alice_test/lib/matcher/alice_request_matcher.dart create mode 100644 packages/alice_test/lib/matcher/alice_response_matcher.dart create mode 100644 packages/alice_test/lib/matcher/header_matcher.dart create mode 100644 packages/alice_test/pubspec.yaml diff --git a/packages/alice_dio/pubspec.yaml b/packages/alice_dio/pubspec.yaml index e208f365..f8a3122a 100644 --- a/packages/alice_dio/pubspec.yaml +++ b/packages/alice_dio/pubspec.yaml @@ -24,4 +24,5 @@ dev_dependencies: flutter_lints: ^4.0.0 test: ^1.25.2 mocktail: ^1.0.4 - http_mock_adapter: ^0.6.1 \ No newline at end of file + http_mock_adapter: ^0.6.1 + alice_test: ^1.0.0 \ No newline at end of file diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index 66a81415..b7d2c64a 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -1,8 +1,8 @@ import 'package:alice/core/alice_core.dart'; import 'package:alice/model/alice_http_call.dart'; -import 'package:alice/model/alice_http_request.dart'; import 'package:alice/model/alice_http_response.dart'; import 'package:alice_dio/alice_dio_adapter.dart'; +import 'package:alice_test/alice_test.dart'; import 'package:dio/dio.dart'; import 'package:http_mock_adapter/http_mock_adapter.dart' as http_mock_adapter; import 'package:mocktail/mocktail.dart'; @@ -80,9 +80,7 @@ void main() { size: 16, checkTime: true, body: '{"result": "ok"}', - headers: { - 'content-type': '[application/json]' - }, + headers: {'content-type': '[application/json]'}, ); verify( @@ -90,154 +88,3 @@ void main() { }); }); } - -TypeMatcher buildCallMatcher({ - bool? checkId, - bool? checkTime, - bool? secured, - bool? loading, - String? client, - String? method, - String? endpoint, - String? server, - String? uri, - int? duration, - TypeMatcher? request, - TypeMatcher? response, -}) { - var matcher = const TypeMatcher(); - if (checkId == true) { - matcher = matcher.having((call) => call.id, "id", greaterThan(0)); - } - if (checkTime == true) { - matcher = matcher.having((call) => call.createdTime.millisecondsSinceEpoch, - "createdTime", greaterThan(0)); - } - if (secured != null) { - matcher = matcher.having((call) => call.secure, "secure", equals(secured)); - } - if (loading != null) { - matcher = - matcher.having((call) => call.loading, "loading", equals(loading)); - } - if (client != null) { - matcher = matcher.having((call) => call.client, "client", equals(client)); - } - if (method != null) { - matcher = matcher.having((call) => call.method, "method", equals(method)); - } - if (endpoint != null) { - matcher = - matcher.having((call) => call.endpoint, "endpoint", equals(endpoint)); - } - if (server != null) { - matcher = matcher.having((call) => call.server, "server", equals(server)); - } - if (uri != null) { - matcher = matcher.having((call) => call.uri, "uri", equals(uri)); - } - if (duration != null) { - matcher = - matcher.having((call) => call.duration, "duration", equals(duration)); - } - if (request != null) { - matcher = - matcher.having((call) => call.request, "request", equals(request)); - } - if (response != null) { - matcher = - matcher.having((call) => call.response, "response", equals(response)); - } - return matcher; -} - -TypeMatcher buildRequestMatcher({ - bool? checkTime, - Map? headers, - String? contentType, - Map? queryParameters, -}) { - var matcher = const TypeMatcher(); - if (checkTime == true) { - matcher = matcher.having((request) => request.time.millisecondsSinceEpoch, - "time", greaterThan(0)); - } - if (headers != null) { - for (var header in headers.entries) { - matcher = matcher.having((request) { - return request.headers; - }, "header", ContainsHeader(header)); - } - } - if (contentType != null) { - matcher = matcher.having( - (request) => request.contentType, "contentType", equals(contentType)); - } - if (queryParameters != null) { - matcher = matcher.having((request) => request.queryParameters, - "queryParameters", equals(queryParameters)); - } - - return matcher; -} - -TypeMatcher buildResponseMatcher({ - int? status, - int? size, - bool? checkTime, - String? body, - Map? headers, -}) { - var matcher = const TypeMatcher(); - if (status != null) { - matcher = - matcher.having((response) => response.status, "status", equals(status)); - } - if (size != null) { - matcher = matcher.having((response) => response.size, "size", equals(size)); - } - if (checkTime == true) { - matcher = matcher.having((response) => response.time.millisecondsSinceEpoch, - "time", greaterThan(0)); - } - if (body != null) { - matcher = matcher.having( - (response) => response.body.toString(), "body", equals(body)); - } - if (headers != null) { - for (var header in headers.entries) { - matcher = matcher.having((response) { - return response.headers; - }, "header", ContainsHeader(header)); - } - } - return matcher; -} - -class ContainsHeader extends Matcher { - final MapEntry? _expected; - - const ContainsHeader(this._expected); - - @override - bool matches(Object? item, Map matchState) { - if (item is Map) { - final mapItem = item[_expected?.key]; - return mapItem == _expected?.value; - } - return false; - } - - @override - Description describe(Description description) => - description.add('contains header').addDescriptionOf(_expected); - - @override - Description describeMismatch(Object? item, Description mismatchDescription, - Map matchState, bool verbose) { - mismatchDescription - .add('does not contain header') - .addDescriptionOf(_expected); - return mismatchDescription; - } -} diff --git a/packages/alice_test/.gitignore b/packages/alice_test/.gitignore new file mode 100644 index 00000000..ac5aa989 --- /dev/null +++ b/packages/alice_test/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/packages/alice_test/.metadata b/packages/alice_test/.metadata new file mode 100644 index 00000000..d36dfbcc --- /dev/null +++ b/packages/alice_test/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "a14f74ff3a1cbd521163c5f03d68113d50af93d3" + channel: "stable" + +project_type: package diff --git a/packages/alice_test/LICENSE b/packages/alice_test/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/packages/alice_test/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/alice_test/README.md b/packages/alice_test/README.md new file mode 100644 index 00000000..6c97c937 --- /dev/null +++ b/packages/alice_test/README.md @@ -0,0 +1,3 @@ +# Alice Test + +Package which exposes test utils for all Alice packages. \ No newline at end of file diff --git a/packages/alice_test/analysis_options.yaml b/packages/alice_test/analysis_options.yaml new file mode 100644 index 00000000..ae9086b0 --- /dev/null +++ b/packages/alice_test/analysis_options.yaml @@ -0,0 +1,10 @@ +analyzer: + exclude: + - "lib/generated_plugin_registrant.dart" + - "**.g.dart" + +include: package:flutter_lints/flutter.yaml + +linter: + rules: + #library_annotations: false diff --git a/packages/alice_test/lib/alice_test.dart b/packages/alice_test/lib/alice_test.dart new file mode 100644 index 00000000..02411624 --- /dev/null +++ b/packages/alice_test/lib/alice_test.dart @@ -0,0 +1,4 @@ +export 'matcher/header_matcher.dart'; +export 'matcher/alice_call_matcher.dart'; +export 'matcher/alice_request_matcher.dart'; +export 'matcher/alice_response_matcher.dart'; diff --git a/packages/alice_test/lib/matcher/alice_call_matcher.dart b/packages/alice_test/lib/matcher/alice_call_matcher.dart new file mode 100644 index 00000000..b8fddac1 --- /dev/null +++ b/packages/alice_test/lib/matcher/alice_call_matcher.dart @@ -0,0 +1,64 @@ +import 'package:alice/model/alice_http_call.dart'; +import 'package:alice/model/alice_http_request.dart'; +import 'package:alice/model/alice_http_response.dart'; +import 'package:test/test.dart'; + +TypeMatcher buildCallMatcher({ + bool? checkId, + bool? checkTime, + bool? secured, + bool? loading, + String? client, + String? method, + String? endpoint, + String? server, + String? uri, + int? duration, + TypeMatcher? request, + TypeMatcher? response, +}) { + var matcher = const TypeMatcher(); + if (checkId == true) { + matcher = matcher.having((call) => call.id, "id", greaterThan(0)); + } + if (checkTime == true) { + matcher = matcher.having((call) => call.createdTime.millisecondsSinceEpoch, + "createdTime", greaterThan(0)); + } + if (secured != null) { + matcher = matcher.having((call) => call.secure, "secure", equals(secured)); + } + if (loading != null) { + matcher = + matcher.having((call) => call.loading, "loading", equals(loading)); + } + if (client != null) { + matcher = matcher.having((call) => call.client, "client", equals(client)); + } + if (method != null) { + matcher = matcher.having((call) => call.method, "method", equals(method)); + } + if (endpoint != null) { + matcher = + matcher.having((call) => call.endpoint, "endpoint", equals(endpoint)); + } + if (server != null) { + matcher = matcher.having((call) => call.server, "server", equals(server)); + } + if (uri != null) { + matcher = matcher.having((call) => call.uri, "uri", equals(uri)); + } + if (duration != null) { + matcher = + matcher.having((call) => call.duration, "duration", equals(duration)); + } + if (request != null) { + matcher = + matcher.having((call) => call.request, "request", equals(request)); + } + if (response != null) { + matcher = + matcher.having((call) => call.response, "response", equals(response)); + } + return matcher; +} diff --git a/packages/alice_test/lib/matcher/alice_request_matcher.dart b/packages/alice_test/lib/matcher/alice_request_matcher.dart new file mode 100644 index 00000000..48847fac --- /dev/null +++ b/packages/alice_test/lib/matcher/alice_request_matcher.dart @@ -0,0 +1,33 @@ +import 'package:alice/model/alice_http_request.dart'; +import 'package:alice_test/matcher/header_matcher.dart'; +import 'package:test/test.dart'; + +TypeMatcher buildRequestMatcher({ + bool? checkTime, + Map? headers, + String? contentType, + Map? queryParameters, +}) { + var matcher = const TypeMatcher(); + if (checkTime == true) { + matcher = matcher.having((request) => request.time.millisecondsSinceEpoch, + "time", greaterThan(0)); + } + if (headers != null) { + for (var header in headers.entries) { + matcher = matcher.having((request) { + return request.headers; + }, "header", HeaderMatcher(header)); + } + } + if (contentType != null) { + matcher = matcher.having( + (request) => request.contentType, "contentType", equals(contentType)); + } + if (queryParameters != null) { + matcher = matcher.having((request) => request.queryParameters, + "queryParameters", equals(queryParameters)); + } + + return matcher; +} diff --git a/packages/alice_test/lib/matcher/alice_response_matcher.dart b/packages/alice_test/lib/matcher/alice_response_matcher.dart new file mode 100644 index 00000000..72eb3185 --- /dev/null +++ b/packages/alice_test/lib/matcher/alice_response_matcher.dart @@ -0,0 +1,36 @@ +import 'package:alice/model/alice_http_response.dart'; +import 'package:alice_test/matcher/header_matcher.dart'; +import 'package:test/test.dart'; + +TypeMatcher buildResponseMatcher({ + int? status, + int? size, + bool? checkTime, + String? body, + Map? headers, +}) { + var matcher = const TypeMatcher(); + if (status != null) { + matcher = + matcher.having((response) => response.status, "status", equals(status)); + } + if (size != null) { + matcher = matcher.having((response) => response.size, "size", equals(size)); + } + if (checkTime == true) { + matcher = matcher.having((response) => response.time.millisecondsSinceEpoch, + "time", greaterThan(0)); + } + if (body != null) { + matcher = matcher.having( + (response) => response.body.toString(), "body", equals(body)); + } + if (headers != null) { + for (var header in headers.entries) { + matcher = matcher.having((response) { + return response.headers; + }, "header", HeaderMatcher(header)); + } + } + return matcher; +} diff --git a/packages/alice_test/lib/matcher/header_matcher.dart b/packages/alice_test/lib/matcher/header_matcher.dart new file mode 100644 index 00000000..4b48c8d4 --- /dev/null +++ b/packages/alice_test/lib/matcher/header_matcher.dart @@ -0,0 +1,29 @@ +import 'package:test/test.dart'; + +class HeaderMatcher extends Matcher { + final MapEntry? _expected; + + const HeaderMatcher(this._expected); + + @override + bool matches(Object? item, Map matchState) { + if (item is Map) { + final mapItem = item[_expected?.key]; + return mapItem == _expected?.value; + } + return false; + } + + @override + Description describe(Description description) => + description.add('contains header').addDescriptionOf(_expected); + + @override + Description describeMismatch(Object? item, Description mismatchDescription, + Map matchState, bool verbose) { + mismatchDescription + .add('does not contain header') + .addDescriptionOf(_expected); + return mismatchDescription; + } +} diff --git a/packages/alice_test/pubspec.yaml b/packages/alice_test/pubspec.yaml new file mode 100644 index 00000000..474064c4 --- /dev/null +++ b/packages/alice_test/pubspec.yaml @@ -0,0 +1,18 @@ +name: alice_test +description: "Test utils for Alice packages." +version: 1.0.0 +repository: https://github.com/jhomlala/alice +homepage: https://github.com/jhomlala/alice +publish_to: none + +environment: + sdk: ^3.0.0 + +dependencies: + alice: ^1.0.0-dev.9 + test: ^1.25.2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^4.0.0 From c776b89c67f379bac876c2dbf2fe8cea7ab04892 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 10:52:18 +0200 Subject: [PATCH 07/14] feat: added post request test --- .../test/alice_dio_adapter_test.dart | 64 +++++++++++++++++++ .../lib/matcher/alice_request_matcher.dart | 4 ++ 2 files changed, 68 insertions(+) diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index b7d2c64a..5cec80f4 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -18,9 +18,11 @@ void main() { setUp(() { registerFallbackValue(AliceHttpCall(0)); registerFallbackValue(AliceHttpResponse()); + aliceCore = AliceCoreMock(); when(() => aliceCore.addCall(any())).thenAnswer((_) => {}); when(() => aliceCore.addResponse(any(), any())).thenAnswer((_) => {}); + aliceDioAdapter = AliceDioAdapter(); aliceDioAdapter.injectCore(aliceCore); @@ -86,5 +88,67 @@ void main() { verify( () => aliceCore.addResponse(any(that: nextResponseMatcher), any())); }); + + test("should handle POST call with json response", () async { + dioAdapter.onPost( + 'https://test.com/json', + (server) => server.reply( + 200, + '{"result": "ok"}', + headers: { + "content-type": ["application/json"] + }, + ), + data: '{"data":"test"}', + headers: {"content-type": "application/json"}, + queryParameters: {"sort":"asc"} + ); + + await dio.post( + 'https://test.com/json', + data: '{"data":"test"}', + queryParameters:{"sort":"asc"}, + options: Options( + headers: {"content-type": "application/json"}, + ), + ); + + final requestMatcher = buildRequestMatcher( + checkTime: true, + headers: {"content-type": "application/json"}, + contentType: "application/json", + body: '{"data":"test"}', + queryParameters: {"sort":"asc"}, + ); + + final responseMatcher = buildResponseMatcher(checkTime: true); + + final callMatcher = buildCallMatcher( + checkId: true, + checkTime: true, + secured: true, + loading: true, + client: 'Dio', + method: 'POST', + endpoint: '/json', + server: 'test.com', + uri: 'https://test.com/json?sort=asc', + duration: 0, + request: requestMatcher, + response: responseMatcher); + + verify(() => aliceCore.addCall(any(that: callMatcher))); + + final nextResponseMatcher = buildResponseMatcher( + status: 200, + size: 16, + checkTime: true, + body: '{"result": "ok"}', + headers: {'content-type': '[application/json]'}, + ); + + verify( + () => aliceCore.addResponse(any(that: nextResponseMatcher), any())); + }); }); } diff --git a/packages/alice_test/lib/matcher/alice_request_matcher.dart b/packages/alice_test/lib/matcher/alice_request_matcher.dart index 48847fac..d7abee92 100644 --- a/packages/alice_test/lib/matcher/alice_request_matcher.dart +++ b/packages/alice_test/lib/matcher/alice_request_matcher.dart @@ -7,6 +7,7 @@ TypeMatcher buildRequestMatcher({ Map? headers, String? contentType, Map? queryParameters, + String? body, }) { var matcher = const TypeMatcher(); if (checkTime == true) { @@ -28,6 +29,9 @@ TypeMatcher buildRequestMatcher({ matcher = matcher.having((request) => request.queryParameters, "queryParameters", equals(queryParameters)); } + if (body != null) { + matcher = matcher.having((request) => request.body, "body", equals(body)); + } return matcher; } From cde5853ed87f5dcc03d65762240215ce01609236 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 12:12:12 +0200 Subject: [PATCH 08/14] feat: added form data tests --- packages/alice_dio/lib/alice_dio_adapter.dart | 1 + .../test/alice_dio_adapter_test.dart | 96 ++++++++++++++++--- .../lib/matcher/alice_request_matcher.dart | 31 ++++-- .../lib/matcher/form_data_field_matcher.dart | 33 +++++++ .../lib/matcher/form_data_file_matcher.dart | 33 +++++++ 5 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 packages/alice_test/lib/matcher/form_data_field_matcher.dart create mode 100644 packages/alice_test/lib/matcher/form_data_file_matcher.dart diff --git a/packages/alice_dio/lib/alice_dio_adapter.dart b/packages/alice_dio/lib/alice_dio_adapter.dart index f9908a84..14749997 100644 --- a/packages/alice_dio/lib/alice_dio_adapter.dart +++ b/packages/alice_dio/lib/alice_dio_adapter.dart @@ -53,6 +53,7 @@ class AliceDioAdapter extends InterceptorsWrapper with AliceAdapter { } request.formDataFields = fields; } + if (data.files.isNotEmpty == true) { final files = []; for (var entry in data.files) { diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index 5cec80f4..361565a1 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -1,4 +1,8 @@ +import 'dart:io'; + import 'package:alice/core/alice_core.dart'; +import 'package:alice/model/alice_form_data_file.dart'; +import 'package:alice/model/alice_from_data_field.dart'; import 'package:alice/model/alice_http_call.dart'; import 'package:alice/model/alice_http_response.dart'; import 'package:alice_dio/alice_dio_adapter.dart'; @@ -91,23 +95,22 @@ void main() { test("should handle POST call with json response", () async { dioAdapter.onPost( - 'https://test.com/json', - (server) => server.reply( - 200, - '{"result": "ok"}', - headers: { - "content-type": ["application/json"] - }, - ), - data: '{"data":"test"}', - headers: {"content-type": "application/json"}, - queryParameters: {"sort":"asc"} - ); + 'https://test.com/json', + (server) => server.reply( + 200, + '{"result": "ok"}', + headers: { + "content-type": ["application/json"] + }, + ), + data: '{"data":"test"}', + headers: {"content-type": "application/json"}, + queryParameters: {"sort": "asc"}); await dio.post( 'https://test.com/json', data: '{"data":"test"}', - queryParameters:{"sort":"asc"}, + queryParameters: {"sort": "asc"}, options: Options( headers: {"content-type": "application/json"}, ), @@ -118,7 +121,7 @@ void main() { headers: {"content-type": "application/json"}, contentType: "application/json", body: '{"data":"test"}', - queryParameters: {"sort":"asc"}, + queryParameters: {"sort": "asc"}, ); final responseMatcher = buildResponseMatcher(checkTime: true); @@ -150,5 +153,70 @@ void main() { verify( () => aliceCore.addResponse(any(that: nextResponseMatcher), any())); }); + + test("should handle form data", () async { + final file = File("image.png"); + file.createSync(); + + var formData = FormData.fromMap({ + 'name': 'Alice', + 'surname': 'test', + 'image': MultipartFile.fromFileSync(file.path) + }); + + dioAdapter.onPost( + 'https://test.com/form', + (server) => server.reply( + 200, + '{"result": "ok"}', + ), + data: formData); + + await dio.post( + 'https://test.com/form', + data: formData, + ); + + final requestMatcher = buildRequestMatcher( + checkTime: true, + formDataFields: [ + const AliceFormDataField('name', 'Alice'), + const AliceFormDataField('surname', 'test'), + ], + formDataFiles: [ + const AliceFormDataFile("image.png", "application/octet-stream", 0), + ], + body: 'Form data', + headers: {'content-type': 'multipart/form-data'}); + final responseMatcher = buildResponseMatcher(checkTime: true); + + final callMatcher = buildCallMatcher( + checkId: true, + checkTime: true, + secured: true, + loading: true, + client: 'Dio', + method: 'POST', + endpoint: '/form', + server: 'test.com', + uri: 'https://test.com/form', + duration: 0, + request: requestMatcher, + response: responseMatcher); + + verify(() => aliceCore.addCall(any(that: callMatcher))); + + final nextResponseMatcher = buildResponseMatcher( + status: 200, + size: 16, + checkTime: true, + body: '{"result": "ok"}', + headers: {'content-type': '[application/json]'}, + ); + + verify( + () => aliceCore.addResponse(any(that: nextResponseMatcher), any())); + file.deleteSync(); + }); }); } diff --git a/packages/alice_test/lib/matcher/alice_request_matcher.dart b/packages/alice_test/lib/matcher/alice_request_matcher.dart index d7abee92..4380c916 100644 --- a/packages/alice_test/lib/matcher/alice_request_matcher.dart +++ b/packages/alice_test/lib/matcher/alice_request_matcher.dart @@ -1,14 +1,19 @@ +import 'package:alice/model/alice_form_data_file.dart'; +import 'package:alice/model/alice_from_data_field.dart'; import 'package:alice/model/alice_http_request.dart'; +import 'package:alice_test/matcher/form_data_field_matcher.dart'; +import 'package:alice_test/matcher/form_data_file_matcher.dart'; import 'package:alice_test/matcher/header_matcher.dart'; import 'package:test/test.dart'; -TypeMatcher buildRequestMatcher({ - bool? checkTime, - Map? headers, - String? contentType, - Map? queryParameters, - String? body, -}) { +TypeMatcher buildRequestMatcher( + {bool? checkTime, + Map? headers, + String? contentType, + Map? queryParameters, + dynamic body, + List? formDataFields, + List? formDataFiles}) { var matcher = const TypeMatcher(); if (checkTime == true) { matcher = matcher.having((request) => request.time.millisecondsSinceEpoch, @@ -32,6 +37,18 @@ TypeMatcher buildRequestMatcher({ if (body != null) { matcher = matcher.having((request) => request.body, "body", equals(body)); } + if (formDataFields != null) { + for (var field in formDataFields) { + matcher = matcher.having((request) => request.formDataFields, + "form data field", FormDataFieldMatcher(field)); + } + } + if (formDataFiles != null) { + for (var file in formDataFiles) { + matcher = matcher.having((request) => request.formDataFiles, + "form data file", FormDataFileMatcher(file)); + } + } return matcher; } diff --git a/packages/alice_test/lib/matcher/form_data_field_matcher.dart b/packages/alice_test/lib/matcher/form_data_field_matcher.dart new file mode 100644 index 00000000..736fcf30 --- /dev/null +++ b/packages/alice_test/lib/matcher/form_data_field_matcher.dart @@ -0,0 +1,33 @@ +import 'package:alice/model/alice_from_data_field.dart'; +import 'package:test/test.dart'; + +class FormDataFieldMatcher extends Matcher { + final AliceFormDataField _expected; + + const FormDataFieldMatcher(this._expected); + + @override + bool matches(Object? item, Map matchState) { + try { + if (item is List) { + final formField = + item.firstWhere((element) => element.name == _expected.name); + return formField.value == _expected.value; + } + } catch (_) {} + return false; + } + + @override + Description describe(Description description) => + description.add('contains form field').addDescriptionOf(_expected); + + @override + Description describeMismatch(Object? item, Description mismatchDescription, + Map matchState, bool verbose) { + mismatchDescription + .add('does not contain form field') + .addDescriptionOf(_expected); + return mismatchDescription; + } +} diff --git a/packages/alice_test/lib/matcher/form_data_file_matcher.dart b/packages/alice_test/lib/matcher/form_data_file_matcher.dart new file mode 100644 index 00000000..19f10b2a --- /dev/null +++ b/packages/alice_test/lib/matcher/form_data_file_matcher.dart @@ -0,0 +1,33 @@ +import 'package:alice/model/alice_form_data_file.dart'; +import 'package:test/test.dart'; + +class FormDataFileMatcher extends Matcher { + final AliceFormDataFile _expected; + + const FormDataFileMatcher(this._expected); + + @override + bool matches(Object? item, Map matchState) { + try { + if (item is List) { + final formFile = item + .firstWhere((element) => element.fileName == _expected.fileName); + return formFile.contentType == _expected.contentType; + } + } catch (_) {} + return false; + } + + @override + Description describe(Description description) => + description.add('contains form file').addDescriptionOf(_expected); + + @override + Description describeMismatch(Object? item, Description mismatchDescription, + Map matchState, bool verbose) { + mismatchDescription + .add('does not contain form file') + .addDescriptionOf(_expected); + return mismatchDescription; + } +} From 1772e05921ee17475b0f78049c4fb498887c5540 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 12:54:26 +0200 Subject: [PATCH 09/14] feat: test error --- .../test/alice_dio_adapter_test.dart | 62 +++++++++++++++++++ packages/alice_test/lib/alice_test.dart | 1 + .../lib/matcher/alice_error_matcher.dart | 15 +++++ 3 files changed, 78 insertions(+) create mode 100644 packages/alice_test/lib/matcher/alice_error_matcher.dart diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index 361565a1..10db4332 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -4,6 +4,7 @@ import 'package:alice/core/alice_core.dart'; import 'package:alice/model/alice_form_data_file.dart'; import 'package:alice/model/alice_from_data_field.dart'; import 'package:alice/model/alice_http_call.dart'; +import 'package:alice/model/alice_http_error.dart'; import 'package:alice/model/alice_http_response.dart'; import 'package:alice_dio/alice_dio_adapter.dart'; import 'package:alice_test/alice_test.dart'; @@ -22,10 +23,12 @@ void main() { setUp(() { registerFallbackValue(AliceHttpCall(0)); registerFallbackValue(AliceHttpResponse()); + registerFallbackValue(AliceHttpError()); aliceCore = AliceCoreMock(); when(() => aliceCore.addCall(any())).thenAnswer((_) => {}); when(() => aliceCore.addResponse(any(), any())).thenAnswer((_) => {}); + when(() => aliceCore.addError(any(), any())).thenAnswer((_) => {}); aliceDioAdapter = AliceDioAdapter(); aliceDioAdapter.injectCore(aliceCore); @@ -219,4 +222,63 @@ void main() { file.deleteSync(); }); }); + + test("should handle call with error", () async { + dioAdapter.onGet( + 'https://test.com/json', + (server) => server.reply( + 500, + '', + ), + headers: {"content-type": "application/json"}, + ); + + try { + await dio.get( + 'https://test.com/json', + options: Options( + headers: {"content-type": "application/json"}, + ), + ); + } catch (_) {} + + final requestMatcher = buildRequestMatcher( + checkTime: true, + headers: {"content-type": "application/json"}, + contentType: "application/json", + queryParameters: {}, + ); + + final responseMatcher = buildResponseMatcher(checkTime: true); + + final callMatcher = buildCallMatcher( + checkId: true, + checkTime: true, + secured: true, + loading: true, + client: 'Dio', + method: 'GET', + endpoint: '/json', + server: 'test.com', + uri: 'https://test.com/json', + duration: 0, + request: requestMatcher, + response: responseMatcher); + + verify(() => aliceCore.addCall(any(that: callMatcher))); + + final nextResponseMatcher = buildResponseMatcher( + status: 500, + size: 0, + checkTime: true, + headers: {'content-type': '[application/json]'}, + ); + + verify(() => aliceCore.addResponse(any(that: nextResponseMatcher), any())); + + final errorMatcher = + buildErrorMatcher(checkError: true, checkStacktrace: true); + + verify(() => aliceCore.addError(any(that: errorMatcher), any())); + }); } diff --git a/packages/alice_test/lib/alice_test.dart b/packages/alice_test/lib/alice_test.dart index 02411624..43143eeb 100644 --- a/packages/alice_test/lib/alice_test.dart +++ b/packages/alice_test/lib/alice_test.dart @@ -2,3 +2,4 @@ export 'matcher/header_matcher.dart'; export 'matcher/alice_call_matcher.dart'; export 'matcher/alice_request_matcher.dart'; export 'matcher/alice_response_matcher.dart'; +export 'matcher/alice_error_matcher.dart'; diff --git a/packages/alice_test/lib/matcher/alice_error_matcher.dart b/packages/alice_test/lib/matcher/alice_error_matcher.dart new file mode 100644 index 00000000..d0c0c6a3 --- /dev/null +++ b/packages/alice_test/lib/matcher/alice_error_matcher.dart @@ -0,0 +1,15 @@ +import 'package:alice/model/alice_http_error.dart'; +import 'package:test/test.dart'; + +TypeMatcher buildErrorMatcher( + {bool? checkError, bool? checkStacktrace}) { + var matcher = const TypeMatcher(); + if (checkError == true) { + matcher = matcher.having((error) => error.error, "error", isNotEmpty); + } + if (checkStacktrace == true) { + matcher = matcher.having((error) => error.error, "stackTrace", isNotEmpty); + } + + return matcher; +} From 465a22c35597013460139d743e548153b9d32d89 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 13:13:25 +0200 Subject: [PATCH 10/14] feat: log in error test --- .../test/alice_dio_adapter_test.dart | 17 ++++++++++-- packages/alice_test/lib/alice_test.dart | 1 + .../lib/matcher/alice_error_matcher.dart | 6 +++-- .../lib/matcher/alice_log_matcher.dart | 27 +++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 packages/alice_test/lib/matcher/alice_log_matcher.dart diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index 10db4332..622f30c7 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -6,6 +6,7 @@ import 'package:alice/model/alice_from_data_field.dart'; import 'package:alice/model/alice_http_call.dart'; import 'package:alice/model/alice_http_error.dart'; import 'package:alice/model/alice_http_response.dart'; +import 'package:alice/model/alice_log.dart'; import 'package:alice_dio/alice_dio_adapter.dart'; import 'package:alice_test/alice_test.dart'; import 'package:dio/dio.dart'; @@ -24,11 +25,13 @@ void main() { registerFallbackValue(AliceHttpCall(0)); registerFallbackValue(AliceHttpResponse()); registerFallbackValue(AliceHttpError()); + registerFallbackValue(AliceLog(message: '')); aliceCore = AliceCoreMock(); when(() => aliceCore.addCall(any())).thenAnswer((_) => {}); when(() => aliceCore.addResponse(any(), any())).thenAnswer((_) => {}); when(() => aliceCore.addError(any(), any())).thenAnswer((_) => {}); + when(() => aliceCore.addLog(any())).thenAnswer((_) => {}); aliceDioAdapter = AliceDioAdapter(); aliceDioAdapter.injectCore(aliceCore); @@ -276,9 +279,19 @@ void main() { verify(() => aliceCore.addResponse(any(that: nextResponseMatcher), any())); - final errorMatcher = - buildErrorMatcher(checkError: true, checkStacktrace: true); + final errorMatcher = buildErrorMatcher( + checkError: true, + checkStacktrace: true, + ); verify(() => aliceCore.addError(any(that: errorMatcher), any())); + + final logMatcher = buildLogMatcher( + checkMessage: true, + checkError: true, + checkStacktrace: true, + checkTime: true, + ); + verify(() => aliceCore.addLog(any(that: logMatcher))); }); } diff --git a/packages/alice_test/lib/alice_test.dart b/packages/alice_test/lib/alice_test.dart index 43143eeb..4a8a97ea 100644 --- a/packages/alice_test/lib/alice_test.dart +++ b/packages/alice_test/lib/alice_test.dart @@ -3,3 +3,4 @@ export 'matcher/alice_call_matcher.dart'; export 'matcher/alice_request_matcher.dart'; export 'matcher/alice_response_matcher.dart'; export 'matcher/alice_error_matcher.dart'; +export 'matcher/alice_log_matcher.dart'; diff --git a/packages/alice_test/lib/matcher/alice_error_matcher.dart b/packages/alice_test/lib/matcher/alice_error_matcher.dart index d0c0c6a3..101d3d5b 100644 --- a/packages/alice_test/lib/matcher/alice_error_matcher.dart +++ b/packages/alice_test/lib/matcher/alice_error_matcher.dart @@ -5,10 +5,12 @@ TypeMatcher buildErrorMatcher( {bool? checkError, bool? checkStacktrace}) { var matcher = const TypeMatcher(); if (checkError == true) { - matcher = matcher.having((error) => error.error, "error", isNotEmpty); + matcher = + matcher.having((error) => error.error.toString(), "error", isNotEmpty); } if (checkStacktrace == true) { - matcher = matcher.having((error) => error.error, "stackTrace", isNotEmpty); + matcher = matcher.having( + (error) => error.stackTrace.toString(), "stackTrace", isNotEmpty); } return matcher; diff --git a/packages/alice_test/lib/matcher/alice_log_matcher.dart b/packages/alice_test/lib/matcher/alice_log_matcher.dart new file mode 100644 index 00000000..023c50e0 --- /dev/null +++ b/packages/alice_test/lib/matcher/alice_log_matcher.dart @@ -0,0 +1,27 @@ +import 'package:alice/model/alice_log.dart'; +import 'package:test/test.dart'; + +TypeMatcher buildLogMatcher({ + bool? checkMessage, + bool? checkError, + bool? checkStacktrace, + bool? checkTime, +}) { + var matcher = const TypeMatcher(); + if (checkMessage != null) { + matcher = matcher.having((log) => log.message, "message", isNotEmpty); + } + if (checkError == true) { + matcher = + matcher.having((log) => log.error.toString(), "error", isNotEmpty); + } + if (checkStacktrace == true) { + matcher = matcher.having( + (log) => log.stackTrace.toString(), "stackTrace", isNotEmpty); + } + if (checkTime == true) { + matcher = matcher.having( + (log) => log.timestamp.millisecondsSinceEpoch, "timestamp", isPositive); + } + return matcher; +} From fce81010971f18b52fa152223bd79b29c077cf59 Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 13:35:55 +0200 Subject: [PATCH 11/14] fix: fixed issue in stats, updated tests --- packages/alice/lib/ui/stats/alice_stats_page.dart | 9 ++++----- packages/alice_dio/test/alice_dio_adapter_test.dart | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/alice/lib/ui/stats/alice_stats_page.dart b/packages/alice/lib/ui/stats/alice_stats_page.dart index 7222498c..0ff277e9 100644 --- a/packages/alice/lib/ui/stats/alice_stats_page.dart +++ b/packages/alice/lib/ui/stats/alice_stats_page.dart @@ -116,11 +116,10 @@ class AliceStatsPage extends StatelessWidget { /// Returns count of error requests. int _getErrorRequests() => _calls - .where( - (AliceHttpCall call) => - (call.response?.status.gte(400) ?? false) && - (call.response?.status.lt(600) ?? false), - ) + .where((AliceHttpCall call) => + (call.response?.status.gte(400) ?? false) && + (call.response?.status.lt(600) ?? false) || + const [-1, 0].contains(call.response?.status)) .toList() .length; diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index 622f30c7..f32c93f9 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -161,7 +161,8 @@ void main() { }); test("should handle form data", () async { - final file = File("image.png"); + final name = '${DateTime.now().microsecondsSinceEpoch}.png'; + final file = File(name); file.createSync(); var formData = FormData.fromMap({ @@ -190,7 +191,7 @@ void main() { const AliceFormDataField('surname', 'test'), ], formDataFiles: [ - const AliceFormDataFile("image.png", "application/octet-stream", 0), + AliceFormDataFile(name, "application/octet-stream", 0), ], body: 'Form data', headers: {'content-type': 'multipart/form-data'}); @@ -222,7 +223,6 @@ void main() { verify( () => aliceCore.addResponse(any(that: nextResponseMatcher), any())); - file.deleteSync(); }); }); From df1e84e8d2734d13d06e60240b907b055949265f Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 14:08:11 +0200 Subject: [PATCH 12/14] feat: added tests --- .../test/alice_dio_adapter_test.dart | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index f32c93f9..d3f69cfa 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -226,6 +226,58 @@ void main() { }); }); + test("should handle call with empty response", () async { + dioAdapter.onGet( + 'https://test.com/json', + (server) => server.reply( + 200, + null, + ), + headers: {"content-type": "application/json"}, + ); + + await dio.get( + 'https://test.com/json', + options: Options( + headers: {"content-type": "application/json"}, + ), + ); + + final requestMatcher = buildRequestMatcher( + checkTime: true, + headers: {"content-type": "application/json"}, + contentType: "application/json", + queryParameters: {}, + ); + + final responseMatcher = buildResponseMatcher(checkTime: true); + + final callMatcher = buildCallMatcher( + checkId: true, + checkTime: true, + secured: true, + loading: true, + client: 'Dio', + method: 'GET', + endpoint: '/json', + server: 'test.com', + uri: 'https://test.com/json', + duration: 0, + request: requestMatcher, + response: responseMatcher); + + verify(() => aliceCore.addCall(any(that: callMatcher))); + + final nextResponseMatcher = buildResponseMatcher( + status: 200, + size: 0, + checkTime: true, + body: '', + ); + + verify(() => aliceCore.addResponse(any(that: nextResponseMatcher), any())); + }); + test("should handle call with error", () async { dioAdapter.onGet( 'https://test.com/json', @@ -294,4 +346,60 @@ void main() { ); verify(() => aliceCore.addLog(any(that: logMatcher))); }); + + test("should handle call with error where response is null", () async { + dioAdapter.onGet( + 'https://test.com/json', + (server) => + server.throws(0, DioException(requestOptions: RequestOptions())), + headers: {"content-type": "application/json"}, + ); + + try { + await dio.get( + 'https://test.com/json', + options: Options( + headers: {"content-type": "application/json"}, + ), + ); + } catch (_) {} + + final nextResponseMatcher = buildResponseMatcher( + status: -1, + size: 0, + checkTime: true, + ); + + verify(() => aliceCore.addResponse(any(that: nextResponseMatcher), any())); + }); + + test("should handle call with error where response is not null", () async { + dioAdapter.onGet( + 'https://test.com/json', + (server) => server.throws( + 0, + DioException( + requestOptions: RequestOptions(), + response: Response(requestOptions: RequestOptions(), data: "{}")), + ), + headers: {"content-type": "application/json"}, + ); + + try { + await dio.get( + 'https://test.com/json', + options: Options( + headers: {"content-type": "application/json"}, + ), + ); + } catch (_) {} + + final nextResponseMatcher = buildResponseMatcher( + size: 2, + body: '{}', + checkTime: true, + ); + + verify(() => aliceCore.addResponse(any(that: nextResponseMatcher), any())); + }); } From 6058471c87a0745015a4fb61043324532f83dfff Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 14:10:04 +0200 Subject: [PATCH 13/14] feat: updated metadata --- packages/alice/CHANGELOG.md | 3 +++ packages/alice/pubspec.yaml | 2 +- packages/alice_dio/CHANGELOG.md | 3 +++ packages/alice_dio/pubspec.yaml | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/alice/CHANGELOG.md b/packages/alice/CHANGELOG.md index 5bb93eed..2557ab49 100644 --- a/packages/alice/CHANGELOG.md +++ b/packages/alice/CHANGELOG.md @@ -1,3 +1,6 @@ +# 1.0.0-dev.11 +* Fixed issue with invalid count of error calls in stats page. + # 1.0.0-dev.10 * [BREAKING_CHANGE] Removed `maxCallsCount`. To change call count, use `storage` constructor parameter diff --git a/packages/alice/pubspec.yaml b/packages/alice/pubspec.yaml index ef0642ee..04af8787 100644 --- a/packages/alice/pubspec.yaml +++ b/packages/alice/pubspec.yaml @@ -1,6 +1,6 @@ name: alice description: Alice is an HTTP Inspector tool which helps debugging http requests. It catches and stores http requests and responses, which can be viewed via simple UI. -version: 1.0.0-dev.10 +version: 1.0.0-dev.11 homepage: https://github.com/jhomlala/alice repository: https://github.com/jhomlala/alice topics: diff --git a/packages/alice_dio/CHANGELOG.md b/packages/alice_dio/CHANGELOG.md index 4ae1042e..7c1e8162 100644 --- a/packages/alice_dio/CHANGELOG.md +++ b/packages/alice_dio/CHANGELOG.md @@ -1,3 +1,6 @@ +# 1.0.5 +* Added tests. + # 1.0.4 * Untrack gitignored files. diff --git a/packages/alice_dio/pubspec.yaml b/packages/alice_dio/pubspec.yaml index aade5713..9d6c7465 100644 --- a/packages/alice_dio/pubspec.yaml +++ b/packages/alice_dio/pubspec.yaml @@ -1,6 +1,6 @@ name: alice_dio description: "Alice + Dio integration. It contains plugin for Alice which allows to use Dio package." -version: 1.0.4 +version: 1.0.5 repository: https://github.com/jhomlala/alice homepage: https://github.com/jhomlala/alice topics: From ff5880317a86640e5e73b9e81ee439d89f76bc5c Mon Sep 17 00:00:00 2001 From: Jakub Homlala Date: Sun, 7 Jul 2024 18:13:57 +0200 Subject: [PATCH 14/14] refactor: general refactor --- packages/alice_dio/test/alice_dio_adapter_test.dart | 3 +-- packages/alice_test/lib/alice_test.dart | 1 + .../test => alice_test/lib/mock}/alice_core_mock.dart | 0 packages/alice_test/pubspec.yaml | 1 + 4 files changed, 3 insertions(+), 2 deletions(-) rename packages/{alice_dio/test => alice_test/lib/mock}/alice_core_mock.dart (100%) diff --git a/packages/alice_dio/test/alice_dio_adapter_test.dart b/packages/alice_dio/test/alice_dio_adapter_test.dart index d3f69cfa..e75fc9aa 100644 --- a/packages/alice_dio/test/alice_dio_adapter_test.dart +++ b/packages/alice_dio/test/alice_dio_adapter_test.dart @@ -14,8 +14,6 @@ import 'package:http_mock_adapter/http_mock_adapter.dart' as http_mock_adapter; import 'package:mocktail/mocktail.dart'; import 'package:test/test.dart'; -import 'alice_core_mock.dart'; - void main() { late AliceCore aliceCore; late AliceDioAdapter aliceDioAdapter; @@ -223,6 +221,7 @@ void main() { verify( () => aliceCore.addResponse(any(that: nextResponseMatcher), any())); + file.deleteSync(); }); }); diff --git a/packages/alice_test/lib/alice_test.dart b/packages/alice_test/lib/alice_test.dart index 4a8a97ea..4dd7d958 100644 --- a/packages/alice_test/lib/alice_test.dart +++ b/packages/alice_test/lib/alice_test.dart @@ -4,3 +4,4 @@ export 'matcher/alice_request_matcher.dart'; export 'matcher/alice_response_matcher.dart'; export 'matcher/alice_error_matcher.dart'; export 'matcher/alice_log_matcher.dart'; +export 'mock/alice_core_mock.dart'; diff --git a/packages/alice_dio/test/alice_core_mock.dart b/packages/alice_test/lib/mock/alice_core_mock.dart similarity index 100% rename from packages/alice_dio/test/alice_core_mock.dart rename to packages/alice_test/lib/mock/alice_core_mock.dart diff --git a/packages/alice_test/pubspec.yaml b/packages/alice_test/pubspec.yaml index 474064c4..6615f8be 100644 --- a/packages/alice_test/pubspec.yaml +++ b/packages/alice_test/pubspec.yaml @@ -11,6 +11,7 @@ environment: dependencies: alice: ^1.0.0-dev.9 test: ^1.25.2 + mocktail: ^1.0.4 dev_dependencies: flutter_test: