From 5c18854c5d629d6ccc7a1ccac4fab3af9a3f510d Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 15:44:25 +0900 Subject: [PATCH 01/11] =?UTF-8?q?add:lint:=20^1.3.0=E3=82=92=E5=B0=8E?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- analysis_options.yaml | 228 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 analysis_options.yaml diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..2b50d37 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,228 @@ +# Specify analysis options. +# +# Until there are meta linter rules, each desired lint must be explicitly enabled. +# See: https://github.com/dart-lang/linter/issues/288 +# +# For a list of lints, see: http://dart-lang.github.io/linter/lints/ +# See the configuration guide for more +# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# +# There are other similar analysis options files in the flutter repos, +# which should be kept in sync with this file: +# +# - analysis_options.yaml (this file) +# - packages/flutter/lib/analysis_options_user.yaml +# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml +# - https://github.com/flutter/engine/blob/master/analysis_options.yaml +# +# This file contains the analysis options used by Flutter tools, such as IntelliJ, +# Android Studio, and the `flutter analyze` command. + +analyzer: + strong-mode: + implicit-casts: true + implicit-dynamic: true + errors: + # treat missing required parameters as a warning (not a hint) + missing_required_param: warning + # treat missing returns as a warning (not a hint) + missing_return: warning + # allow having TODOs in the code + todo: ignore + # allow self-reference to deprecated members (we do this because otherwise we have + # to annotate every member in every test, assert, etc, when we deprecate something) + deprecated_member_use_from_same_package: ignore + # Ignore analyzer hints for updating pubspecs when using Future or + # Stream and not importing dart:async + # Please see https://github.com/flutter/flutter/pull/24528 for details. + sdk_version_async_exported_from_core: ignore + exclude: + - "bin/cache/**" + # the following two are relative to the stocks example and the flutter package respectively + # see https://github.com/dart-lang/sdk/issues/28463 + - "lib/i18n/messages_*.dart" + - "lib/src/http/**" + +linter: + rules: + # these rules are documented on and in the same order as + # the Dart Lint rules page to make maintenance easier + # https://github.com/dart-lang/linter/blob/master/example/all.yaml + - always_declare_return_types + - always_put_control_body_on_new_line + # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 + - always_require_non_null_named_parameters + - always_specify_types + # - always_use_package_imports # we do this commonly + - annotate_overrides + # - avoid_annotating_with_dynamic # conflicts with always_specify_types + # - avoid_as # required for implicit-casts: true + - avoid_bool_literals_in_conditional_expressions + # - avoid_catches_without_on_clauses # we do this commonly + # - avoid_catching_errors # we do this commonly + - avoid_classes_with_only_static_members + # - avoid_double_and_int_checks # only useful when targeting JS runtime + - avoid_empty_else + - avoid_equals_and_hash_code_on_mutable_classes + # - avoid_escaping_inner_quotes # not yet tested + - avoid_field_initializers_in_const_classes + - avoid_function_literals_in_foreach_calls + # - avoid_implementing_value_types # not yet tested + - avoid_init_to_null + # - avoid_js_rounded_ints # only useful when targeting JS runtime + - avoid_null_checks_in_equality_operators + # - avoid_positional_boolean_parameters # not yet tested + # - avoid_print # not yet tested + # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) + # - avoid_redundant_argument_values # not yet tested + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + # - avoid_returning_null # there are plenty of valid reasons to return null + # - avoid_returning_null_for_future # not yet tested + - avoid_returning_null_for_void + # - avoid_returning_this # there are plenty of valid reasons to return this + # - avoid_setters_without_getters # not yet tested + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_slow_async_io + # - avoid_type_to_string # we do this commonly + - avoid_types_as_parameter_names + # - avoid_types_on_closure_parameters # conflicts with always_specify_types + # - avoid_unnecessary_containers # not yet tested + - avoid_unused_constructor_parameters + - avoid_void_async + # - avoid_web_libraries_in_flutter # not yet tested + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + # - cascade_invocations # not yet tested + - cast_nullable_to_non_nullable + # - close_sinks # not reliable enough + # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 + # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 + - control_flow_in_finally + # - curly_braces_in_flow_control_structures # not required by flutter style + # - diagnostic_describe_all_properties # not yet tested + - directives_ordering + # - do_not_use_environment # we do this commonly + - empty_catches + - empty_constructor_bodies + - empty_statements + - exhaustive_cases + # - file_names # not yet tested + - flutter_style_todos + - hash_and_equals + - implementation_imports + # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 + - iterable_contains_unrelated_type + # - join_return_with_assignment # not required by flutter style + - leading_newlines_in_multiline_strings + - library_names + - library_prefixes + # - lines_longer_than_80_chars # not required by flutter style + - list_remove_unrelated_type + # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 + # - missing_whitespace_between_adjacent_strings # not yet tested + - no_adjacent_strings_in_list + # - no_default_cases # too many false positives + - no_duplicate_case_values + - no_logic_in_create_state + # - no_runtimeType_toString # ok in tests; we enable this only in packages/ + - non_constant_identifier_names + - null_check_on_nullable_type_parameter + # - null_closures # not required by flutter style + # - omit_local_variable_types # opposite of always_specify_types + # - one_member_abstracts # too many false positives + # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 + - overridden_fields + - package_api_docs + # - package_names # non conforming packages in sdk + - package_prefixed_library_names + # - parameter_assignments # we do this commonly + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + # - prefer_asserts_with_message # not required by flutter style + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + # - prefer_constructors_over_static_methods # far too many false positives + - prefer_contains + # - prefer_double_quotes # opposite of prefer_single_quotes + - prefer_equal_for_default_values + # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + - prefer_for_elements_to_map_fromIterable + - prefer_foreach + # - prefer_function_declarations_over_variables # not yet tested + - prefer_generic_function_type_aliases + - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + # - prefer_int_literals # not yet tested + # - prefer_interpolation_to_compose_strings # not yet tested + - prefer_is_empty + - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + # - prefer_mixin # https://github.com/dart-lang/language/issues/32 + # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 + # - prefer_relative_imports # not yet tested + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + # - provide_deprecation_message # not yet tested + # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml + - recursive_getters + # - sized_box_for_whitespace # not yet tested + - slash_for_doc_comments + # - sort_child_properties_last # not yet tested + - sort_constructors_first + # - sort_pub_dependencies # prevents separating pinned transitive dependencies + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + - tighten_type_of_initializing_formals + # - type_annotate_public_apis # subset of always_specify_types + - type_init_formals + # - unawaited_futures # too many false positives + # - unnecessary_await_in_return # not yet tested + - unnecessary_brace_in_string_interps + - unnecessary_const + # - unnecessary_final # conflicts with prefer_final_locals + - unnecessary_getters_setters + # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 + - unnecessary_new + - unnecessary_null_aware_assignments + # - unnecessary_null_checks # not yet tested + - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations + - unnecessary_overrides + - unnecessary_parenthesis + # - unnecessary_raw_strings # not yet tested + - unnecessary_statements + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this + - unrelated_type_equality_checks + # - unsafe_html # not yet tested + - use_full_hex_values_for_flutter_colors + # - use_function_type_syntax_for_parameters # not yet tested + - use_is_even_rather_than_modulo + # - use_key_in_widget_constructors # not yet tested + - use_late_for_private_fields_and_variables + - use_raw_strings + - use_rethrow_when_possible + # - use_setters_to_change_properties # not yet tested + # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 + # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review + - valid_regexps + - void_checks \ No newline at end of file From 4b65fef34d95d84f9e902ed5c2f9c76f554a0421 Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 15:44:54 +0900 Subject: [PATCH 02/11] add:lint: ^1.3.0 --- analysis_options.yaml | 259 ++++++------------------------------------ pubspec.lock | 7 ++ pubspec.yaml | 1 + 3 files changed, 42 insertions(+), 225 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 2b50d37..ac4f3d6 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,228 +1,37 @@ -# Specify analysis options. -# -# Until there are meta linter rules, each desired lint must be explicitly enabled. -# See: https://github.com/dart-lang/linter/issues/288 -# -# For a list of lints, see: http://dart-lang.github.io/linter/lints/ -# See the configuration guide for more -# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer -# -# There are other similar analysis options files in the flutter repos, -# which should be kept in sync with this file: -# -# - analysis_options.yaml (this file) -# - packages/flutter/lib/analysis_options_user.yaml -# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml -# - https://github.com/flutter/engine/blob/master/analysis_options.yaml -# -# This file contains the analysis options used by Flutter tools, such as IntelliJ, -# Android Studio, and the `flutter analyze` command. - -analyzer: - strong-mode: - implicit-casts: true - implicit-dynamic: true - errors: - # treat missing required parameters as a warning (not a hint) - missing_required_param: warning - # treat missing returns as a warning (not a hint) - missing_return: warning - # allow having TODOs in the code - todo: ignore - # allow self-reference to deprecated members (we do this because otherwise we have - # to annotate every member in every test, assert, etc, when we deprecate something) - deprecated_member_use_from_same_package: ignore - # Ignore analyzer hints for updating pubspecs when using Future or - # Stream and not importing dart:async - # Please see https://github.com/flutter/flutter/pull/24528 for details. - sdk_version_async_exported_from_core: ignore - exclude: - - "bin/cache/**" - # the following two are relative to the stocks example and the flutter package respectively - # see https://github.com/dart-lang/sdk/issues/28463 - - "lib/i18n/messages_*.dart" - - "lib/src/http/**" +include: package:lint/analysis_options.yaml linter: rules: - # these rules are documented on and in the same order as - # the Dart Lint rules page to make maintenance easier - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 - - always_require_non_null_named_parameters - - always_specify_types - # - always_use_package_imports # we do this commonly - - annotate_overrides - # - avoid_annotating_with_dynamic # conflicts with always_specify_types - # - avoid_as # required for implicit-casts: true - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses # we do this commonly - # - avoid_catching_errors # we do this commonly - - avoid_classes_with_only_static_members - # - avoid_double_and_int_checks # only useful when targeting JS runtime - - avoid_empty_else - - avoid_equals_and_hash_code_on_mutable_classes - # - avoid_escaping_inner_quotes # not yet tested - - avoid_field_initializers_in_const_classes - - avoid_function_literals_in_foreach_calls - # - avoid_implementing_value_types # not yet tested - - avoid_init_to_null - # - avoid_js_rounded_ints # only useful when targeting JS runtime - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters # not yet tested - # - avoid_print # not yet tested - # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) - # - avoid_redundant_argument_values # not yet tested - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - # - avoid_returning_null # there are plenty of valid reasons to return null - # - avoid_returning_null_for_future # not yet tested - - avoid_returning_null_for_void - # - avoid_returning_this # there are plenty of valid reasons to return this - # - avoid_setters_without_getters # not yet tested - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - # - avoid_type_to_string # we do this commonly - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters # conflicts with always_specify_types - # - avoid_unnecessary_containers # not yet tested - - avoid_unused_constructor_parameters - - avoid_void_async - # - avoid_web_libraries_in_flutter # not yet tested - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - # - cascade_invocations # not yet tested - - cast_nullable_to_non_nullable - # - close_sinks # not reliable enough - # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 - # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 - - control_flow_in_finally - # - curly_braces_in_flow_control_structures # not required by flutter style - # - diagnostic_describe_all_properties # not yet tested - - directives_ordering - # - do_not_use_environment # we do this commonly - - empty_catches - - empty_constructor_bodies - - empty_statements - - exhaustive_cases - # - file_names # not yet tested - - flutter_style_todos - - hash_and_equals - - implementation_imports - # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 - - iterable_contains_unrelated_type - # - join_return_with_assignment # not required by flutter style - - leading_newlines_in_multiline_strings - - library_names - - library_prefixes - # - lines_longer_than_80_chars # not required by flutter style - - list_remove_unrelated_type - # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 - # - missing_whitespace_between_adjacent_strings # not yet tested - - no_adjacent_strings_in_list - # - no_default_cases # too many false positives - - no_duplicate_case_values - - no_logic_in_create_state - # - no_runtimeType_toString # ok in tests; we enable this only in packages/ - - non_constant_identifier_names - - null_check_on_nullable_type_parameter - # - null_closures # not required by flutter style - # - omit_local_variable_types # opposite of always_specify_types - # - one_member_abstracts # too many false positives - # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 - - overridden_fields - - package_api_docs - # - package_names # non conforming packages in sdk - - package_prefixed_library_names - # - parameter_assignments # we do this commonly - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - # - prefer_asserts_with_message # not required by flutter style - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - # - prefer_constructors_over_static_methods # far too many false positives - - prefer_contains - # - prefer_double_quotes # opposite of prefer_single_quotes - - prefer_equal_for_default_values - # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - # - prefer_function_declarations_over_variables # not yet tested - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - # - prefer_int_literals # not yet tested - # - prefer_interpolation_to_compose_strings # not yet tested - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - # - prefer_mixin # https://github.com/dart-lang/language/issues/32 - # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 - # - prefer_relative_imports # not yet tested - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - # - provide_deprecation_message # not yet tested - # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml - - recursive_getters - # - sized_box_for_whitespace # not yet tested - - slash_for_doc_comments - # - sort_child_properties_last # not yet tested - - sort_constructors_first - # - sort_pub_dependencies # prevents separating pinned transitive dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - # - type_annotate_public_apis # subset of always_specify_types - - type_init_formals - # - unawaited_futures # too many false positives - # - unnecessary_await_in_return # not yet tested - - unnecessary_brace_in_string_interps - - unnecessary_const - # - unnecessary_final # conflicts with prefer_final_locals - - unnecessary_getters_setters - # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 - - unnecessary_new - - unnecessary_null_aware_assignments - # - unnecessary_null_checks # not yet tested - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - # - unnecessary_raw_strings # not yet tested - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unrelated_type_equality_checks - # - unsafe_html # not yet tested - - use_full_hex_values_for_flutter_colors - # - use_function_type_syntax_for_parameters # not yet tested - - use_is_even_rather_than_modulo - # - use_key_in_widget_constructors # not yet tested - - use_late_for_private_fields_and_variables - - use_raw_strings - - use_rethrow_when_possible - # - use_setters_to_change_properties # not yet tested - # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 - # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review - - valid_regexps - - void_checks \ No newline at end of file + # ------ Disable individual rules ----- # + # --- # + # Turn off what you don't like. # + # ------------------------------------- # + + # Use parameter order as in json response + always_put_required_named_parameters_first: false + + # Util classes are awesome! + avoid_classes_with_only_static_members: false + + + # ------ Enable individual rules ------ # + # --- # + # These rules here are good but too # + # opinionated to enable them by default # + # ------------------------------------- # + + # Make constructors the first thing in every class + sort_constructors_first: true + + # The new tabs vs. spaces. Choose wisely + prefer_single_quotes: true + prefer_double_quotes: true + + # Good packages document everything + public_member_api_docs: true + + # Blindly follow the Flutter code style, which prefers types everywhere + always_specify_types: true + + # Back to the 80s + lines_longer_than_80_chars: true diff --git a/pubspec.lock b/pubspec.lock index 41d4896..9ee5d94 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -93,6 +93,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.16.1" + lint: + dependency: "direct main" + description: + name: lint + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 6550e56..40fd789 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: provider: ^4.3.2+2 sqflite: ^1.3.2+1 shared_preferences: ^0.5.12+4 + lint: ^1.3.0 dev_dependencies: flutter_test: From d464e05f6c42eb75c0e3e582193d38be57d6f2b7 Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 15:53:11 +0900 Subject: [PATCH 03/11] =?UTF-8?q?fix:lint=E3=81=9D=E3=81=AE=E3=81=BE?= =?UTF-8?q?=E3=81=BE=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8Fpedantic=5Fmono?= =?UTF-8?q?=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- analysis_options.yaml | 39 ++------------------------------------- pubspec.lock | 14 +++++++------- pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 45 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index ac4f3d6..c6d040c 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,37 +1,2 @@ -include: package:lint/analysis_options.yaml - -linter: - rules: - # ------ Disable individual rules ----- # - # --- # - # Turn off what you don't like. # - # ------------------------------------- # - - # Use parameter order as in json response - always_put_required_named_parameters_first: false - - # Util classes are awesome! - avoid_classes_with_only_static_members: false - - - # ------ Enable individual rules ------ # - # --- # - # These rules here are good but too # - # opinionated to enable them by default # - # ------------------------------------- # - - # Make constructors the first thing in every class - sort_constructors_first: true - - # The new tabs vs. spaces. Choose wisely - prefer_single_quotes: true - prefer_double_quotes: true - - # Good packages document everything - public_member_api_docs: true - - # Blindly follow the Flutter code style, which prefers types everywhere - always_specify_types: true - - # Back to the 80s - lines_longer_than_80_chars: true +# https://pub.dev/packages/pedantic_mono +include: package:pedantic_mono/analysis_options.yaml \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 9ee5d94..fe9c1ed 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -93,13 +93,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.16.1" - lint: - dependency: "direct main" - description: - name: lint - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" matcher: dependency: transitive description: @@ -149,6 +142,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.4+3" + pedantic_mono: + dependency: "direct dev" + description: + name: pedantic_mono + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0+3" platform: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 40fd789..d25e159 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,11 +17,11 @@ dependencies: provider: ^4.3.2+2 sqflite: ^1.3.2+1 shared_preferences: ^0.5.12+4 - lint: ^1.3.0 dev_dependencies: flutter_test: sdk: flutter + pedantic_mono: any flutter: uses-material-design: true From 7b5d28c43fc86de65fe8beb26424eab5f56778b9 Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 16:01:17 +0900 Subject: [PATCH 04/11] =?UTF-8?q?fix:common/*=E3=81=AElint=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/database_provider.dart | 40 ++++++++++---------- lib/common/persistence_storage_provider.dart | 8 ++-- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/lib/common/database_provider.dart b/lib/common/database_provider.dart index ec2fe06..091978d 100644 --- a/lib/common/database_provider.dart +++ b/lib/common/database_provider.dart @@ -9,7 +9,9 @@ import 'package:path/path.dart'; import 'package:sqflite/sqflite.dart'; class DatabaseProvider { - final databaseName = "TodoItem.db"; + DatabaseProvider._(); + + final databaseName = 'TodoItem.db'; final databaseVersion = 2; final migrations = [ ''' @@ -17,16 +19,12 @@ class DatabaseProvider { ''' ]; - DatabaseProvider._(); - static final DatabaseProvider instance = DatabaseProvider._(); Database _database; Future get database async { - if (_database != null) return _database; - _database = await initDatabase(); - return _database; + return _database ??= await initDatabase(); } void _createTable(Batch batch) { @@ -42,19 +40,21 @@ class DatabaseProvider { '''); } - initDatabase() async { - return await openDatabase(join(await getDatabasesPath(), databaseName), - version: databaseVersion, - onCreate: (db, version) async { - var batch = db.batch(); - _createTable(batch); - await batch.commit(); - }, - onDowngrade: onDatabaseDowngradeDelete, - onUpgrade: (db, oldVersion, newVersion) async { - for (var i = oldVersion - 1; i <= newVersion - 1; i++) { - await db.execute(migrations[i]); - } - }); + Future initDatabase() async { + final result = + await openDatabase(join(await getDatabasesPath(), databaseName), + version: databaseVersion, + onCreate: (db, version) async { + final batch = db.batch(); + _createTable(batch); + await batch.commit(); + }, + onDowngrade: onDatabaseDowngradeDelete, + onUpgrade: (db, oldVersion, newVersion) async { + for (var i = oldVersion - 1; i <= newVersion - 1; i++) { + await db.execute(migrations[i]); + } + }); + return result; } } diff --git a/lib/common/persistence_storage_provider.dart b/lib/common/persistence_storage_provider.dart index 8b9732a..6cf382b 100644 --- a/lib/common/persistence_storage_provider.dart +++ b/lib/common/persistence_storage_provider.dart @@ -15,13 +15,11 @@ class PersistenceStorageProvider { SharedPreferences _prefs; Future get prefs async { - if (_prefs != null) return _prefs; - _prefs = await initSharedPreferences(); - return _prefs; + return _prefs ??= await initSharedPreferences(); } - initSharedPreferences() async { - SharedPreferences prefs = await SharedPreferences.getInstance(); + Future initSharedPreferences() async { + final prefs = await SharedPreferences.getInstance(); return prefs; } } From 8f1da2849bc4287e077d06dbdc203db04c2d54eb Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 16:11:51 +0900 Subject: [PATCH 05/11] =?UTF-8?q?fix:domain/*=E3=81=AElint=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/domain/todo_item.dart | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/domain/todo_item.dart b/lib/domain/todo_item.dart index e159e75..95a8f60 100644 --- a/lib/domain/todo_item.dart +++ b/lib/domain/todo_item.dart @@ -14,6 +14,15 @@ class TodoItem { this.updatedAt, this.isDone}); + factory TodoItem.fromMap(Map json) => TodoItem( + id: json['id'] as int, + title: json['title'] as String, + body: json['body'] as String, + createdAt: DateTime.parse(json['createdAt'] as String).toLocal(), + updatedAt: DateTime.parse(json['updatedAt'] as String).toLocal(), + isDone: json['isDone'] == '1', + ); + final int id; String title; String body; @@ -29,25 +38,16 @@ class TodoItem { bool get getIsDone => isDone; Map toMap() { - return { + return { 'id': id, 'title': title, 'body': body, 'createdAt': createdAt.toUtc().toIso8601String(), 'updatedAt': updatedAt.toUtc().toIso8601String(), - 'isDone': (isDone) ? 1 : 0, + 'isDone': isDone ? 1 : 0, }; } - factory TodoItem.fromMap(Map json) => TodoItem( - id: json["id"], - title: json["title"], - body: json["body"], - createdAt: DateTime.parse(json["createdAt"]).toLocal(), - updatedAt: DateTime.parse(json["updatedAt"]).toLocal(), - isDone: (json["isDone"] == "1") ? true : false, - ); - @override String toString() { return 'Todo{id: $id, title: $title, createdAt: $createdAt}'; From a3a13e9d934bf7432eca904c9732ab1419e24b4d Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 16:12:17 +0900 Subject: [PATCH 06/11] =?UTF-8?q?fix:infrastructure/*=E3=81=AElint?= =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../todo_item_repository_impl.dart | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/infrastructure/todo_item_repository_impl.dart b/lib/infrastructure/todo_item_repository_impl.dart index e1177bd..f267b70 100644 --- a/lib/infrastructure/todo_item_repository_impl.dart +++ b/lib/infrastructure/todo_item_repository_impl.dart @@ -5,7 +5,6 @@ * https://opensource.org/licenses/mit-license.php * */ -import 'package:sqflite/sqflite.dart'; import 'package:todo_app_sample_flutter/common/database_provider.dart'; import 'package:todo_app_sample_flutter/domain/todo_item.dart'; import 'package:todo_app_sample_flutter/domain/todo_item_repository.dart'; @@ -17,7 +16,7 @@ class TodoItemRepositoryImpl implements TodoItemRepository { @override Future create( String title, String body, bool isDone, DateTime now) async { - final Map row = { + final row = { 'title': title, 'body': body, 'createdAt': now.toString(), @@ -28,8 +27,8 @@ class TodoItemRepositoryImpl implements TodoItemRepository { final id = await db.insert(table, row); return TodoItem( id: id, - title: row["title"], - body: row["body"], + title: row['title'] as String, + body: row['body'] as String, createdAt: now, updatedAt: now, isDone: isDone, @@ -38,7 +37,7 @@ class TodoItemRepositoryImpl implements TodoItemRepository { @override Future> findAll({bool viewCompletedItems = true}) async { - final Database db = await instance.database; + final db = await instance.database; final rows = (viewCompletedItems == null || viewCompletedItems) ? await db.rawQuery('SELECT * FROM $table ORDER BY updatedAt DESC') @@ -51,26 +50,30 @@ class TodoItemRepositoryImpl implements TodoItemRepository { @override Future find(int id) async { final db = await instance.database; - final rows = await db.rawQuery('SELECT * FROM $table WHERE id = ?', [id]); - if (rows.isEmpty) return null; - return TodoItem.fromMap(rows.first); + final rows = + await db.rawQuery('SELECT * FROM $table WHERE id = ?', [id]); + if (rows.isEmpty) { + return null; + } else { + return TodoItem.fromMap(rows.first); + } } @override Future updateIsDoneById(int id, bool isDone) async { - print("id=$id,isDone=$isDone"); + print('id=$id,isDone=$isDone'); final row = { 'id': id, - 'isDone': (isDone) ? 1 : 0, + 'isDone': isDone ? 1 : 0, }; final db = await instance.database; - await db.update(table, row, where: 'id = ?', whereArgs: [id]); + await db.update(table, row, where: 'id = ?', whereArgs: [id]); } @override Future delete(int id) async { final db = await instance.database; - await db.delete(table, where: "id = ?", whereArgs: [id]); + await db.delete(table, where: 'id = ?', whereArgs: [id]); } @override @@ -82,6 +85,6 @@ class TodoItemRepositoryImpl implements TodoItemRepository { 'updatedAt': todoItem.updatedAt.toString(), }; final db = await instance.database; - await db.update(table, row, where: 'id = ?', whereArgs: [todoItem.id]); + await db.update(table, row, where: 'id = ?', whereArgs: [todoItem.id]); } } From c539db6a975c5ac9aab8b75963b44184e4400dc1 Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 16:48:56 +0900 Subject: [PATCH 07/11] =?UTF-8?q?fix:lint=E3=82=A8=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../todo_item_detail_model.dart | 12 +++---- .../todo_item_detail_page.dart | 31 +++++++++--------- .../todo_list/todo_list_page.dart | 32 +++++++++---------- test/todo_item_test.dart | 2 +- 4 files changed, 39 insertions(+), 38 deletions(-) diff --git a/lib/presentation/todo_item_detail/todo_item_detail_model.dart b/lib/presentation/todo_item_detail/todo_item_detail_model.dart index c2f3cdf..b0ff3c8 100644 --- a/lib/presentation/todo_item_detail/todo_item_detail_model.dart +++ b/lib/presentation/todo_item_detail/todo_item_detail_model.dart @@ -13,15 +13,15 @@ class TodoItemDetailModel extends ChangeNotifier { TodoItemDetailModel({ @required TodoItemRepository todoItemRepository, }) : _todoItemRepository = todoItemRepository; - TodoItemRepository _todoItemRepository; + final TodoItemRepository _todoItemRepository; - String todoTitle = ""; - String todoBody = ""; + String todoTitle = ''; + String todoBody = ''; bool isDone = false; Future add() async { if (todoTitle == null || todoTitle.isEmpty) { - throw ("タイトルを入力してください。"); + throw 'タイトルを入力してください。'; } await _todoItemRepository.create( todoTitle, @@ -35,8 +35,8 @@ class TodoItemDetailModel extends ChangeNotifier { Future update(int id) async { final todoItem = TodoItem( id: id, - title: (todoTitle.isEmpty) ? todoTitle = "" : todoTitle, - body: (todoBody.isEmpty) ? "" : todoBody, + title: (todoTitle.isEmpty) ? todoTitle = '' : todoTitle, + body: (todoBody.isEmpty) ? '' : todoBody, updatedAt: DateTime.now(), ); await _todoItemRepository.update(todoItem); diff --git a/lib/presentation/todo_item_detail/todo_item_detail_page.dart b/lib/presentation/todo_item_detail/todo_item_detail_page.dart index 5a86ac9..239a681 100644 --- a/lib/presentation/todo_item_detail/todo_item_detail_page.dart +++ b/lib/presentation/todo_item_detail/todo_item_detail_page.dart @@ -12,12 +12,12 @@ import 'package:todo_app_sample_flutter/domain/todo_item_repository.dart'; import 'package:todo_app_sample_flutter/presentation/todo_item_detail/todo_item_detail_model.dart'; class TodoItemDetailPage extends StatelessWidget { - TodoItemDetailPage({this.todoItem}); + const TodoItemDetailPage({this.todoItem}); final TodoItem todoItem; @override Widget build(BuildContext context) { - final bool isUpdate = todoItem != null; + final isUpdate = todoItem != null; final titleEditingController = TextEditingController(); final detailEditingController = TextEditingController(); titleEditingController.text = todoItem?.title; @@ -28,51 +28,52 @@ class TodoItemDetailPage extends StatelessWidget { ), child: Scaffold( appBar: AppBar( - title: Text(isUpdate ? "タスクの更新" : "新規追加"), + title: Text(isUpdate ? 'タスクの更新' : '新規追加'), ), body: Consumer(builder: (context, model, child) { model.todoTitle = todoItem?.title; model.todoBody = todoItem?.body; return Padding( - padding: const EdgeInsets.all(16.0), + padding: const EdgeInsets.all(16), child: Column( children: [ TextField( - decoration: InputDecoration( - labelText: "タイトル", - hintText: "やること", + decoration: const InputDecoration( + labelText: 'タイトル', + hintText: 'やること', ), onChanged: (title) { model.todoTitle = title; }, controller: titleEditingController, ), - SizedBox( + const SizedBox( height: 16, ), TextField( - decoration: InputDecoration( - labelText: "詳細", - hintText: "やることの詳細", + decoration: const InputDecoration( + labelText: '詳細', + hintText: 'やることの詳細', ), onChanged: (body) { model.todoBody = body; }, controller: detailEditingController, ), - SizedBox( + const SizedBox( height: 16, ), RaisedButton( - child: Text(isUpdate ? "更新する" : "追加する"), + child: Text(isUpdate ? '更新する' : '追加する'), onPressed: () async { try { isUpdate ? await model.update(todoItem.id) : await model.add(); Navigator.pop(context); + // ignore: avoid_catches_without_on_clauses } catch (e) { - showDialog( + await showDialog( context: context, builder: (BuildContext context) { return AlertDialog( @@ -82,7 +83,7 @@ class TodoItemDetailPage extends StatelessWidget { onPressed: () { Navigator.of(context).pop(); }, - child: Text("OK"), + child: const Text('OK'), ) ], ); diff --git a/lib/presentation/todo_list/todo_list_page.dart b/lib/presentation/todo_list/todo_list_page.dart index 9d35eb5..0c9bbea 100644 --- a/lib/presentation/todo_list/todo_list_page.dart +++ b/lib/presentation/todo_list/todo_list_page.dart @@ -28,14 +28,14 @@ class TodoListPage extends StatelessWidget { )..init(), child: Scaffold( appBar: AppBar( - title: Text("TODOAppSample-Flutter"), + title: const Text('TODOAppSample-Flutter'), actions: [ Consumer(builder: (context, model, child) { return PopupMenuButton( - initialValue: "model.viewCompletedItems", - onSelected: (String s) { + initialValue: 'model.viewCompletedItems', + onSelected: (String s)async { model.changeViewCompletedItems(s); - model.getTodoList(); + await model.getTodoList(); }, itemBuilder: (BuildContext context) { return _displayConfig.map((String s) { @@ -65,7 +65,7 @@ class TodoListPage extends StatelessWidget { title: RichText( text: TextSpan( text: todo.title, - style: TextStyle( + style: const TextStyle( color: Colors.black87, ), ), @@ -73,12 +73,12 @@ class TodoListPage extends StatelessWidget { onTap: () { pushWithReload(context, model, todoItem: todo); }, - onLongPress: () { - showDialog( + onLongPress: () async{ + await showDialog( context: context, builder: (BuildContext context) { return AlertDialog( - title: Text("${todo.title}を削除しますか?"), + title: Text('${todo.title}を削除しますか?'), actions: [ FlatButton( onPressed: () { @@ -86,13 +86,13 @@ class TodoListPage extends StatelessWidget { model.getTodoList(); Navigator.of(context).pop(); }, - child: Text("はい"), + child: const Text('はい'), ), FlatButton( onPressed: () { Navigator.of(context).pop(); }, - child: Text("いいえ"), + child: const Text('いいえ'), ), ], ); @@ -103,8 +103,8 @@ class TodoListPage extends StatelessWidget { ) ?.toList() ?? [ - ListTile( - title: Text(""), + const ListTile( + title: Text(''), ) ], ); @@ -115,20 +115,20 @@ class TodoListPage extends StatelessWidget { onPressed: () { pushWithReload(context, model); }, - child: Icon(Icons.add), + child: const Icon(Icons.add), ); }), ), ); } - void pushWithReload(BuildContext context, TodoListModel model, + Future pushWithReload(BuildContext context, TodoListModel model, {TodoItem todoItem}) async { - await Navigator.push( + await Navigator.push( context, MaterialPageRoute( builder: (context) => (todoItem == null) - ? TodoItemDetailPage() + ? const TodoItemDetailPage() : TodoItemDetailPage(todoItem: todoItem), fullscreenDialog: true, ), diff --git a/test/todo_item_test.dart b/test/todo_item_test.dart index e12a83b..7b79da5 100644 --- a/test/todo_item_test.dart +++ b/test/todo_item_test.dart @@ -78,7 +78,7 @@ void main() { }); group("fromMapのテスト", () { - final Map json = { + final json = { 'id': 0, 'title': 'title', 'body': 'body', From 73b5c06edb1df4660fc9831d26ed57aaa06d9dfc Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 17:07:55 +0900 Subject: [PATCH 08/11] =?UTF-8?q?fix:lib=E5=86=85=E3=81=AElint=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=81=99=E3=81=B9=E3=81=A6=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/domain/storage_repository.dart | 2 +- lib/domain/todo_item_repository.dart | 16 +++++++--- .../todo_item_repository_impl.dart | 27 +++++++++++----- .../todo_item_detail_model.dart | 19 +++++++----- .../todo_item_detail_page.dart | 3 +- .../todo_list/todo_list_model.dart | 31 +++++++++++-------- .../todo_list/todo_list_page.dart | 18 +++++------ test/todo_list_model_test.dart | 21 +++++-------- 8 files changed, 79 insertions(+), 58 deletions(-) diff --git a/lib/domain/storage_repository.dart b/lib/domain/storage_repository.dart index 25d1499..f93f0b9 100644 --- a/lib/domain/storage_repository.dart +++ b/lib/domain/storage_repository.dart @@ -11,4 +11,4 @@ abstract class StorageRepository { Future isExistKey(String key); } -const String VIEW_COMPLETED_ITEMS_KEY = "view_completed_items"; +const String viewCompletedItemsKey = 'view_completed_items'; diff --git a/lib/domain/todo_item_repository.dart b/lib/domain/todo_item_repository.dart index e0d75b2..662a1da 100644 --- a/lib/domain/todo_item_repository.dart +++ b/lib/domain/todo_item_repository.dart @@ -1,10 +1,16 @@ +import 'package:flutter/material.dart'; import 'package:todo_app_sample_flutter/domain/todo_item.dart'; abstract class TodoItemRepository { - Future create(String title, String body, bool isDone, DateTime now); + Future create({ + @required String title, + @required String body, + @required bool isDone, + @required DateTime now, + }); Future> findAll({bool viewCompletedItems}); - Future find(int id); - Future update(TodoItem todoItem); - Future updateIsDoneById(int id, bool isDone); - Future delete(int id); + Future find({@required int id}); + Future update({@required TodoItem todoItem}); + Future updateIsDoneById({@required int id, @required bool isDone}); + Future delete({@required int id}); } diff --git a/lib/infrastructure/todo_item_repository_impl.dart b/lib/infrastructure/todo_item_repository_impl.dart index f267b70..ad9622f 100644 --- a/lib/infrastructure/todo_item_repository_impl.dart +++ b/lib/infrastructure/todo_item_repository_impl.dart @@ -5,6 +5,7 @@ * https://opensource.org/licenses/mit-license.php * */ +import 'package:flutter/material.dart'; import 'package:todo_app_sample_flutter/common/database_provider.dart'; import 'package:todo_app_sample_flutter/domain/todo_item.dart'; import 'package:todo_app_sample_flutter/domain/todo_item_repository.dart'; @@ -14,8 +15,12 @@ class TodoItemRepositoryImpl implements TodoItemRepository { static DatabaseProvider instance = DatabaseProvider.instance; @override - Future create( - String title, String body, bool isDone, DateTime now) async { + Future create({ + @required String title, + @required String body, + @required bool isDone, + @required DateTime now, + }) async { final row = { 'title': title, 'body': body, @@ -43,12 +48,15 @@ class TodoItemRepositoryImpl implements TodoItemRepository { ? await db.rawQuery('SELECT * FROM $table ORDER BY updatedAt DESC') : await db.rawQuery( 'SELECT * FROM $table WHERE isDone = 0 ORDER BY updatedAt DESC'); - if (rows.isEmpty) return null; - return rows.map((json) => TodoItem.fromMap(json)).toList(); + if (rows.isEmpty) { + return null; + } else { + return rows.map((json) => TodoItem.fromMap(json)).toList(); + } } @override - Future find(int id) async { + Future find({@required int id}) async { final db = await instance.database; final rows = await db.rawQuery('SELECT * FROM $table WHERE id = ?', [id]); @@ -60,7 +68,10 @@ class TodoItemRepositoryImpl implements TodoItemRepository { } @override - Future updateIsDoneById(int id, bool isDone) async { + Future updateIsDoneById({ + @required int id, + @required bool isDone, + }) async { print('id=$id,isDone=$isDone'); final row = { 'id': id, @@ -71,13 +82,13 @@ class TodoItemRepositoryImpl implements TodoItemRepository { } @override - Future delete(int id) async { + Future delete({@required int id}) async { final db = await instance.database; await db.delete(table, where: 'id = ?', whereArgs: [id]); } @override - Future update(TodoItem todoItem) async { + Future update({@required TodoItem todoItem}) async { final row = { 'id': todoItem.id, 'title': todoItem.title, diff --git a/lib/presentation/todo_item_detail/todo_item_detail_model.dart b/lib/presentation/todo_item_detail/todo_item_detail_model.dart index b0ff3c8..b201a25 100644 --- a/lib/presentation/todo_item_detail/todo_item_detail_model.dart +++ b/lib/presentation/todo_item_detail/todo_item_detail_model.dart @@ -19,16 +19,21 @@ class TodoItemDetailModel extends ChangeNotifier { String todoBody = ''; bool isDone = false; + void setTodoItem(TodoItem todoItem) { + todoTitle = todoItem.title; + todoBody = todoItem.body; + } + Future add() async { if (todoTitle == null || todoTitle.isEmpty) { - throw 'タイトルを入力してください。'; + final Error error = ArgumentError('タイトルを入力してください。'); + throw error; } await _todoItemRepository.create( - todoTitle, - (todoBody.isEmpty) ? "" : todoBody, - isDone, - DateTime.now(), - ); + title: todoTitle, + body: (todoBody.isEmpty) ? '' : todoBody, + isDone: isDone, + now: DateTime.now()); notifyListeners(); } @@ -39,7 +44,7 @@ class TodoItemDetailModel extends ChangeNotifier { body: (todoBody.isEmpty) ? '' : todoBody, updatedAt: DateTime.now(), ); - await _todoItemRepository.update(todoItem); + await _todoItemRepository.update(todoItem: todoItem); notifyListeners(); } } diff --git a/lib/presentation/todo_item_detail/todo_item_detail_page.dart b/lib/presentation/todo_item_detail/todo_item_detail_page.dart index 239a681..e3b2dc0 100644 --- a/lib/presentation/todo_item_detail/todo_item_detail_page.dart +++ b/lib/presentation/todo_item_detail/todo_item_detail_page.dart @@ -31,8 +31,7 @@ class TodoItemDetailPage extends StatelessWidget { title: Text(isUpdate ? 'タスクの更新' : '新規追加'), ), body: Consumer(builder: (context, model, child) { - model.todoTitle = todoItem?.title; - model.todoBody = todoItem?.body; + todoItem ?? model.setTodoItem(todoItem); return Padding( padding: const EdgeInsets.all(16), child: Column( diff --git a/lib/presentation/todo_list/todo_list_model.dart b/lib/presentation/todo_list/todo_list_model.dart index a0a7869..3054c94 100644 --- a/lib/presentation/todo_list/todo_list_model.dart +++ b/lib/presentation/todo_list/todo_list_model.dart @@ -32,39 +32,44 @@ class TodoListModel extends ChangeNotifier { notifyListeners(); } - Future updateIsDone(int id, bool isDone) async { - await _todoItemRepository.updateIsDoneById(id, isDone); + Future updateIsDone({@required int id, @required bool isDone}) async { + await _todoItemRepository.updateIsDoneById(id: id, isDone: isDone); notifyListeners(); } - Future deleteTodoItem(int id) async { - await _todoItemRepository.delete(id); + Future deleteTodoItem({@required int id}) async { + await _todoItemRepository.delete(id: id); notifyListeners(); } - Future changeViewCompletedItems(String s) async { - switch (s) { - case VIEW_COMPLETED_ITEMS_TRUE_STRING: + Future deleteAndReload({@required int id}) async { + await deleteTodoItem(id: id); + await getTodoList(); + } + + Future changeViewCompletedItems(String viewCompletedItemString) async { + switch (viewCompletedItemString) { + case viewCompletedItemsTrueString: viewCompletedItems = true; break; - case VIEW_COMPLETED_ITEMS_FALSE_STRING: + case viewCompletedItemsFalseString: viewCompletedItems = false; break; } await _storageRepository.savePersistenceStorage( - VIEW_COMPLETED_ITEMS_KEY, viewCompletedItems.toString()); + viewCompletedItemsKey, viewCompletedItems.toString()); } Future loadViewCompletedItems() async { - if (!await _storageRepository.isExistKey(VIEW_COMPLETED_ITEMS_KEY)) { + if (!await _storageRepository.isExistKey(viewCompletedItemsKey)) { return null; } else { final result = await _storageRepository - .loadPersistenceStorage(VIEW_COMPLETED_ITEMS_KEY); + .loadPersistenceStorage(viewCompletedItemsKey); return result == 'true'; } } } -const String VIEW_COMPLETED_ITEMS_TRUE_STRING = "完了済みのアイテムを表示する"; -const String VIEW_COMPLETED_ITEMS_FALSE_STRING = "完了済みのアイテムを表示しない"; +const String viewCompletedItemsTrueString = '完了済みのアイテムを表示する'; +const String viewCompletedItemsFalseString = '完了済みのアイテムを表示しない'; diff --git a/lib/presentation/todo_list/todo_list_page.dart b/lib/presentation/todo_list/todo_list_page.dart index 0c9bbea..6645472 100644 --- a/lib/presentation/todo_list/todo_list_page.dart +++ b/lib/presentation/todo_list/todo_list_page.dart @@ -15,8 +15,8 @@ import 'package:todo_app_sample_flutter/presentation/todo_list/todo_list_model.d class TodoListPage extends StatelessWidget { final _displayConfig = [ - VIEW_COMPLETED_ITEMS_TRUE_STRING, - VIEW_COMPLETED_ITEMS_FALSE_STRING + viewCompletedItemsTrueString, + viewCompletedItemsFalseString ]; @override @@ -33,9 +33,9 @@ class TodoListPage extends StatelessWidget { Consumer(builder: (context, model, child) { return PopupMenuButton( initialValue: 'model.viewCompletedItems', - onSelected: (String s)async { + onSelected: (String s) async { model.changeViewCompletedItems(s); - await model.getTodoList(); + await model.getTodoList(); }, itemBuilder: (BuildContext context) { return _displayConfig.map((String s) { @@ -59,7 +59,8 @@ class TodoListPage extends StatelessWidget { value: todo.isDone, onChanged: (bool value) { todo.isDone = !todo.isDone; - model.updateIsDone(todo.id, todo.isDone); + model.updateIsDone( + id: todo.id, isDone: todo.isDone); }, ), title: RichText( @@ -73,7 +74,7 @@ class TodoListPage extends StatelessWidget { onTap: () { pushWithReload(context, model, todoItem: todo); }, - onLongPress: () async{ + onLongPress: () async { await showDialog( context: context, builder: (BuildContext context) { @@ -81,9 +82,8 @@ class TodoListPage extends StatelessWidget { title: Text('${todo.title}を削除しますか?'), actions: [ FlatButton( - onPressed: () { - model.deleteTodoItem(todo.id); - model.getTodoList(); + onPressed: () async { + await model.deleteAndReload(id: todo.id); Navigator.of(context).pop(); }, child: const Text('はい'), diff --git a/test/todo_list_model_test.dart b/test/todo_list_model_test.dart index 1574dab..160d941 100644 --- a/test/todo_list_model_test.dart +++ b/test/todo_list_model_test.dart @@ -126,14 +126,12 @@ void main() { storageRepository.clear(); // メソッド実行 - await model.changeViewCompletedItems(VIEW_COMPLETED_ITEMS_TRUE_STRING); + await model.changeViewCompletedItems(viewCompletedItemsTrueString); // 結果確認 + expect(await storageRepository.isExistKey(viewCompletedItemsKey), true); expect( - await storageRepository.isExistKey(VIEW_COMPLETED_ITEMS_KEY), true); - expect( - await storageRepository - .loadPersistenceStorage(VIEW_COMPLETED_ITEMS_KEY), + await storageRepository.loadPersistenceStorage(viewCompletedItemsKey), 'true'); }); }); @@ -147,8 +145,7 @@ void main() { final result = await model.loadViewCompletedItems(); // 結果確認 - expect( - await storageRepository.isExistKey(VIEW_COMPLETED_ITEMS_KEY), false); + expect(await storageRepository.isExistKey(viewCompletedItemsKey), false); expect(result, null); }); @@ -156,18 +153,16 @@ void main() { // 事前準備 storageRepository.clear(); storageRepository.savePersistenceStorage( - VIEW_COMPLETED_ITEMS_KEY, VIEW_COMPLETED_ITEMS_TRUE_STRING); + viewCompletedItemsKey, viewCompletedItemsTrueString); // メソッド実行 await model.loadViewCompletedItems(); // 結果確認 + expect(await storageRepository.isExistKey(viewCompletedItemsKey), true); expect( - await storageRepository.isExistKey(VIEW_COMPLETED_ITEMS_KEY), true); - expect( - await storageRepository - .loadPersistenceStorage(VIEW_COMPLETED_ITEMS_KEY), - VIEW_COMPLETED_ITEMS_TRUE_STRING); + await storageRepository.loadPersistenceStorage(viewCompletedItemsKey), + viewCompletedItemsTrueString); }); }); } From 9f469b93cd54d0b4d828acb3680088bb41cc82ac Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 17:37:56 +0900 Subject: [PATCH 09/11] =?UTF-8?q?fix:test=E3=82=82=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E4=BF=AE=E6=AD=A3=E5=AE=8C=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../todo_item_repository_mem_impl.dart | 36 +++++----- test/todo_item_detail_model_test.dart | 31 ++++---- test/todo_list_model_test.dart | 71 +++++++++++-------- 3 files changed, 81 insertions(+), 57 deletions(-) diff --git a/test/infrastructure/todo_item_repository_mem_impl.dart b/test/infrastructure/todo_item_repository_mem_impl.dart index 03f1e3a..199e6ce 100644 --- a/test/infrastructure/todo_item_repository_mem_impl.dart +++ b/test/infrastructure/todo_item_repository_mem_impl.dart @@ -5,6 +5,7 @@ * https://opensource.org/licenses/mit-license.php * */ +import 'package:flutter/material.dart'; import 'package:todo_app_sample_flutter/domain/todo_item.dart'; import 'package:todo_app_sample_flutter/domain/todo_item_repository.dart'; @@ -27,8 +28,12 @@ class TodoItemRepositoryMemImpl implements TodoItemRepository { } @override - Future create( - String title, String body, bool isDone, DateTime now) { + Future create({ + @required String title, + @required String body, + @required bool isDone, + @required DateTime now, + }) { final result = TodoItem( id: _currentId, title: title, @@ -42,19 +47,17 @@ class TodoItemRepositoryMemImpl implements TodoItemRepository { } @override - Future delete(int id) { + Future delete({@required int id}) { _data.remove(id); return null; } @override Future> findAll({bool viewCompletedItems = true}) { - List result = []; - final List todoItems = List.unmodifiable(_data.values); + var result = []; + final todoItems = List.unmodifiable(_data.values); if (!viewCompletedItems) { - todoItems.forEach((element) { - result.add(element); - }); + todoItems.forEach(result.add); } else { result = todoItems; } @@ -62,24 +65,23 @@ class TodoItemRepositoryMemImpl implements TodoItemRepository { } @override - Future find(int id) { + Future find({@required int id}) { return Future.value(_data[id]); } @override - Future updateIsDoneById(int id, bool isDone) { - final todoItem = _data[id]; - todoItem.isDone = isDone; + Future updateIsDoneById({@required int id, @required bool isDone}) { + final todoItem = _data[id]..isDone = isDone; _data[id] = todoItem; return null; } @override - Future update(TodoItem todoItem) { - TodoItem updateData = _data[todoItem.id]; - updateData.title = todoItem.title; - updateData.body = todoItem.body; - updateData.updatedAt = todoItem.updatedAt; + Future update({@required TodoItem todoItem}) { + final updateData = _data[todoItem.id] + ..title = todoItem.title + ..body = todoItem.body + ..updatedAt = todoItem.updatedAt; _data[todoItem.id] = updateData; return null; } diff --git a/test/todo_item_detail_model_test.dart b/test/todo_item_detail_model_test.dart index 3720e95..77fa165 100644 --- a/test/todo_item_detail_model_test.dart +++ b/test/todo_item_detail_model_test.dart @@ -15,9 +15,8 @@ import 'package:todo_app_sample_flutter/presentation/todo_item_detail/todo_item_ import 'infrastructure/todo_item_repository_mem_impl.dart'; void main() { - final TodoItemRepositoryMemImpl repository = TodoItemRepositoryMemImpl(); - final TodoItemDetailModel model = - TodoItemDetailModel(todoItemRepository: repository); + final repository = TodoItemRepositoryMemImpl(); + final model = TodoItemDetailModel(todoItemRepository: repository); final dummyDate = DateTime.now(); group('add', () { @@ -31,14 +30,15 @@ void main() { createdAt: dummyDate, updatedAt: dummyDate, ); - model.todoTitle = data.title; - model.todoBody = data.body; + model + ..todoTitle = data.title + ..todoBody = data.body; // メソッド実行 - bool isSuccessful = true; + var isSuccessful = true; try { await model.add(); - } catch (e) { + } on Exception { isSuccessful = false; } @@ -67,16 +67,23 @@ void main() { createdAt: dummyDate, updatedAt: dummyDate, ); + // repository.create( + // '変更前', '変更前', false, DateTime.now().subtract(Duration(days: 1))); repository.create( - '変更前', '変更前', false, DateTime.now().subtract(Duration(days: 1))); - model.todoTitle = data.title; - model.todoBody = data.body; + title: '変更前', + body: '変更前', + isDone: false, + now: DateTime.now().subtract(const Duration(days: 1)), + ); + model + ..todoTitle = data.title + ..todoBody = data.body; // メソッド実行 - bool isSuccessful = true; + var isSuccessful = true; try { await model.update(repository.currentId); - } catch (e) { + } on Exception { isSuccessful = false; } diff --git a/test/todo_list_model_test.dart b/test/todo_list_model_test.dart index 160d941..829bb8e 100644 --- a/test/todo_list_model_test.dart +++ b/test/todo_list_model_test.dart @@ -14,16 +14,15 @@ import 'infrastructure/storage_repository_mem_impl.dart'; import 'infrastructure/todo_item_repository_mem_impl.dart'; void main() { - final StorageRepositoryMemImpl storageRepository = StorageRepositoryMemImpl(); - final TodoItemRepositoryMemImpl todoItemRepository = - TodoItemRepositoryMemImpl(); + final storageRepository = StorageRepositoryMemImpl(); + final todoItemRepository = TodoItemRepositoryMemImpl(); final model = TodoListModel( storageRepository: storageRepository, todoItemRepository: todoItemRepository); final now = DateTime.now(); final yesterday = DateTime(now.year, now.month, now.day - 1, now.hour, now.minute); - final List data = [ + final data = [ TodoItem( id: 1, title: 'title1', @@ -51,18 +50,24 @@ void main() { test('正常系', () async { // 事前準備 todoItemRepository.clear(); - data.forEach((todoItem) { - todoItemRepository.incrementId(); - todoItemRepository.create( - todoItem.title, todoItem.body, todoItem.isDone, now); - }); + + for (final todoItem in data) { + todoItemRepository + ..incrementId() + ..create( + title: todoItem.title, + body: todoItem.body, + isDone: todoItem.isDone, + now: now); + } + model.viewCompletedItems = true; // メソッド実行 - bool isSuccessful = true; + var isSuccessful = true; try { await model.getTodoList(); - } catch (e) { + } on Exception { isSuccessful = false; } @@ -83,14 +88,18 @@ void main() { test('正常系', () async { // 事前準備 todoItemRepository.clear(); - data.forEach((todoItem) { - todoItemRepository.incrementId(); - todoItemRepository.create( - todoItem.title, todoItem.body, todoItem.isDone, now); - }); + for (final todoItem in data) { + todoItemRepository + ..incrementId() + ..create( + title: todoItem.title, + body: todoItem.body, + isDone: todoItem.isDone, + now: now); + } // メソッド実行 - await model.updateIsDone(2, true); + await model.updateIsDone(id: 2, isDone: true); // 結果確認 final result = await todoItemRepository.findAll(); @@ -102,21 +111,26 @@ void main() { test('正常系', () async { // 事前準備 todoItemRepository.clear(); - data.forEach((todoItem) { - todoItemRepository.incrementId(); - todoItemRepository.create( - todoItem.title, todoItem.body, todoItem.isDone, now); - }); + for (final todoItem in data) { + todoItemRepository + ..incrementId() + ..create( + title: todoItem.title, + body: todoItem.body, + isDone: todoItem.isDone, + now: now); + } // メソッド実行 - await model.deleteTodoItem(1); + await model.deleteTodoItem(id: 1); // 結果確認 final result = await todoItemRepository.findAll(); expect(result.length, 2); - result.forEach((value) { + + for (final value in result) { expect(value.id != 1, true); - }); + } }); }); @@ -151,9 +165,10 @@ void main() { test('正常系:keyがある時', () async { // 事前準備 - storageRepository.clear(); - storageRepository.savePersistenceStorage( - viewCompletedItemsKey, viewCompletedItemsTrueString); + storageRepository + ..clear() + ..savePersistenceStorage( + viewCompletedItemsKey, viewCompletedItemsTrueString); // メソッド実行 await model.loadViewCompletedItems(); From 33d786964d521b1fa278f797595d6ea2d6b05dc6 Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 17:39:06 +0900 Subject: [PATCH 10/11] =?UTF-8?q?fix:=E4=B8=8D=E8=A6=81=E3=81=AAimport?= =?UTF-8?q?=E6=96=87=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/todo_item_detail_model_test.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/todo_item_detail_model_test.dart b/test/todo_item_detail_model_test.dart index 77fa165..656bebd 100644 --- a/test/todo_item_detail_model_test.dart +++ b/test/todo_item_detail_model_test.dart @@ -5,9 +5,6 @@ * https://opensource.org/licenses/mit-license.php * */ - -import 'dart:io'; - import 'package:flutter_test/flutter_test.dart'; import 'package:todo_app_sample_flutter/domain/todo_item.dart'; import 'package:todo_app_sample_flutter/presentation/todo_item_detail/todo_item_detail_model.dart'; From 3a92e4831a3d7fb359bb4796450e0653e503a0cf Mon Sep 17 00:00:00 2001 From: tokku5552 Date: Sat, 13 Feb 2021 18:24:12 +0900 Subject: [PATCH 11/11] =?UTF-8?q?add:yaml=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflow/flutter_analyze.yaml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflow/flutter_analyze.yaml diff --git a/.github/workflow/flutter_analyze.yaml b/.github/workflow/flutter_analyze.yaml new file mode 100644 index 0000000..5c9f93a --- /dev/null +++ b/.github/workflow/flutter_analyze.yaml @@ -0,0 +1,22 @@ +name: Flutter_Analyzer + +on: + pull_request: + types: [opened, synchronize] + push: + branches: + - master + +jobs: + flutter_analyze: + runs-on: ubuntu-latest + timeout-minutes: 1 + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 1 + - uses: subosito/flutter-action@v1 + with: + channel: 'beta' + - run: flutter pub get + - run: flutter analyze \ No newline at end of file