diff --git a/src/ReactiveUI.Tests/Suspension/DummyAppState.cs b/src/ReactiveUI.Tests/Suspension/DummyAppState.cs new file mode 100644 index 0000000000..4758459dc4 --- /dev/null +++ b/src/ReactiveUI.Tests/Suspension/DummyAppState.cs @@ -0,0 +1,6 @@ +namespace ReactiveUI.Tests.Suspension +{ + public class DummyAppState + { + } +} diff --git a/src/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsTests.cs b/src/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsTests.cs new file mode 100644 index 0000000000..39966c0f93 --- /dev/null +++ b/src/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsTests.cs @@ -0,0 +1,58 @@ +using System; +using Shouldly; +using Xunit; + +namespace ReactiveUI.Tests.Suspension +{ + public class SuspensionHostExtensionsTests + { + [Fact] + public void GetAppStateReturns() + { + var fixture = new SuspensionHost(); + fixture.AppState = new DummyAppState(); + + var result = fixture.GetAppState(); + + result.ShouldBe(fixture.AppState); + } + + [Fact] + public void NullSuspensionHostThrowsException() + { + var result = Record.Exception(() => ((SuspensionHost)null!).SetupDefaultSuspendResume()); + + result.ShouldBeOfType(); + } + + [Fact] + public void NullAppStateDoesNotThrowException() + { + var fixture = new SuspensionHost(); + + var result = Record.Exception(() => fixture.SetupDefaultSuspendResume()); + + result.ShouldBeNull(); + } + + [Fact] + public void ObserveAppStateDoesNotThrowException() + { + var fixture = new SuspensionHost(); + + var result = Record.Exception(() => fixture.ObserveAppState().Subscribe()); + + result.ShouldBeNull(); + } + + [Fact] + public void ObserveAppStateDoesNotThrowInvalidCastException() + { + var fixture = new SuspensionHost(); + + var result = Record.Exception(() => fixture.ObserveAppState().Subscribe()); + + result.ShouldNotBeOfType(); + } + } +} diff --git a/src/ReactiveUI/Suspension/SuspensionHostExtensions.cs b/src/ReactiveUI/Suspension/SuspensionHostExtensions.cs index 41c8e1c66e..51e416ade3 100644 --- a/src/ReactiveUI/Suspension/SuspensionHostExtensions.cs +++ b/src/ReactiveUI/Suspension/SuspensionHostExtensions.cs @@ -24,8 +24,9 @@ public static class SuspensionHostExtensions public static IObservable ObserveAppState(this ISuspensionHost item) where T : class { - return item.WhenAny(x => x.AppState, x => (T)x) - .Where(x => x != null); + return item.WhenAny(suspensionHost => suspensionHost.AppState, observedChange => observedChange.Value) + .Where(x => x != null) + .Cast(); } /// @@ -41,12 +42,7 @@ public static T GetAppState(this ISuspensionHost item) throw new ArgumentNullException(nameof(item)); } - if (item.AppState == null) - { - throw new NullReferenceException(nameof(item.AppState)); - } - - return (T)item.AppState; + return (T)item.AppState!; } /// @@ -63,11 +59,6 @@ public static IDisposable SetupDefaultSuspendResume(this ISuspensionHost item, I throw new ArgumentNullException(nameof(item)); } - if (item.AppState == null) - { - throw new NullReferenceException(nameof(item.AppState)); - } - var ret = new CompositeDisposable(); driver ??= Locator.Current.GetService(); @@ -77,7 +68,7 @@ public static IDisposable SetupDefaultSuspendResume(this ISuspensionHost item, I .Subscribe(_ => item.Log().Info("Invalidated app state"))); ret.Add(item.ShouldPersistState - .SelectMany(x => driver.SaveState(item.AppState).Finally(x.Dispose)) + .SelectMany(x => driver.SaveState(item.AppState!).Finally(x.Dispose)) .LoggedCatch(item, Observables.Unit, "Tried to persist app state") .Subscribe(_ => item.Log().Info("Persisted application state")));