public async Task ViewModel_WhenRefreshed_ShouldDisposePreviousNotificationsSubscriptions( IFixture fixture, TestSchedulers scheduler, int[] values) { //arrange var notifications = scheduler.CreateColdObservable<int>(); var sut = new UpdatableObservableViewModelBuilderOptions<int, int[], int>( _ => { }, ct => Task.FromResult(values), () => notifications, scheduler, scheduler, scheduler) .UpdateAction((i, o) => () => { }) .ToViewModel(); const long disposeTime = 805; //act scheduler.Start(); await sut.RefreshAsync(); //we advance to an arbitrary time scheduler.AdvanceBy(disposeTime); //the subscription to the new observable should happen here //the first subscription should be dispose at the current scheduler time await sut.RefreshAsync(); //assert notifications.Subscriptions[0].Unsubscribe.Should().Be(disposeTime); }
public async Task ViewModel_ShouldReturnCorrectValue( IFixture fixture, TestSchedulers scheduler) { //arrange const int insertionIndex = 5; var initialList = fixture.CreateMany<int>(10).ToArray(); var addedList = fixture.CreateMany<int>(10).ToArray(); var expected = initialList.Take(insertionIndex) .Concat(addedList.Reverse()) .Concat(initialList.Skip(insertionIndex)) .ToArray(); var notifications = scheduler.CreateColdObservable(addedList.Select((i, ii) => OnNext(Subscribed + 1 + ii, i)).ToArray()); var sut = new UpdatableObservableViewModelBuilderOptions<int, int[], int>( _ => { }, ct => Task.FromResult(initialList), () => notifications, scheduler, scheduler, scheduler) .UpdateAction((i, o) => () => o.Insert(insertionIndex, i)) .ToViewModel(); //act scheduler.Start(); await sut.RefreshAsync(); scheduler.AdvanceBy(Disposed); var actual = ((IObservableViewModel<ObservableCollection<int>>)sut).CurrentValue; //assert actual.ShouldAllBeEquivalentTo(expected); }
public void Customize(IFixture fixture) { var testScheduler = new TestSchedulers(); fixture.Register<IScheduler>(() => testScheduler); fixture.Register<ISchedulers>(() => testScheduler); fixture.Register<TestScheduler>(() => testScheduler); fixture.Register<ThrowingTestScheduler>(() => testScheduler); fixture.Register<IPriorityScheduler>(() => testScheduler); fixture.Register(() => testScheduler); fixture.Register<Unit>(() => Unit.Default); fixture.Customizations.Add(new ReplaySubjectSpecimenBuilder()); }
public void ToViewModel_ShouldReturnCorrectValue( Task<object> value, TestSchedulers scheduler) { //arrange var sut = new ObservableViewModelBuilderOptions<object>(model => { }, ct => value, scheduler); //act var actual = sut.ToViewModel(); //assert actual.Should().BeOfType<ObservableViewModel<object>>() .And.Match<ObservableViewModel<object>>(model => model.Source(CancellationToken.None) == value); }
public async Task OnNext_WhenSubscribingThenPushingFirstValue_AndFirstValueIsDefaultValue_ShouldReturnCorrectValue( TestSchedulers schedulers) { //arrange var observer = schedulers.CreateObserver<int>(); var sut = new ObservableProperty<int>(schedulers); var expected = sut.Value; sut.Subscribe(observer); //act sut.OnNext(expected); //assert observer.Values().Last().Should().Be(expected); }
public void CanExecuteChanged_WhenObservableYieldValue_ShouldYieldValue( [Frozen]Subject<bool> canExecuteObservable, [Frozen]Mock<ICanExecuteStrategy<object>> inner, ObserveCanExecuteStrategy<object> sut, TestSchedulers schedulers, object arg) { //arrange var observer = schedulers.CreateObserver<Unit>(); sut.CanExecuteChanged.Subscribe(observer); //act canExecuteObservable.OnNext(true); //assert observer.Values().Should().HaveCount(1); }
public void Execute_ShouldBeCalledWithArg( IObservable<object> value, object arg, TestSchedulers schedulers) { //arrange object actual = null; var sut = new ObservableMvvmCommand<object, object>(o => { actual = o; return value; }, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>()); //act sut.Execute(arg); schedulers.AdvanceBy(200); //assert actual.Should().Be(arg); }
public void Execute_ShouldCallCallback( object expected, TestSchedulers schedulers) { //arrange object actual = null; var value = Observable.Return(expected, ImmediateScheduler.Instance); var sut = new ObservableMvvmCommand<object, object>( o => value, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>(), doObserver: () => Observer.Create<object>(o => actual = o), doScheduler: ImmediateScheduler.Instance); //act sut.Execute(null); schedulers.AdvanceBy(200); //assert actual.Should().Be(expected); }
public async Task ViewModel_WhenError_WithRefreshOnCollectionUpdateNotification_ShouldRefresh( IFixture fixture, TestSchedulers scheduler, int[] expectedValue) { //arrange var notifications = scheduler.CreateColdObservable(OnNext(200, 1)); var observer = scheduler.CreateObserver<ObservableViewModelNotification>(); var count = 0; var sut = new UpdatableObservableViewModelBuilderOptions<int, int[], int>( _ => { }, async ct => { if (++count == 1) throw new Exception(); else return expectedValue; }, () => notifications, scheduler, scheduler, scheduler) .UpdateAction((i, o) => () => { }) .RefreshOnCollectionUpdateNotification() .ToViewModel(); sut.Subscribe(observer); //act await sut.RefreshAsync(); scheduler.AdvanceBy(300); //assert observer.Values().Last().Value.As<ObservableCollection<int>>().ShouldAllBeEquivalentTo(expectedValue); }
public void Execute_WithError_ShouldExecuteErrorTask( object obj, Exception expected, TestSchedulers schedulers) { //arrange Exception actual = null; var value = Observable.Throw<object>(expected, ImmediateScheduler.Instance); Func<CancellationToken, Exception, Task> errorTask = async (ct, ex) => actual = ex; var sut = new ObservableMvvmCommand<object, object>(_ => value, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>(), errorTask: errorTask); //act sut.Execute(obj); schedulers.AdvanceBy(200); //assert actual.Should().Be(expected); }
public void Execute_WithObservableYielding3Values_ShouldReturnCorrectResult( object value1, object value2, object value3, TestSchedulers schedulers, ThrowingTestScheduler scheduler) { //arrange var observable = scheduler.CreateColdObservable(OnNext(10, value1), OnNext(20, value2), OnNext(30, value3), OnCompleted(40, new object())); var observer = scheduler.CreateObserver<object>(); var sut = new ObservableMvvmCommand<object, object>(o => observable, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>(), doObserver: () => observer, doScheduler: ImmediateScheduler.Instance); //act sut.Execute(null); //allow any work scheduled with the schedulers to advance schedulers.AdvanceBy(200); //allow notifications to advance scheduler.AdvanceBy(200); //assert observer.Messages.AssertEqual(OnNext(10, value1), OnNext(20, value2), OnNext(30, value3), OnCompleted(40, new object())); }
public void Execute_WhenErrorInErrorAction_ShouldCallNotifyNotExecuting( Mock<ICanExecuteStrategy<object>> canExecute, Exception error, object obj, TestSchedulers schedulers) { //arrange var value = Observable.Throw<object>(error, ImmediateScheduler.Instance); Func<CancellationToken, Exception, Task> errorTask = async (ct, ex) => { throw new Exception(); }; var sut = new ObservableMvvmCommand<object, object>(_ => value, schedulers, schedulers, "name", canExecute.Object, errorTask: errorTask); //act sut.Execute(obj); schedulers.AdvanceBy(200); //assert canExecute.Verify(c => c.NotifyNotExecuting(obj), Times.Once()); }
public void Execute_WhenError_ShouldCallNotifyNotExecuting( Mock<ICanExecuteStrategy<object>> canExecute, Exception error, object obj, TestSchedulers schedulers) { //arrange var value = Observable.Throw<object>(error, ImmediateScheduler.Instance); var sut = new ObservableMvvmCommand<object, object>(_ => value, schedulers, schedulers, "name", canExecute.Object); //act sut.Execute(obj); schedulers.AdvanceBy(200); //assert canExecute.Verify(c => c.NotifyNotExecuting(obj), Times.Once()); }
public void Execute_ShouldCallNotifyExecuting( [Frozen]Mock<ICanExecuteStrategy<object>> canExecute, ObservableMvvmCommand<object, object> sut, [Frozen]object obj, TestSchedulers schedulers) { //arrange //act sut.Execute(obj); schedulers.AdvanceBy(200); //assert canExecute.Verify(c => c.NotifyExecuting(obj), Times.Once()); }
public void Execute_ShouldCallOnError( Exception expected, TestSchedulers schedulers) { //arrange Exception actual = null; var value = Observable.Throw<object>(expected, ImmediateScheduler.Instance); var sut = new ObservableMvvmCommand<object, object>( o => value, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>(), doObserver: () => Observer.Create<object>(_ => { }, e => actual = e), doScheduler: ImmediateScheduler.Instance); //act sut.Execute(null); schedulers.AdvanceBy(200); //assert actual.Should().Be(expected); }
public void ToViewModel_ShouldSaveViewModel( Task<object> source, TestSchedulers scheduler) { //arrange IObservableViewModel viewModel = null; var sut = new ObservableViewModelBuilderOptions<object>(model => viewModel = model, ct => source, scheduler); //act var actual = sut.ToViewModel(); //assert actual.Should().Be(viewModel.As<ObservableViewModel<object>>()); }
public void SetDefaultError_ShouldReturnTrue( Func<CancellationToken, Exception, Task> error, Func<object, IObservable<object>> observable, TestSchedulers schedulers) { //arrange var sut = new ObservableMvvmCommand<object, object>(observable, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>()); //act var actual = sut.SetDefaultError(error); //assert actual.Should().BeTrue(); }
public void SetDefaultError_ErrorAlreadySetFromConstructor_ShouldReturnFalse( Func<CancellationToken, Exception, Task> errorTask, Func<CancellationToken, Exception, Task> expectedErrorTask, Func<object, IObservable<object>> observable, TestSchedulers schedulers) { //arrange var sut = new ObservableMvvmCommand<object, object>(observable, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>(), errorTask: expectedErrorTask); //act var actual = sut.SetDefaultError(errorTask); //assert actual.Should().BeFalse(); }
public void DecorateDoFactory_ShouldDecorateDo( Func<object, IObservable<object>> observable, IObserver<object> expected, TestSchedulers schedulers) { //arrange var sut = new ObservableMvvmCommand<object, object>(observable, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>()); //act sut.DecorateDo(observer => expected); var actual = sut.DoObserver(); //assert actual.Should().Be(expected); }
public void ViewModel_WhenInitialized_WithRefreshOnCollectionUpdateNotification_ShouldRefresh( IFixture fixture, TestSchedulers scheduler, int[] expectedValue) { //arrange var notifications = scheduler.CreateColdObservable(OnNext(200, 1)); var observer = scheduler.CreateObserver<ObservableViewModelNotification>(); var sut = new UpdatableObservableViewModelBuilderOptions<int, int[], int>( _ => { }, ct => Task.FromResult(expectedValue), () => notifications, scheduler, scheduler, scheduler) .UpdateAction((i, o) => () => { }) .RefreshOnCollectionUpdateNotification() .ToViewModel(); sut.Subscribe(observer); //act scheduler.Start(); //assert var expected = new ObservableViewModelNotification() { Status = ObservableViewModelStatus.Value, Value = expectedValue }; observer.Values().Last().Value.As<ObservableCollection<int>>().ShouldAllBeEquivalentTo(expectedValue); }
public void Execute_ShouldExecuteObservable( TestSchedulers schedulers) { //arrange bool observableCalled = false; var value = Observable.Return(Unit.Default, ImmediateScheduler.Instance) .Do(unit => observableCalled = true); var sut = new ObservableMvvmCommand<object, System.Reactive.Unit>(o => value, schedulers, schedulers, "name", new AlwaysTrueCanExecuteStrategy<object>()); //act sut.Execute(null); schedulers.AdvanceBy(200); //assert observableCalled.Should().BeTrue(); }