public async Task ChangingValueOfAttachedOptionShouldTriggerUpdate() { // Arrange var tcs = new TaskCompletionSource <int>(); var dispatcher = CreateDispatcher(); Task <IValueCalculationResult <int> > CalculationTaskFactory(CancellationToken ct) { return(Task.FromResult <IValueCalculationResult <int> >(ValueCalculationResult.Success(123))); } void HandleResultCallback(int arg) { tcs.SetResult(arg); } using var sut = new AsyncValueCalculator <int>(dispatcher, CalculationTaskFactory, HandleResultCallback); var option = Substitute.For <IValueOption>(); sut.Attach(option); // Act option.ValueChanged += Raise.Event(); // Assert var result = await tcs.Task; Assert.Equal(123, result); }
public void FailShouldCreateFailedResult() { // Act var actual = ValueCalculationResult.Fail <int>(); // Assert Assert.NotNull(actual); Assert.False(actual.Success); }
public void SuccessShouldCreateResultWithCorrectValue() { // Arrange var expected = 123; // Act var actual = ValueCalculationResult.Success(expected); // Assert Assert.NotNull(actual); Assert.True(actual.Success); Assert.Equal(expected, actual.Value); }
private async Task <IValueCalculationResult <IEnumerable <TfsRepository> > > FetchRepositoriesAsync(CancellationToken token) { try { var repositories = await _repository.FetchAvailableRepositories(AsRawData()); return(ValueCalculationResult.Success(repositories)); } catch (Exception) { return(ValueCalculationResult.Fail <IEnumerable <TfsRepository> >()); } }
private async Task <IValueCalculationResult <IEnumerable <TfsProject> > > FetchProjectsAsync(CancellationToken token) { try { var projects = await _project.FetchAvailableProjects(AsRawData()); return(ValueCalculationResult.Success(projects)); } catch (Exception) { return(ValueCalculationResult.Fail <IEnumerable <TfsProject> >()); } }
public async Task UpdateShouldSetAndResetLoadingFlagOfAffectedOptions() { // Arrange var tcs = new TaskCompletionSource <int>(); var dispatcher = CreateDispatcher(); var updateFinishBlock = new ManualResetEventSlim(false); async Task <IValueCalculationResult <int> > CalculationTaskFactory(CancellationToken ct) { await Task.Delay(50, ct); return(ValueCalculationResult.Success(123)); } void HandleResultCallback(int arg) { tcs.SetResult(arg); } using var sut = new AsyncValueCalculator <int>(dispatcher, CalculationTaskFactory, HandleResultCallback); var option = Substitute.For <IValueOption>(); sut.Affect(option); option.When(o => o.IsLoading = false) .Do(x => updateFinishBlock.Set()); // Act sut.Update(); // Assert await tcs.Task; updateFinishBlock.Wait(TimeSpan.FromSeconds(1)); Assert.False(option.IsLoading); option.Received(1).IsLoading = true; option.Received(1).IsLoading = false; }
public async Task MultipleUpdateShouldTriggerCallbackOnlyOnce() { // As with all async code there is much magic happening here: // We want to start a second update while the first one is still running. // To do so we start the first update wait for a WaitHandle to be // signaled and then start the second update. // // When the update method is run, it will signal the wait handle // then wait some time to let the second update start // // The callback will set a TaskCompletionSource and this task is awaited // in the test. // // The asserts check that // - The update method was called twice // - The result callback was only called once // - The affected option is not loading anymore // - The loading flags was set and unset correctly // // Arrange var tcs = new TaskCompletionSource <int>(); var dispatcher = CreateDispatcher(); var callbackCount = 0; var calculationCount = 0; var updateStartBlock = new ManualResetEventSlim(false); var updateFinishBlock = new ManualResetEventSlim(false); async Task <IValueCalculationResult <int> > CalculationTaskFactory(CancellationToken ct) { Interlocked.Increment(ref calculationCount); updateStartBlock.Set(); await Task.Delay(25, ct); return(ValueCalculationResult.Success(123)); } void HandleResultCallback(int arg) { Interlocked.Increment(ref callbackCount); tcs.SetResult(arg); } using var sut = new AsyncValueCalculator <int>(dispatcher, CalculationTaskFactory, HandleResultCallback); var option = Substitute.For <IValueOption>(); sut.Affect(option); option.When(o => o.IsLoading = false) .Do(x => updateFinishBlock.Set()); // Act sut.Update(); updateStartBlock.Wait(); sut.Update(); // Assert await tcs.Task; updateFinishBlock.Wait(TimeSpan.FromSeconds(1)); Assert.Equal(1, callbackCount); Assert.Equal(2, calculationCount); Assert.False(option.IsLoading); option.Received(2).IsLoading = true; option.Received(1).IsLoading = false; }