From 74cc883c4556ff7f8aa47d6ea10185e32add72e5 Mon Sep 17 00:00:00 2001 From: Tod Bachman Date: Thu, 10 Aug 2017 13:35:14 -0500 Subject: [PATCH] UIP-2614 Update UiComponent to implement DisposableManagerV6 --- .../component_declaration/component_base.dart | 24 +++++++++++-- pubspec.yaml | 2 +- .../component_base_test.dart | 34 +++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/lib/src/component_declaration/component_base.dart b/lib/src/component_declaration/component_base.dart index 96488ce3b..e47b99e3b 100644 --- a/lib/src/component_declaration/component_base.dart +++ b/lib/src/component_declaration/component_base.dart @@ -135,7 +135,7 @@ typedef TProps BuilderOnlyUiFactory(); /// } /// /// > Related: [UiStatefulComponent] -abstract class UiComponent extends react.Component implements DisposableManagerV3 { +abstract class UiComponent extends react.Component implements DisposableManagerV6 { Disposable _disposableProxy; /// The props for the non-forwarding props defined in this component. @@ -291,6 +291,9 @@ abstract class UiComponent extends react.Component imple @override Future getManagedDelayedFuture(Duration duration, T callback()) => _getDisposableProxy().getManagedDelayedFuture(duration, callback); + + @override + ManagedDisposer getManagedDisposer(Disposer disposer) => _getDisposableProxy().getManagedDisposer(disposer); @override Timer getManagedPeriodicTimer(Duration duration, void callback(Timer timer)) => @@ -300,6 +303,17 @@ abstract class UiComponent extends react.Component imple Timer getManagedTimer(Duration duration, void callback()) => _getDisposableProxy().getManagedTimer(duration, callback); + @override + StreamSubscription listenToStream( + Stream stream, void onData(T event), + {Function onError, void onDone(), bool cancelOnError}) => + _getDisposableProxy().listenToStream( + stream, onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); + + @override + Disposable manageAndReturnDisposable(Disposable disposable) => + _getDisposableProxy().manageAndReturnDisposable(disposable); + @override Completer manageCompleter(Completer completer) => _getDisposableProxy().manageCompleter(completer); @@ -308,20 +322,24 @@ abstract class UiComponent extends react.Component imple void manageDisposable(Disposable disposable) => _getDisposableProxy().manageDisposable(disposable); + /// DEPRECATED. Use [getManagedDisposer] instead. + @Deprecated('2.0.0') @override void manageDisposer(Disposer disposer) => _getDisposableProxy().manageDisposer(disposer); - + @override void manageStreamController(StreamController controller) => _getDisposableProxy().manageStreamController(controller); + /// DEPRECATED. Use [listenToStream] instead. + @Deprecated('2.0.0') @override void manageStreamSubscription(StreamSubscription subscription) => _getDisposableProxy().manageStreamSubscription(subscription); /// Instantiates a new [Disposable] instance on the first call to the - /// [DisposableManagerV3] method. + /// [DisposableManagerV6] method. Disposable _getDisposableProxy() { if (_disposableProxy == null) { _disposableProxy = new Disposable(); diff --git a/pubspec.yaml b/pubspec.yaml index 9c28c1be5..6af58bd78 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: react: "^3.4.3" source_span: "^1.4.0" transformer_utils: "^0.1.1" - w_common: "^1.6.0" + w_common: "^1.8.0" w_flux: "^2.7.1" platform_detect: "^1.3.2" quiver: ">=0.21.4 <0.26.0" diff --git a/test/over_react/component_declaration/component_base_test.dart b/test/over_react/component_declaration/component_base_test.dart index 982340dae..b220874bf 100644 --- a/test/over_react/component_declaration/component_base_test.dart +++ b/test/over_react/component_declaration/component_base_test.dart @@ -710,6 +710,17 @@ main() { await unmountAndDisposal(); }); + test('should call managed disposer returned by getManagedDisposer', () async { + var disposerCalled = false; + var disposer = component.getManagedDisposer(() async => disposerCalled = true); + expect(disposer, new isInstanceOf()); + + expect(disposerCalled, isFalse); + await unmountAndDisposal(); + expect(disposerCalled, isTrue); + expect(disposer.isDisposed, isTrue); + }); + test('should cancel periodic timer', () async { var timer = component.getManagedPeriodicTimer(shortDuration, expectAsync1((_) {}, count: 0, reason: 'Did not expect callback to be invoked.')); @@ -728,6 +739,29 @@ main() { expect(timer.isActive, isFalse); }); + test('should cancel stream subscription returned by listenToStream', () async{ + var streamController = new StreamController.broadcast(); + // ignore: cancel_subscriptions + var streamSubscription = component.listenToStream(streamController.stream, expectAsync1((_) {}, + count: 0, + reason: 'Did not expect event after cancelling subscription')); + expect(streamSubscription, new isInstanceOf()); + + await unmountAndDisposal(); + + streamController + ..add(null) + ..close(); + }); + + test('should dispose managed Disposable returned by manageAndReturnDisposable', () async { + var disposable = new Disposable(); + expect(component.manageAndReturnDisposable(disposable), same(disposable)); + expect(disposable.isDisposed, isFalse); + await unmountAndDisposal(); + expect(disposable.isDisposed, isTrue); + }); + test('should complete uncompleted managed Completer with ObjectDisposedException', () async { var completer = new Completer(); component.manageCompleter(completer);