Jonny Borges
Committed by GitHub

Merge pull request #579 from Grohden/chore/pipeline-analyzer

chore: add analyzer to PR check pipeline
... ... @@ -20,8 +20,7 @@ jobs:
flutter-version: '1.20.2'
channel: 'stable'
- run: flutter pub get
# run static analys code
#- run: flutter analyze
- run: flutter analyze
# run flutter widgets tests and unit tests
- run: flutter test --coverage
# Upload coverage reports to Codecov
... ...
include: package:effective_dart/analysis_options.yaml
# Include option is buggy:
# https://github.com/flutter/flutter/issues/62591
# In case the include issue gets fixed, lines below INCLUDE_FIX
# can be removed
# include: package:effective_dart/analysis_options.1.2.0.yaml
analyzer:
strong-mode:
implicit-casts: false
... ... @@ -10,3 +15,71 @@ linter:
# Desirable, but would be breaking changes:
avoid_positional_boolean_parameters: false
constant_identifier_names: false
include_file_not_found: false
# INCLUDE_FIX (copy of effective dart 1.2.0)
# STYLE
camel_case_types: true
camel_case_extensions: true
library_names: true
file_names: true
library_prefixes: true
non_constant_identifier_names: true
directives_ordering: true
lines_longer_than_80_chars: true # avoid
curly_braces_in_flow_control_structures: true
# DOCUMENTATION
slash_for_doc_comments: true
package_api_docs: true # prefer
#- comment_references # Unused because https://github.com/dart-lang/sdk/issues/36974
# USAGE
implementation_imports: true
avoid_relative_lib_imports: true # prefer
prefer_relative_imports: true # prefer
prefer_adjacent_string_concatenation: true
prefer_interpolation_to_compose_strings: true # prefer
unnecessary_brace_in_string_interps: true # avoid
prefer_collection_literals: true
avoid_function_literals_in_foreach_calls: true # avoid
prefer_iterable_whereType: true
prefer_function_declarations_over_variables: true
unnecessary_lambdas: true
prefer_equal_for_default_values: true
avoid_init_to_null: true
unnecessary_getters_setters: true
#- unnecessary_getters # prefer # Disabled pending fix: https://github.com/dart-lang/linter/issues/23
#- prefer_expression_function_bodies # consider
unnecessary_this: true
prefer_initializing_formals: true
type_init_formals: true
empty_constructor_bodies: true
unnecessary_new: true
unnecessary_const: true
avoid_catches_without_on_clauses: true # avoid
avoid_catching_errors: true
use_rethrow_when_possible: true
# DESIGN
use_to_and_as_if_applicable: true # prefer
one_member_abstracts: true # avoid
avoid_classes_with_only_static_members: true # avoid
prefer_mixin: true
prefer_final_fields: true # prefer
use_setters_to_change_properties: true
avoid_setters_without_getters: true
avoid_returning_null: true # avoid
avoid_returning_this: true # avoid
type_annotate_public_apis: true # prefer
#- prefer_typing_uninitialized_variables # consider
omit_local_variable_types: true # avoid
avoid_types_on_closure_parameters: true # avoid
avoid_return_types_on_setters: true # avoid
prefer_generic_function_type_aliases: true
avoid_private_typedef_functions: true # prefer
#- use_function_type_syntax_for_parameters # consider
hash_and_equals: true
avoid_equals_and_hash_code_on_mutable_classes: true # avoid
avoid_null_checks_in_equality_operators: true
... ...
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_demo/routes/app_pages.dart';
import 'routes/app_pages.dart';
import 'shared/logger/logger_utils.dart';
void main() {
... ...
import 'package:dio/dio.dart';
import 'package:get/get.dart';
import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart';
import 'package:get_demo/pages/home/presentation/controllers/home_controller.dart';
import '../data/home_repository.dart';
import '../domain/adapters/repository_adapter.dart';
import '../presentation/controllers/home_controller.dart';
class HomeBinding extends Bindings {
@override
... ...
import 'package:dio/dio.dart';
import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart';
import 'package:get_demo/pages/home/domain/entity/cases_model.dart';
import '../domain/adapters/repository_adapter.dart';
import '../domain/entity/cases_model.dart';
class HomeRepository implements IHomeRepository {
HomeRepository({this.dio});
... ... @@ -13,7 +14,7 @@ class HomeRepository implements IHomeRepository {
final response = await dio.get("https://api.covid19api.com/summary");
return CasesModel.fromJson(response.data as Map<String, dynamic>);
} catch (e) {
} on Exception catch (e) {
print(e.toString());
return Future.error(e.toString());
}
... ...
import 'package:get_demo/pages/home/domain/entity/cases_model.dart';
import '../entity/cases_model.dart';
// ignore: one_member_abstracts
abstract class IHomeRepository {
Future<CasesModel> getCases();
}
... ...
import 'package:get/get.dart';
import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart';
import 'package:get_demo/pages/home/domain/entity/cases_model.dart';
import '../../domain/adapters/repository_adapter.dart';
import '../../domain/entity/cases_model.dart';
enum Status { loading, success, error }
... ... @@ -22,14 +23,16 @@ class HomeController extends GetxController {
/// fetch cases from Api
Future<void> fetchDataFromApi() async {
/// When the repository returns the value, change the status to success, and fill in "cases"
/// When the repository returns the value, change the status to success,
/// and fill in "cases"
return homeRepository.getCases().then(
(data) {
cases(data);
status(Status.success);
},
/// In case of error, print the error and change the status to Status.error
/// In case of error, print the error and change the status
/// to Status.error
onError: (err) {
print("$err");
return status(Status.error);
... ...
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_demo/pages/home/domain/entity/cases_model.dart';
import '../controllers/home_controller.dart';
class CountryView extends GetWidget<HomeController> {
... ... @@ -30,7 +31,7 @@ class CountryView extends GetWidget<HomeController> {
child: ListView.builder(
itemCount: controller.cases.value.countries.length,
itemBuilder: (context, index) {
Country country = controller.cases.value.countries[index];
final country = controller.cases.value.countries[index];
return ListTile(
onTap: () {
Get.toNamed('/details', arguments: country);
... ...
... ... @@ -2,12 +2,13 @@ import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_demo/pages/home/domain/entity/cases_model.dart';
import '../../domain/entity/cases_model.dart';
class DetailsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
Country country = Get.arguments as Country;
final country = Get.arguments as Country;
return Container(
decoration: BoxDecoration(
image: DecorationImage(
... ...
... ... @@ -2,7 +2,8 @@ import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_demo/pages/home/presentation/controllers/home_controller.dart';
import '../controllers/home_controller.dart';
class HomeView extends GetView<HomeController> {
@override
... ... @@ -28,7 +29,7 @@ class HomeView extends GetView<HomeController> {
body: Center(
child: Obx(
() {
Status status = controller.status.value;
final status = controller.status.value;
if (status == Status.loading) return CircularProgressIndicator();
if (status == Status.error) return Text('Error on connection :(');
return Column(
... ...
import 'package:get/get.dart';
import 'package:get_demo/pages/home/bindings/home_binding.dart';
import 'package:get_demo/pages/home/presentation/views/country_view.dart';
import 'package:get_demo/pages/home/presentation/views/details_view.dart';
import 'package:get_demo/pages/home/presentation/views/home_view.dart';
import '../pages/home/bindings/home_binding.dart';
import '../pages/home/presentation/views/country_view.dart';
import '../pages/home/presentation/views/details_view.dart';
import '../pages/home/presentation/views/home_view.dart';
part 'app_routes.dart';
// ignore: avoid_classes_with_only_static_members
class AppPages {
static const INITIAL = Routes.HOME;
... ...
class Logger {
// Sample of abstract logging function
static void write(String text, {bool isError = false}) {
print('** ' + text + ' [' + isError.toString() + ']');
print('** $text [$isError]');
}
}
... ...
... ... @@ -49,7 +49,7 @@ void main() {
binding.builder();
/// recover your controller
HomeController controller = Get.find();
final controller = Get.find<HomeController>();
/// check if onInit was called
expect(controller.initialized, true);
... ...
... ... @@ -4,7 +4,8 @@ import 'dart:collection';
import '../rx_core/rx_interface.dart';
/// global object that registers against `GetX` and `Obx`, and allows the reactivity
/// global object that registers against `GetX` and `Obx`, and allows the
/// reactivity
/// of those `Widgets` and Rx values.
RxInterface getObs;
... ... @@ -207,6 +208,9 @@ class RxBool extends _RxImpl<bool> {
/// Toggles the bool [value] between false and true.
/// A shortcut for `flag.value = !flag.value;`
/// FIXME: why return this? fluent interface is not
/// not really a dart thing since we have '..' operator
// ignore: avoid_returning_this
RxBool toggle() {
subject.add(_value = !_value);
return this;
... ... @@ -295,7 +299,8 @@ class RxInt extends _BaseRxNum<int> {
}
/// Foundation class used for custom `Types` outside the common native Dart types.
/// Foundation class used for custom `Types` outside the common native Dart
/// types.
/// For example, any custom "Model" class, like User().obs will use `Rx` as
/// wrapper.
class Rx<T> extends _RxImpl<T> {
... ...
... ... @@ -27,6 +27,7 @@ typedef GetStateUpdate = bool Function();
// TODO: check performance HIT for the extra method call.
mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> {
// To avoid the creation of an anonym function to be GC later.
// ignore: prefer_function_declarations_over_variables
static final VoidCallback _stateCallback = () {};
/// Experimental method to replace setState((){});
... ... @@ -68,12 +69,11 @@ class GetxController extends DisposableInterface {
// for (final rs in _updatersGroupIds[id]) rs();
// }
ids.forEach((id) {
// _updatersIds[id]?.call(() {}); //<old>
// _updatersGroupIds[id]?.forEach((rs) => rs(() {})); //<old>
for (final id in ids) {
_updatersIds[id]?.call();
// ignore: avoid_function_literals_in_foreach_calls
_updatersGroupIds[id]?.forEach((rs) => rs());
});
}
}
}
... ...