public void RunAndVerifyExecutingStep(ConfigurableProgressEvents progressEvents, IProgressStep currentStep, int?currentVmIndex) { ProgressStepViewModel currentVM = currentVmIndex.HasValue ? this.visualizer.ViewModel.Steps[currentVmIndex.Value] : null; bool isFinalState = ProgressControllerHelper.IsFinalState(currentStep.ExecutionState) && this.IsLastStep(currentStep); // Trigger the event progressEvents.InvokeStepExecutionChanged(new StepExecutionChangedEventArgs(currentStep)); // Assert if (currentVmIndex.HasValue) { VerifyProgress(this.visualizer, this.ExpectedMainProgress, currentVM, this.ExpectedSubProgress); if (isFinalState) { this.testSubject.CurrentExecutingGroup.Should().BeNull("Not expecting any executing group"); } else { IProgressStep[] steps = this.GetAllStepsInGroup(currentStep); if (currentStep.ImpactsProgress) { steps.Should().NotBeNull("There should be at least one step in the group"); VerifyExecutionGroup(this.testSubject.CurrentExecutingGroup, steps); } else { steps.Should().BeNull("Not expecting any steps in group since not impacting, so there's no group for it"); } } } else { currentVM.Should().BeNull("Current VM should be null, since not impacts progress"); (this.testSubject.CurrentExecutingGroup == null || this.testSubject.CurrentExecutingGroup.ExecutingStep == null) .Should().BeTrue("Not expecting any changes for non impacting steps"); } }
/// <summary> /// Updates the <see cref="ProgressStepViewModel"/> with the current step changes. /// The <see cref="ProgressStepViewModel"/> represents a <see cref="ExecutionGroup"/> /// of one visible step and zero or more hidden steps. The progress in <see cref="ProgressStepViewModel"/> /// is used as the sub progress and it will be indeterminate if there's one indeterminate /// <see cref="IProgressStep"/> in <see cref="ExecutionGroup"/>, otherwise the sub progress /// will be relative to the number of steps in <see cref="ExecutionGroup"/>. /// </summary> /// <param name="e">Execution update</param> private void UpdateViewModelStep(StepExecutionChangedEventArgs e) { ThreadHelper.ThrowIfNotOnUIThread(); ProgressStepViewModel vm = this.progressStepToViewModelMapping[e.Step]; ExecutionGroup executionGroup = this.viewModelToExecutionGroupMapping[vm]; bool isLastStep = e.Step == executionGroup.Steps.Last(); double groupCompletionPercentange = GetCompletedStepCount(executionGroup.Steps) / (double)executionGroup.Steps.Count; this.CurrentExecutingGroup = executionGroup; executionGroup.ExecutingStep = e.Step; // Update the step VM // Progress update: Indeterminate step progress should remain as it was // and the determinate step progress should be updated switch (e.State) { case StepExecutionState.NotStarted: Debug.Fail("Unexpected transition to NotStarted"); if (!vm.Progress.IsIndeterminate) { vm.Progress.SetUpperBoundLimitedValue(0); } break; case StepExecutionState.Executing: if (!vm.Progress.IsIndeterminate) { Debug.Assert(!executionGroup.Steps.Any(s => s.Indeterminate), "Not expecting any Indeterminate steps"); vm.Progress.SetUpperBoundLimitedValue(groupCompletionPercentange + (e.Progress / (double)executionGroup.Steps.Count)); } vm.ExecutionState = e.State; vm.ProgressDetailText = e.ProgressDetailText; break; default: Debug.Assert(ProgressControllerHelper.IsFinalState(e.State), "Unexpected non-final state", "State: {0}", e.State); if (!vm.Progress.IsIndeterminate) { vm.Progress.SetUpperBoundLimitedValue(groupCompletionPercentange); } // Succeeded state which is not the last will indicate // that the group is still executing if (e.State == StepExecutionState.Succeeded && !isLastStep) { vm.ExecutionState = StepExecutionState.Executing; } else { vm.ExecutionState = e.State; } executionGroup.ExecutingStep = null; if (isLastStep) { vm.ProgressDetailText = null; this.CurrentExecutingGroup = null; } break; } vm.ProgressDetailText = e.ProgressDetailText; }
private static double GetCompletedStepCount(IEnumerable <IProgressStep> steps) { return((double)steps.Count(s => ProgressControllerHelper.IsFinalState(s.ExecutionState))); }