/// <summary> /// Verifies that the <see cref="ProgressControllerStep"/> was initialized correctly /// </summary> /// <param name="testSubject">The step to verify</param> /// <param name="attributes">Step attributes</param> /// <param name="displayText">Step display text</param> public static void VerifyInitialized(ProgressControllerStep testSubject, StepAttributes attributes, string displayText = null) { StepExecution expectedExecution = (attributes & StepAttributes.BackgroundThread) != 0 ? StepExecution.BackgroundThread : StepExecution.ForegroundThread; bool expectedHidden = (attributes & StepAttributes.Hidden) != 0 ? true : false; bool expectedCancellable = (attributes & StepAttributes.NonCancellable) != 0 ? false : true; bool expectedImpactingProgress = (attributes & StepAttributes.NoProgressImpact) != 0 ? false : true; bool expectedIndeterminate = (attributes & StepAttributes.Indeterminate) != 0 ? true : false; CheckState(testSubject, StepExecutionState.NotStarted); Assert.AreEqual(displayText, testSubject.DisplayText, "Unexpected display text"); Assert.AreEqual(expectedCancellable, testSubject.Cancellable, "Cancellable: Unexpected post initialization value"); Assert.AreEqual(expectedIndeterminate, testSubject.Indeterminate, "Indeterminate: Unexpected post initialization value"); Assert.AreEqual(expectedExecution, testSubject.Execution, "Execution: Unexpected post initialization value"); Assert.AreEqual(expectedHidden, testSubject.Hidden, "Hidden: Unexpected post initialization value"); Assert.AreEqual(expectedImpactingProgress, testSubject.ImpactsProgress, "ImpactingProgress: Unexpected post initialization value"); if (expectedIndeterminate) { Assert.IsTrue(ProgressControllerHelper.IsIndeterminate(testSubject.Progress), "Progess: Should be Indeterminate"); } else { Assert.AreEqual(0, testSubject.Progress, "Progress: Unexpected post initialization value"); } }
void IProgressErrorNotifier.Notify(Exception ex) { if (ex == null) { throw new ArgumentNullException(nameof(ex)); } VsShellUtilities.ShowMessageBox(this.serviceProvider, ProgressControllerHelper.FormatErrorMessage(ex, this.messageFormat, this.logWholeMessage), this.messageTitle, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); }
void IProgressErrorNotifier.Notify(Exception ex) { if (ex == null) { throw new ArgumentNullException(nameof(ex)); } VsThreadingHelper.RunInline(this.serviceProvider, VsTaskRunContext.UIThreadNormalPriority, () => { int hr = this.pane.OutputStringThreadSafe(ProgressControllerHelper.FormatErrorMessage(ex, this.messageFormat, this.logFullException) + Environment.NewLine); if (this.ensureOutputVisible && ErrorHandler.Succeeded(hr) && ErrorHandler.Succeeded(pane.Activate())) { ShowOutputWindowFrame(serviceProvider); } }); }
private static void VerifyProgressSequence(bool determinate, Tuple <string, double>[] expectedSequence, Tuple <string, double>[] actualSequence) { // There's an extra executing notification for the transition from NotStarted -> Executing actualSequence.Should().HaveCount(expectedSequence.Length + 1, "Unexpected sequence length"); actualSequence[0].Item1.Should().BeNull("The default transition should be with null display progress text"); if (determinate) { actualSequence[0].Item2.Should().Be(0.0, "For determinate steps the initial percentage is 0%"); } else { ProgressControllerHelper.IsIndeterminate(actualSequence[0].Item2).Should().BeTrue("Should be indeterminate"); } for (int i = 0; i < expectedSequence.Length; i++) { actualSequence[i + 1].Should().Be(expectedSequence[i], "Unexpected sequence item"); } }
private static void VerifyProgressSequence(bool determinate, Tuple <string, double>[] expectedSequence, Tuple <string, double>[] actualSequence) { // There's an extra executing notification for the transition from NotStarted -> Executing Assert.AreEqual(expectedSequence.Length + 1, actualSequence.Length, "Unexpected sequence length"); Assert.IsNull(actualSequence[0].Item1, "The default transition should be with null display progress text"); if (determinate) { Assert.AreEqual(0.0, actualSequence[0].Item2, "For determinate steps the initial percentage is 0%"); } else { Assert.IsTrue(ProgressControllerHelper.IsIndeterminate(actualSequence[0].Item2), "Should be indeterminate"); } for (int i = 0; i < expectedSequence.Length; i++) { Assert.AreEqual(expectedSequence[i], actualSequence[i + 1], "Unexpected sequence item"); } }
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"); } }
void IProgressErrorNotifier.Notify(Exception ex) { if (ex == null) { throw new ArgumentNullException(nameof(ex)); } VsThreadingHelper.RunInline(this.serviceProvider, VsTaskRunContext.UIThreadNormalPriority, () => { IVsActivityLog log = (IVsActivityLog)this.serviceProvider.GetService(typeof(SVsActivityLog)); if (log != null) { log.LogEntry((uint)__ACTIVITYLOG_ENTRYTYPE.ALE_ERROR, this.entrySource, ProgressControllerHelper.FormatErrorMessage(ex, messageFormat, logWholeMessage)); } else { Debug.Fail("Cannot find SVsActivityLog"); } }); }
/// <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))); }