From 857eb4de2bb28eebabdeae3dca15f36cbaa55aa7 Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 18:35:25 -0500 Subject: [PATCH 1/9] feat(package): Update connectivity_plus plugin and related checks Updated the connectivity plugin to a newer version. Adjusted network status check to handle multiple results instead of a single one. Updated SDK and Flutter versions in pubspec.yaml file. Adapted tests to reflect these changes. --- example/macos/Flutter/GeneratedPluginRegistrant.swift | 2 +- lib/src/exception_handler/dio/exception_handler_dio.dart | 5 +++-- pubspec.yaml | 8 ++++---- .../dio/dio_http_response_extension_test.dart | 2 +- .../exception_handler/dio/exception_handler_dio_test.dart | 8 ++++---- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index c62a8be..ad535f5 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,5 +8,5 @@ import Foundation import connectivity_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) } diff --git a/lib/src/exception_handler/dio/exception_handler_dio.dart b/lib/src/exception_handler/dio/exception_handler_dio.dart index 45322d8..2100449 100644 --- a/lib/src/exception_handler/dio/exception_handler_dio.dart +++ b/lib/src/exception_handler/dio/exception_handler_dio.dart @@ -177,9 +177,10 @@ class DioExceptionHandler implements ClientExceptionHandler { /// _isConnected checks the current network connectivity status. static Future _isConnected() async { - final ConnectivityResult result = await connectivity.checkConnectivity(); + final List result = + await connectivity.checkConnectivity(); - return result != ConnectivityResult.none; + return !result.contains(ConnectivityResult.none); } /// _handleHttpResponse processes the HTTP response and handles different diff --git a/pubspec.yaml b/pubspec.yaml index 2f5276d..24de8fb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,14 +1,14 @@ name: exception_handler description: A Dart package for streamlined API handling and robust exception management in Flutter apps. -version: 2.0.2 +version: 3.0.0 homepage: "https://github.com/andgar2010/exception_handler" environment: - sdk: '>=3.0.0 <4.0.0' - flutter: ">=3.10.0" + sdk: '>=3.3.0 <4.0.0' + flutter: ">=3.19.0" dependencies: - connectivity_plus: ^5.0.2 + connectivity_plus: ^6.0.1 dio: ^5.4.1 equatable: ^2.0.5 http_exception: ^2.0.0 diff --git a/test/src/exception_handler/dio/dio_http_response_extension_test.dart b/test/src/exception_handler/dio/dio_http_response_extension_test.dart index 830090b..d7b17e7 100644 --- a/test/src/exception_handler/dio/dio_http_response_extension_test.dart +++ b/test/src/exception_handler/dio/dio_http_response_extension_test.dart @@ -55,7 +55,7 @@ void main() { mockConnectivity = MockConnectivity(); DioExceptionHandler.connectivity = mockConnectivity; when(() => mockConnectivity.checkConnectivity()) - .thenAnswer((_) async => ConnectivityResult.mobile); + .thenAnswer((final _) async => [ConnectivityResult.mobile]); }); group('fromJson', () { diff --git a/test/src/exception_handler/dio/exception_handler_dio_test.dart b/test/src/exception_handler/dio/exception_handler_dio_test.dart index 3410a47..8b01f3b 100644 --- a/test/src/exception_handler/dio/exception_handler_dio_test.dart +++ b/test/src/exception_handler/dio/exception_handler_dio_test.dart @@ -99,7 +99,7 @@ void main() { .thenThrow(DioException(requestOptions: RequestOptions())); when(() => mockConnectivity.checkConnectivity()) - .thenAnswer((_) async => ConnectivityResult.none); + .thenAnswer((final _) async => [ConnectivityResult.none]); final result = await DioExceptionHandler.callApi_(mockApiHandler); @@ -386,7 +386,7 @@ void main() { ); when(() => mockConnectivity.checkConnectivity()) - .thenAnswer((_) async => ConnectivityResult.wifi); + .thenAnswer((final _) async => [ConnectivityResult.wifi]); final ResultState result = await DioExceptionHandler.callApi_(mockApiHandler); @@ -416,7 +416,7 @@ void main() { ); when(() => mockConnectivity.checkConnectivity()) - .thenAnswer((_) async => ConnectivityResult.wifi); + .thenAnswer((final _) async => [ConnectivityResult.wifi]); final ResultState result = await DioExceptionHandler.callApi_(mockApiHandler); @@ -446,7 +446,7 @@ void main() { ); when(() => mockConnectivity.checkConnectivity()) - .thenAnswer((_) async => ConnectivityResult.wifi); + .thenAnswer((final _) async => [ConnectivityResult.wifi]); final ResultState result = await DioExceptionHandler.callApi_(mockApiHandler); From cfade06b7a92bf30cc875affc25fd5f1f2532751 Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 18:36:35 -0500 Subject: [PATCH 2/9] refactor(analysis_options): Update linter rules and metrics Updated several linter rules for better code quality. Enabled previously commented out linting rules, added new ones, and removed some unnecessary ones. Also enabled the metrics section with specific complexity parameters. --- analysis_options.yaml | 52 +++++++++-------- ...ent.dart => client_exception_handler.dart} | 8 +-- lib/src/exception_handler/dio/dio.dart | 2 +- .../dio/dio_http_response_extension.dart | 14 ++--- .../dio/exception_handler_dio.dart | 30 +++++----- ...ptions_state.dart => exception_state.dart} | 31 +++++----- lib/src/result_state/result_state.dart | 2 +- lib/src/src.dart | 4 +- lib/src/utils/custom_equatable.dart | 8 +-- lib/src/utils/isolates/_isolates_io.dart | 4 +- lib/src/utils/isolates/_isolates_web.dart | 4 +- lib/src/utils/isolates/isolates.dart | 6 +- test/mocks.dart | 2 +- .../dio/dio_http_response_extension_test.dart | 58 +++++++++++-------- .../dio/exception_handler_dio_test.dart | 41 ++++++------- test/src/exception_handler/typedef_test.dart | 5 +- 16 files changed, 144 insertions(+), 127 deletions(-) rename lib/src/exception_handler/{exception_handler_client.dart => client_exception_handler.dart} (77%) rename lib/src/exception_state/{exceptions_state.dart => exception_state.dart} (88%) diff --git a/analysis_options.yaml b/analysis_options.yaml index 56f2547..cf0b46b 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -12,6 +12,10 @@ analyzer: implicit-casts: false implicit-dynamic: false + exclude: + - lib/**/*.g.dart + - lib/generated/*.g.dart + # Lint rules and documentation, see http://dart-lang.github.io/linter/lints linter: rules: @@ -33,7 +37,7 @@ linter: # - always_specify_types # More disbuting - avoid_annotating_with_dynamic - avoid_bool_literals_in_conditional_expressions - # - avoid_catching_errors # tempory disabled because working validation + - avoid_catching_errors # tempory disabled because working validation - avoid_classes_with_only_static_members - avoid_double_and_int_checks - avoid_field_initializers_in_const_classes @@ -64,7 +68,10 @@ linter: - prefer_const_literals_to_create_immutables - prefer_constructors_over_static_methods - prefer_expression_function_bodies + - prefer_final_fields + - prefer_final_in_for_each - prefer_final_locals + - prefer_final_parameters - prefer_foreach - prefer_single_quotes # - public_member_api_docs # TODO: Update Docs @@ -87,10 +94,10 @@ dart_code_linter: # - package:dart_code_linter/presets/all.yaml # - package:dart_code_linter/presets/intl.yaml - # metrics: - # cyclomatic-complexity: 20 - # number-of-parameters: 4 - # maximum-nesting-level: 5 + metrics: + cyclomatic-complexity: 20 + number-of-parameters: 4 + maximum-nesting-level: 5 metrics-exclude: - test/** @@ -109,23 +116,20 @@ dart_code_linter: - did-change-dependencies-method - did-update-widget-method - dispose-method - # - format-comment: true - - no-magic-number: - allowed: [0, 2, 100, 200, 300, 400, 401, 402, 403, 404, 500, 501, 600] - # - allow-only-once: true + - format-comment: true # - avoid-dynamic: true - # - avoid-passing-async-when-sync-expected: true - # - avoid-redundant-async: true - # - avoid-unnecessary-type-assertions: true - # - avoid-unnecessary-type-casts: true - # - avoid-unrelated-type-assertions: true - # - avoid-unused-parameters: true - # - avoid-nested-conditional-expressions: true - # - newline-before-return: true - # - no-boolean-literal-compare: true - # - no-empty-block: true - # - prefer-trailing-comma: true - # - prefer-conditional-expressions: true - # - no-equal-then-else: true - # - prefer-moving-to-variable: true - # - prefer-match-file-name: true \ No newline at end of file + - avoid-passing-async-when-sync-expected: true + - avoid-redundant-async: true + - avoid-unnecessary-type-assertions: true + - avoid-unnecessary-type-casts: true + - avoid-unrelated-type-assertions: true + - avoid-unused-parameters: true + - avoid-nested-conditional-expressions: true + - newline-before-return: true + - no-boolean-literal-compare: true + - no-empty-block: true + - prefer-trailing-comma: true + - prefer-conditional-expressions: true + - no-equal-then-else: true + - prefer-moving-to-variable: true + - prefer-match-file-name: true diff --git a/lib/src/exception_handler/exception_handler_client.dart b/lib/src/exception_handler/client_exception_handler.dart similarity index 77% rename from lib/src/exception_handler/exception_handler_client.dart rename to lib/src/exception_handler/client_exception_handler.dart index 7b62271..46cb425 100644 --- a/lib/src/exception_handler/exception_handler_client.dart +++ b/lib/src/exception_handler/client_exception_handler.dart @@ -16,16 +16,16 @@ abstract class ClientExceptionHandler { /// ExceptionState and parsed data. /// Future> callApi( - ApiHandler apiHandler, { - HandleHttpParseResponse? handleHttpParseResponse, + final ApiHandler apiHandler, { + final HandleHttpParseResponse? handleHttpParseResponse, }); /// Method [callApi] is a generic method to handle API calls and return a tuple of /// ExceptionState and parsed data. /// static Future> callApi_( - ApiHandler apiHandler, { - HandleHttpParseResponse? handleHttpParseResponse, + final ApiHandler apiHandler, { + final HandleHttpParseResponse? handleHttpParseResponse, }) async { throw UnimplementedError(); } diff --git a/lib/src/exception_handler/dio/dio.dart b/lib/src/exception_handler/dio/dio.dart index 39044e6..04afd57 100644 --- a/lib/src/exception_handler/dio/dio.dart +++ b/lib/src/exception_handler/dio/dio.dart @@ -2,5 +2,5 @@ // All rights reserved. Use of this source code // is governed by a Apache-2.0 license that can be found in the LICENSE file. -export 'dio_http_response_extension.dart'; export 'exception_handler_dio.dart'; +export 'dio_http_response_extension.dart'; diff --git a/lib/src/exception_handler/dio/dio_http_response_extension.dart b/lib/src/exception_handler/dio/dio_http_response_extension.dart index d891ed7..36b3040 100644 --- a/lib/src/exception_handler/dio/dio_http_response_extension.dart +++ b/lib/src/exception_handler/dio/dio_http_response_extension.dart @@ -8,7 +8,7 @@ import '../../../exception_handler.dart'; /// An extension on `Future` providing methods for handling Dio HTTP responses and converting them /// into [ResultState] or [ResultState>] types. -extension HttpResponseDioExtension on Future> { +extension DioHttpResponseExtension on Future> { /// Converts a Dio HTTP response into an [ResultState] type using /// a custom `fromJson` method. /// @@ -87,12 +87,13 @@ extension HttpResponseDioExtension on Future> { /// ``` /// Future> fromJson( - TModel Function(Map) fromJson, + final TModel Function(Map) fromJson, ) async => await DioExceptionHandler.callApi_, TModel>( ApiHandler( apiCall: () => this, // Same: response = dio.get('https://'). - parserModel: (Object? data) => fromJson(data as Map), + parserModel: (final Object? data) => + fromJson(data as Map), ), ); @@ -173,14 +174,13 @@ extension HttpResponseDioExtension on Future> { /// } /// ``` Future>> fromJsonAsList( - TModel Function(Map) fromJson, + final TModel Function(Map) fromJson, ) async => await DioExceptionHandler.callApi_, List>( ApiHandler( apiCall: () => this, // Same: response = dio.get('https://'). - parserModel: (Object? data) => (data as List>) - .map((item) => fromJson(item)) - .toList(), + parserModel: (final Object? data) => + (data as List>).map(fromJson).toList(), ), ); } diff --git a/lib/src/exception_handler/dio/exception_handler_dio.dart b/lib/src/exception_handler/dio/exception_handler_dio.dart index 2100449..9cb8a8f 100644 --- a/lib/src/exception_handler/dio/exception_handler_dio.dart +++ b/lib/src/exception_handler/dio/exception_handler_dio.dart @@ -16,8 +16,8 @@ import '../../../exception_handler.dart'; /// any parsing exceptions. /// Future> handleHttpGenericParseResponseDio( - int statusCode, - ResponseParser responseParser, + final int statusCode, + final ResponseParser responseParser, ) async { try { return FailureState( @@ -48,7 +48,7 @@ Future> handleHttpGenericParseResponseDio( /// Method [handleHttp2xxParseResponseDio] tries to parse the response and handle /// any parsing exceptions. Future> handleHttp2xxParseResponseDio( - ResponseParser, TModel> responseParser, + final ResponseParser, TModel> responseParser, ) async { try { final TModel dataModelParsed = await compute( @@ -59,7 +59,7 @@ Future> handleHttp2xxParseResponseDio( return SuccessState(dataModelParsed); } catch (e) { try { - // TODO(andgar2010): need more investigation about compute error on platform windows + // TODO(andgar2010): need more investigation about compute error on platform windows. log( ''' Handle error compute. @@ -123,8 +123,8 @@ class DioExceptionHandler implements ClientExceptionHandler { /// {@endtemplate} @override Future> callApi( - ApiHandler apiHandler, { - HandleHttpParseResponse? handleHttpParseResponse, + final ApiHandler apiHandler, { + final HandleHttpParseResponse? handleHttpParseResponse, }) async { handleParseResponse_ = handleHttpParseResponse ?? HandleHttpParseResponse, TModel>( @@ -167,9 +167,9 @@ class DioExceptionHandler implements ClientExceptionHandler { /// {@macro DioExceptionHandler_callApi_} static Future> callApi_( - ApiHandler apiHandler, { - HandleHttpParseResponse? handleHttpParseResponse, - }) async => + final ApiHandler apiHandler, { + final HandleHttpParseResponse? handleHttpParseResponse, + }) => DioExceptionHandler().callApi( apiHandler, handleHttpParseResponse: handleHttpParseResponse, @@ -186,7 +186,7 @@ class DioExceptionHandler implements ClientExceptionHandler { /// _handleHttpResponse processes the HTTP response and handles different /// status codes. static Future> _handleHttpResponse( - ResponseParser, TModel> responseParser, + final ResponseParser, TModel> responseParser, ) async { final int? statusCode = responseParser.response.statusCode; @@ -194,8 +194,8 @@ class DioExceptionHandler implements ClientExceptionHandler { } static Future> _handleStatusCode( - int? statusCode, - ResponseParser, TModel> responseParser, + final int? statusCode, + final ResponseParser, TModel> responseParser, ) async => // coverage:ignore-start switch (statusCode) { @@ -234,8 +234,8 @@ class DioExceptionHandler implements ClientExceptionHandler { /// _handleDioException handles exceptions from the Dio library, /// particularly around connectivity. static Future> _handleDioException( - DioException e, - StackTrace s, + final DioException e, + final StackTrace s, ) async { const String start = 'This exception was thrown because the response has a status code of '; @@ -250,7 +250,7 @@ class DioExceptionHandler implements ClientExceptionHandler { ResponseParser( response: Response(requestOptions: RequestOptions()), // coverage:ignore-start - parserModel: (_) => Object() as TModel, + parserModel: (final _) => Object() as TModel, // coverage:ignore-end exception: e, stackTrace: s, diff --git a/lib/src/exception_state/exceptions_state.dart b/lib/src/exception_state/exception_state.dart similarity index 88% rename from lib/src/exception_state/exceptions_state.dart rename to lib/src/exception_state/exception_state.dart index da5304a..19aac1b 100644 --- a/lib/src/exception_state/exceptions_state.dart +++ b/lib/src/exception_state/exception_state.dart @@ -32,8 +32,8 @@ sealed class ExceptionState extends CustomEquatable /// the exception. class DataClientExceptionState extends ExceptionState { DataClientExceptionState({ - required String message, - required StackTrace stackTrace, + required final String message, + required final StackTrace stackTrace, }) : super(message: message, stackTrace: stackTrace) { log( 'Client exception captured:', @@ -44,7 +44,8 @@ class DataClientExceptionState extends ExceptionState { } @override - Map get namedProps => {'clientException': message}; + Map get namedProps => + {'clientException': message}; } /// [DataParseExceptionState] handles exceptions related to parsing issues @@ -55,8 +56,8 @@ class DataClientExceptionState extends ExceptionState { /// the exception. class DataParseExceptionState extends ExceptionState { DataParseExceptionState({ - required StackTrace stackTrace, - String message = 'Error parsing data.', + required final StackTrace stackTrace, + final String message = 'Error parsing data.', }) : super(message: message, stackTrace: stackTrace) { log( 'Unable to parse the json:', @@ -78,8 +79,8 @@ class DataParseExceptionState extends ExceptionState { class DataHttpExceptionState extends ExceptionState { DataHttpExceptionState({ required this.httpException, - required StackTrace stackTrace, - String? message, + required final StackTrace stackTrace, + final String? message, }) : super( message: message ?? '', stackTrace: stackTrace, @@ -107,8 +108,8 @@ class DataHttpExceptionState extends ExceptionState { /// the exception. class DataNetworkExceptionState extends ExceptionState { DataNetworkExceptionState({ - required StackTrace stackTrace, - String message = 'A network error occurred.', + required final StackTrace stackTrace, + final String message = 'A network error occurred.', }) : super(message: message, stackTrace: stackTrace) { log( 'Network exception captured:', @@ -130,8 +131,8 @@ class DataNetworkExceptionState extends ExceptionState { /// the exception. class DataCacheExceptionState extends ExceptionState { DataCacheExceptionState({ - required StackTrace stackTrace, - String message = 'A cache error occurred.', + required final StackTrace stackTrace, + final String message = 'A cache error occurred.', }) : super(message: message, stackTrace: stackTrace) { log( 'Cache exception captured:', @@ -153,8 +154,8 @@ class DataCacheExceptionState extends ExceptionState { /// the exception. class DataInvalidInputExceptionState extends ExceptionState { DataInvalidInputExceptionState({ - required StackTrace stackTrace, - String message = 'Invalid input provided.', + required final StackTrace stackTrace, + final String message = 'Invalid input provided.', }) : super(message: message, stackTrace: stackTrace) { log( 'Invalid Input exception captured:', @@ -176,8 +177,8 @@ class DataInvalidInputExceptionState extends ExceptionState { /// the exception. class DataUnknownExceptionState extends ExceptionState { DataUnknownExceptionState({ - required String message, - required StackTrace stackTrace, + required final String message, + required final StackTrace stackTrace, }) : super(message: message, stackTrace: stackTrace) { log( 'Unknown exception captured:', diff --git a/lib/src/result_state/result_state.dart b/lib/src/result_state/result_state.dart index 2cbb435..063a081 100644 --- a/lib/src/result_state/result_state.dart +++ b/lib/src/result_state/result_state.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code // is governed by a Apache-2.0 license that can be found in the LICENSE file. -import '../exception_state/exceptions_state.dart'; +import '../exception_state/exception_state.dart'; import '../utils/utils.dart'; /// An sealed base ResultState class diff --git a/lib/src/src.dart b/lib/src/src.dart index c1d990a..953fca3 100644 --- a/lib/src/src.dart +++ b/lib/src/src.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code // is governed by a Apache-2.0 license that can be found in the LICENSE file. -export 'exception_handler/exception_handler_client.dart'; -export 'exception_state/exceptions_state.dart'; +export 'exception_handler/client_exception_handler.dart'; +export 'exception_state/exception_state.dart'; export 'result_state/result_state.dart'; export 'utils/utils.dart'; diff --git a/lib/src/utils/custom_equatable.dart b/lib/src/utils/custom_equatable.dart index bdaae08..a7ccb30 100644 --- a/lib/src/utils/custom_equatable.dart +++ b/lib/src/utils/custom_equatable.dart @@ -4,7 +4,7 @@ import 'package:equatable/equatable.dart'; -import '../exception_state/exceptions_state.dart'; +import '../exception_state/exception_state.dart'; abstract class CustomEquatable extends Equatable { const CustomEquatable(); @@ -17,11 +17,11 @@ abstract class CustomEquatable extends Equatable { final String type = runtimeType.toString(); final String propList = namedProps.entries .map( - (MapEntry e) => (e.value is num || + (final MapEntry e) => (e.value is num || e.value is Exception || e.value is Enum || - e.value - is ExceptionState || // For internal exception handler. + // For internal exception handler. + e.value is ExceptionState || e.value == null) ? '${e.key}: ${e.value}' : e.value != null && e.value != '' diff --git a/lib/src/utils/isolates/_isolates_io.dart b/lib/src/utils/isolates/_isolates_io.dart index 9e5e306..5029627 100644 --- a/lib/src/utils/isolates/_isolates_io.dart +++ b/lib/src/utils/isolates/_isolates_io.dart @@ -15,8 +15,8 @@ export 'isolates.dart' show ComputeCallback; /// The dart:io implementation of [isolate.compute]. @pragma('vm:prefer-inline') Future compute( - isolates.ComputeCallback callback, - M message, { + final isolates.ComputeCallback callback, + final M message, { String? debugLabel, }) async { debugLabel ??= kReleaseMode ? 'compute' : callback.toString(); diff --git a/lib/src/utils/isolates/_isolates_web.dart b/lib/src/utils/isolates/_isolates_web.dart index 76ffbba..c137328 100644 --- a/lib/src/utils/isolates/_isolates_web.dart +++ b/lib/src/utils/isolates/_isolates_web.dart @@ -11,8 +11,8 @@ export 'isolates.dart' show ComputeCallback; /// The dart:html implementation of [isolate.compute]. @pragma('dart2js:tryInline') Future compute( - isolates.ComputeCallback callback, - M message, + final isolates.ComputeCallback callback, + final M message, ) async { // To avoid blocking the UI immediately for an expensive function call, we // pump a single frame to allow the framework to complete the current set diff --git a/lib/src/utils/isolates/isolates.dart b/lib/src/utils/isolates/isolates.dart index d24a9b9..50440c4 100644 --- a/lib/src/utils/isolates/isolates.dart +++ b/lib/src/utils/isolates/isolates.dart @@ -79,9 +79,9 @@ typedef ComputeImpl = Future Function( /// executes `callback`. [Timeline] events produced by that isolate will have /// the name associated with them. This is useful when profiling an application. Future compute( - ComputeCallback callback, - M message, { - String? debugLabel, + final ComputeCallback callback, + final M message, { + final String? debugLabel, }) { return isolates.compute(callback, message, debugLabel: debugLabel); } diff --git a/test/mocks.dart b/test/mocks.dart index 965d8f1..5fb3db2 100644 --- a/test/mocks.dart +++ b/test/mocks.dart @@ -26,7 +26,7 @@ class UserModel { this.website, }); - factory UserModel.fromJson(Map json) { + factory UserModel.fromJson(final Map json) { if (json case { 'id': final int? id, diff --git a/test/src/exception_handler/dio/dio_http_response_extension_test.dart b/test/src/exception_handler/dio/dio_http_response_extension_test.dart index d7b17e7..959daf7 100644 --- a/test/src/exception_handler/dio/dio_http_response_extension_test.dart +++ b/test/src/exception_handler/dio/dio_http_response_extension_test.dart @@ -14,7 +14,7 @@ class UserModel { required this.name, }); - factory UserModel.fromJson(Map json) => UserModel( + factory UserModel.fromJson(final Map json) => UserModel( id: json['id'] as int, name: json['name'] as String, ); @@ -27,7 +27,7 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); group('HttpResponseDioExtension', () { final requestOptions = - RequestOptions(path: '/data', validateStatus: (status) => true); + RequestOptions(path: '/data', validateStatus: (final status) => true); final data = {'id': 1, 'name': 'John Doe'}; @@ -37,8 +37,8 @@ void main() { ]; Future futureDioException( - DioExceptionType type, { - Response? response, + final DioExceptionType type, { + final Response? response, }) => Future.delayed( const Duration(microseconds: 10), @@ -262,8 +262,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != null), + requestOptions: RequestOptions( + validateStatus: (final status) => status != null, + ), statusCode: null, ), ); @@ -302,8 +303,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != 100), + requestOptions: RequestOptions( + validateStatus: (final status) => status != 100, + ), statusCode: 100, ), ); @@ -336,8 +338,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != 300), + requestOptions: RequestOptions( + validateStatus: (final status) => status != 300, + ), statusCode: 300, ), ); @@ -369,8 +372,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != 400), + requestOptions: RequestOptions( + validateStatus: (final status) => status != 400, + ), statusCode: 400, ), ); @@ -403,8 +407,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != 500), + requestOptions: RequestOptions( + validateStatus: (final status) => status != 500, + ), statusCode: 500, ), ); @@ -642,8 +647,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != null), + requestOptions: RequestOptions( + validateStatus: (final status) => status != null, + ), statusCode: null, ), ); @@ -682,8 +688,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != 100), + requestOptions: RequestOptions( + validateStatus: (final status) => status != 100, + ), statusCode: 100, ), ); @@ -715,8 +722,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != 300), + requestOptions: RequestOptions( + validateStatus: (final status) => status != 300, + ), statusCode: 300, ), ); @@ -748,8 +756,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != 400), + requestOptions: RequestOptions( + validateStatus: (final status) => status != 400, + ), statusCode: 400, ), ); @@ -781,8 +790,9 @@ void main() { final dioResponse = futureDioException( DioExceptionType.badResponse, response: Response>( - requestOptions: - RequestOptions(validateStatus: (status) => status != 500), + requestOptions: RequestOptions( + validateStatus: (final status) => status != 500, + ), statusCode: 500, ), ); diff --git a/test/src/exception_handler/dio/exception_handler_dio_test.dart b/test/src/exception_handler/dio/exception_handler_dio_test.dart index 8b01f3b..7a3685b 100644 --- a/test/src/exception_handler/dio/exception_handler_dio_test.dart +++ b/test/src/exception_handler/dio/exception_handler_dio_test.dart @@ -29,7 +29,7 @@ void main() { 'Successful API call returns parsed data', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), data: {'key': 'value'}, statusCode: 200, @@ -39,7 +39,8 @@ void main() { final ResultState result = await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (Object? data) => (data as Map)['key'] as String, + parserModel: (final Object? data) => + (data as Map)['key'] as String, ), ); @@ -61,7 +62,7 @@ void main() { 'API call with 401 status code returns unauthorized exception', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), statusCode: 401, ), @@ -70,7 +71,7 @@ void main() { final result = await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (Object? data) => data as String, + parserModel: (final Object? data) => data as String, ), ); @@ -122,7 +123,7 @@ void main() { final result = await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (Object? data) => data as String, + parserModel: (final Object? data) => data as String, ), ); @@ -145,7 +146,7 @@ void main() { 'API call with parsing error', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), data: 'Invalid data', statusCode: 200, @@ -155,7 +156,7 @@ void main() { final ResultState result = await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (Object? data) => int.parse(data as String) + parserModel: (final Object? data) => int.parse(data as String) .toString(), // Intentional parse error ), ); @@ -184,7 +185,7 @@ void main() { requestOptions: RequestOptions(path: ''), statusCode: 300, ), - parserModel: (res) => null, + parserModel: (final res) => null, ), ); @@ -206,7 +207,7 @@ void main() { 'should return FailureState with DataHttpException for 4xx error', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), statusCode: 400, ), @@ -215,7 +216,7 @@ void main() { await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (res) => null, + parserModel: (final res) => null, ), ); @@ -239,7 +240,7 @@ void main() { 'should return FailureState with DataHttpException for 404 error', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), statusCode: 404, ), @@ -248,7 +249,7 @@ void main() { await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (res) => null, + parserModel: (final res) => null, ), ); @@ -273,7 +274,7 @@ void main() { 'should return FailureState with DataHttpException for 500 error', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), statusCode: 500, ), @@ -282,7 +283,7 @@ void main() { await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (res) => null, + parserModel: (final res) => null, ), ); expect(result, isA>()); @@ -305,7 +306,7 @@ void main() { 'should return FailureState with DataHttpException for 501 error', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), statusCode: 501, ), @@ -314,7 +315,7 @@ void main() { await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (res) => null, + parserModel: (final res) => null, ), ); @@ -338,7 +339,7 @@ void main() { 'should return FailureState with DataHttpException for 600 error', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), statusCode: 600, ), @@ -347,7 +348,7 @@ void main() { await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (res) => null, + parserModel: (final res) => null, ), ); @@ -496,7 +497,7 @@ void main() { 'API call with unknown error', () async { when(() => mockDio.get(any())).thenAnswer( - (_) async => Response( + (final _) async => Response( requestOptions: RequestOptions(path: ''), data: 'Invalid data', statusCode: 200, @@ -506,7 +507,7 @@ void main() { final ResultState result = await DioExceptionHandler.callApi_( ApiHandler( apiCall: () => mockDio.get('test'), - parserModel: (Object? data) { + parserModel: (final Object? data) { throw Exception('Error Unknown'); // Intentional error }, ), diff --git a/test/src/exception_handler/typedef_test.dart b/test/src/exception_handler/typedef_test.dart index 3fe9cc3..e4cf635 100644 --- a/test/src/exception_handler/typedef_test.dart +++ b/test/src/exception_handler/typedef_test.dart @@ -14,7 +14,7 @@ void main() { statusCode: 200, requestOptions: RequestOptions(), ); - String mockParserModel(Object? data) => 'Parsed $data'; + String mockParserModel(final Object? data) => 'Parsed $data'; final handler = ApiHandler, String>( apiCall: mockApiCall, @@ -35,7 +35,8 @@ void main() { statusCode: 200, requestOptions: RequestOptions(), ); - String mockParserModel(Object? data) => (data as Map)['key'] as String; + String mockParserModel(final Object? data) => + (data as Map)['key'] as String; final parser = ResponseParser, String>( response: mockResponse, parserModel: mockParserModel, From b7fff1ec4c56389e90efcfdde47c5b549dc35817 Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 18:36:57 -0500 Subject: [PATCH 3/9] feat(dependencies): Update dio package version The dio package version in the dependencies has been updated from 5.4.1 to 5.4.2 for better performance and bug fixes. --- example/pubspec.lock | 34 +++++++++++++++++----------------- pubspec.lock | 22 +++++++--------------- pubspec.yaml | 2 +- 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index 356cbe5..ef09107 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -53,18 +53,18 @@ packages: dependency: transitive description: name: connectivity_plus - sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0" + sha256: e9feae83b1849f61bad9f6f33ee00646e3410d54ce0821e02f262f9901dad3c9 url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "6.0.1" connectivity_plus_platform_interface: dependency: transitive description: name: connectivity_plus_platform_interface - sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a + sha256: b6a56efe1e6675be240de39107281d4034b64ac23438026355b4234042a35adb url: "https://pub.dev" source: hosted - version: "1.2.4" + version: "2.0.0" cupertino_icons: dependency: "direct main" description: @@ -85,10 +85,10 @@ packages: dependency: "direct main" description: name: dio - sha256: "49af28382aefc53562459104f64d16b9dfd1e8ef68c862d5af436cc8356ce5a8" + sha256: "50fec96118958b97c727d0d8f67255d3683f16cc1f90d9bc917b5d4fe3abeca9" url: "https://pub.dev" source: hosted - version: "5.4.1" + version: "5.4.2" equatable: dependency: transitive description: @@ -103,7 +103,7 @@ packages: path: ".." relative: true source: path - version: "2.0.2" + version: "3.0.0" fake_async: dependency: transitive description: @@ -167,14 +167,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.0" - js: - dependency: transitive - description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" - source: hosted - version: "0.6.7" leak_tracker: dependency: transitive description: @@ -340,6 +332,14 @@ packages: url: "https://pub.dev" source: hosted version: "13.0.0" + web: + dependency: transitive + description: + name: web + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + url: "https://pub.dev" + source: hosted + version: "0.5.1" xml: dependency: transitive description: @@ -349,5 +349,5 @@ packages: source: hosted version: "6.5.0" sdks: - dart: ">=3.3.0-279.1.beta <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/pubspec.lock b/pubspec.lock index adab59e..51a9a41 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -85,18 +85,18 @@ packages: dependency: "direct main" description: name: connectivity_plus - sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0" + sha256: e9feae83b1849f61bad9f6f33ee00646e3410d54ce0821e02f262f9901dad3c9 url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "6.0.1" connectivity_plus_platform_interface: dependency: transitive description: name: connectivity_plus_platform_interface - sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a + sha256: b6a56efe1e6675be240de39107281d4034b64ac23438026355b4234042a35adb url: "https://pub.dev" source: hosted - version: "1.2.4" + version: "2.0.0" convert: dependency: transitive description: @@ -150,10 +150,10 @@ packages: dependency: "direct main" description: name: dio - sha256: "49af28382aefc53562459104f64d16b9dfd1e8ef68c862d5af436cc8356ce5a8" + sha256: "50fec96118958b97c727d0d8f67255d3683f16cc1f90d9bc917b5d4fe3abeca9" url: "https://pub.dev" source: hosted - version: "5.4.1" + version: "5.4.2" equatable: dependency: "direct main" description: @@ -274,14 +274,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.0" - js: - dependency: transitive - description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" - source: hosted - version: "0.6.7" json_annotation: dependency: transitive description: @@ -562,4 +554,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.3.0 <4.0.0" - flutter: ">=3.10.0" + flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index 24de8fb..c904de6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: connectivity_plus: ^6.0.1 - dio: ^5.4.1 + dio: ^5.4.2 equatable: ^2.0.5 http_exception: ^2.0.0 flutter: From caf47c3d7012efaa6afcc477217e14d58f2c1313 Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 18:37:48 -0500 Subject: [PATCH 4/9] refactor(exception_handler): Rename dio exception handler file Renamed the 'exception_handler_dio.dart' to 'dio_exception_handler.dart' for better readability and consistency. Updated all relevant exports accordingly. --- lib/src/exception_handler/dio/dio.dart | 2 +- .../{exception_handler_dio.dart => dio_exception_handler.dart} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/src/exception_handler/dio/{exception_handler_dio.dart => dio_exception_handler.dart} (100%) diff --git a/lib/src/exception_handler/dio/dio.dart b/lib/src/exception_handler/dio/dio.dart index 04afd57..1ea3651 100644 --- a/lib/src/exception_handler/dio/dio.dart +++ b/lib/src/exception_handler/dio/dio.dart @@ -2,5 +2,5 @@ // All rights reserved. Use of this source code // is governed by a Apache-2.0 license that can be found in the LICENSE file. -export 'exception_handler_dio.dart'; +export 'dio_exception_handler.dart'; export 'dio_http_response_extension.dart'; diff --git a/lib/src/exception_handler/dio/exception_handler_dio.dart b/lib/src/exception_handler/dio/dio_exception_handler.dart similarity index 100% rename from lib/src/exception_handler/dio/exception_handler_dio.dart rename to lib/src/exception_handler/dio/dio_exception_handler.dart From 3bb602ca162d53bbdb69958c792f199f637d1f8b Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 18:52:49 -0500 Subject: [PATCH 5/9] docs: updated changelog 3.0.0 --- CHANGELOG.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d0f889..1e8ac8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## [3.0.0] - 2024-03-26 + +### Changed - 3.0.0 + +* **Dependency**: Updated the `dio` package version from `5.4.1` to `5.4.2`. +* **Dependency**: Updated the `connectivity_plus` plugin from version `^5.0.2` to `^6.0.1`. + +### Breaking Changes - 3.0.0 + +* **SDK and Flutter versions**: + Increased the minimum Dart version from `>=3.0.0 <4.0.0` to `>=3.3.0 <4.0.0` and the Flutter version from `>=3.0.0` to `>=3.19.0` in the `pubspec.yaml` file. This change may affect developers working on older versions of the SDK or Flutter. + +### Added - 3.0.0 + +* **Code Quality**: Enhanced linter rules for improved code quality, enabling previously commented-out linting rules, adding new ones, and notably, the addition of metrics with specific complexity parameters to drive better code practices. + ## [2.0.2] - 2024-03-11 Overall, these changes primarily revolve around improving exception handling and string formatting versatility. @@ -49,7 +65,7 @@ Overall, these changes primarily revolve around improving exception handling and ## [2.0.0] - 2024-03-10 -### Breaking Changes +### Breaking Changes - 2.0.0 Refactor of Exception Handling: The conversion of DioExceptionHandler into a mixin and the static method adjustments represent a breaking change for any existing codebases that instantiate DioExceptionHandler or rely on its previous class structure. Projects will need to update their exception handling implementations to adapt to this refactor. This change aims to streamline the process and enhance overall usability, but will require attention during migration to the new version. From 0ce2da6f1c0087f5e6979a29ecae770acf2eadb3 Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 18:52:58 -0500 Subject: [PATCH 6/9] refactor(analysis_options): Disable somes rules Temporarily disabled the 'avoid_catching_errors' linting rule in analysis options for ongoing validation work. --- analysis_options.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index cf0b46b..7e1a230 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -37,7 +37,7 @@ linter: # - always_specify_types # More disbuting - avoid_annotating_with_dynamic - avoid_bool_literals_in_conditional_expressions - - avoid_catching_errors # tempory disabled because working validation + # - avoid_catching_errors # tempory disabled because working validation - avoid_classes_with_only_static_members - avoid_double_and_int_checks - avoid_field_initializers_in_const_classes @@ -116,7 +116,7 @@ dart_code_linter: - did-change-dependencies-method - did-update-widget-method - dispose-method - - format-comment: true + # - format-comment: true # - avoid-dynamic: true - avoid-passing-async-when-sync-expected: true - avoid-redundant-async: true @@ -124,7 +124,7 @@ dart_code_linter: - avoid-unnecessary-type-casts: true - avoid-unrelated-type-assertions: true - avoid-unused-parameters: true - - avoid-nested-conditional-expressions: true + # - avoid-nested-conditional-expressions: true - newline-before-return: true - no-boolean-literal-compare: true - no-empty-block: true @@ -132,4 +132,4 @@ dart_code_linter: - prefer-conditional-expressions: true - no-equal-then-else: true - prefer-moving-to-variable: true - - prefer-match-file-name: true + # - prefer-match-file-name: true From 7e4d1d0a23bdff4838d854cde745f0f1be81d75a Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 19:06:15 -0500 Subject: [PATCH 7/9] refactor: Improve code readability Enhanced the formatting of test cases in mocks and exception handler for better readability. Added line breaks to improve clarity and structure of the tests. --- test/mocks.dart | 1 + test/src/exception_handler/typedef_test.dart | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/test/mocks.dart b/test/mocks.dart index 5fb3db2..1552c24 100644 --- a/test/mocks.dart +++ b/test/mocks.dart @@ -64,6 +64,7 @@ class UserModel { data['email'] = email; data['phone'] = phone; data['website'] = website; + return data; } } diff --git a/test/src/exception_handler/typedef_test.dart b/test/src/exception_handler/typedef_test.dart index e4cf635..6a0f7bf 100644 --- a/test/src/exception_handler/typedef_test.dart +++ b/test/src/exception_handler/typedef_test.dart @@ -41,10 +41,12 @@ void main() { response: mockResponse, parserModel: mockParserModel, ); - test('should correctly parse the response using the given parserModel', - () { - expect(parser.parserModel(parser.response.data), equals('value')); - }); + test( + 'should correctly parse the response using the given parserModel', + () { + expect(parser.parserModel(parser.response.data), equals('value')); + }, + ); test( 'should correct toString', () { From 3cda7cf2f36d1b34b1aed83e28ab3cf73ad7cd3d Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 19:11:53 -0500 Subject: [PATCH 8/9] chore(workflows): Update coverage tool version Upgraded the version of VeryGoodOpenSource/very_good_coverage from v2 to v3 in GitHub workflows. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3dfa975..15e0559 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,7 +86,7 @@ jobs: run: dart pub publish --dry-run - name: 📊 Check Code Coverage - uses: VeryGoodOpenSource/very_good_coverage@v2 + uses: VeryGoodOpenSource/very_good_coverage@v3 with: path: "./coverage/lcov.info" min_coverage: 99 From cebe6c30fd8619242e9490959e6674138f446ea9 Mon Sep 17 00:00:00 2001 From: "Andres Garcia (TECH-ANDGAR)" Date: Tue, 26 Mar 2024 19:12:20 -0500 Subject: [PATCH 9/9] chore(workflows): Increase minimum coverage requirement The minimum code coverage requirement has been increased from 99% to 100% in the build workflow. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15e0559..282e410 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,7 +89,7 @@ jobs: uses: VeryGoodOpenSource/very_good_coverage@v3 with: path: "./coverage/lcov.info" - min_coverage: 99 + min_coverage: 100 - name: ⬆️ Upload Coverage to Coveralls uses: coverallsapp/github-action@v2.2.3