From 0a3e4c73f723d6af3732bdfd616bb7593a8544e5 Mon Sep 17 00:00:00 2001 From: f-person Date: Wed, 13 Oct 2021 12:29:15 +0400 Subject: [PATCH] Upgrade to Flutter 2 and null-safety --- .gitignore | 2 ++ example/ios/.gitignore | 1 + example/ios/Flutter/AppFrameworkInfo.plist | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 24 ++------------ .../contents.xcworkspacedata | 2 +- example/lib/main.dart | 21 +++++++------ example/lib/stores.dart | 18 +++++------ example/pubspec.yaml | 3 ++ lib/src/action.dart | 14 ++++----- lib/src/store.dart | 27 +++++++++------- lib/src/store_watcher.dart | 31 ++++++++++--------- pubspec.yaml | 11 +++---- test/action_test.dart | 21 +++++++------ test/store_test.dart | 9 ++++-- 14 files changed, 91 insertions(+), 95 deletions(-) diff --git a/.gitignore b/.gitignore index fd138f1..86b55d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,14 @@ .atom/ .idea/ *.iml +.vscode/ # dart .packages .pub packages pubspec.lock +.dart_tool/ # flutter build/ diff --git a/example/ios/.gitignore b/example/ios/.gitignore index 1e1aafd..a6a3c89 100644 --- a/example/ios/.gitignore +++ b/example/ios/.gitignore @@ -38,5 +38,6 @@ Icon? /Flutter/Flutter.framework /Flutter/Generated.xcconfig /ServiceDefinitions.json +/Flutter/flutter_export_environment.sh Pods/ diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 6c2de80..3a9c234 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -25,6 +25,6 @@ arm64 MinimumOSVersion - 8.0 + 9.0 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 1c026b0..3398eb2 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -8,12 +8,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; @@ -30,8 +25,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -41,15 +34,12 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -63,8 +53,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -74,10 +62,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, - 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, @@ -192,7 +177,6 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -212,7 +196,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; @@ -265,7 +249,6 @@ /* Begin XCBuildConfiguration section */ 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -309,7 +292,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -319,7 +302,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -357,7 +339,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a1..919434a 100644 --- a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/example/lib/main.dart b/example/lib/main.dart index f9d5c37..e36693d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,7 +16,7 @@ void main() { class ChatScreen extends StatefulWidget { /// Creates a widget that watches stores. - ChatScreen({Key key}) : super(key: key); + ChatScreen({Key? key}) : super(key: key); @override ChatScreenState createState() => new ChatScreenState(); @@ -33,8 +33,8 @@ class ChatScreen extends StatefulWidget { class ChatScreenState extends State with StoreWatcherMixin { // Never write to these stores directly. Use Actions. - ChatMessageStore messageStore; - ChatUserStore chatUserStore; + late ChatMessageStore messageStore; + late ChatUserStore chatUserStore; final TextEditingController msgController = new TextEditingController(); @@ -52,23 +52,24 @@ class ChatScreenState extends State // Demonstrates using a custom change handler. messageStore = - listenToStore(messageStoreToken, handleChatMessageStoreChanged); + listenToStore(messageStoreToken, handleChatMessageStoreChanged) + as ChatMessageStore; // Demonstrates using the default handler, which just calls setState(). - chatUserStore = listenToStore(userStoreToken); + chatUserStore = listenToStore(userStoreToken) as ChatUserStore; } void handleChatMessageStoreChanged(Store store) { - ChatMessageStore messageStore = store; + ChatMessageStore messageStore = store as ChatMessageStore; if (messageStore.currentMessage.isEmpty) { - msgController.clear(); + msgController.clear(); } setState(() {}); } Widget _buildTextComposer(BuildContext context, ChatMessageStore messageStore, ChatUserStore userStore) { - final ValueChanged commitMessage = (String _) { + final ValueChanged commitMessage = (String? _) { commitCurrentMessageAction(userStore.me); }; @@ -122,8 +123,8 @@ class ChatMessageListItem extends StatefulWidget { class ChatMessageListItemState extends State with SingleTickerProviderStateMixin { - AnimationController _animationController; - Animation _animation; + late AnimationController _animationController; + late Animation _animation; @override void initState() { diff --git a/example/lib/stores.dart b/example/lib/stores.dart index 1a02500..487d22e 100644 --- a/example/lib/stores.dart +++ b/example/lib/stores.dart @@ -4,29 +4,29 @@ import 'dart:math' show Random; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show Color, Colors; import 'package:flutter_flux/flutter_flux.dart'; class ChatUser { - ChatUser({this.name, this.color}); + ChatUser({required this.name, required this.color}); final String name; final Color color; } class ChatMessage { - ChatMessage({this.sender, this.text}); + ChatMessage({required this.sender, required this.text}); final ChatUser sender; final String text; } class ChatMessageStore extends Store { ChatMessageStore() { - triggerOnAction(setCurrentMessageAction, (String value) { - _currentMessage = value; + triggerOnAction(setCurrentMessageAction, (String? value) { + _currentMessage = value ?? ''; }); - triggerOnAction(commitCurrentMessageAction, (ChatUser me) { + triggerOnAction(commitCurrentMessageAction, (ChatUser? me) { final ChatMessage message = - new ChatMessage(sender: me, text: _currentMessage); + new ChatMessage(sender: me!, text: _currentMessage); _messages.add(message); _currentMessage = ''; }); @@ -46,12 +46,12 @@ class ChatUserStore extends Store { ChatUserStore() { final String name = "Guest${new Random().nextInt(1000)}"; final Color color = - Colors.accents[new Random().nextInt(Colors.accents.length)][700]; + Colors.accents[new Random().nextInt(Colors.accents.length)][700]!; _me = new ChatUser(name: name, color: color); // This store does not currently handle any actions. } - ChatUser _me; + late ChatUser _me; ChatUser get me => _me; } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 4d08d9c..1fabc0f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -13,3 +13,6 @@ dev_dependencies: flutter: uses-material-design: true + +environment: + sdk: '>=2.12.0 <3.0.0' diff --git a/lib/src/action.dart b/lib/src/action.dart index fc2254d..258cc63 100644 --- a/lib/src/action.dart +++ b/lib/src/action.dart @@ -41,12 +41,12 @@ typedef void OnData(T event); /// when a consumer needs to check state changes immediately after invoking an /// action. /// -class Action implements Function { - List> _listeners = >[]; +class Action { + List> _listeners = >[]; /// Dispatch this [Action] to all listeners. If a payload is supplied, it will /// be passed to each listener's callback, otherwise null will be passed. - Future> call([T payload]) { + Future> call([T? payload]) { // Invoke all listeners in a microtask to enable waiting on futures. The // microtask queue is emptied before the event loop continues. This ensures // synchronous listeners are invoked in the current tick of the event loop @@ -60,7 +60,7 @@ class Action implements Function { // for stream-based actions vs. 0.14 ms for this action implementation. return Future.wait( _listeners.map( - (OnData l) => new Future.microtask(() => l(payload)) + (OnData l) => new Future.microtask(() => l(payload)), ), ); } @@ -74,7 +74,7 @@ class Action implements Function { /// dispatched. A payload of type [T] will be passed to the callback if /// supplied at dispatch time, otherwise null will be passed. Returns an /// [ActionSubscription] which provides means to cancel the subscription. - ActionSubscription listen(OnData onData) { + ActionSubscription listen(OnData onData) { _listeners.add(onData); return new ActionSubscription(() => _listeners.remove(onData)); } @@ -84,14 +84,14 @@ typedef void _OnCancel(); /// A subscription used to cancel registered listeners to an [Action]. class ActionSubscription { - final _OnCancel _onCancel; + final _OnCancel? _onCancel; ActionSubscription(this._onCancel); /// Cancel this subscription to an [Action] void cancel() { if (_onCancel != null) { - _onCancel(); + _onCancel!(); } } } diff --git a/lib/src/store.dart b/lib/src/store.dart index 2d84e08..d238162 100644 --- a/lib/src/store.dart +++ b/lib/src/store.dart @@ -48,19 +48,20 @@ class Store { /// As an example, [transformer] could be used to throttle the number of /// triggers this [Store] emits for state that may update extremely frequently /// (like scroll position). - Store.withTransformer(StreamTransformer transformer) { + Store.withTransformer(StreamTransformer transformer) { _streamController = new StreamController(); // apply a transform to the stream if supplied - _stream = - _streamController.stream.transform(transformer).asBroadcastStream(); + _stream = _streamController.stream + .transform(transformer) + .asBroadcastStream() as Stream; } /// Stream controller for [_stream]. Used by [trigger]. - StreamController _streamController; + late StreamController _streamController; /// Broadcast stream of "data updated" events. Listened to in [listen]. - Stream _stream; + late Stream _stream; void dispose() { _streamController.close(); @@ -79,10 +80,9 @@ class Store { /// A convenience method for listening to an [action] and triggering /// automatically. The callback doesn't call return, so the return /// type of onAction is null. - void triggerOnAction(Action action, - [dynamic onAction(T payload)]) { + void triggerOnAction(Action action, [dynamic onAction(T? payload)?]) { if (onAction != null) { - action.listen((T payload) async { + action.listen((T? payload) async { await onAction(payload); trigger(); }); @@ -102,7 +102,6 @@ class Store { /// void (null) or true. void triggerOnConditionalAction( Action action, FutureOr onAction(T payload)) { - assert(action != null); action.listen((dynamic payload) async { // Action functions must return bool, or a Future. dynamic result = onAction(payload); @@ -123,8 +122,12 @@ class Store { /// Each time this `Store` triggers (by calling [trigger]), indicating that /// data has been mutated, [onData] will be called. StreamSubscription listen(void onData(Store event), - {Function onError, void onDone(), bool cancelOnError}) { - return _stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); + {Function? onError, void onDone()?, bool? cancelOnError}) { + return _stream.listen( + onData, + onError: onError, + onDone: onDone, + cancelOnError: cancelOnError, + ); } } diff --git a/lib/src/store_watcher.dart b/lib/src/store_watcher.dart index f45882f..f4a8f81 100644 --- a/lib/src/store_watcher.dart +++ b/lib/src/store_watcher.dart @@ -19,12 +19,13 @@ import 'package:flutter/foundation.dart'; import 'store.dart'; /// Signature for a function the lets the caller listen to a store. -typedef Store ListenToStore(StoreToken token, [ValueChanged onStoreChanged]); +typedef Store ListenToStore(StoreToken token, + [ValueChanged onStoreChanged]); /// A widget that rebuilds when the [Store]s it is listening to change. abstract class StoreWatcher extends StatefulWidget { /// Creates a widget that watches stores. - StoreWatcher({ Key key }) : super(key: key); + StoreWatcher({Key? key}) : super(key: key); /// Override this function to build widgets that depend on the current value /// of the store. @@ -47,8 +48,8 @@ abstract class StoreWatcher extends StatefulWidget { } /// State for a [StoreWatcher] widget. -class StoreWatcherState extends State with StoreWatcherMixin { - +class StoreWatcherState extends State + with StoreWatcherMixin { final Map _storeTokens = {}; @override @@ -64,7 +65,7 @@ class StoreWatcherState extends State with StoreWatcherMixin onStoreChanged]) { + Store listenToStore(StoreToken token, [ValueChanged? onStoreChanged]) { final Store store = super.listenToStore(token, onStoreChanged); _storeTokens[token] = store; return store; @@ -79,17 +80,19 @@ class StoreWatcherState extends State with StoreWatcherMixin on State{ - final Map> _streamSubscriptions = >{}; +mixin StoreWatcherMixin on State { + final Map> _streamSubscriptions = + >{}; /// Start receiving notifications from the given store, optionally routed /// to the given function. /// /// By default, [onStoreChanged] will be called when the store changes. @protected - Store listenToStore(StoreToken token, [ValueChanged onStoreChanged]) { + Store listenToStore(StoreToken token, [ValueChanged? onStoreChanged]) { final Store store = token._value; - _streamSubscriptions[store] = store.listen(onStoreChanged ?? _handleStoreChanged); + _streamSubscriptions[store] = + store.listen(onStoreChanged ?? _handleStoreChanged); return store; } @@ -104,7 +107,7 @@ mixin StoreWatcherMixin on State{ @override void dispose() { final Iterable> subscriptions = - _streamSubscriptions.values; + _streamSubscriptions.values; for (final StreamSubscription subscription in subscriptions) subscription.cancel(); _streamSubscriptions.clear(); @@ -115,9 +118,8 @@ mixin StoreWatcherMixin on State{ // TODO(abarth): We cancel our subscriptions in [dispose], which means we // shouldn't receive this callback when we're not mounted. If that's the // case, we should change this check into an assert that we are mounted. - if (!mounted) - return; - setState(() { }); + if (!mounted) return; + setState(() {}); } } @@ -139,8 +141,7 @@ class StoreToken { @override bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) - return false; + if (other.runtimeType != runtimeType) return false; final StoreToken typedOther = other; return identical(_value, typedOther._value); } diff --git a/pubspec.yaml b/pubspec.yaml index f3351f4..c70083e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,17 +5,16 @@ version: 4.1.3 description: Flux library for Flutter, featuring unidirectional dataflow inspired by reflux and Facebook's flux architecture. homepage: https://github.com/google/flutter_flux dependencies: - meta: ^1.0.3 + meta: ^1.7.0 flutter: sdk: flutter dev_dependencies: - quiver: '>=2.0.0 <3.0.0' - test: ^1.5.1 - mockito: ^4.0.0 + quiver: ^3.0.1 + test: ^1.17.10 + mockito: ^5.0.16 flutter_test: sdk: flutter - environment: - sdk: ">=1.24.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' diff --git a/test/action_test.dart b/test/action_test.dart index 9c34a00..61b75e8 100644 --- a/test/action_test.dart +++ b/test/action_test.dart @@ -20,7 +20,7 @@ import 'package:test/test.dart'; void main() { group('Action', () { - Action action; + late Action action; setUp(() { action = new Action(); @@ -37,7 +37,7 @@ void main() { final Completer c = new Completer(); final Action _action = new Action(); - _action.listen((String payload) { + _action.listen((String? payload) { expect(payload, equals(null)); c.complete(); }); @@ -48,7 +48,7 @@ void main() { test('should support dispatch with a payload', () async { final Completer c = new Completer(); - action.listen((String payload) { + action.listen((String? payload) { expect(payload, equals('990 guerrero')); c.complete(); }); @@ -59,7 +59,7 @@ void main() { test('should dispatch by default when called', () async { final Completer c = new Completer(); - action.listen((String payload) { + action.listen((String? payload) { expect(payload, equals('990 guerrero')); c.complete(); }); @@ -132,7 +132,7 @@ void main() { test('should surface errors in listeners', () { Action action = new Action(); - action.listen((int _) => throw new UnimplementedError()); + action.listen((int? _) => throw new UnimplementedError()); expect(action(0), throwsUnimplementedError); }); }); @@ -141,7 +141,8 @@ void main() { test('should stop listening when subscription is canceled', () async { Action action = new Action(); bool listened = false; - ActionSubscription subscription = action.listen((Null _) => listened = true); + ActionSubscription subscription = + action.listen((Null _) => listened = true); await action(); expect(listened, isTrue); @@ -185,12 +186,12 @@ void main() { stopwatch.reset(); - Completer syncCompleter; - Completer asyncCompleter; + Completer? syncCompleter; + Completer? asyncCompleter; Action action = new Action(); - action.listen((Null _) => syncCompleter.complete()); + action.listen((Null _) => syncCompleter?.complete()); action.listen((Null _) async { - asyncCompleter.complete(); + asyncCompleter?.complete(); }); stopwatch.start(); for (int i = 0; i < sampleSize; i++) { diff --git a/test/store_test.dart b/test/store_test.dart index 39c5304..87d8f58 100644 --- a/test/store_test.dart +++ b/test/store_test.dart @@ -22,8 +22,8 @@ import 'package:test/test.dart'; void main() { group('Store', () { - Store store; - Action action; + late Store store; + late Action action; setUp(() { store = new Store(); @@ -58,6 +58,7 @@ void main() { void onAction(Null _) { wasTriggered = true; } + store.triggerOnAction(action, onAction); store.listen(expectAsync1((Store listenedStore) { expect(listenedStore, equals(store)); @@ -74,6 +75,7 @@ void main() { wasTriggered = true; return true; } + store.triggerOnConditionalAction(action, onAction); store.listen(expectAsync1((Store listenedStore) { expect(listenedStore, equals(store)); @@ -104,6 +106,7 @@ void main() { await new Future.delayed(new Duration(milliseconds: 30)); afterTimer = true; } + store.triggerOnAction(action, asyncCallback); store.listen(expectAsync1((Store listenedStore) { expect(listenedStore, equals(store)); @@ -117,7 +120,7 @@ void main() { () { final Action _action = new Action(); int counter = 0; - store.triggerOnAction(_action, (int payload) => counter = payload); + store.triggerOnAction(_action, (int? payload) => counter = payload!); store.listen(expectAsync1((Store listenedStore) { expect(listenedStore, equals(store)); expect(counter, equals(17));