Skip to content

Commit

Permalink
♻️ refactor ChopperClient constructor (#461)
Browse files Browse the repository at this point in the history
  • Loading branch information
techouse authored Aug 2, 2023
1 parent aa63283 commit a386e86
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 34 deletions.
62 changes: 33 additions & 29 deletions chopper/lib/src/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ base class ChopperClient {
/// (statusCode < 200 || statusCode >= 300\).
final ErrorConverter? errorConverter;

final Map<Type, ChopperService> _services = {};
final _requestInterceptors = [];
final _responseInterceptors = [];
final _requestController = StreamController<Request>.broadcast();
final _responseController = StreamController<Response>.broadcast();
late final Map<Type, ChopperService> _services;
late final List _requestInterceptors;
late final List _responseInterceptors;
final StreamController<Request> _requestController =
StreamController<Request>.broadcast();
final StreamController<Response> _responseController =
StreamController<Response>.broadcast();

final bool _clientIsInternal;

Expand Down Expand Up @@ -112,44 +114,46 @@ base class ChopperClient {
ChopperClient({
Uri? baseUrl,
http.Client? client,
Iterable interceptors = const [],
Iterable? interceptors,
this.authenticator,
this.converter,
this.errorConverter,
Iterable<ChopperService> services = const [],
Iterable<ChopperService>? services,
}) : assert(
baseUrl == null || !baseUrl.hasQuery,
'baseUrl should not contain query parameters.'
'Use a request interceptor to add default query parameters'),
baseUrl == null || !baseUrl.hasQuery,
'baseUrl should not contain query parameters. '
'Use a request interceptor to add default query parameters',
),
baseUrl = baseUrl ?? Uri(),
httpClient = client ?? http.Client(),
_clientIsInternal = client == null {
if (!interceptors.every(_isAnInterceptor)) {
throw ArgumentError(
'Unsupported type for interceptors, it only support the following types:\n'
'${allowedInterceptorsType.join('\n - ')}',
);
}

_requestInterceptors.addAll(interceptors.where(_isRequestInterceptor));
_responseInterceptors.addAll(interceptors.where(_isResponseInterceptor));

services.toSet().forEach((s) {
s.client = this;
_services[s.definitionType] = s;
});
_clientIsInternal = client == null,
assert(
interceptors?.every(_isAnInterceptor) ?? true,
'Unsupported type for interceptors, it only support the following types:\n'
' - ${allowedInterceptorsType.join('\n - ')}',
),
_requestInterceptors = [
...?interceptors?.where(_isRequestInterceptor),
],
_responseInterceptors = [
...?interceptors?.where(_isResponseInterceptor),
] {
_services = <Type, ChopperService>{
for (final ChopperService service in services?.toSet() ?? [])
service.definitionType: service..client = this
};
}

bool _isRequestInterceptor(value) =>
static bool _isRequestInterceptor(value) =>
value is RequestInterceptor || value is RequestInterceptorFunc;

bool _isResponseInterceptor(value) =>
static bool _isResponseInterceptor(value) =>
value is ResponseInterceptor ||
value is ResponseInterceptorFunc1 ||
value is ResponseInterceptorFunc2 ||
value is DynamicResponseInterceptorFunc;

bool _isAnInterceptor(value) =>
static bool _isAnInterceptor(value) =>
_isResponseInterceptor(value) || _isRequestInterceptor(value);

/// Retrieve any service included in the [ChopperClient]
Expand Down Expand Up @@ -182,7 +186,7 @@ base class ChopperClient {
Future<Request> _encodeRequest(Request request) async =>
converter?.convertRequest(request) ?? request;

Future<Response<BodyType>> _decodeResponse<BodyType, InnerType>(
static Future<Response<BodyType>> _decodeResponse<BodyType, InnerType>(
Response response,
Converter withConverter,
) async =>
Expand Down
40 changes: 35 additions & 5 deletions chopper/test/base_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -647,20 +647,50 @@ void main() {
});

test('wrong type for interceptor', () {
expect(
() => ChopperClient(interceptors: [(bool foo) => 'bar']),
throwsA(isA<AssertionError>()),
);

try {
ChopperClient(
interceptors: [
(bool foo) => 'bar',
],
);
} on ArgumentError catch (e) {
} on AssertionError catch (error) {
expect(
e.toString(),
'Invalid argument(s): Unsupported type for interceptors, it only support the following types:\n'
'${allowedInterceptorsType.join('\n - ')}',
error.toString(),
contains(
'Unsupported type for interceptors, it only support the following types:\n'
' - ${allowedInterceptorsType.join('\n - ')}',
),
);
}
});
}, testOn: 'vm');

test('wrong type for interceptor', () {
expect(
() => ChopperClient(interceptors: [(bool foo) => 'bar']),
throwsA(isA<AssertionError>()),
);

try {
ChopperClient(
interceptors: [
(bool foo) => 'bar',
],
);
} on AssertionError catch (error) {
expect(
error.toString(),
contains(
'Unsupported type for interceptors, it only support the following types:\\n'
' - ${allowedInterceptorsType.join('\\n - ')}',
),
);
}
}, testOn: 'browser');

test('Query Map 1', () async {
final httpClient = MockClient((request) async {
Expand Down

0 comments on commit a386e86

Please sign in to comment.