| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:doro_tech/src/data/service/characters/characters_service.dart'; + 2 : import 'package:doro_tech/src/domain/models/character_model.dart'; + 3 : import 'package:doro_tech/src/shared/pagination/paginated_response.dart'; + 4 : import 'package:doro_tech/src/shared/pagination/pagination.dart'; + 5 : import 'package:doro_tech/src/shared/utils/app_error.dart'; + 6 : import 'package:result_dart/src/result_dart_base.dart'; + 7 : + 8 : import '../../../domain/enums/gender_enum.dart'; + 9 : import '../../../domain/enums/status_enum.dart'; + 10 : import 'characters_repository.dart'; + 11 : + 12 : class CharactersRepositoryImpl implements ICharactersRepository { + 13 : final ICharactersService charactersService; + 14 : + 15 1 : CharactersRepositoryImpl({required this.charactersService}); + 16 : + 17 1 : @override + 18 : Future<ResultDart<PaginatedResponse<CharacterModel>, AppError>> + 19 : getCharacters({ + 20 : required Pagination pagination, + 21 : String? name, + 22 : GenderEnum? gender, + 23 : StatusEnum? status, + 24 : }) { + 25 2 : return charactersService.getCharacters( + 26 : pagination: pagination, + 27 : name: name, + 28 : gender: gender, + 29 : status: status, + 30 : ); + 31 : } + 32 : + 33 1 : @override + 34 : Future<ResultDart<List<CharacterModel>, AppError>> getFavoriteCharacters({ + 35 : required List<int> charactersIds, + 36 : }) { + 37 2 : return charactersService.getFavoriteCharacters( + 38 : charactersIds: charactersIds, + 39 : ); + 40 : } + 41 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| characters_repository_impl.dart | +
+ |
+ 100.0 % | +5 | +5 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:doro_tech/src/domain/models/episode_model.dart'; + 2 : + 3 : import 'package:doro_tech/src/shared/utils/app_error.dart'; + 4 : import 'package:result_dart/src/result_dart_base.dart'; + 5 : + 6 : import '../../service/episodes/episodes_service.dart'; + 7 : import 'episodes_repository.dart'; + 8 : + 9 : class EpisodesRepositoryImpl implements IEpisodesRepository { + 10 : final IEpisodesService episodesService; + 11 : + 12 1 : EpisodesRepositoryImpl({required this.episodesService}); + 13 : + 14 1 : @override + 15 : Future<ResultDart<List<EpisodeModel>, AppError>> getEpisodesByIds({ + 16 : required List<int> episodesIds, + 17 : }) { + 18 2 : return episodesService.getEpisodesByIds(episodesIds: episodesIds); + 19 : } + 20 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| episodes_repository_impl.dart | +
+ |
+ 100.0 % | +3 | +3 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import '../../../shared/utils/app_error.dart'; + 2 : import '../../service/favorites/favorites_service.dart'; + 3 : import 'favorites_repository.dart'; + 4 : import 'package:result_dart/result_dart.dart'; + 5 : + 6 : class FavoritesRepositoryImpl implements IFavoritesRepository { + 7 : final IFavoritesService favoritesService; + 8 : + 9 1 : FavoritesRepositoryImpl({required this.favoritesService}); + 10 : + 11 1 : @override + 12 : Future<ResultDart<bool, AppError>> saveFavoriteId({required int characterId}) { + 13 2 : return favoritesService.saveFavoriteId(characterId: characterId); + 14 : } + 15 : + 16 1 : @override + 17 : Future<ResultDart<bool, AppError>> deleteFavoriteId({required int characterId}) { + 18 2 : return favoritesService.deleteFavoriteId(characterId: characterId); + 19 : } + 20 : + 21 1 : @override + 22 : Future<ResultDart<List<int>, AppError>> getFavoriteIds() { + 23 2 : return favoritesService.getFavoriteIds(); + 24 : } + 25 : + 26 1 : @override + 27 : Future<ResultDart<bool, AppError>> deleteAllFavoriteIds() { + 28 2 : return favoritesService.deleteAllFavoriteIds(); + 29 : } + 30 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| favorites_repository_impl.dart | +
+ |
+ 100.0 % | +9 | +9 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| theme_repository_impl.dart | +
+ |
+ 100.0 % | +5 | +5 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:flutter/material.dart'; + 2 : import 'package:result_dart/result_dart.dart'; + 3 : + 4 : import '../../../shared/utils/app_error.dart'; + 5 : import 'theme_repository.dart'; + 6 : import '../../service/theme/theme_service.dart'; + 7 : + 8 : class ThemeRepositoryImpl implements IThemeRepository { + 9 : final IThemeService themeService; + 10 : + 11 1 : ThemeRepositoryImpl({required this.themeService}); + 12 : + 13 1 : @override + 14 : Future<ResultDart<ThemeMode, AppError>> getThemeMode() { + 15 2 : return themeService.getThemeMode(); + 16 : } + 17 : + 18 1 : @override + 19 : Future<ResultDart<bool, AppError>> saveThemeMode(ThemeMode mode) { + 20 2 : return themeService.saveThemeMode(mode); + 21 : } + 22 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:dio/dio.dart'; + 2 : import 'package:doro_tech/src/domain/models/character_model.dart'; + 3 : import 'package:doro_tech/src/shared/pagination/paginated_response.dart'; + 4 : import 'package:doro_tech/src/shared/pagination/pagination.dart'; + 5 : import 'package:doro_tech/src/shared/utils/app_error.dart'; + 6 : import 'package:result_dart/src/result_dart_base.dart'; + 7 : + 8 : import '../../../domain/enums/gender_enum.dart'; + 9 : import '../../../domain/enums/status_enum.dart'; + 10 : import '../../../shared/utils/logger.dart'; + 11 : import 'characters_service.dart'; + 12 : + 13 : class CharactersServiceImpl implements ICharactersService { + 14 : final Dio _dio; + 15 : + 16 1 : CharactersServiceImpl(this._dio); + 17 : + 18 1 : @override + 19 : Future<ResultDart<PaginatedResponse<CharacterModel>, AppError>> + 20 : getCharacters({ + 21 : required Pagination pagination, + 22 : String? name, + 23 : GenderEnum? gender, + 24 : StatusEnum? status, + 25 : }) async { + 26 : try { + 27 2 : final Response response = await _dio.get( + 28 : 'https://rickandmortyapi.com/api/character', + 29 1 : queryParameters: { + 30 2 : 'page': pagination.page, + 31 2 : if (name != null && name.isNotEmpty) ...{'name': name}, + 32 3 : if (gender != null && gender != GenderEnum.all) ...{'gender': gender.genderLabel}, + 33 3 : if (status != null && status != StatusEnum.all) ...{'status': status.statusLabel}, + 34 : }, + 35 : ); + 36 : + 37 2 : if (response.statusCode == 200) { + 38 : final List<CharacterModel> characters = + 39 4 : (response.data['results'] as List).map((character) { + 40 1 : return CharacterModel.fromJson(character); + 41 1 : }).toList(); + 42 : + 43 1 : return Success( + 44 1 : PaginatedResponse( + 45 1 : pagination: pagination.copyWith( + 46 3 : total: response.data['info']['count'], + 47 : ), + 48 : data: characters, + 49 : ), + 50 : ); + 51 : } + 52 : + 53 1 : Log.error( + 54 2 : "Erro ao listar personagens. Server error: ${response.statusMessage}", + 55 : ); + 56 : + 57 1 : return Failure( + 58 1 : AppError( + 59 : message: + 60 2 : "Erro ao listar personagens. Server error: ${response.statusMessage}", + 61 : type: AppErrorType.server, + 62 : ), + 63 : ); + 64 1 : } on DioException catch (e) { + 65 7 : if (e.response?.statusCode == 404 && e.response?.data['error'] == 'There is nothing here') { + 66 3 : Log.error("API retorna 404 quando nenhum item é encontrado pelo filtro: ${e.message}"); + 67 1 : return Success( + 68 1 : PaginatedResponse( + 69 : pagination: pagination, + 70 1 : data: [], + 71 : ), + 72 : ); + 73 : } + 74 : + 75 3 : Log.error("Erro de rede Dio: ${e.message}"); + 76 1 : return Failure( + 77 1 : AppError( + 78 2 : message: "Erro de rede Dio: ${e.message}", + 79 : type: AppErrorType.network, + 80 : ), + 81 : ); + 82 : } catch (e) { + 83 2 : Log.error("Erro inesperado: $e"); + 84 1 : return Failure( + 85 2 : AppError(message: "Erro inesperado: $e", type: AppErrorType.local), + 86 : ); + 87 : } + 88 : } + 89 : + 90 1 : @override + 91 : Future<ResultDart<List<CharacterModel>, AppError>> getFavoriteCharacters({ + 92 : required List<int> charactersIds, + 93 : }) async { + 94 : try { + 95 2 : final Response response = await _dio.get( + 96 1 : 'https://rickandmortyapi.com/api/character/$charactersIds', + 97 : ); + 98 : + 99 2 : if (response.statusCode == 200) { + 100 3 : final List<CharacterModel> characters = (response.data as List).map(( + 101 : character, + 102 : ) { + 103 1 : return CharacterModel.fromJson(character); + 104 1 : }).toList(); + 105 : + 106 1 : return Success(characters); + 107 : } + 108 : + 109 1 : Log.error( + 110 2 : "Erro ao listar personagens favoritos. Server error: ${response.statusMessage}", + 111 : ); + 112 : + 113 1 : return Failure( + 114 1 : AppError( + 115 : message: + 116 2 : "Erro ao listar personagens favoritos. Server error: ${response.statusMessage}", + 117 : type: AppErrorType.server, + 118 : ), + 119 : ); + 120 1 : } on DioException catch (e) { + 121 3 : Log.error("Erro de rede Dio: ${e.message}"); + 122 1 : return Failure( + 123 1 : AppError( + 124 2 : message: "Erro de rede Dio: ${e.message}", + 125 : type: AppErrorType.network, + 126 : ), + 127 : ); + 128 : } catch (e) { + 129 2 : Log.error("Erro inesperado: $e"); + 130 1 : return Failure( + 131 2 : AppError(message: "Erro inesperado: $e", type: AppErrorType.local), + 132 : ); + 133 : } + 134 : } + 135 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| characters_service_impl.dart | +
+ |
+ 100.0 % | +55 | +55 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:dio/dio.dart'; + 2 : import 'package:doro_tech/src/domain/models/episode_model.dart'; + 3 : import 'package:doro_tech/src/shared/utils/app_error.dart'; + 4 : import 'package:result_dart/src/result_dart_base.dart'; + 5 : + 6 : import '../../../shared/utils/logger.dart'; + 7 : import 'episodes_service.dart'; + 8 : + 9 : class EpisodesServiceImpl implements IEpisodesService { + 10 : final Dio _dio; + 11 : + 12 1 : EpisodesServiceImpl(this._dio); + 13 : + 14 1 : @override + 15 : Future<ResultDart<List<EpisodeModel>, AppError>> getEpisodesByIds({ + 16 : required List<int> episodesIds, + 17 : }) async { + 18 : try { + 19 2 : final Response response = await _dio.get( + 20 1 : 'https://rickandmortyapi.com/api/episode/$episodesIds', + 21 : ); + 22 : + 23 2 : if (response.statusCode == 200) { + 24 3 : final List<EpisodeModel> episodes = (response.data as List).map(( + 25 : episode, + 26 : ) { + 27 1 : return EpisodeModel.fromJson(episode); + 28 1 : }).toList(); + 29 : + 30 1 : return Success(episodes); + 31 : } + 32 : + 33 1 : Log.error( + 34 2 : "Erro ao consultar episódios. Server error: ${response.statusMessage}", + 35 : ); + 36 : + 37 1 : return Failure( + 38 1 : AppError( + 39 : message: + 40 2 : "Erro ao consultar episódios. Server error: ${response.statusMessage}", + 41 : type: AppErrorType.server, + 42 : ), + 43 : ); + 44 1 : } on DioException catch (e) { + 45 3 : Log.error("Erro de rede Dio: ${e.message}"); + 46 1 : return Failure( + 47 1 : AppError( + 48 2 : message: "Erro de rede Dio: ${e.message}", + 49 : type: AppErrorType.network, + 50 : ), + 51 : ); + 52 : } catch (e) { + 53 2 : Log.error("Erro inesperado: $e"); + 54 1 : return Failure( + 55 2 : AppError(message: "Erro inesperado: $e", type: AppErrorType.local), + 56 : ); + 57 : } + 58 : } + 59 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| episodes_service_impl.dart | +
+ |
+ 100.0 % | +22 | +22 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:shared_preferences/shared_preferences.dart'; + 2 : import 'package:result_dart/result_dart.dart'; + 3 : + 4 : import '../../../shared/utils/app_error.dart'; + 5 : import '../../../shared/utils/logger.dart'; + 6 : import 'favorites_service.dart'; + 7 : + 8 : class FavoritesServiceImpl implements IFavoritesService { + 9 : static const String _favoritesKey = 'favorites'; + 10 : final SharedPreferences _prefs; + 11 : + 12 1 : FavoritesServiceImpl(this._prefs); + 13 : + 14 1 : @override + 15 : Future<ResultDart<bool, AppError>> saveFavoriteId({required int characterId}) async { + 16 : try { + 17 2 : final List<String> favorites = _prefs.getStringList(_favoritesKey) ?? <String>[]; + 18 : + 19 1 : final String characterIdStr = characterId.toString(); + 20 : + 21 1 : if (!favorites.contains(characterIdStr)) { + 22 1 : favorites.add(characterIdStr); + 23 2 : await _prefs.setStringList(_favoritesKey, favorites); + 24 : } + 25 : + 26 : return const Success(true); + 27 : } catch (e) { + 28 1 : Log.error('Erro ao salvar favoritos'); + 29 1 : return Failure( + 30 1 : AppError( + 31 : message: 'Erro ao salvar favoritos', + 32 : type: AppErrorType.local, + 33 : ), + 34 : ); + 35 : } + 36 : } + 37 : + 38 1 : @override + 39 : Future<ResultDart<bool, AppError>> deleteFavoriteId({required int characterId}) async { + 40 : try { + 41 2 : final List<String> favoriteIds = _prefs.getStringList(_favoritesKey) ?? <String>[]; + 42 : + 43 2 : favoriteIds.remove(characterId.toString()); + 44 2 : await _prefs.setStringList(_favoritesKey, favoriteIds); + 45 : + 46 : return const Success(true); + 47 : } catch (e) { + 48 1 : Log.error('Erro ao deletar favoritos'); + 49 1 : return Failure( + 50 1 : AppError( + 51 : message: 'Erro ao deletar favoritos', + 52 : type: AppErrorType.local, + 53 : ), + 54 : ); + 55 : } + 56 : } + 57 : + 58 1 : @override + 59 : Future<ResultDart<List<int>, AppError>> getFavoriteIds() async { + 60 : try { + 61 2 : final List<String> favoriteIds = _prefs.getStringList(_favoritesKey) ?? <String>[]; + 62 4 : final List<int> favoritesInt = favoriteIds.map((e) => int.parse(e)).toList(); + 63 1 : return Success(favoritesInt); + 64 : } catch (e) { + 65 1 : Log.error('Erro ao buscar favoritos'); + 66 1 : return Failure( + 67 1 : AppError( + 68 : message: 'Erro ao buscar favoritos', + 69 : type: AppErrorType.local, + 70 : ), + 71 : ); + 72 : } + 73 : } + 74 : + 75 1 : @override + 76 : Future<ResultDart<bool, AppError>> deleteAllFavoriteIds() async { + 77 : try { + 78 2 : final isRemoved = await _prefs.remove(_favoritesKey); + 79 : + 80 1 : return Success(isRemoved); + 81 : } catch (e) { + 82 1 : Log.error('Erro ao deletar todos favoritos'); + 83 1 : return Failure( + 84 1 : AppError( + 85 : message: 'Erro ao deletar todos favoritos', + 86 : type: AppErrorType.local, + 87 : ), + 88 : ); + 89 : } + 90 : } + 91 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| favorites_service_impl.dart | +
+ |
+ 100.0 % | +30 | +30 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| theme_service_impl.dart | +
+ |
+ 100.0 % | +12 | +12 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:flutter/material.dart'; + 2 : import 'package:result_dart/result_dart.dart'; + 3 : import 'package:shared_preferences/shared_preferences.dart'; + 4 : + 5 : import '../../../shared/utils/app_error.dart'; + 6 : import '../../../shared/utils/logger.dart'; + 7 : import 'theme_service.dart'; + 8 : + 9 : class ThemeServiceImpl implements IThemeService { + 10 : static const _themeModeKey = 'theme_mode'; + 11 : final SharedPreferences _prefs; + 12 : + 13 1 : ThemeServiceImpl(this._prefs); + 14 : + 15 1 : @override + 16 : Future<ResultDart<ThemeMode, AppError>> getThemeMode() async { + 17 : try { + 18 2 : final themeModeIndex = _prefs.getInt(_themeModeKey); + 19 : if (themeModeIndex == null) { + 20 : return const Success(ThemeMode.system); + 21 : } + 22 2 : return Success(ThemeMode.values[themeModeIndex]); + 23 : } catch (e) { + 24 1 : Log.error('Erro ao consultar tema salvo'); + 25 1 : return Failure( + 26 1 : AppError( + 27 : message: 'Erro ao consultar tema salvo', + 28 : type: AppErrorType.local, + 29 : ), + 30 : ); + 31 : } + 32 : } + 33 : + 34 1 : @override + 35 : Future<ResultDart<bool, AppError>> saveThemeMode(ThemeMode mode) async { + 36 : try { + 37 3 : await _prefs.setInt(_themeModeKey, mode.index); + 38 : return const Success(true); + 39 : } catch (e) { + 40 1 : Log.error('Erro ao salvar tema'); + 41 1 : return Failure( + 42 1 : AppError( + 43 : message: 'Erro ao salvar tema', + 44 : type: AppErrorType.local, + 45 : ), + 46 : ); + 47 : } + 48 : } + 49 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : enum GenderEnum { + 2 : male('Male'), + 3 : female('Female'), + 4 : genderless('Genderless'), + 5 : unknown('Unknown'), + 6 : all('All'); + 7 : + 8 : final String genderLabel; + 9 : + 10 : const GenderEnum(this.genderLabel); + 11 : + 12 3 : static GenderEnum fromString(String? genderLabel) { + 13 3 : return values.firstWhere( + 14 15 : (gender) => gender.genderLabel.toUpperCase() == genderLabel?.toUpperCase(), + 15 2 : orElse: () => unknown, + 16 : ); + 17 : } + 18 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| gender_enum.dart | +
+ |
+ 100.0 % | +4 | +4 | +|
| status_enum.dart | +
+ |
+ 100.0 % | +4 | +4 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| gender_enum.dart | +
+ |
+ 100.0 % | +4 | +4 | +|
| status_enum.dart | +
+ |
+ 100.0 % | +4 | +4 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| gender_enum.dart | +
+ |
+ 100.0 % | +4 | +4 | +|
| status_enum.dart | +
+ |
+ 100.0 % | +4 | +4 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:flutter/material.dart'; + 2 : + 3 : enum StatusEnum { + 4 : alive('Alive', Colors.green), + 5 : dead('Dead', Colors.red), + 6 : unknown('Unknown', Colors.grey), + 7 : all('All', Colors.white); + 8 : + 9 : final String statusLabel; + 10 : final Color statusColor; + 11 : + 12 : const StatusEnum(this.statusLabel, this.statusColor); + 13 : + 14 3 : static StatusEnum fromString(String? statusLabel) { + 15 3 : return values.firstWhere( + 16 15 : (status) => status.statusLabel.toUpperCase() == statusLabel?.toUpperCase(), + 17 2 : orElse: () => unknown, + 18 : ); + 19 : } + 20 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import '../enums/gender_enum.dart'; + 2 : import '../enums/status_enum.dart'; + 3 : + 4 : class CharacterModel { + 5 : final int id; + 6 : final String name; + 7 : final String species; + 8 : final StatusEnum status; + 9 : final String image; + 10 : final String origin; + 11 : final GenderEnum gender; + 12 : final String location; + 13 : final List<int> episodesIds; + 14 : + 15 3 : CharacterModel({ + 16 : required this.id, + 17 : required this.name, + 18 : required this.species, + 19 : required this.status, + 20 : required this.image, + 21 : required this.origin, + 22 : required this.gender, + 23 : required this.location, + 24 : required this.episodesIds, + 25 : }); + 26 : + 27 2 : factory CharacterModel.fromJson(Map<String, dynamic> json) { + 28 2 : return CharacterModel( + 29 2 : id: json['id'], + 30 2 : name: json['name'] ?? 'Unknown', + 31 2 : species: json['species'] ?? 'Unknown', + 32 4 : status: StatusEnum.fromString(json['status']), + 33 2 : image: json['image'] ?? '', + 34 4 : origin: json['origin']['name'] ?? 'Unknown', + 35 4 : gender: GenderEnum.fromString(json['gender']), + 36 4 : location: json['location']['name'] ?? 'Unknown', + 37 5 : episodesIds: (json['episode'] as List<dynamic>).map((url) { + 38 2 : final uriParts = url.toString().split('/'); + 39 2 : return int.parse(uriParts.last); + 40 2 : }).toList(), + 41 : ); + 42 : } + 43 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : class EpisodeModel { + 2 : final int id; + 3 : final String name; + 4 : final String episode; + 5 : + 6 3 : EpisodeModel({ + 7 : required this.id, + 8 : required this.name, + 9 : required this.episode, + 10 : }); + 11 : + 12 2 : factory EpisodeModel.fromJson(Map<String, dynamic> json) { + 13 2 : return EpisodeModel( + 14 2 : id: json['id'] as int, + 15 2 : name: json['name'] as String? ?? '', + 16 2 : episode: json['episode'] as String? ?? '', + 17 : ); + 18 : } + 19 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| character_model.dart | +
+ |
+ 100.0 % | +15 | +15 | +|
| episode_model.dart | +
+ |
+ 100.0 % | +6 | +6 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| episode_model.dart | +
+ |
+ 100.0 % | +6 | +6 | +|
| character_model.dart | +
+ |
+ 100.0 % | +15 | +15 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| character_model.dart | +
+ |
+ 100.0 % | +15 | +15 | +|
| episode_model.dart | +
+ |
+ 100.0 % | +6 | +6 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| Directory |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| data/repository/characters/ | +
+ |
+ 100.0 % | +5 | +5 | +|
| data/repository/episodes/ | +
+ |
+ 100.0 % | +3 | +3 | +|
| data/repository/favorites/ | +
+ |
+ 100.0 % | +9 | +9 | +|
| data/repository/theme/ | +
+ |
+ 100.0 % | +5 | +5 | +|
| data/service/characters/ | +
+ |
+ 100.0 % | +55 | +55 | +|
| data/service/episodes/ | +
+ |
+ 100.0 % | +22 | +22 | +|
| data/service/favorites/ | +
+ |
+ 100.0 % | +30 | +30 | +|
| data/service/theme/ | +
+ |
+ 100.0 % | +12 | +12 | +|
| domain/enums/ | +
+ |
+ 100.0 % | +8 | +8 | +|
| domain/models/ | +
+ |
+ 100.0 % | +21 | +21 | +|
| shared/pagination/ | +
+ |
+ 50.0 % | +16 | +8 | +|
| shared/utils/ | +
+ |
+ 37.5 % | +16 | +6 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| Directory |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| shared/utils/ | +
+ |
+ 37.5 % | +16 | +6 | +|
| shared/pagination/ | +
+ |
+ 50.0 % | +16 | +8 | +|
| data/repository/episodes/ | +
+ |
+ 100.0 % | +3 | +3 | +|
| data/repository/characters/ | +
+ |
+ 100.0 % | +5 | +5 | +|
| data/repository/theme/ | +
+ |
+ 100.0 % | +5 | +5 | +|
| domain/enums/ | +
+ |
+ 100.0 % | +8 | +8 | +|
| data/repository/favorites/ | +
+ |
+ 100.0 % | +9 | +9 | +|
| data/service/theme/ | +
+ |
+ 100.0 % | +12 | +12 | +|
| domain/models/ | +
+ |
+ 100.0 % | +21 | +21 | +|
| data/service/episodes/ | +
+ |
+ 100.0 % | +22 | +22 | +|
| data/service/favorites/ | +
+ |
+ 100.0 % | +30 | +30 | +|
| data/service/characters/ | +
+ |
+ 100.0 % | +55 | +55 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| Directory |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| data/repository/characters/ | +
+ |
+ 100.0 % | +5 | +5 | +|
| data/repository/episodes/ | +
+ |
+ 100.0 % | +3 | +3 | +|
| data/repository/favorites/ | +
+ |
+ 100.0 % | +9 | +9 | +|
| data/repository/theme/ | +
+ |
+ 100.0 % | +5 | +5 | +|
| data/service/characters/ | +
+ |
+ 100.0 % | +55 | +55 | +|
| data/service/episodes/ | +
+ |
+ 100.0 % | +22 | +22 | +|
| data/service/favorites/ | +
+ |
+ 100.0 % | +30 | +30 | +|
| data/service/theme/ | +
+ |
+ 100.0 % | +12 | +12 | +|
| domain/enums/ | +
+ |
+ 100.0 % | +8 | +8 | +|
| domain/models/ | +
+ |
+ 100.0 % | +21 | +21 | +|
| shared/pagination/ | +
+ |
+ 50.0 % | +16 | +8 | +|
| shared/utils/ | +
+ |
+ 37.5 % | +16 | +6 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| paginated_response.dart | +
+ |
+ 25.0 % | +4 | +1 | +|
| pagination.dart | +
+ |
+ 58.3 % | +12 | +7 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| paginated_response.dart | +
+ |
+ 25.0 % | +4 | +1 | +|
| pagination.dart | +
+ |
+ 58.3 % | +12 | +7 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| paginated_response.dart | +
+ |
+ 25.0 % | +4 | +1 | +|
| pagination.dart | +
+ |
+ 58.3 % | +12 | +7 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:doro_tech/src/shared/pagination/pagination.dart'; + 2 : + 3 : class PaginatedResponse<T> { + 4 : Pagination pagination; + 5 : final List<T> data; + 6 : + 7 2 : PaginatedResponse({required this.pagination, required this.data}); + 8 : + 9 0 : void merge(PaginatedResponse<T> newPage) { + 10 0 : pagination = newPage.pagination.copyWith(page: newPage.pagination.page + 1); + 11 0 : data.addAll(newPage.data); + 12 : } + 13 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : class Pagination { + 2 : final int page; + 3 : final int offset; + 4 : final int perPage; + 5 : final int itemsCount; + 6 : final int? total; + 7 : + 8 2 : Pagination({ + 9 : this.page = 1, + 10 : this.offset = 0, + 11 : this.perPage = 10, + 12 : this.itemsCount = 0, + 13 : this.total, + 14 : }); + 15 : + 16 0 : bool get hasMorePages { + 17 0 : if(total != null){ + 18 0 : return (page <= ((total! / perPage).ceil())); + 19 : } + 20 0 : return itemsCount == perPage; + 21 : } + 22 : + 23 2 : Pagination copyWith({ + 24 : int? page, + 25 : int? offset, + 26 : int? perPage, + 27 : int? itemsCount, + 28 : int? total, + 29 : }) { + 30 2 : return Pagination( + 31 2 : page: page ?? this.page, + 32 2 : offset: offset ?? this.offset, + 33 2 : perPage: perPage ?? this.perPage, + 34 2 : itemsCount: itemsCount ?? this.itemsCount, + 35 0 : total: total ?? this.total, + 36 : ); + 37 : } + 38 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : enum AppErrorType { + 2 : local, // SharedPreferences, SQLite, arquivos locais + 3 : network, // Sem internet, timeout, DNS + 4 : server, // 500, 404, API down + 5 : validation, // Dados inválidos + 6 : auth, // Token expirado, não autorizado + 7 : requisitionLimit, // Limite de requisição + 8 : unknown, // Erro não categorizado + 9 : } + 10 : + 11 : class AppError { + 12 : final String message; + 13 : final AppErrorType type; + 14 : + 15 8 : AppError({ + 16 : required this.message, + 17 : required this.type, + 18 : }); + 19 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| app_error.dart | +
+ |
+ 100.0 % | +1 | +1 | +|
| logger.dart | +
+ |
+ 33.3 % | +15 | +5 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| logger.dart | +
+ |
+ 33.3 % | +15 | +5 | +|
| app_error.dart | +
+ |
+ 100.0 % | +1 | +1 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | ||
| File |
+ Line Coverage |
+ ||||
| Rate | +Total | +Hit | +|||
| app_error.dart | +
+ |
+ 100.0 % | +1 | +1 | +|
| logger.dart | +
+ |
+ 33.3 % | +15 | +5 | +|
| Note: 'Function Coverage' columns elided as function owner is not identified. | +|||||
| Generated by: LCOV version 2.3.1-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : import 'package:logger/logger.dart'; + 2 : + 3 : class Log { + 4 : + 5 : // Verbose log + 6 0 : static void verbose(String msg) { + 7 0 : _getLogger().v(msg); + 8 : } + 9 : + 10 : // Debug log + 11 0 : static void debug(String msg) { + 12 0 : _getLogger().d(msg); + 13 : } + 14 : + 15 : // Info log + 16 0 : static void info(String msg) { + 17 0 : _getLogger().i(msg); + 18 : } + 19 : + 20 : // Warning log + 21 0 : static void warning(String msg) { + 22 0 : _getLogger().w(msg); + 23 : } + 24 : + 25 : // Error log + 26 4 : static void error(String msg) { + 27 8 : _getLogger().e(msg); + 28 : } + 29 : + 30 : // What a terrible failure log + 31 0 : static void wtf(String msg) { + 32 0 : _getLogger().wtf(msg); + 33 : } + 34 : + 35 4 : static Logger _getLogger () { + 36 4 : return Logger( + 37 : filter: null, // Use the default LogFilter (-> only log in debug mode) + 38 8 : printer: PrefixPrinter(PrettyPrinter( + 39 : + 40 : methodCount: 0, // number of method calls to be displayed + 41 : errorMethodCount: 8, // number of method calls if stacktrace is provided + 42 : lineLength: 120, // width of the output + 43 : colors: true, // Colorful log messages + 44 : printEmojis: true, // Print an emoji for each log message + 45 : printTime: false // Should each log print contain a timestamp + 46 : )), // Use the PrettyPrinter to format and print log + 47 : output: null, // Use the default LogOutput (-> send everything to console) + 48 : ); + 49 : } + 50 : } ++ |
+
| Generated by: LCOV version 2.3.1-1 |