From 92b5415b534b21e7b5b7917b2b52d6d39590780e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klemen=20Tu=C5=A1ar?= Date: Sat, 18 Feb 2023 13:43:31 +0000 Subject: [PATCH 1/7] #290 implement Equatable --- chopper/lib/src/base.dart | 16 +++++++++++- chopper/lib/src/http_logging_interceptor.dart | 5 ++++ chopper/lib/src/interceptor.dart | 6 ++++- chopper/lib/src/request.dart | 25 +++++++++++++++++-- chopper/lib/src/response.dart | 10 +++++++- chopper/lib/src/utils.dart | 9 ++++++- chopper/pubspec.yaml | 1 + 7 files changed, 66 insertions(+), 6 deletions(-) diff --git a/chopper/lib/src/base.dart b/chopper/lib/src/base.dart index 4fa556c2..b44079a3 100644 --- a/chopper/lib/src/base.dart +++ b/chopper/lib/src/base.dart @@ -7,6 +7,7 @@ import 'package:chopper/src/interceptor.dart'; import 'package:chopper/src/request.dart'; import 'package:chopper/src/response.dart'; import 'package:chopper/src/utils.dart'; +import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; @@ -26,7 +27,7 @@ final List allowedInterceptorsType = [ /// /// It manages registered services, encodes and decodes data, and intercepts /// requests and responses. -class ChopperClient { +class ChopperClient with EquatableMixin { /// Base URL of each request of the registered services. /// E.g., the hostname of your service. final Uri baseUrl; @@ -515,6 +516,19 @@ class ChopperClient { /// A stream of processed [Response]s, as in after all [Converter]s and /// [ResponseInterceptor]s have been run. Stream get onResponse => _responseController.stream; + + @override + List get props => [ + baseUrl, + httpClient, + _clientIsInternal, + _requestInterceptors, + _responseInterceptors, + authenticator, + converter, + errorConverter, + _services, + ]; } /// A marker and helper class used by `chopper_generator` to generate network diff --git a/chopper/lib/src/http_logging_interceptor.dart b/chopper/lib/src/http_logging_interceptor.dart index 0be43965..a9726920 100644 --- a/chopper/lib/src/http_logging_interceptor.dart +++ b/chopper/lib/src/http_logging_interceptor.dart @@ -4,6 +4,7 @@ import 'package:chopper/src/interceptor.dart'; import 'package:chopper/src/request.dart'; import 'package:chopper/src/response.dart'; import 'package:chopper/src/utils.dart'; +import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; @@ -70,6 +71,7 @@ enum Level { /// or in a non-production environment. @immutable class HttpLoggingInterceptor + with EquatableMixin implements RequestInterceptor, ResponseInterceptor { const HttpLoggingInterceptor({this.level = Level.body}) : _logBody = level == Level.body, @@ -170,4 +172,7 @@ class HttpLoggingInterceptor return response; } + + @override + List get props => [level]; } diff --git a/chopper/lib/src/interceptor.dart b/chopper/lib/src/interceptor.dart index 0e123237..f46eec11 100644 --- a/chopper/lib/src/interceptor.dart +++ b/chopper/lib/src/interceptor.dart @@ -5,6 +5,7 @@ import 'package:chopper/src/constants.dart'; import 'package:chopper/src/request.dart'; import 'package:chopper/src/response.dart'; import 'package:chopper/src/utils.dart'; +import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; @@ -105,7 +106,7 @@ abstract class ErrorConverter { /// Note that this interceptor will overwrite existing headers having the same /// keys as [headers]. @immutable -class HeadersInterceptor implements RequestInterceptor { +class HeadersInterceptor with EquatableMixin implements RequestInterceptor { final Map headers; const HeadersInterceptor(this.headers); @@ -113,6 +114,9 @@ class HeadersInterceptor implements RequestInterceptor { @override Future onRequest(Request request) async => applyHeaders(request, headers); + + @override + List get props => [headers]; } typedef ResponseInterceptorFunc1 = FutureOr> diff --git a/chopper/lib/src/request.dart b/chopper/lib/src/request.dart index e418f2c2..e4ecfdb6 100644 --- a/chopper/lib/src/request.dart +++ b/chopper/lib/src/request.dart @@ -2,11 +2,12 @@ import 'dart:async'; import 'package:chopper/src/extensions.dart'; import 'package:chopper/src/utils.dart'; +import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; /// This class represents an HTTP request that can be made with Chopper. -class Request extends http.BaseRequest { +class Request extends http.BaseRequest with EquatableMixin { final Uri uri; final Uri baseUri; final dynamic body; @@ -207,11 +208,25 @@ class Request extends http.BaseRequest { return request; } + + @override + List get props => [ + method, + uri, + baseUri, + body, + parameters, + headers, + multipart, + parts, + useBrackets, + includeNullQueryVars, + ]; } /// Represents a part in a multipart request. @immutable -class PartValue { +class PartValue with EquatableMixin { final T value; final String name; @@ -227,6 +242,12 @@ class PartValue { name ?? this.name, value ?? this.value as NewType, ); + + @override + List get props => [ + name, + value, + ]; } /// Represents a file part in a multipart request. diff --git a/chopper/lib/src/response.dart b/chopper/lib/src/response.dart index 1fc29fac..8f44e1c5 100644 --- a/chopper/lib/src/response.dart +++ b/chopper/lib/src/response.dart @@ -1,5 +1,6 @@ import 'dart:typed_data'; +import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; @@ -15,7 +16,7 @@ import 'package:meta/meta.dart'; /// Future> fetchItem(); /// ``` @immutable -class Response { +class Response with EquatableMixin { /// The [http.BaseResponse] from `package:http` that this [Response] wraps. final http.BaseResponse base; @@ -65,4 +66,11 @@ class Response { /// call was successful, else this will be `null`. String get bodyString => base is http.Response ? (base as http.Response).body : ''; + + @override + List get props => [ + base, + body, + error, + ]; } diff --git a/chopper/lib/src/utils.dart b/chopper/lib/src/utils.dart index 656c637c..c8853170 100644 --- a/chopper/lib/src/utils.dart +++ b/chopper/lib/src/utils.dart @@ -1,6 +1,7 @@ import 'dart:collection'; import 'package:chopper/chopper.dart'; +import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:logging/logging.dart'; /// Creates a new [Request] by copying [request] and adding a header with the @@ -130,7 +131,7 @@ Iterable<_Pair> _iterableToQuery( String _normalizeValue(value) => Uri.encodeComponent(value?.toString() ?? ''); -class _Pair { +class _Pair with EquatableMixin { final A first; final B second; final bool useBrackets; @@ -145,6 +146,12 @@ class _Pair { String toString() => useBrackets ? '$first${Uri.encodeQueryComponent('[]')}=$second' : '$first=$second'; + + @override + List get props => [ + first, + second, + ]; } bool isTypeOf() => _Instance() is _Instance; diff --git a/chopper/pubspec.yaml b/chopper/pubspec.yaml index ad1ac78f..a9ac7e53 100644 --- a/chopper/pubspec.yaml +++ b/chopper/pubspec.yaml @@ -8,6 +8,7 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: + equatable: ^2.0.5 http: ">=0.13.0 <1.0.0" logging: ^1.0.0 meta: ^1.3.0 From 719fd4ad42989e0b57e3b9d2d27ba452d4ff3d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klemen=20Tu=C5=A1ar?= Date: Sun, 19 Feb 2023 14:07:09 +0000 Subject: [PATCH 2/7] :heavy_plus_sign: add faker and data_fixture_dart as dev dependencies --- chopper/pubspec.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chopper/pubspec.yaml b/chopper/pubspec.yaml index a9ac7e53..815db4be 100644 --- a/chopper/pubspec.yaml +++ b/chopper/pubspec.yaml @@ -18,7 +18,9 @@ dev_dependencies: build_test: ^2.0.0 collection: ^1.16.0 coverage: ^1.0.2 - dart_code_metrics: ^4.8.1 + dart_code_metrics: '>=4.8.1 <6.0.0' + data_fixture_dart: ^2.2.0 + faker: ^2.1.0 http_parser: ^4.0.0 lints: ^2.0.0 test: ^1.16.4 From b9d05eb5e3ae9e8376375900fc73b5c236ce3631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klemen=20Tu=C5=A1ar?= Date: Sun, 19 Feb 2023 14:07:33 +0000 Subject: [PATCH 3/7] :white_check_mark: add Request equatability test --- chopper/test/equatable_test.dart | 95 ++++++++++++++++++++++ chopper/test/fixtures/request_fixture.dart | 36 ++++++++ 2 files changed, 131 insertions(+) create mode 100644 chopper/test/equatable_test.dart create mode 100644 chopper/test/fixtures/request_fixture.dart diff --git a/chopper/test/equatable_test.dart b/chopper/test/equatable_test.dart new file mode 100644 index 00000000..ad4da81f --- /dev/null +++ b/chopper/test/equatable_test.dart @@ -0,0 +1,95 @@ +import 'package:chopper/chopper.dart'; +import 'package:faker/faker.dart'; +import 'package:test/test.dart'; + +import 'fixtures/request_fixture.dart'; + +void main() { + final Faker faker = Faker(); + + group('Request', () { + final Uri baseUrl = Uri.parse(faker.internet.httpsUrl()); + late Request request; + + setUp(() { + request = RequestFixture.factory.makeSingle(); + }); + + test('should return true when comparing two identical objects', () { + expect( + Request( + 'GET', + Uri.parse('/foo'), + baseUrl, + headers: {'bar': 'baz'}, + ), + equals( + Request( + 'GET', + Uri.parse('/foo'), + baseUrl, + headers: {'bar': 'baz'}, + ), + ), + ); + }); + + test( + 'should return true when comparing original with copy', + () => expect( + request, + equals( + request.copyWith(), + ), + ), + ); + + test( + 'should return false when comparing two different objects', + () => expect( + request, + isNot( + equals( + RequestFixture.factory.makeSingle(), + ), + ), + ), + ); + + test( + 'should return false when comparing to null', + () => expect( + request, + isNot( + equals(null), + ), + ), + ); + + test( + 'should return false when comparing to an object of a different type', + () { + expect( + request, + isNot( + equals(faker.lorem.word()), + ), + ); + }, + ); + + test( + 'should return false when comparing to an object with different props', + () => expect( + request, + isNot( + equals( + request.copyWith( + headers: {'bar': 'bazzz'}, + ), + ), + ), + ), + ); + }); +} diff --git a/chopper/test/fixtures/request_fixture.dart b/chopper/test/fixtures/request_fixture.dart new file mode 100644 index 00000000..6d422cf4 --- /dev/null +++ b/chopper/test/fixtures/request_fixture.dart @@ -0,0 +1,36 @@ +import 'dart:convert' show jsonEncode; + +import 'package:chopper/chopper.dart' show Request; +import 'package:data_fixture_dart/data_fixture_dart.dart'; +import 'package:meta/meta.dart'; + +extension RequestFixture on Request { + static RequestFixtureFactory get factory => RequestFixtureFactory(); +} + +@internal +class RequestFixtureFactory extends FixtureFactory { + @override + FixtureDefinition definition() { + final String method = + faker.randomGenerator.element(['GET', 'POST', 'PUT', 'DELETE']); + + return define( + (Faker faker) => Request( + method, + Uri.parse('/${faker.lorem.word()}'), + Uri.https(faker.internet.domainName()), + headers: faker.randomGenerator.boolean() + ? {'x-${faker.lorem.word()}': faker.lorem.word()} + : {}, + parameters: faker.randomGenerator.boolean() + ? {faker.lorem.word(): faker.lorem.word()} + : null, + body: + faker.randomGenerator.boolean() && ['POST', 'PUT'].contains(method) + ? jsonEncode({faker.lorem.word(): faker.lorem.sentences(10)}) + : null, + ), + ); + } +} From 930b0d45b259f4974ca8f1189f90d462683cadce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klemen=20Tu=C5=A1ar?= Date: Sun, 19 Feb 2023 19:55:51 +0000 Subject: [PATCH 4/7] :white_check_mark: add Response equatability test --- chopper/test/equatable_test.dart | 97 +++++++++++++++++++ .../test/fixtures/http_response_fixture.dart | 29 ++++++ chopper/test/fixtures/payload_fixture.dart | 19 ++++ chopper/test/fixtures/response_fixture.dart | 29 ++++++ .../test/helpers/http_response_extension.dart | 21 ++++ chopper/test/helpers/payload.dart | 27 ++++++ 6 files changed, 222 insertions(+) create mode 100644 chopper/test/fixtures/http_response_fixture.dart create mode 100644 chopper/test/fixtures/payload_fixture.dart create mode 100644 chopper/test/fixtures/response_fixture.dart create mode 100644 chopper/test/helpers/http_response_extension.dart create mode 100644 chopper/test/helpers/payload.dart diff --git a/chopper/test/equatable_test.dart b/chopper/test/equatable_test.dart index ad4da81f..8259ea90 100644 --- a/chopper/test/equatable_test.dart +++ b/chopper/test/equatable_test.dart @@ -1,8 +1,15 @@ +import 'dart:convert' show jsonEncode; + import 'package:chopper/chopper.dart'; import 'package:faker/faker.dart'; +import 'package:http/http.dart' as http; import 'package:test/test.dart'; +import 'fixtures/http_response_fixture.dart' as http_fixture; +import 'fixtures/payload_fixture.dart'; import 'fixtures/request_fixture.dart'; +import 'fixtures/response_fixture.dart'; +import 'helpers/payload.dart'; void main() { final Faker faker = Faker(); @@ -92,4 +99,94 @@ void main() { ), ); }); + + group('Response', () { + late Payload payload; + late Response response; + + setUp(() { + payload = PayloadFixture.factory.makeSingle(); + response = ResponseFixture.factory() + .redefine(ResponseFixture.factory().body(payload)) + .makeSingle(); + }); + + test('should return true when comparing two identical objects', () { + final http.Response base = http_fixture.ResponseFixture.factory + .redefine( + http_fixture.ResponseFixture.factory.body( + jsonEncode(payload), + ), + ) + .makeSingle(); + + expect( + Response(base, payload), + equals( + Response(base, payload), + ), + ); + }); + + test( + 'should return true when comparing original with copy', + () => expect( + response, + equals( + response.copyWith(), + ), + ), + ); + + test( + 'should return false when comparing two different objects', + () => expect( + response, + isNot( + equals( + ResponseFixture.factory() + .redefine(ResponseFixture.factory() + .body(PayloadFixture.factory.makeSingle())) + .makeSingle(), + ), + ), + ), + ); + + test( + 'should return false when comparing to null', + () => expect( + response, + isNot( + equals(null), + ), + ), + ); + + test( + 'should return false when comparing to an object of a different type', + () { + expect( + response, + isNot( + equals(faker.lorem.word()), + ), + ); + }, + ); + + test( + 'should return false when comparing to an object with different props', + () => expect( + response, + isNot( + equals( + response.copyWith( + body: PayloadFixture.factory.makeSingle(), + ), + ), + ), + ), + ); + }); } diff --git a/chopper/test/fixtures/http_response_fixture.dart b/chopper/test/fixtures/http_response_fixture.dart new file mode 100644 index 00000000..6b6b6071 --- /dev/null +++ b/chopper/test/fixtures/http_response_fixture.dart @@ -0,0 +1,29 @@ +import 'dart:convert' show jsonEncode; + +import 'package:data_fixture_dart/data_fixture_dart.dart'; +import 'package:http/http.dart' as http; +import 'package:meta/meta.dart'; + +import '../helpers/http_response_extension.dart'; +import 'payload_fixture.dart'; + +extension ResponseFixture on http.Response { + static ResponseFactory get factory => ResponseFactory(); +} + +@internal +class ResponseFactory extends FixtureFactory { + @override + FixtureDefinition definition() => define( + (Faker faker) => http.Response( + jsonEncode(PayloadFixture.factory.makeSingle().toJson()), + 200, + ), + ); + + FixtureRedefinitionBuilder body(String? body) => + (http.Response response) => response.copyWith(body: body); + + FixtureRedefinitionBuilder statusCode(int? statusCode) => + (http.Response response) => response.copyWith(statusCode: statusCode); +} diff --git a/chopper/test/fixtures/payload_fixture.dart b/chopper/test/fixtures/payload_fixture.dart new file mode 100644 index 00000000..435883cf --- /dev/null +++ b/chopper/test/fixtures/payload_fixture.dart @@ -0,0 +1,19 @@ +import 'package:data_fixture_dart/data_fixture_dart.dart'; +import 'package:meta/meta.dart'; + +import '../helpers/payload.dart'; + +extension PayloadFixture on Payload { + static PayloadFactory get factory => PayloadFactory(); +} + +@internal +class PayloadFactory extends FixtureFactory { + @override + FixtureDefinition definition() => define( + (Faker faker) => Payload( + statusCode: 200, + message: faker.lorem.sentence(), + ), + ); +} diff --git a/chopper/test/fixtures/response_fixture.dart b/chopper/test/fixtures/response_fixture.dart new file mode 100644 index 00000000..cd604e4f --- /dev/null +++ b/chopper/test/fixtures/response_fixture.dart @@ -0,0 +1,29 @@ +import 'package:chopper/chopper.dart' show Response; +import 'package:data_fixture_dart/data_fixture_dart.dart'; +import 'package:http/http.dart' as http; +import 'package:meta/meta.dart'; + +import 'http_response_fixture.dart' as http_fixture; + +extension ResponseFixture on Response { + static ResponseFixtureFactory factory() => ResponseFixtureFactory(); +} + +@internal +class ResponseFixtureFactory extends FixtureFactory> { + @override + FixtureDefinition> definition() { + final http.Response base = + http_fixture.ResponseFixture.factory.makeSingle(); + + return define( + (Faker faker) => Response(base, null), + ); + } + + FixtureRedefinitionBuilder> body(T? body) => + (Response response) => response.copyWith(body: body); + + FixtureRedefinitionBuilder> error(Object? value) => + (Response response) => response.copyWith(bodyError: value); +} diff --git a/chopper/test/helpers/http_response_extension.dart b/chopper/test/helpers/http_response_extension.dart new file mode 100644 index 00000000..17094acf --- /dev/null +++ b/chopper/test/helpers/http_response_extension.dart @@ -0,0 +1,21 @@ +import 'package:http/http.dart' as http; + +extension HttpResponseExtension on http.Response { + http.Response copyWith({ + String? body, + int? statusCode, + Map? headers, + bool? isRedirect, + bool? persistentConnection, + String? reasonPhrase, + }) => + http.Response( + body ?? this.body, + statusCode ?? this.statusCode, + request: request, + headers: headers ?? this.headers, + reasonPhrase: reasonPhrase ?? this.reasonPhrase, + isRedirect: isRedirect ?? this.isRedirect, + persistentConnection: persistentConnection ?? this.persistentConnection, + ); +} diff --git a/chopper/test/helpers/payload.dart b/chopper/test/helpers/payload.dart new file mode 100644 index 00000000..4c4ea8a3 --- /dev/null +++ b/chopper/test/helpers/payload.dart @@ -0,0 +1,27 @@ +import 'package:equatable/equatable.dart'; + +class Payload with EquatableMixin { + const Payload({ + this.statusCode = 200, + this.message = 'OK', + }); + + final int statusCode; + final String message; + + factory Payload.fromJson(Map json) => Payload( + statusCode: json['statusCode'] as int? ?? 200, + message: json['message'] as String? ?? 'OK', + ); + + Map toJson() => { + 'statusCode': statusCode, + 'message': message, + }; + + @override + List get props => [ + statusCode, + message, + ]; +} From ca41a1391738ceead7048125ab9247b0356f21e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klemen=20Tu=C5=A1ar?= Date: Sun, 19 Feb 2023 20:00:43 +0000 Subject: [PATCH 5/7] :fire: Remove some obsolete equatables --- chopper/lib/src/http_logging_interceptor.dart | 5 ----- chopper/lib/src/interceptor.dart | 6 +----- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/chopper/lib/src/http_logging_interceptor.dart b/chopper/lib/src/http_logging_interceptor.dart index a9726920..0be43965 100644 --- a/chopper/lib/src/http_logging_interceptor.dart +++ b/chopper/lib/src/http_logging_interceptor.dart @@ -4,7 +4,6 @@ import 'package:chopper/src/interceptor.dart'; import 'package:chopper/src/request.dart'; import 'package:chopper/src/response.dart'; import 'package:chopper/src/utils.dart'; -import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; @@ -71,7 +70,6 @@ enum Level { /// or in a non-production environment. @immutable class HttpLoggingInterceptor - with EquatableMixin implements RequestInterceptor, ResponseInterceptor { const HttpLoggingInterceptor({this.level = Level.body}) : _logBody = level == Level.body, @@ -172,7 +170,4 @@ class HttpLoggingInterceptor return response; } - - @override - List get props => [level]; } diff --git a/chopper/lib/src/interceptor.dart b/chopper/lib/src/interceptor.dart index f46eec11..0e123237 100644 --- a/chopper/lib/src/interceptor.dart +++ b/chopper/lib/src/interceptor.dart @@ -5,7 +5,6 @@ import 'package:chopper/src/constants.dart'; import 'package:chopper/src/request.dart'; import 'package:chopper/src/response.dart'; import 'package:chopper/src/utils.dart'; -import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; @@ -106,7 +105,7 @@ abstract class ErrorConverter { /// Note that this interceptor will overwrite existing headers having the same /// keys as [headers]. @immutable -class HeadersInterceptor with EquatableMixin implements RequestInterceptor { +class HeadersInterceptor implements RequestInterceptor { final Map headers; const HeadersInterceptor(this.headers); @@ -114,9 +113,6 @@ class HeadersInterceptor with EquatableMixin implements RequestInterceptor { @override Future onRequest(Request request) async => applyHeaders(request, headers); - - @override - List get props => [headers]; } typedef ResponseInterceptorFunc1 = FutureOr> From b1e4db6a117116e070e9578c4696184549020b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klemen=20Tu=C5=A1ar?= Date: Sun, 19 Feb 2023 21:26:11 +0000 Subject: [PATCH 6/7] :fire: Remove some obsolete equatables --- chopper/lib/src/base.dart | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/chopper/lib/src/base.dart b/chopper/lib/src/base.dart index b44079a3..4fa556c2 100644 --- a/chopper/lib/src/base.dart +++ b/chopper/lib/src/base.dart @@ -7,7 +7,6 @@ import 'package:chopper/src/interceptor.dart'; import 'package:chopper/src/request.dart'; import 'package:chopper/src/response.dart'; import 'package:chopper/src/utils.dart'; -import 'package:equatable/equatable.dart' show EquatableMixin; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; @@ -27,7 +26,7 @@ final List allowedInterceptorsType = [ /// /// It manages registered services, encodes and decodes data, and intercepts /// requests and responses. -class ChopperClient with EquatableMixin { +class ChopperClient { /// Base URL of each request of the registered services. /// E.g., the hostname of your service. final Uri baseUrl; @@ -516,19 +515,6 @@ class ChopperClient with EquatableMixin { /// A stream of processed [Response]s, as in after all [Converter]s and /// [ResponseInterceptor]s have been run. Stream get onResponse => _responseController.stream; - - @override - List get props => [ - baseUrl, - httpClient, - _clientIsInternal, - _requestInterceptors, - _responseInterceptors, - authenticator, - converter, - errorConverter, - _services, - ]; } /// A marker and helper class used by `chopper_generator` to generate network From c047118c320d2dc0fedf0c18a011a1fdb4b93753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klemen=20Tu=C5=A1ar?= Date: Sun, 19 Feb 2023 21:47:26 +0000 Subject: [PATCH 7/7] :white_check_mark: add PartValue equatability test --- chopper/test/equatable_test.dart | 78 ++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/chopper/test/equatable_test.dart b/chopper/test/equatable_test.dart index 8259ea90..7bdebeae 100644 --- a/chopper/test/equatable_test.dart +++ b/chopper/test/equatable_test.dart @@ -189,4 +189,82 @@ void main() { ), ); }); + + group('PartValue', () { + late PartValue partValue; + + setUp(() { + partValue = PartValue( + faker.lorem.word(), + faker.lorem.word(), + ); + }); + + test('should return true when comparing two identical objects', () { + expect( + PartValue('foo', 'bar'), + equals( + PartValue('foo', 'bar'), + ), + ); + }); + + test( + 'should return true when comparing original with copy', + () => expect( + partValue, + equals( + partValue.copyWith(), + ), + ), + ); + + test( + 'should return false when comparing two different objects', + () => expect( + partValue, + isNot( + equals( + PartValue('bar', 'baz'), + ), + ), + ), + ); + + test( + 'should return false when comparing to null', + () => expect( + partValue, + isNot( + equals(null), + ), + ), + ); + + test( + 'should return false when comparing to an object of a different type', + () { + expect( + partValue, + isNot( + equals(faker.lorem.word()), + ), + ); + }, + ); + + test( + 'should return false when comparing to an object with different props', + () => expect( + partValue, + isNot( + equals( + partValue.copyWith( + value: 'bar', + ), + ), + ), + ), + ); + }); }