From cf196fbbae2d8edef36e1ad0b10aff054ad4472d Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 12:50:52 +0700 Subject: [PATCH 01/13] Update the the code to current flutter version Document used: https://dart.dev/null-safety https://pub.dev/packages/internet_connection_checker --- .flutter-plugins-dependencies | 1 - ios/Flutter/flutter_export_environment.sh | 10 ---------- pubspec.yaml | 20 ++++++++++---------- 3 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 .flutter-plugins-dependencies delete mode 100755 ios/Flutter/flutter_export_environment.sh diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies deleted file mode 100644 index ee15714..0000000 --- a/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}]} \ No newline at end of file diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh deleted file mode 100755 index 047511c..0000000 --- a/ios/Flutter/flutter_export_environment.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=C:\Flutter\flutter" -export "FLUTTER_APPLICATION_PATH=D:\Projects\Playground_and_Learning\flutter-tdd-clean-architecture-course" -export "FLUTTER_TARGET=lib\main.dart" -export "FLUTTER_BUILD_DIR=build" -export "SYMROOT=${SOURCE_ROOT}/../build\ios" -export "FLUTTER_FRAMEWORK_DIR=C:\Flutter\flutter\bin\cache\artifacts\engine\ios" -export "FLUTTER_BUILD_NAME=1.0.0" -export "FLUTTER_BUILD_NUMBER=1" diff --git a/pubspec.yaml b/pubspec.yaml index dcdb532..98e99e4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,32 +1,32 @@ name: clean_architecture_tdd_course description: TDD Clean Architecture for Flutter -version: 1.0.0+1 +version: 1.0.0+2 environment: - sdk: '>=2.6.0 <3.0.0' + sdk: ">=3.0.6 <4.0.0" dependencies: flutter: sdk: flutter # Service locator - get_it: ^3.1.0 + get_it: ^7.6.4 # Bloc for state management - flutter_bloc: ^3.0.0 + flutter_bloc: ^8.1.3 # Value equality - equatable: ^1.0.1 + equatable: ^2.0.5 # Functional programming thingies - dartz: ^0.8.9 + dartz: ^0.10.1 # Remote API - data_connection_checker: ^0.3.4 - http: ^0.12.0+3 + internet_connection_checker: ^1.0.0+1 + http: ^1.1.0 # Local cache - shared_preferences: ^0.5.6 + shared_preferences: ^2.2.1 dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.1 + mockito: ^5.4.2 flutter: uses-material-design: true From 6d27b9d70de421caecb4336546147092504205e3 Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 13:36:12 +0700 Subject: [PATCH 02/13] Upgrading pre 1.12 Android projects --- .flutter-plugins-dependencies | 1 + android/app/src/main/AndroidManifest.xml | 21 +- .../MainActivity.kt | 9 +- ios/Flutter/flutter_export_environment.sh | 13 + pubspec.lock | 446 +++++++++++++----- 5 files changed, 359 insertions(+), 131 deletions(-) create mode 100644 .flutter-plugins-dependencies create mode 100644 ios/Flutter/flutter_export_environment.sh diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies new file mode 100644 index 0000000..7bb61dd --- /dev/null +++ b/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 13:35:24.073880","version":"3.10.6"} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 9a07a92..d5a9f3e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,33 +1,22 @@ - + - - + + - + + diff --git a/android/app/src/main/kotlin/com/resocoder/clean_architecture_tdd_course/MainActivity.kt b/android/app/src/main/kotlin/com/resocoder/clean_architecture_tdd_course/MainActivity.kt index 27bc908..6fa3fb0 100644 --- a/android/app/src/main/kotlin/com/resocoder/clean_architecture_tdd_course/MainActivity.kt +++ b/android/app/src/main/kotlin/com/resocoder/clean_architecture_tdd_course/MainActivity.kt @@ -1,13 +1,6 @@ package com.resocoder.clean_architecture_tdd_course -import android.os.Bundle - -import io.flutter.app.FlutterActivity -import io.flutter.plugins.GeneratedPluginRegistrant +import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - GeneratedPluginRegistrant.registerWith(this) - } } diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh new file mode 100644 index 0000000..86a5506 --- /dev/null +++ b/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=C:\dev\src\flutter" +export "FLUTTER_APPLICATION_PATH=D:\Project\repos\flutter-tdd-clean-architecture-course" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=lib\main.dart" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=2" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=true" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/pubspec.lock b/pubspec.lock index 31a1964..ce4a87f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,90 +1,182 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: + _fe_analyzer_shared: dependency: transitive description: - name: archive - url: "https://pub.dartlang.org" + name: _fe_analyzer_shared + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + url: "https://pub.dev" source: hosted - version: "2.0.11" + version: "61.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + url: "https://pub.dev" + source: hosted + version: "5.13.0" args: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" source: hosted - version: "1.5.2" + version: "2.4.2" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.11.0" bloc: dependency: transitive description: name: bloc - url: "https://pub.dartlang.org" + sha256: "3820f15f502372d979121de1f6b97bfcf1630ebff8fe1d52fb2b0bfa49be5b49" + url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "8.1.2" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: a8de5955205b4d1dbbbc267daddf2178bd737e4bab8987c04a500478c9651e74 + url: "https://pub.dev" + source: hosted + version: "8.6.3" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted - version: "1.0.5" - charcode: + version: "1.1.1" + code_builder: dependency: transitive description: - name: charcode - url: "https://pub.dartlang.org" + name: code_builder + sha256: "1be9be30396d7e4c0db42c35ea6ccd7cc6a1e19916b5dc64d6ac216b5544d677" + url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "4.7.0" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + url: "https://pub.dev" source: hosted - version: "1.14.11" + version: "1.17.1" convert: dependency: transitive description: name: convert - url: "https://pub.dartlang.org" + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "3.1.1" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" source: hosted - version: "2.1.3" - dartz: - dependency: "direct main" + version: "3.0.3" + dart_style: + dependency: transitive description: - name: dartz - url: "https://pub.dartlang.org" + name: dart_style + sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + url: "https://pub.dev" source: hosted - version: "0.8.9" - data_connection_checker: + version: "2.3.2" + dartz: dependency: "direct main" description: - name: data_connection_checker - url: "https://pub.dartlang.org" + name: dartz + sha256: e6acf34ad2e31b1eb00948692468c30ab48ac8250e0f0df661e29f12dd252168 + url: "https://pub.dev" source: hosted - version: "0.3.4" + version: "0.10.1" equatable: dependency: "direct main" description: name: equatable - url: "https://pub.dartlang.org" + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + file: + dependency: transitive + description: + name: file + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "6.1.4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -94,9 +186,10 @@ packages: dependency: "direct main" description: name: flutter_bloc - url: "https://pub.dartlang.org" + sha256: e74efb89ee6945bcbce74a5b3a5a3376b088e5f21f55c263fc38cbdc6237faae + url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "8.1.3" flutter_test: dependency: "direct dev" description: flutter @@ -111,196 +204,335 @@ packages: dependency: "direct main" description: name: get_it - url: "https://pub.dartlang.org" + sha256: f79870884de16d689cf9a7d15eedf31ed61d750e813c538a6efb92660fea83c3 + url: "https://pub.dev" + source: hosted + version: "7.6.4" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "2.1.2" http: dependency: "direct main" description: name: http - url: "https://pub.dartlang.org" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + url: "https://pub.dev" source: hosted - version: "0.12.0+3" + version: "1.1.0" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + internet_connection_checker: + dependency: "direct main" + description: + name: internet_connection_checker + sha256: "1c683e63e89c9ac66a40748b1b20889fd9804980da732bf2b58d6d5456c8e876" + url: "https://pub.dev" source: hosted - version: "3.1.3" - image: + version: "1.0.0+1" + js: dependency: transitive description: - name: image - url: "https://pub.dartlang.org" + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "0.6.7" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + url: "https://pub.dev" + source: hosted + version: "0.12.15" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.12.6" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" source: hosted - version: "1.1.8" + version: "1.9.1" mockito: dependency: "direct dev" description: name: mockito - url: "https://pub.dartlang.org" + sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616" + url: "https://pub.dev" source: hosted - version: "4.1.1" + version: "5.4.2" nested: dependency: transitive description: name: nested - url: "https://pub.dartlang.org" + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" source: hosted - version: "0.0.4" + version: "1.0.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" source: hosted - version: "1.6.4" - pedantic: + version: "1.8.3" + path_provider_linux: dependency: transitive description: - name: pedantic - url: "https://pub.dartlang.org" + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" source: hosted - version: "1.8.0+1" - petitparser: + version: "2.2.1" + path_provider_platform_interface: dependency: transitive description: - name: petitparser - url: "https://pub.dartlang.org" + name: path_provider_platform_interface + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + url: "https://pub.dev" source: hosted - version: "2.4.0" - provider: + version: "2.1.1" + path_provider_windows: dependency: transitive description: - name: provider - url: "https://pub.dartlang.org" + name: path_provider_windows + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + url: "https://pub.dev" source: hosted - version: "4.0.1" - quiver: + version: "2.2.1" + platform: dependency: transitive description: - name: quiver - url: "https://pub.dartlang.org" + name: platform + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + url: "https://pub.dev" source: hosted - version: "2.0.5" - rxdart: + version: "3.1.2" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + url: "https://pub.dev" + source: hosted + version: "2.1.6" + provider: + dependency: transitive + description: + name: provider + sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + url: "https://pub.dev" + source: hosted + version: "6.0.5" + pub_semver: dependency: transitive description: - name: rxdart - url: "https://pub.dartlang.org" + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" source: hosted - version: "0.23.1" + version: "2.1.4" shared_preferences: dependency: "direct main" description: name: shared_preferences - url: "https://pub.dartlang.org" + sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac + url: "https://pub.dev" source: hosted - version: "0.5.6" - shared_preferences_macos: + version: "2.2.1" + shared_preferences_android: dependency: transitive description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" + name: shared_preferences_android + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + url: "https://pub.dev" source: hosted - version: "0.0.1+3" + version: "2.2.1" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + url: "https://pub.dev" + source: hosted + version: "2.3.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a + url: "https://pub.dev" + source: hosted + version: "2.3.1" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "2.3.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - url: "https://pub.dartlang.org" + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f + url: "https://pub.dev" source: hosted - version: "0.1.2+2" + version: "2.3.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 + url: "https://pub.dev" + source: hosted + version: "1.4.0" source_span: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.5.5" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.9.3" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + url: "https://pub.dev" source: hosted - version: "0.2.11" + version: "0.5.1" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" source: hosted - version: "1.1.6" + version: "1.3.2" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + win32: + dependency: transitive + description: + name: win32 + sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + url: "https://pub.dev" + source: hosted + version: "5.0.9" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + url: "https://pub.dev" source: hosted - version: "2.0.8" - xml: + version: "1.0.3" + yaml: dependency: transitive description: - name: xml - url: "https://pub.dartlang.org" + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" source: hosted - version: "3.5.0" + version: "3.1.2" sdks: - dart: ">=2.6.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4 <2.0.0" + dart: ">=3.0.6 <4.0.0" + flutter: ">=3.7.0" From f58409aa424a3d41557957a6c9c7cb8c9112bdc9 Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 14:23:02 +0700 Subject: [PATCH 03/13] Removed meta's required annotation --- .../datasources/number_trivia_local_data_source.dart | 3 +-- .../number_trivia_remote_data_source.dart | 4 +--- .../data/models/number_trivia_model.dart | 5 ++--- .../repositories/number_trivia_repository_impl.dart | 7 +++---- .../number_trivia/domain/entities/number_trivia.dart | 5 ++--- .../domain/usecases/get_concrete_number_trivia.dart | 3 +-- .../presentation/bloc/number_trivia_bloc.dart | 12 ++++-------- .../presentation/bloc/number_trivia_event.dart | 2 -- .../presentation/bloc/number_trivia_state.dart | 6 ++---- 9 files changed, 16 insertions(+), 31 deletions(-) diff --git a/lib/features/number_trivia/data/datasources/number_trivia_local_data_source.dart b/lib/features/number_trivia/data/datasources/number_trivia_local_data_source.dart index 9a9bec4..cd4f29e 100644 --- a/lib/features/number_trivia/data/datasources/number_trivia_local_data_source.dart +++ b/lib/features/number_trivia/data/datasources/number_trivia_local_data_source.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:clean_architecture_tdd_course/core/error/exceptions.dart'; -import 'package:meta/meta.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../models/number_trivia_model.dart'; @@ -21,7 +20,7 @@ const CACHED_NUMBER_TRIVIA = 'CACHED_NUMBER_TRIVIA'; class NumberTriviaLocalDataSourceImpl implements NumberTriviaLocalDataSource { final SharedPreferences sharedPreferences; - NumberTriviaLocalDataSourceImpl({@required this.sharedPreferences}); + NumberTriviaLocalDataSourceImpl({required this.sharedPreferences}); @override Future getLastNumberTrivia() { diff --git a/lib/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart b/lib/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart index 978c225..ec3cdde 100644 --- a/lib/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart +++ b/lib/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart @@ -1,7 +1,5 @@ import 'dart:convert'; - import 'package:http/http.dart' as http; -import 'package:meta/meta.dart'; import '../../../../core/error/exceptions.dart'; import '../models/number_trivia_model.dart'; @@ -21,7 +19,7 @@ abstract class NumberTriviaRemoteDataSource { class NumberTriviaRemoteDataSourceImpl implements NumberTriviaRemoteDataSource { final http.Client client; - NumberTriviaRemoteDataSourceImpl({@required this.client}); + NumberTriviaRemoteDataSourceImpl({required this.client}); @override Future getConcreteNumberTrivia(int number) => diff --git a/lib/features/number_trivia/data/models/number_trivia_model.dart b/lib/features/number_trivia/data/models/number_trivia_model.dart index 240960a..05ac9d3 100644 --- a/lib/features/number_trivia/data/models/number_trivia_model.dart +++ b/lib/features/number_trivia/data/models/number_trivia_model.dart @@ -1,10 +1,9 @@ import 'package:clean_architecture_tdd_course/features/number_trivia/domain/entities/number_trivia.dart'; -import 'package:meta/meta.dart'; class NumberTriviaModel extends NumberTrivia { NumberTriviaModel({ - @required String text, - @required int number, + required String text, + required int number, }) : super(text: text, number: number); factory NumberTriviaModel.fromJson(Map json) { diff --git a/lib/features/number_trivia/data/repositories/number_trivia_repository_impl.dart b/lib/features/number_trivia/data/repositories/number_trivia_repository_impl.dart index eb79106..d7c58a3 100644 --- a/lib/features/number_trivia/data/repositories/number_trivia_repository_impl.dart +++ b/lib/features/number_trivia/data/repositories/number_trivia_repository_impl.dart @@ -1,5 +1,4 @@ import 'package:dartz/dartz.dart'; -import 'package:meta/meta.dart'; import '../../../../core/error/failures.dart'; import '../../../../core/error/exceptions.dart'; @@ -17,9 +16,9 @@ class NumberTriviaRepositoryImpl implements NumberTriviaRepository { final NetworkInfo networkInfo; NumberTriviaRepositoryImpl({ - @required this.remoteDataSource, - @required this.localDataSource, - @required this.networkInfo, + required this.remoteDataSource, + required this.localDataSource, + required this.networkInfo, }); @override diff --git a/lib/features/number_trivia/domain/entities/number_trivia.dart b/lib/features/number_trivia/domain/entities/number_trivia.dart index 8e7e0ee..a6c825d 100644 --- a/lib/features/number_trivia/domain/entities/number_trivia.dart +++ b/lib/features/number_trivia/domain/entities/number_trivia.dart @@ -1,13 +1,12 @@ import 'package:equatable/equatable.dart'; -import 'package:meta/meta.dart'; class NumberTrivia extends Equatable { final String text; final int number; NumberTrivia({ - @required this.text, - @required this.number, + required this.text, + required this.number, }); @override diff --git a/lib/features/number_trivia/domain/usecases/get_concrete_number_trivia.dart b/lib/features/number_trivia/domain/usecases/get_concrete_number_trivia.dart index 1128270..d6f3766 100644 --- a/lib/features/number_trivia/domain/usecases/get_concrete_number_trivia.dart +++ b/lib/features/number_trivia/domain/usecases/get_concrete_number_trivia.dart @@ -1,6 +1,5 @@ import 'package:dartz/dartz.dart'; import 'package:equatable/equatable.dart'; -import 'package:meta/meta.dart'; import '../../../../core/error/failures.dart'; import '../../../../core/usecases/usecase.dart'; @@ -21,7 +20,7 @@ class GetConcreteNumberTrivia implements UseCase { class Params extends Equatable { final int number; - Params({@required this.number}); + Params({required this.number}); @override List get props => [number]; diff --git a/lib/features/number_trivia/presentation/bloc/number_trivia_bloc.dart b/lib/features/number_trivia/presentation/bloc/number_trivia_bloc.dart index 03c80ff..c6a37fe 100644 --- a/lib/features/number_trivia/presentation/bloc/number_trivia_bloc.dart +++ b/lib/features/number_trivia/presentation/bloc/number_trivia_bloc.dart @@ -5,7 +5,6 @@ import 'package:clean_architecture_tdd_course/core/error/failures.dart'; import 'package:clean_architecture_tdd_course/core/usecases/usecase.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/domain/entities/number_trivia.dart'; import 'package:dartz/dartz.dart'; -import 'package:meta/meta.dart'; import './bloc.dart'; import '../../../../core/util/input_converter.dart'; @@ -23,13 +22,10 @@ class NumberTriviaBloc extends Bloc { final InputConverter inputConverter; NumberTriviaBloc({ - @required GetConcreteNumberTrivia concrete, - @required GetRandomNumberTrivia random, - @required this.inputConverter, - }) : assert(concrete != null), - assert(random != null), - assert(inputConverter != null), - getConcreteNumberTrivia = concrete, + required GetConcreteNumberTrivia concrete, + required GetRandomNumberTrivia random, + required this.inputConverter, + }) : getConcreteNumberTrivia = concrete, getRandomNumberTrivia = random; @override diff --git a/lib/features/number_trivia/presentation/bloc/number_trivia_event.dart b/lib/features/number_trivia/presentation/bloc/number_trivia_event.dart index 37f7a93..aba9630 100644 --- a/lib/features/number_trivia/presentation/bloc/number_trivia_event.dart +++ b/lib/features/number_trivia/presentation/bloc/number_trivia_event.dart @@ -1,7 +1,5 @@ import 'package:equatable/equatable.dart'; -import 'package:meta/meta.dart'; -@immutable abstract class NumberTriviaEvent extends Equatable { @override List get props => []; diff --git a/lib/features/number_trivia/presentation/bloc/number_trivia_state.dart b/lib/features/number_trivia/presentation/bloc/number_trivia_state.dart index 2cb1321..603d825 100644 --- a/lib/features/number_trivia/presentation/bloc/number_trivia_state.dart +++ b/lib/features/number_trivia/presentation/bloc/number_trivia_state.dart @@ -1,8 +1,6 @@ import 'package:clean_architecture_tdd_course/features/number_trivia/domain/entities/number_trivia.dart'; import 'package:equatable/equatable.dart'; -import 'package:meta/meta.dart'; -@immutable abstract class NumberTriviaState extends Equatable { @override List get props => []; @@ -15,7 +13,7 @@ class Loading extends NumberTriviaState {} class Loaded extends NumberTriviaState { final NumberTrivia trivia; - Loaded({@required this.trivia}); + Loaded({required this.trivia}); @override List get props => [trivia]; @@ -24,7 +22,7 @@ class Loaded extends NumberTriviaState { class Error extends NumberTriviaState { final String message; - Error({@required this.message}); + Error({required this.message}); @override List get props => [message]; From 57e30a93c5ad018e2dbd10c3f5e220b37928edcb Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 14:24:51 +0700 Subject: [PATCH 04/13] Replace Key with nullable key --- .../number_trivia/presentation/widgets/loading_widget.dart | 2 +- .../number_trivia/presentation/widgets/message_display.dart | 4 ++-- .../number_trivia/presentation/widgets/trivia_controls.dart | 2 +- .../number_trivia/presentation/widgets/trivia_display.dart | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/features/number_trivia/presentation/widgets/loading_widget.dart b/lib/features/number_trivia/presentation/widgets/loading_widget.dart index a7b7506..56e806b 100644 --- a/lib/features/number_trivia/presentation/widgets/loading_widget.dart +++ b/lib/features/number_trivia/presentation/widgets/loading_widget.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; class LoadingWidget extends StatelessWidget { const LoadingWidget({ - Key key, + Key? key, }) : super(key: key); @override diff --git a/lib/features/number_trivia/presentation/widgets/message_display.dart b/lib/features/number_trivia/presentation/widgets/message_display.dart index 6e55f53..8d55e50 100644 --- a/lib/features/number_trivia/presentation/widgets/message_display.dart +++ b/lib/features/number_trivia/presentation/widgets/message_display.dart @@ -4,8 +4,8 @@ class MessageDisplay extends StatelessWidget { final String message; const MessageDisplay({ - Key key, - @required this.message, + Key? key, + required this.message, }) : super(key: key); @override diff --git a/lib/features/number_trivia/presentation/widgets/trivia_controls.dart b/lib/features/number_trivia/presentation/widgets/trivia_controls.dart index 4774ea1..e2dbd77 100644 --- a/lib/features/number_trivia/presentation/widgets/trivia_controls.dart +++ b/lib/features/number_trivia/presentation/widgets/trivia_controls.dart @@ -4,7 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; class TriviaControls extends StatefulWidget { const TriviaControls({ - Key key, + Key? key, }) : super(key: key); @override diff --git a/lib/features/number_trivia/presentation/widgets/trivia_display.dart b/lib/features/number_trivia/presentation/widgets/trivia_display.dart index 5174ac4..34291d8 100644 --- a/lib/features/number_trivia/presentation/widgets/trivia_display.dart +++ b/lib/features/number_trivia/presentation/widgets/trivia_display.dart @@ -5,8 +5,8 @@ class TriviaDisplay extends StatelessWidget { final NumberTrivia numberTrivia; const TriviaDisplay({ - Key key, - @required this.numberTrivia, + Key? key, + required this.numberTrivia, }) : super(key: key); @override From f8cb23f906bd8a949e56c499eb817b82b55403bf Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 14:29:58 +0700 Subject: [PATCH 05/13] Replace data_connection_checker with internet_connection_checker https://pub.dev/packages/internet_connection_checker --- lib/core/network/network_info.dart | 5 +++-- lib/injection_container.dart | 7 +++++-- test/core/network/network_info_test.dart | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/core/network/network_info.dart b/lib/core/network/network_info.dart index adabbe3..237e68c 100644 --- a/lib/core/network/network_info.dart +++ b/lib/core/network/network_info.dart @@ -1,11 +1,12 @@ -import 'package:data_connection_checker/data_connection_checker.dart'; +import 'package:internet_connection_checker/internet_connection_checker.dart'; + abstract class NetworkInfo { Future get isConnected; } class NetworkInfoImpl implements NetworkInfo { - final DataConnectionChecker connectionChecker; + final InternetConnectionChecker connectionChecker; NetworkInfoImpl(this.connectionChecker); diff --git a/lib/injection_container.dart b/lib/injection_container.dart index 20b6e22..f6fd5bd 100644 --- a/lib/injection_container.dart +++ b/lib/injection_container.dart @@ -1,4 +1,5 @@ -import 'package:data_connection_checker/data_connection_checker.dart'; +import 'package:internet_connection_checker/internet_connection_checker.dart'; + import 'package:get_it/get_it.dart'; import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; @@ -54,7 +55,9 @@ Future init() async { //! External final sharedPreferences = await SharedPreferences.getInstance(); + final internetConnectionChecker = InternetConnectionChecker(); + sl.registerLazySingleton(() => sharedPreferences); sl.registerLazySingleton(() => http.Client()); - sl.registerLazySingleton(() => DataConnectionChecker()); + sl.registerLazySingleton(() => internetConnectionChecker); } diff --git a/test/core/network/network_info_test.dart b/test/core/network/network_info_test.dart index 3cb59e2..5260d1d 100644 --- a/test/core/network/network_info_test.dart +++ b/test/core/network/network_info_test.dart @@ -1,9 +1,9 @@ import 'package:clean_architecture_tdd_course/core/network/network_info.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:data_connection_checker/data_connection_checker.dart'; +import 'package:internet_connection_checker/internet_connection_checker.dart'; -class MockDataConnectionChecker extends Mock implements DataConnectionChecker {} +class MockDataConnectionChecker extends Mock implements InternetConnectionChecker {} void main() { NetworkInfoImpl networkInfo; From b2b48831e04a8efd499e7d8c13c3025d117df007 Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 14:40:14 +0700 Subject: [PATCH 06/13] Fix non-nullable instatnce feild must be initialized. --- .../presentation/widgets/trivia_controls.dart | 2 +- test/core/network/network_info_test.dart | 4 ++-- test/core/util/input_converter_test.dart | 2 +- .../datasources/number_trivia_local_data_source_test.dart | 4 ++-- .../number_trivia_remote_data_source_test.dart | 4 ++-- .../repositories/number_trivia_repository_impl_test.dart | 8 ++++---- .../domain/usecases/get_concrete_number_trivia_test.dart | 4 ++-- .../domain/usecases/get_random_number_trivia_test.dart | 5 ++--- .../presentation/bloc/number_trivia_bloc_test.dart | 8 ++++---- 9 files changed, 20 insertions(+), 21 deletions(-) diff --git a/lib/features/number_trivia/presentation/widgets/trivia_controls.dart b/lib/features/number_trivia/presentation/widgets/trivia_controls.dart index e2dbd77..de1e582 100644 --- a/lib/features/number_trivia/presentation/widgets/trivia_controls.dart +++ b/lib/features/number_trivia/presentation/widgets/trivia_controls.dart @@ -13,7 +13,7 @@ class TriviaControls extends StatefulWidget { class _TriviaControlsState extends State { final controller = TextEditingController(); - String inputStr; + late String inputStr; @override Widget build(BuildContext context) { diff --git a/test/core/network/network_info_test.dart b/test/core/network/network_info_test.dart index 5260d1d..3370d9e 100644 --- a/test/core/network/network_info_test.dart +++ b/test/core/network/network_info_test.dart @@ -6,8 +6,8 @@ import 'package:internet_connection_checker/internet_connection_checker.dart'; class MockDataConnectionChecker extends Mock implements InternetConnectionChecker {} void main() { - NetworkInfoImpl networkInfo; - MockDataConnectionChecker mockDataConnectionChecker; + late NetworkInfoImpl networkInfo; + late MockDataConnectionChecker mockDataConnectionChecker; setUp(() { mockDataConnectionChecker = MockDataConnectionChecker(); diff --git a/test/core/util/input_converter_test.dart b/test/core/util/input_converter_test.dart index 78c18e8..3995305 100644 --- a/test/core/util/input_converter_test.dart +++ b/test/core/util/input_converter_test.dart @@ -3,7 +3,7 @@ import 'package:dartz/dartz.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { - InputConverter inputConverter; + late InputConverter inputConverter; setUp(() { inputConverter = InputConverter(); diff --git a/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart b/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart index 9ad69b1..42e744c 100644 --- a/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart +++ b/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart @@ -13,8 +13,8 @@ import '../../../../fixtures/fixture_reader.dart'; class MockSharedPreferences extends Mock implements SharedPreferences {} void main() { - NumberTriviaLocalDataSourceImpl dataSource; - MockSharedPreferences mockSharedPreferences; + late NumberTriviaLocalDataSourceImpl dataSource; + late MockSharedPreferences mockSharedPreferences; setUp(() { mockSharedPreferences = MockSharedPreferences(); diff --git a/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart b/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart index 9e1e3f5..c7129be 100644 --- a/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart +++ b/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart @@ -13,8 +13,8 @@ import '../../../../fixtures/fixture_reader.dart'; class MockHttpClient extends Mock implements http.Client {} void main() { - NumberTriviaRemoteDataSourceImpl dataSource; - MockHttpClient mockHttpClient; + late NumberTriviaRemoteDataSourceImpl dataSource; + late MockHttpClient mockHttpClient; setUp(() { mockHttpClient = MockHttpClient(); diff --git a/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart b/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart index c4c9d61..0f084fb 100644 --- a/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart +++ b/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart @@ -18,10 +18,10 @@ class MockLocalDataSource extends Mock implements NumberTriviaLocalDataSource {} class MockNetworkInfo extends Mock implements NetworkInfo {} void main() { - NumberTriviaRepositoryImpl repository; - MockRemoteDataSource mockRemoteDataSource; - MockLocalDataSource mockLocalDataSource; - MockNetworkInfo mockNetworkInfo; + late NumberTriviaRepositoryImpl repository; + late MockRemoteDataSource mockRemoteDataSource; + late MockLocalDataSource mockLocalDataSource; + late MockNetworkInfo mockNetworkInfo; setUp(() { mockRemoteDataSource = MockRemoteDataSource(); diff --git a/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart b/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart index 8e0297d..df174a3 100644 --- a/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart +++ b/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart @@ -9,8 +9,8 @@ class MockNumberTriviaRepository extends Mock implements NumberTriviaRepository {} void main() { - GetConcreteNumberTrivia usecase; - MockNumberTriviaRepository mockNumberTriviaRepository; + late GetConcreteNumberTrivia usecase; + late MockNumberTriviaRepository mockNumberTriviaRepository; setUp(() { mockNumberTriviaRepository = MockNumberTriviaRepository(); diff --git a/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart b/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart index f07116b..4eda2a8 100644 --- a/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart +++ b/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart @@ -1,7 +1,6 @@ import 'package:clean_architecture_tdd_course/core/usecases/usecase.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/domain/entities/number_trivia.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/domain/repositories/number_trivia_repository.dart'; -import 'package:clean_architecture_tdd_course/features/number_trivia/domain/usecases/get_concrete_number_trivia.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/domain/usecases/get_random_number_trivia.dart'; import 'package:dartz/dartz.dart'; import 'package:mockito/mockito.dart'; @@ -11,8 +10,8 @@ class MockNumberTriviaRepository extends Mock implements NumberTriviaRepository {} void main() { - GetRandomNumberTrivia usecase; - MockNumberTriviaRepository mockNumberTriviaRepository; + late GetRandomNumberTrivia usecase; + late MockNumberTriviaRepository mockNumberTriviaRepository; setUp(() { mockNumberTriviaRepository = MockNumberTriviaRepository(); diff --git a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart index 87d9089..68c083a 100644 --- a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart +++ b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart @@ -17,10 +17,10 @@ class MockGetRandomNumberTrivia extends Mock implements GetRandomNumberTrivia {} class MockInputConverter extends Mock implements InputConverter {} void main() { - NumberTriviaBloc bloc; - MockGetConcreteNumberTrivia mockGetConcreteNumberTrivia; - MockGetRandomNumberTrivia mockGetRandomNumberTrivia; - MockInputConverter mockInputConverter; + late NumberTriviaBloc bloc; + late MockGetConcreteNumberTrivia mockGetConcreteNumberTrivia; + late MockGetRandomNumberTrivia mockGetRandomNumberTrivia; + late MockInputConverter mockInputConverter; setUp(() { mockGetConcreteNumberTrivia = MockGetConcreteNumberTrivia(); From 4dc2338797070e7c7a0ea04017c33d6ab48f6da0 Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 14:45:55 +0700 Subject: [PATCH 07/13] Replace `String` url to `Uri` parse from string The version: http: ^0.12.0+3 -> http: ^1.1.0 --- .../data/datasources/number_trivia_remote_data_source.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart b/lib/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart index ec3cdde..65d68b4 100644 --- a/lib/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart +++ b/lib/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart @@ -31,7 +31,7 @@ class NumberTriviaRemoteDataSourceImpl implements NumberTriviaRemoteDataSource { Future _getTriviaFromUrl(String url) async { final response = await client.get( - url, + Uri.parse(url), headers: { 'Content-Type': 'application/json', }, From 0c1a14db0dd21699c27a192db8624fbc90c391af Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 15:39:23 +0700 Subject: [PATCH 08/13] Remove `deprecated` Widget --- .../number_trivia/presentation/widgets/trivia_controls.dart | 6 ++---- lib/main.dart | 4 +++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/features/number_trivia/presentation/widgets/trivia_controls.dart b/lib/features/number_trivia/presentation/widgets/trivia_controls.dart index de1e582..6bc64c0 100644 --- a/lib/features/number_trivia/presentation/widgets/trivia_controls.dart +++ b/lib/features/number_trivia/presentation/widgets/trivia_controls.dart @@ -37,16 +37,14 @@ class _TriviaControlsState extends State { Row( children: [ Expanded( - child: RaisedButton( + child: ElevatedButton( child: Text('Search'), - color: Theme.of(context).accentColor, - textTheme: ButtonTextTheme.primary, onPressed: dispatchConcrete, ), ), SizedBox(width: 10), Expanded( - child: RaisedButton( + child: ElevatedButton( child: Text('Get random trivia'), onPressed: dispatchRandom, ), diff --git a/lib/main.dart b/lib/main.dart index 3fdd5d0..39ec47a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,7 +15,9 @@ class MyApp extends StatelessWidget { title: 'Number Trivia', theme: ThemeData( primaryColor: Colors.green.shade800, - accentColor: Colors.green.shade600, + colorScheme: ColorScheme.fromSwatch( + primarySwatch: Colors.green, + ), ), home: NumberTriviaPage(), ); From c491b0977ea7e0cae749c3c9f98ee4b0438d965b Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 15:42:47 +0700 Subject: [PATCH 09/13] Fixed `Widget` is a potentially non-nullable type --- .../number_trivia/presentation/pages/number_trivia_page.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/features/number_trivia/presentation/pages/number_trivia_page.dart b/lib/features/number_trivia/presentation/pages/number_trivia_page.dart index d3332b1..9c5fbdf 100644 --- a/lib/features/number_trivia/presentation/pages/number_trivia_page.dart +++ b/lib/features/number_trivia/presentation/pages/number_trivia_page.dart @@ -44,6 +44,10 @@ class NumberTriviaPage extends StatelessWidget { message: state.message, ); } + return SizedBox( + height: MediaQuery.of(context).size.height / 3, + child: const Placeholder(), + ); }, ), SizedBox(height: 20), From 1445c89acc321d9787a5296c94e3706a87b9b318 Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 16:27:13 +0700 Subject: [PATCH 10/13] Add Mock dependencies using Mockito instead of inheriting Mock https://docs.flutter.dev/cookbook/testing/unit/mocking --- .flutter-plugins-dependencies | 2 +- .../number_trivia_repository_impl.dart | 3 +- pubspec.lock | 152 ++++++++++ pubspec.yaml | 1 + .../number_trivia_local_data_source_test.dart | 6 +- ...r_trivia_local_data_source_test.mocks.dart | 201 +++++++++++++ ...number_trivia_remote_data_source_test.dart | 18 +- ..._trivia_remote_data_source_test.mocks.dart | 272 ++++++++++++++++++ .../number_trivia_repository_impl_test.dart | 17 +- ...ber_trivia_repository_impl_test.mocks.dart | 135 +++++++++ .../get_concrete_number_trivia_test.dart | 7 +- ...get_concrete_number_trivia_test.mocks.dart | 82 ++++++ .../bloc/number_trivia_bloc_test.dart | 17 +- .../bloc/number_trivia_bloc_test.mocks.dart | 155 ++++++++++ 14 files changed, 1033 insertions(+), 35 deletions(-) create mode 100644 test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.mocks.dart create mode 100644 test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.mocks.dart create mode 100644 test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.mocks.dart create mode 100644 test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.mocks.dart create mode 100644 test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.mocks.dart diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 7bb61dd..063071f 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 13:35:24.073880","version":"3.10.6"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 16:00:49.485408","version":"3.10.6"} \ No newline at end of file diff --git a/lib/features/number_trivia/data/repositories/number_trivia_repository_impl.dart b/lib/features/number_trivia/data/repositories/number_trivia_repository_impl.dart index d7c58a3..d228843 100644 --- a/lib/features/number_trivia/data/repositories/number_trivia_repository_impl.dart +++ b/lib/features/number_trivia/data/repositories/number_trivia_repository_impl.dart @@ -1,3 +1,4 @@ +import 'package:clean_architecture_tdd_course/features/number_trivia/data/models/number_trivia_model.dart'; import 'package:dartz/dartz.dart'; import '../../../../core/error/failures.dart'; @@ -43,7 +44,7 @@ class NumberTriviaRepositoryImpl implements NumberTriviaRepository { if (await networkInfo.isConnected) { try { final remoteTrivia = await getConcreteOrRandom(); - localDataSource.cacheNumberTrivia(remoteTrivia); + localDataSource.cacheNumberTrivia(remoteTrivia as NumberTriviaModel); return Right(remoteTrivia); } on ServerException { return Left(ServerFailure()); diff --git a/pubspec.lock b/pubspec.lock index ce4a87f..f259173 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -57,6 +57,46 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "64e12b0521812d1684b1917bc80945625391cb9bdd4312536b1d69dcb6133ed8" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" + url: "https://pub.dev" + source: hosted + version: "2.4.6" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 + url: "https://pub.dev" + source: hosted + version: "7.2.11" built_collection: dependency: transitive description: @@ -81,6 +121,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" clock: dependency: transitive description: @@ -200,6 +248,14 @@ packages: description: flutter source: sdk version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" + source: hosted + version: "3.2.0" get_it: dependency: "direct main" description: @@ -216,6 +272,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + graphs: + dependency: transitive + description: + name: graphs + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" + source: hosted + version: "2.3.1" http: dependency: "direct main" description: @@ -224,6 +288,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" http_parser: dependency: transitive description: @@ -240,6 +312,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0+1" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" js: dependency: transitive description: @@ -248,6 +328,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" + source: hosted + version: "4.8.1" logging: dependency: transitive description: @@ -280,6 +368,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" mockito: dependency: "direct dev" description: @@ -352,6 +448,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.6" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" provider: dependency: transitive description: @@ -368,6 +472,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" + source: hosted + version: "1.2.3" shared_preferences: dependency: "direct main" description: @@ -424,6 +536,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + url: "https://pub.dev" + source: hosted + version: "1.0.4" sky_engine: dependency: transitive description: flutter @@ -461,6 +589,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -485,6 +621,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" typed_data: dependency: transitive description: @@ -509,6 +653,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" + source: hosted + version: "2.4.0" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 98e99e4..cdb70ff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,6 +24,7 @@ dependencies: shared_preferences: ^2.2.1 dev_dependencies: + build_runner: ^2.4.6 flutter_test: sdk: flutter mockito: ^5.4.2 diff --git a/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart b/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart index 42e744c..f25b0b6 100644 --- a/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart +++ b/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart @@ -3,15 +3,15 @@ import 'dart:convert'; import 'package:clean_architecture_tdd_course/core/error/exceptions.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/data/datasources/number_trivia_local_data_source.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/data/models/number_trivia_model.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:matcher/matcher.dart'; import '../../../../fixtures/fixture_reader.dart'; +import 'number_trivia_local_data_source_test.mocks.dart'; -class MockSharedPreferences extends Mock implements SharedPreferences {} - +@GenerateMocks([SharedPreferences]) void main() { late NumberTriviaLocalDataSourceImpl dataSource; late MockSharedPreferences mockSharedPreferences; diff --git a/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.mocks.dart b/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.mocks.dart new file mode 100644 index 0000000..47fdd5a --- /dev/null +++ b/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.mocks.dart @@ -0,0 +1,201 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in clean_architecture_tdd_course/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:shared_preferences/shared_preferences.dart' as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [SharedPreferences]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockSharedPreferences extends _i1.Mock implements _i2.SharedPreferences { + MockSharedPreferences() { + _i1.throwOnMissingStub(this); + } + + @override + Set getKeys() => (super.noSuchMethod( + Invocation.method( + #getKeys, + [], + ), + returnValue: {}, + ) as Set); + + @override + Object? get(String? key) => (super.noSuchMethod(Invocation.method( + #get, + [key], + )) as Object?); + + @override + bool? getBool(String? key) => (super.noSuchMethod(Invocation.method( + #getBool, + [key], + )) as bool?); + + @override + int? getInt(String? key) => (super.noSuchMethod(Invocation.method( + #getInt, + [key], + )) as int?); + + @override + double? getDouble(String? key) => (super.noSuchMethod(Invocation.method( + #getDouble, + [key], + )) as double?); + + @override + String? getString(String? key) => (super.noSuchMethod(Invocation.method( + #getString, + [key], + )) as String?); + + @override + bool containsKey(String? key) => (super.noSuchMethod( + Invocation.method( + #containsKey, + [key], + ), + returnValue: false, + ) as bool); + + @override + List? getStringList(String? key) => + (super.noSuchMethod(Invocation.method( + #getStringList, + [key], + )) as List?); + + @override + _i3.Future setBool( + String? key, + bool? value, + ) => + (super.noSuchMethod( + Invocation.method( + #setBool, + [ + key, + value, + ], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future setInt( + String? key, + int? value, + ) => + (super.noSuchMethod( + Invocation.method( + #setInt, + [ + key, + value, + ], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future setDouble( + String? key, + double? value, + ) => + (super.noSuchMethod( + Invocation.method( + #setDouble, + [ + key, + value, + ], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future setString( + String? key, + String? value, + ) => + (super.noSuchMethod( + Invocation.method( + #setString, + [ + key, + value, + ], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future setStringList( + String? key, + List? value, + ) => + (super.noSuchMethod( + Invocation.method( + #setStringList, + [ + key, + value, + ], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future remove(String? key) => (super.noSuchMethod( + Invocation.method( + #remove, + [key], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future commit() => (super.noSuchMethod( + Invocation.method( + #commit, + [], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future clear() => (super.noSuchMethod( + Invocation.method( + #clear, + [], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future reload() => (super.noSuchMethod( + Invocation.method( + #reload, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); +} diff --git a/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart b/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart index c7129be..a11591d 100644 --- a/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart +++ b/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart @@ -3,21 +3,21 @@ import 'dart:convert'; import 'package:clean_architecture_tdd_course/core/error/exceptions.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/data/models/number_trivia_model.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:matcher/matcher.dart'; import 'package:http/http.dart' as http; import '../../../../fixtures/fixture_reader.dart'; +import 'number_trivia_remote_data_source_test.mocks.dart'; -class MockHttpClient extends Mock implements http.Client {} - +@GenerateMocks([http.Client]) void main() { - late NumberTriviaRemoteDataSourceImpl dataSource; - late MockHttpClient mockHttpClient; + late NumberTriviaRemoteDataSourceImpl dataSource; + late MockClient mockHttpClient; setUp(() { - mockHttpClient = MockHttpClient(); + mockHttpClient = MockClient(); dataSource = NumberTriviaRemoteDataSourceImpl(client: mockHttpClient); }); @@ -46,7 +46,7 @@ void main() { dataSource.getConcreteNumberTrivia(tNumber); // assert verify(mockHttpClient.get( - 'http://numbersapi.com/$tNumber', + Uri.parse('http://numbersapi.com/$tNumber'), headers: { 'Content-Type': 'application/json', }, @@ -93,7 +93,9 @@ void main() { dataSource.getRandomNumberTrivia(); // assert verify(mockHttpClient.get( - 'http://numbersapi.com/random', + Uri.parse( + 'http://numbersapi.com/random', + ), headers: { 'Content-Type': 'application/json', }, diff --git a/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.mocks.dart b/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.mocks.dart new file mode 100644 index 0000000..6308a75 --- /dev/null +++ b/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.mocks.dart @@ -0,0 +1,272 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in clean_architecture_tdd_course/test/features/number_trivia/data/datasources/number_trivia_remote_data_source_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; +import 'dart:convert' as _i4; +import 'dart:typed_data' as _i5; + +import 'package:http/http.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeResponse_0 extends _i1.SmartFake implements _i2.Response { + _FakeResponse_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeStreamedResponse_1 extends _i1.SmartFake + implements _i2.StreamedResponse { + _FakeStreamedResponse_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [Client]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockClient extends _i1.Mock implements _i2.Client { + MockClient() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Future<_i2.Response> head( + Uri? url, { + Map? headers, + }) => + (super.noSuchMethod( + Invocation.method( + #head, + [url], + {#headers: headers}, + ), + returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_0( + this, + Invocation.method( + #head, + [url], + {#headers: headers}, + ), + )), + ) as _i3.Future<_i2.Response>); + + @override + _i3.Future<_i2.Response> get( + Uri? url, { + Map? headers, + }) => + (super.noSuchMethod( + Invocation.method( + #get, + [url], + {#headers: headers}, + ), + returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_0( + this, + Invocation.method( + #get, + [url], + {#headers: headers}, + ), + )), + ) as _i3.Future<_i2.Response>); + + @override + _i3.Future<_i2.Response> post( + Uri? url, { + Map? headers, + Object? body, + _i4.Encoding? encoding, + }) => + (super.noSuchMethod( + Invocation.method( + #post, + [url], + { + #headers: headers, + #body: body, + #encoding: encoding, + }, + ), + returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_0( + this, + Invocation.method( + #post, + [url], + { + #headers: headers, + #body: body, + #encoding: encoding, + }, + ), + )), + ) as _i3.Future<_i2.Response>); + + @override + _i3.Future<_i2.Response> put( + Uri? url, { + Map? headers, + Object? body, + _i4.Encoding? encoding, + }) => + (super.noSuchMethod( + Invocation.method( + #put, + [url], + { + #headers: headers, + #body: body, + #encoding: encoding, + }, + ), + returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_0( + this, + Invocation.method( + #put, + [url], + { + #headers: headers, + #body: body, + #encoding: encoding, + }, + ), + )), + ) as _i3.Future<_i2.Response>); + + @override + _i3.Future<_i2.Response> patch( + Uri? url, { + Map? headers, + Object? body, + _i4.Encoding? encoding, + }) => + (super.noSuchMethod( + Invocation.method( + #patch, + [url], + { + #headers: headers, + #body: body, + #encoding: encoding, + }, + ), + returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_0( + this, + Invocation.method( + #patch, + [url], + { + #headers: headers, + #body: body, + #encoding: encoding, + }, + ), + )), + ) as _i3.Future<_i2.Response>); + + @override + _i3.Future<_i2.Response> delete( + Uri? url, { + Map? headers, + Object? body, + _i4.Encoding? encoding, + }) => + (super.noSuchMethod( + Invocation.method( + #delete, + [url], + { + #headers: headers, + #body: body, + #encoding: encoding, + }, + ), + returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_0( + this, + Invocation.method( + #delete, + [url], + { + #headers: headers, + #body: body, + #encoding: encoding, + }, + ), + )), + ) as _i3.Future<_i2.Response>); + + @override + _i3.Future read( + Uri? url, { + Map? headers, + }) => + (super.noSuchMethod( + Invocation.method( + #read, + [url], + {#headers: headers}, + ), + returnValue: _i3.Future.value(''), + ) as _i3.Future); + + @override + _i3.Future<_i5.Uint8List> readBytes( + Uri? url, { + Map? headers, + }) => + (super.noSuchMethod( + Invocation.method( + #readBytes, + [url], + {#headers: headers}, + ), + returnValue: _i3.Future<_i5.Uint8List>.value(_i5.Uint8List(0)), + ) as _i3.Future<_i5.Uint8List>); + + @override + _i3.Future<_i2.StreamedResponse> send(_i2.BaseRequest? request) => + (super.noSuchMethod( + Invocation.method( + #send, + [request], + ), + returnValue: + _i3.Future<_i2.StreamedResponse>.value(_FakeStreamedResponse_1( + this, + Invocation.method( + #send, + [request], + ), + )), + ) as _i3.Future<_i2.StreamedResponse>); + + @override + void close() => super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValueForMissingStub: null, + ); +} diff --git a/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart b/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart index 0f084fb..9de4140 100644 --- a/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart +++ b/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart @@ -7,25 +7,22 @@ import 'package:clean_architecture_tdd_course/features/number_trivia/data/models import 'package:clean_architecture_tdd_course/features/number_trivia/data/repositories/number_trivia_repository_impl.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/domain/entities/number_trivia.dart'; import 'package:dartz/dartz.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; -class MockRemoteDataSource extends Mock - implements NumberTriviaRemoteDataSource {} - -class MockLocalDataSource extends Mock implements NumberTriviaLocalDataSource {} - -class MockNetworkInfo extends Mock implements NetworkInfo {} +import 'number_trivia_repository_impl_test.mocks.dart'; +@GenerateMocks([NumberTriviaRemoteDataSource,NumberTriviaLocalDataSource,NetworkInfo]) void main() { late NumberTriviaRepositoryImpl repository; - late MockRemoteDataSource mockRemoteDataSource; - late MockLocalDataSource mockLocalDataSource; + late MockNumberTriviaRemoteDataSource mockRemoteDataSource; + late MockNumberTriviaLocalDataSource mockLocalDataSource; late MockNetworkInfo mockNetworkInfo; setUp(() { - mockRemoteDataSource = MockRemoteDataSource(); - mockLocalDataSource = MockLocalDataSource(); + mockRemoteDataSource = MockNumberTriviaRemoteDataSource(); + mockLocalDataSource = MockNumberTriviaLocalDataSource(); mockNetworkInfo = MockNetworkInfo(); repository = NumberTriviaRepositoryImpl( remoteDataSource: mockRemoteDataSource, diff --git a/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.mocks.dart b/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.mocks.dart new file mode 100644 index 0000000..e987ce0 --- /dev/null +++ b/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.mocks.dart @@ -0,0 +1,135 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in clean_architecture_tdd_course/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; + +import 'package:clean_architecture_tdd_course/core/network/network_info.dart' + as _i6; +import 'package:clean_architecture_tdd_course/features/number_trivia/data/datasources/number_trivia_local_data_source.dart' + as _i5; +import 'package:clean_architecture_tdd_course/features/number_trivia/data/datasources/number_trivia_remote_data_source.dart' + as _i3; +import 'package:clean_architecture_tdd_course/features/number_trivia/data/models/number_trivia_model.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeNumberTriviaModel_0 extends _i1.SmartFake + implements _i2.NumberTriviaModel { + _FakeNumberTriviaModel_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [NumberTriviaRemoteDataSource]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockNumberTriviaRemoteDataSource extends _i1.Mock + implements _i3.NumberTriviaRemoteDataSource { + MockNumberTriviaRemoteDataSource() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.NumberTriviaModel> getConcreteNumberTrivia(int? number) => + (super.noSuchMethod( + Invocation.method( + #getConcreteNumberTrivia, + [number], + ), + returnValue: + _i4.Future<_i2.NumberTriviaModel>.value(_FakeNumberTriviaModel_0( + this, + Invocation.method( + #getConcreteNumberTrivia, + [number], + ), + )), + ) as _i4.Future<_i2.NumberTriviaModel>); + + @override + _i4.Future<_i2.NumberTriviaModel> getRandomNumberTrivia() => + (super.noSuchMethod( + Invocation.method( + #getRandomNumberTrivia, + [], + ), + returnValue: + _i4.Future<_i2.NumberTriviaModel>.value(_FakeNumberTriviaModel_0( + this, + Invocation.method( + #getRandomNumberTrivia, + [], + ), + )), + ) as _i4.Future<_i2.NumberTriviaModel>); +} + +/// A class which mocks [NumberTriviaLocalDataSource]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockNumberTriviaLocalDataSource extends _i1.Mock + implements _i5.NumberTriviaLocalDataSource { + MockNumberTriviaLocalDataSource() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.NumberTriviaModel> getLastNumberTrivia() => + (super.noSuchMethod( + Invocation.method( + #getLastNumberTrivia, + [], + ), + returnValue: + _i4.Future<_i2.NumberTriviaModel>.value(_FakeNumberTriviaModel_0( + this, + Invocation.method( + #getLastNumberTrivia, + [], + ), + )), + ) as _i4.Future<_i2.NumberTriviaModel>); + + @override + _i4.Future cacheNumberTrivia(_i2.NumberTriviaModel? triviaToCache) => + (super.noSuchMethod( + Invocation.method( + #cacheNumberTrivia, + [triviaToCache], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); +} + +/// A class which mocks [NetworkInfo]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockNetworkInfo extends _i1.Mock implements _i6.NetworkInfo { + MockNetworkInfo() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future get isConnected => (super.noSuchMethod( + Invocation.getter(#isConnected), + returnValue: _i4.Future.value(false), + ) as _i4.Future); +} diff --git a/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart b/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart index df174a3..c79b52e 100644 --- a/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart +++ b/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart @@ -2,11 +2,14 @@ import 'package:clean_architecture_tdd_course/features/number_trivia/domain/enti import 'package:clean_architecture_tdd_course/features/number_trivia/domain/repositories/number_trivia_repository.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/domain/usecases/get_concrete_number_trivia.dart'; import 'package:dartz/dartz.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; -class MockNumberTriviaRepository extends Mock - implements NumberTriviaRepository {} +import 'get_concrete_number_trivia_test.mocks.dart'; + + +@GenerateMocks([NumberTriviaRepository]) void main() { late GetConcreteNumberTrivia usecase; diff --git a/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.mocks.dart b/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.mocks.dart new file mode 100644 index 0000000..880da8a --- /dev/null +++ b/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.mocks.dart @@ -0,0 +1,82 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in clean_architecture_tdd_course/test/features/number_trivia/domain/usecases/get_concrete_number_trivia_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; + +import 'package:clean_architecture_tdd_course/core/error/failures.dart' as _i5; +import 'package:clean_architecture_tdd_course/features/number_trivia/domain/entities/number_trivia.dart' + as _i6; +import 'package:clean_architecture_tdd_course/features/number_trivia/domain/repositories/number_trivia_repository.dart' + as _i3; +import 'package:dartz/dartz.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeEither_0 extends _i1.SmartFake implements _i2.Either { + _FakeEither_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [NumberTriviaRepository]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockNumberTriviaRepository extends _i1.Mock + implements _i3.NumberTriviaRepository { + MockNumberTriviaRepository() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>> getConcreteNumberTrivia( + int? number) => + (super.noSuchMethod( + Invocation.method( + #getConcreteNumberTrivia, + [number], + ), + returnValue: + _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>>.value( + _FakeEither_0<_i5.Failure, _i6.NumberTrivia>( + this, + Invocation.method( + #getConcreteNumberTrivia, + [number], + ), + )), + ) as _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>>); + + @override + _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>> + getRandomNumberTrivia() => (super.noSuchMethod( + Invocation.method( + #getRandomNumberTrivia, + [], + ), + returnValue: + _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>>.value( + _FakeEither_0<_i5.Failure, _i6.NumberTrivia>( + this, + Invocation.method( + #getRandomNumberTrivia, + [], + ), + )), + ) as _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>>); +} diff --git a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart index 68c083a..0c1b7ca 100644 --- a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart +++ b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart @@ -6,21 +6,18 @@ import 'package:clean_architecture_tdd_course/features/number_trivia/domain/usec import 'package:clean_architecture_tdd_course/features/number_trivia/domain/usecases/get_random_number_trivia.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/presentation/bloc/bloc.dart'; import 'package:dartz/dartz.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; -class MockGetConcreteNumberTrivia extends Mock - implements GetConcreteNumberTrivia {} - -class MockGetRandomNumberTrivia extends Mock implements GetRandomNumberTrivia {} - -class MockInputConverter extends Mock implements InputConverter {} +import 'number_trivia_bloc_test.mocks.dart'; +@GenerateMocks([GetConcreteNumberTrivia, GetRandomNumberTrivia, InputConverter]) void main() { - late NumberTriviaBloc bloc; - late MockGetConcreteNumberTrivia mockGetConcreteNumberTrivia; - late MockGetRandomNumberTrivia mockGetRandomNumberTrivia; - late MockInputConverter mockInputConverter; + late NumberTriviaBloc bloc; + late MockGetConcreteNumberTrivia mockGetConcreteNumberTrivia; + late MockGetRandomNumberTrivia mockGetRandomNumberTrivia; + late MockInputConverter mockInputConverter; setUp(() { mockGetConcreteNumberTrivia = MockGetConcreteNumberTrivia(); diff --git a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.mocks.dart b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.mocks.dart new file mode 100644 index 0000000..08a953f --- /dev/null +++ b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.mocks.dart @@ -0,0 +1,155 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in clean_architecture_tdd_course/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i5; + +import 'package:clean_architecture_tdd_course/core/error/failures.dart' as _i6; +import 'package:clean_architecture_tdd_course/core/usecases/usecase.dart' + as _i9; +import 'package:clean_architecture_tdd_course/core/util/input_converter.dart' + as _i10; +import 'package:clean_architecture_tdd_course/features/number_trivia/domain/entities/number_trivia.dart' + as _i7; +import 'package:clean_architecture_tdd_course/features/number_trivia/domain/repositories/number_trivia_repository.dart' + as _i2; +import 'package:clean_architecture_tdd_course/features/number_trivia/domain/usecases/get_concrete_number_trivia.dart' + as _i4; +import 'package:clean_architecture_tdd_course/features/number_trivia/domain/usecases/get_random_number_trivia.dart' + as _i8; +import 'package:dartz/dartz.dart' as _i3; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeNumberTriviaRepository_0 extends _i1.SmartFake + implements _i2.NumberTriviaRepository { + _FakeNumberTriviaRepository_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeEither_1 extends _i1.SmartFake implements _i3.Either { + _FakeEither_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [GetConcreteNumberTrivia]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGetConcreteNumberTrivia extends _i1.Mock + implements _i4.GetConcreteNumberTrivia { + MockGetConcreteNumberTrivia() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.NumberTriviaRepository get repository => (super.noSuchMethod( + Invocation.getter(#repository), + returnValue: _FakeNumberTriviaRepository_0( + this, + Invocation.getter(#repository), + ), + ) as _i2.NumberTriviaRepository); + + @override + _i5.Future<_i3.Either<_i6.Failure, _i7.NumberTrivia>> call( + _i4.Params? params) => + (super.noSuchMethod( + Invocation.method( + #call, + [params], + ), + returnValue: + _i5.Future<_i3.Either<_i6.Failure, _i7.NumberTrivia>>.value( + _FakeEither_1<_i6.Failure, _i7.NumberTrivia>( + this, + Invocation.method( + #call, + [params], + ), + )), + ) as _i5.Future<_i3.Either<_i6.Failure, _i7.NumberTrivia>>); +} + +/// A class which mocks [GetRandomNumberTrivia]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGetRandomNumberTrivia extends _i1.Mock + implements _i8.GetRandomNumberTrivia { + MockGetRandomNumberTrivia() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.NumberTriviaRepository get repository => (super.noSuchMethod( + Invocation.getter(#repository), + returnValue: _FakeNumberTriviaRepository_0( + this, + Invocation.getter(#repository), + ), + ) as _i2.NumberTriviaRepository); + + @override + _i5.Future<_i3.Either<_i6.Failure, _i7.NumberTrivia>> call( + _i9.NoParams? params) => + (super.noSuchMethod( + Invocation.method( + #call, + [params], + ), + returnValue: + _i5.Future<_i3.Either<_i6.Failure, _i7.NumberTrivia>>.value( + _FakeEither_1<_i6.Failure, _i7.NumberTrivia>( + this, + Invocation.method( + #call, + [params], + ), + )), + ) as _i5.Future<_i3.Either<_i6.Failure, _i7.NumberTrivia>>); +} + +/// A class which mocks [InputConverter]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockInputConverter extends _i1.Mock implements _i10.InputConverter { + MockInputConverter() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Either<_i6.Failure, int> stringToUnsignedInteger(String? str) => + (super.noSuchMethod( + Invocation.method( + #stringToUnsignedInteger, + [str], + ), + returnValue: _FakeEither_1<_i6.Failure, int>( + this, + Invocation.method( + #stringToUnsignedInteger, + [str], + ), + ), + ) as _i3.Either<_i6.Failure, int>); +} From 1beacac427d9553f0b65bd60a7c321e4b4a98f26 Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 16:36:16 +0700 Subject: [PATCH 11/13] Refactor `NumberTriviaBloc` constructor --- .flutter-plugins-dependencies | 2 +- .../presentation/bloc/number_trivia_bloc.dart | 13 ++++++------- .../presentation/pages/number_trivia_page.dart | 2 +- lib/injection_container.dart | 4 ++-- .../presentation/bloc/number_trivia_bloc_test.dart | 6 +++--- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 063071f..bce7449 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 16:00:49.485408","version":"3.10.6"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 16:31:48.964802","version":"3.10.6"} \ No newline at end of file diff --git a/lib/features/number_trivia/presentation/bloc/number_trivia_bloc.dart b/lib/features/number_trivia/presentation/bloc/number_trivia_bloc.dart index c6a37fe..f528144 100644 --- a/lib/features/number_trivia/presentation/bloc/number_trivia_bloc.dart +++ b/lib/features/number_trivia/presentation/bloc/number_trivia_bloc.dart @@ -22,16 +22,15 @@ class NumberTriviaBloc extends Bloc { final InputConverter inputConverter; NumberTriviaBloc({ - required GetConcreteNumberTrivia concrete, - required GetRandomNumberTrivia random, + required this.getConcreteNumberTrivia, + required this.getRandomNumberTrivia, required this.inputConverter, - }) : getConcreteNumberTrivia = concrete, - getRandomNumberTrivia = random; + }) : super(Empty()); - @override - NumberTriviaState get initialState => Empty(); + // @override + // NumberTriviaState get initialState => Empty(); - @override + // @override Stream mapEventToState( NumberTriviaEvent event, ) async* { diff --git a/lib/features/number_trivia/presentation/pages/number_trivia_page.dart b/lib/features/number_trivia/presentation/pages/number_trivia_page.dart index 9c5fbdf..ed56f41 100644 --- a/lib/features/number_trivia/presentation/pages/number_trivia_page.dart +++ b/lib/features/number_trivia/presentation/pages/number_trivia_page.dart @@ -1,5 +1,5 @@ import 'package:clean_architecture_tdd_course/features/number_trivia/presentation/bloc/bloc.dart'; -import 'package:clean_architecture_tdd_course/features/number_trivia/presentation/bloc/number_trivia_bloc.dart'; + import 'package:clean_architecture_tdd_course/features/number_trivia/presentation/widgets/widgets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/lib/injection_container.dart b/lib/injection_container.dart index f6fd5bd..4fee325 100644 --- a/lib/injection_container.dart +++ b/lib/injection_container.dart @@ -21,9 +21,9 @@ Future init() async { // Bloc sl.registerFactory( () => NumberTriviaBloc( - concrete: sl(), + getConcreteNumberTrivia: sl(), inputConverter: sl(), - random: sl(), + getRandomNumberTrivia: sl(), ), ); diff --git a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart index 0c1b7ca..8fe7817 100644 --- a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart +++ b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart @@ -25,15 +25,15 @@ void main() { mockInputConverter = MockInputConverter(); bloc = NumberTriviaBloc( - concrete: mockGetConcreteNumberTrivia, - random: mockGetRandomNumberTrivia, + getConcreteNumberTrivia: mockGetConcreteNumberTrivia, + getRandomNumberTrivia: mockGetRandomNumberTrivia, inputConverter: mockInputConverter, ); }); test('initialState should be Empty', () { // assert - expect(bloc.initialState, equals(Empty())); + expect(bloc.state, equals(Empty())); }); group('GetTriviaForConcreteNumber', () { From 0e9aa8edca9fd1325eeae8a73cb4251db505b0a6 Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 17:05:53 +0700 Subject: [PATCH 12/13] Replace `Mock Class` with `GenerateMocks` Added more stub in Assert in order to success the Test --- .flutter-plugins-dependencies | 2 +- test/core/network/network_info_test.dart | 10 +- .../core/network/network_info_test.mocks.dart | 136 ++++++++++++++++++ .../number_trivia_local_data_source_test.dart | 3 + .../number_trivia_repository_impl_test.dart | 15 +- .../get_random_number_trivia_test.dart | 6 +- .../get_random_number_trivia_test.mocks.dart | 82 +++++++++++ 7 files changed, 242 insertions(+), 12 deletions(-) create mode 100644 test/core/network/network_info_test.mocks.dart create mode 100644 test/features/number_trivia/domain/usecases/get_random_number_trivia_test.mocks.dart diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index bce7449..281e551 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 16:31:48.964802","version":"3.10.6"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 16:59:53.138110","version":"3.10.6"} \ No newline at end of file diff --git a/test/core/network/network_info_test.dart b/test/core/network/network_info_test.dart index 3370d9e..dc3973f 100644 --- a/test/core/network/network_info_test.dart +++ b/test/core/network/network_info_test.dart @@ -1,16 +1,18 @@ import 'package:clean_architecture_tdd_course/core/network/network_info.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:internet_connection_checker/internet_connection_checker.dart'; -class MockDataConnectionChecker extends Mock implements InternetConnectionChecker {} +import 'network_info_test.mocks.dart'; +@GenerateMocks([InternetConnectionChecker]) void main() { - late NetworkInfoImpl networkInfo; - late MockDataConnectionChecker mockDataConnectionChecker; + late NetworkInfoImpl networkInfo; + late MockInternetConnectionChecker mockDataConnectionChecker; setUp(() { - mockDataConnectionChecker = MockDataConnectionChecker(); + mockDataConnectionChecker = MockInternetConnectionChecker(); networkInfo = NetworkInfoImpl(mockDataConnectionChecker); }); diff --git a/test/core/network/network_info_test.mocks.dart b/test/core/network/network_info_test.mocks.dart new file mode 100644 index 0000000..a67427e --- /dev/null +++ b/test/core/network/network_info_test.mocks.dart @@ -0,0 +1,136 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in clean_architecture_tdd_course/test/core/network/network_info_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:internet_connection_checker/internet_connection_checker.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeDuration_0 extends _i1.SmartFake implements Duration { + _FakeDuration_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAddressCheckResult_1 extends _i1.SmartFake + implements _i2.AddressCheckResult { + _FakeAddressCheckResult_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [InternetConnectionChecker]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockInternetConnectionChecker extends _i1.Mock + implements _i2.InternetConnectionChecker { + MockInternetConnectionChecker() { + _i1.throwOnMissingStub(this); + } + + @override + Duration get checkInterval => (super.noSuchMethod( + Invocation.getter(#checkInterval), + returnValue: _FakeDuration_0( + this, + Invocation.getter(#checkInterval), + ), + ) as Duration); + + @override + Duration get checkTimeout => (super.noSuchMethod( + Invocation.getter(#checkTimeout), + returnValue: _FakeDuration_0( + this, + Invocation.getter(#checkTimeout), + ), + ) as Duration); + + @override + List<_i2.AddressCheckOptions> get addresses => (super.noSuchMethod( + Invocation.getter(#addresses), + returnValue: <_i2.AddressCheckOptions>[], + ) as List<_i2.AddressCheckOptions>); + + @override + set addresses(List<_i2.AddressCheckOptions>? value) => super.noSuchMethod( + Invocation.setter( + #addresses, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i3.Future get hasConnection => (super.noSuchMethod( + Invocation.getter(#hasConnection), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future<_i2.InternetConnectionStatus> get connectionStatus => + (super.noSuchMethod( + Invocation.getter(#connectionStatus), + returnValue: _i3.Future<_i2.InternetConnectionStatus>.value( + _i2.InternetConnectionStatus.connected), + ) as _i3.Future<_i2.InternetConnectionStatus>); + + @override + _i3.Stream<_i2.InternetConnectionStatus> get onStatusChange => + (super.noSuchMethod( + Invocation.getter(#onStatusChange), + returnValue: _i3.Stream<_i2.InternetConnectionStatus>.empty(), + ) as _i3.Stream<_i2.InternetConnectionStatus>); + + @override + bool get hasListeners => (super.noSuchMethod( + Invocation.getter(#hasListeners), + returnValue: false, + ) as bool); + + @override + bool get isActivelyChecking => (super.noSuchMethod( + Invocation.getter(#isActivelyChecking), + returnValue: false, + ) as bool); + + @override + _i3.Future<_i2.AddressCheckResult> isHostReachable( + _i2.AddressCheckOptions? options) => + (super.noSuchMethod( + Invocation.method( + #isHostReachable, + [options], + ), + returnValue: + _i3.Future<_i2.AddressCheckResult>.value(_FakeAddressCheckResult_1( + this, + Invocation.method( + #isHostReachable, + [options], + ), + )), + ) as _i3.Future<_i2.AddressCheckResult>); +} diff --git a/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart b/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart index f25b0b6..9cb6543 100644 --- a/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart +++ b/test/features/number_trivia/data/datasources/number_trivia_local_data_source_test.dart @@ -61,6 +61,9 @@ void main() { test( 'should call SharedPreferences to cache the data', () async { + //arrange + when(mockSharedPreferences.setString(any, any)) + .thenAnswer((_) async => true); // act dataSource.cacheNumberTrivia(tNumberTriviaModel); // assert diff --git a/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart b/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart index 9de4140..709ed8a 100644 --- a/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart +++ b/test/features/number_trivia/data/repositories/number_trivia_repository_impl_test.dart @@ -13,12 +13,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'number_trivia_repository_impl_test.mocks.dart'; -@GenerateMocks([NumberTriviaRemoteDataSource,NumberTriviaLocalDataSource,NetworkInfo]) +@GenerateMocks( + [NumberTriviaRemoteDataSource, NumberTriviaLocalDataSource, NetworkInfo]) void main() { - late NumberTriviaRepositoryImpl repository; - late MockNumberTriviaRemoteDataSource mockRemoteDataSource; - late MockNumberTriviaLocalDataSource mockLocalDataSource; - late MockNetworkInfo mockNetworkInfo; + late NumberTriviaRepositoryImpl repository; + late MockNumberTriviaRemoteDataSource mockRemoteDataSource; + late MockNumberTriviaLocalDataSource mockLocalDataSource; + late MockNetworkInfo mockNetworkInfo; setUp(() { mockRemoteDataSource = MockNumberTriviaRemoteDataSource(); @@ -62,6 +63,8 @@ void main() { () async { // arrange when(mockNetworkInfo.isConnected).thenAnswer((_) async => true); + when(mockRemoteDataSource.getConcreteNumberTrivia(any)) + .thenAnswer((_) async => tNumberTriviaModel); // act repository.getConcreteNumberTrivia(tNumber); // assert @@ -157,6 +160,8 @@ void main() { () async { // arrange when(mockNetworkInfo.isConnected).thenAnswer((_) async => true); + when(mockRemoteDataSource.getRandomNumberTrivia()) + .thenAnswer((_) async => tNumberTriviaModel); // act repository.getRandomNumberTrivia(); // assert diff --git a/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart b/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart index 4eda2a8..1c831c5 100644 --- a/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart +++ b/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart @@ -3,11 +3,13 @@ import 'package:clean_architecture_tdd_course/features/number_trivia/domain/enti import 'package:clean_architecture_tdd_course/features/number_trivia/domain/repositories/number_trivia_repository.dart'; import 'package:clean_architecture_tdd_course/features/number_trivia/domain/usecases/get_random_number_trivia.dart'; import 'package:dartz/dartz.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; -class MockNumberTriviaRepository extends Mock - implements NumberTriviaRepository {} +import 'get_concrete_number_trivia_test.mocks.dart'; + +@GenerateMocks([NumberTriviaRepository]) void main() { late GetRandomNumberTrivia usecase; diff --git a/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.mocks.dart b/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.mocks.dart new file mode 100644 index 0000000..e442e97 --- /dev/null +++ b/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.mocks.dart @@ -0,0 +1,82 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in clean_architecture_tdd_course/test/features/number_trivia/domain/usecases/get_random_number_trivia_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; + +import 'package:clean_architecture_tdd_course/core/error/failures.dart' as _i5; +import 'package:clean_architecture_tdd_course/features/number_trivia/domain/entities/number_trivia.dart' + as _i6; +import 'package:clean_architecture_tdd_course/features/number_trivia/domain/repositories/number_trivia_repository.dart' + as _i3; +import 'package:dartz/dartz.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeEither_0 extends _i1.SmartFake implements _i2.Either { + _FakeEither_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [NumberTriviaRepository]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockNumberTriviaRepository extends _i1.Mock + implements _i3.NumberTriviaRepository { + MockNumberTriviaRepository() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>> getConcreteNumberTrivia( + int? number) => + (super.noSuchMethod( + Invocation.method( + #getConcreteNumberTrivia, + [number], + ), + returnValue: + _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>>.value( + _FakeEither_0<_i5.Failure, _i6.NumberTrivia>( + this, + Invocation.method( + #getConcreteNumberTrivia, + [number], + ), + )), + ) as _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>>); + + @override + _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>> + getRandomNumberTrivia() => (super.noSuchMethod( + Invocation.method( + #getRandomNumberTrivia, + [], + ), + returnValue: + _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>>.value( + _FakeEither_0<_i5.Failure, _i6.NumberTrivia>( + this, + Invocation.method( + #getRandomNumberTrivia, + [], + ), + )), + ) as _i4.Future<_i2.Either<_i5.Failure, _i6.NumberTrivia>>); +} From f46c907ba846a1bfb2b2f9d54dd291e9a2c671eb Mon Sep 17 00:00:00 2001 From: Phat Nguyen <89678375+ngtphat-towa@users.noreply.github.com> Date: Sat, 7 Oct 2023 17:15:26 +0700 Subject: [PATCH 13/13] Updated tests to use `async*` for state change tracking in Bloc --- .flutter-plugins-dependencies | 2 +- .../bloc/number_trivia_bloc_test.dart | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 281e551..02483ee 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 16:59:53.138110","version":"3.10.6"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.3.4\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.1\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.1\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\ElTow\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.2.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2023-10-07 17:12:25.509079","version":"3.10.6"} \ No newline at end of file diff --git a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart index 8fe7817..33551f7 100644 --- a/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart +++ b/test/features/number_trivia/presentation/bloc/number_trivia_bloc_test.dart @@ -44,10 +44,12 @@ void main() { void setUpMockInputConverterSuccess() => when(mockInputConverter.stringToUnsignedInteger(any)) .thenReturn(Right(tNumberParsed)); - + // The Bloc state is managed using a Stream. Therefore, we use async* instead of async. This is because async* allows us to yield each state change, effectively catching and handling each one. + // For a more detailed explanation on the difference between async and async*, you can refer to this StackOverflow post: + // https://stackoverflow.com/questions/55397023/whats-the-difference-between-async-and-async-in-dart#:~:text=Async%20functions%20execute%20synchronously%20until,async%20function%20body%20executes%20immediately.&text=Async*%20is%20used%20to%20create,is%20wrapped%20in%20a%20Stream. test( 'should call the InputConverter to validate and convert the string to an unsigned integer', - () async { + () async* { // arrange setUpMockInputConverterSuccess(); // act @@ -60,7 +62,7 @@ void main() { test( 'should emit [Error] when the input is invalid', - () async { + () async* { // arrange when(mockInputConverter.stringToUnsignedInteger(any)) .thenReturn(Left(InvalidInputFailure())); @@ -77,7 +79,7 @@ void main() { test( 'should get data from the concrete use case', - () async { + () async* { // arrange setUpMockInputConverterSuccess(); when(mockGetConcreteNumberTrivia(any)) @@ -92,7 +94,7 @@ void main() { test( 'should emit [Loading, Loaded] when data is gotten successfully', - () async { + () async* { // arrange setUpMockInputConverterSuccess(); when(mockGetConcreteNumberTrivia(any)) @@ -111,7 +113,7 @@ void main() { test( 'should emit [Loading, Error] when getting data fails', - () async { + () async* { // arrange setUpMockInputConverterSuccess(); when(mockGetConcreteNumberTrivia(any)) @@ -130,7 +132,7 @@ void main() { test( 'should emit [Loading, Error] with a proper message for the error when getting data fails', - () async { + () async* { // arrange setUpMockInputConverterSuccess(); when(mockGetConcreteNumberTrivia(any)) @@ -153,7 +155,7 @@ void main() { test( 'should get data from the random use case', - () async { + () async* { // arrange when(mockGetRandomNumberTrivia(any)) .thenAnswer((_) async => Right(tNumberTrivia)); @@ -167,7 +169,7 @@ void main() { test( 'should emit [Loading, Loaded] when data is gotten successfully', - () async { + () async* { // arrange when(mockGetRandomNumberTrivia(any)) .thenAnswer((_) async => Right(tNumberTrivia)); @@ -185,7 +187,7 @@ void main() { test( 'should emit [Loading, Error] when getting data fails', - () async { + () async* { // arrange when(mockGetRandomNumberTrivia(any)) .thenAnswer((_) async => Left(ServerFailure())); @@ -203,7 +205,7 @@ void main() { test( 'should emit [Loading, Error] with a proper message for the error when getting data fails', - () async { + () async* { // arrange when(mockGetRandomNumberTrivia(any)) .thenAnswer((_) async => Left(CacheFailure()));