public void ProgressObserver_ProgressUpdate_VisibleHiddenNotImpacting()
        {
            // Setup
            bool randomIndeterminate = Environment.TickCount % 2 == 0;
            ConfigurableProgressTestOperation noImpacting1 = CreateRandomStep(visible: true, indeterminate: randomIndeterminate, impacting: false);
            noImpacting1.ExecutionState = StepExecutionState.NotStarted;
            noImpacting1.Progress = 0;

            ConfigurableProgressTestOperation hidden1 = CreateRandomStep(visible: false, indeterminate: false, impacting: true);
            hidden1.ExecutionState = StepExecutionState.NotStarted;
            hidden1.Progress = 0;

            ConfigurableProgressTestOperation noImpacting2 = CreateRandomStep(visible: true, indeterminate: randomIndeterminate, impacting: false);
            noImpacting2.ExecutionState = StepExecutionState.NotStarted;
            noImpacting2.Progress = 0;

            ConfigurableProgressTestOperation visible1 = CreateRandomStep(visible: true, indeterminate: false, impacting: true);
            visible1.ExecutionState = StepExecutionState.NotStarted;
            visible1.Progress = 0;

            ConfigurableProgressTestOperation visible2 = CreateRandomStep(visible: true, indeterminate: false, impacting: true);
            visible2.ExecutionState = StepExecutionState.NotStarted;
            visible2.Progress = 0;

            ConfigurableProgressTestOperation hidden2 = CreateRandomStep(visible: false, indeterminate: false, impacting: true);
            hidden2.ExecutionState = StepExecutionState.NotStarted;
            hidden2.Progress = 0;

            ConfigurableProgressTestOperation[] steps = new[] { noImpacting1, hidden1, noImpacting2, visible1, visible2, hidden2 };
            this.progressEvents.Steps = steps;
            this.CreateTestSubject();
            double mainProgressSections = steps.Count(s => s.ImpactsProgress);

            // Verify initial state
            VerifyProgress(this.testVisualizer, 0, null, 0);

            ExecutionVerifier verifier = new ExecutionVerifier(this.testVisualizer, this.testSubject);
            verifier.AppendStepToGroup(0, hidden1);
            verifier.AppendStepToGroup(0, visible1);
            verifier.AppendStepToGroup(1, visible2);
            verifier.AppendStepToGroup(1, hidden2);

            // Non-impacting started to execute
            noImpacting1.Progress = 0;
            noImpacting1.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting1, null);

            // Non-impacting reports progress
            noImpacting1.Progress = 0.5;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting1, null);

            // Non-impacting completes
            noImpacting1.Progress = 1.0;
            noImpacting1.ExecutionState = StepExecutionState.Succeeded;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting1, null);

            // Hidden1 starts
            hidden1.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, hidden1, 0);

            // Hidden1 reports progress
            hidden1.Progress = 0.5;
            verifier.ExpectedSubProgress = hidden1.Progress / 2.0; // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = hidden1.Progress / mainProgressSections; // relative to the number of impacting steps
            verifier.RunAndVerifyExecutingStep(this.progressEvents, hidden1, 0);

            // Hidden1 completes
            hidden1.ExecutionState = StepExecutionState.Cancelled;
            verifier.ExpectedSubProgress = 1.0 / 2.0; // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = 1.0 / mainProgressSections; // relative to the number of impacting steps
            verifier.RunAndVerifyExecutingStep(this.progressEvents, hidden1, 0);

            // Non-impacting started to execute
            noImpacting2.Progress = 0;
            noImpacting2.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting2, 0);

            // Non-impacting reports progress
            noImpacting2.Progress = 0.5;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting2, 0);

            // Non-impacting completes
            noImpacting2.Progress = 1.0;
            noImpacting2.ExecutionState = StepExecutionState.Succeeded;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting2, 0);

            // Visible1 starts
            visible1.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, visible1, 0);

            // Visible1 reports progress
            visible1.Progress = 1.0;
            verifier.ExpectedSubProgress = 2.0 / 2.0; // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = 2.0 / mainProgressSections; // relative to the number of impacting steps
            verifier.RunAndVerifyExecutingStep(this.progressEvents, visible1, 0);

            // Visible1 completes
            visible1.ExecutionState = StepExecutionState.Failed;
            verifier.ExpectedSubProgress = 1.0;
            verifier.ExpectedMainProgress = 2.0 / mainProgressSections; // relative to the number of impacting steps
            verifier.RunAndVerifyExecutingStep(this.progressEvents, visible1, 0);

            // Visible2 completes
            visible2.ExecutionState = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress = 1.0 / 2.0;  // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = 3.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, visible2, 1);

            // Hidden2 completes
            hidden2.ExecutionState = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress = 2.0 / 2.0; // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = 4.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, hidden2, 1);
        }
        public void ProgressObserver_ProgressUpdate_VisibleHiddenNotImpacting()
        {
            // Setup
            bool randomIndeterminate = Environment.TickCount % 2 == 0;
            ConfigurableProgressTestOperation noImpacting1 = CreateRandomStep(visible: true, indeterminate: randomIndeterminate, impacting: false);

            noImpacting1.ExecutionState = StepExecutionState.NotStarted;
            noImpacting1.Progress       = 0;

            ConfigurableProgressTestOperation hidden1 = CreateRandomStep(visible: false, indeterminate: false, impacting: true);

            hidden1.ExecutionState = StepExecutionState.NotStarted;
            hidden1.Progress       = 0;

            ConfigurableProgressTestOperation noImpacting2 = CreateRandomStep(visible: true, indeterminate: randomIndeterminate, impacting: false);

            noImpacting2.ExecutionState = StepExecutionState.NotStarted;
            noImpacting2.Progress       = 0;

            ConfigurableProgressTestOperation visible1 = CreateRandomStep(visible: true, indeterminate: false, impacting: true);

            visible1.ExecutionState = StepExecutionState.NotStarted;
            visible1.Progress       = 0;

            ConfigurableProgressTestOperation visible2 = CreateRandomStep(visible: true, indeterminate: false, impacting: true);

            visible2.ExecutionState = StepExecutionState.NotStarted;
            visible2.Progress       = 0;

            ConfigurableProgressTestOperation hidden2 = CreateRandomStep(visible: false, indeterminate: false, impacting: true);

            hidden2.ExecutionState = StepExecutionState.NotStarted;
            hidden2.Progress       = 0;

            ConfigurableProgressTestOperation[] steps = new[] { noImpacting1, hidden1, noImpacting2, visible1, visible2, hidden2 };
            this.progressEvents.Steps = steps;
            this.CreateTestSubject();
            double mainProgressSections = steps.Count(s => s.ImpactsProgress);

            // Verify initial state
            VerifyProgress(this.testVisualizer, 0, null, 0);

            ExecutionVerifier verifier = new ExecutionVerifier(this.testVisualizer, this.testSubject);

            verifier.AppendStepToGroup(0, hidden1);
            verifier.AppendStepToGroup(0, visible1);
            verifier.AppendStepToGroup(1, visible2);
            verifier.AppendStepToGroup(1, hidden2);

            // Non-impacting started to execute
            noImpacting1.Progress       = 0;
            noImpacting1.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting1, null);

            // Non-impacting reports progress
            noImpacting1.Progress = 0.5;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting1, null);

            // Non-impacting completes
            noImpacting1.Progress       = 1.0;
            noImpacting1.ExecutionState = StepExecutionState.Succeeded;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting1, null);

            // Hidden1 starts
            hidden1.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, hidden1, 0);

            // Hidden1 reports progress
            hidden1.Progress              = 0.5;
            verifier.ExpectedSubProgress  = hidden1.Progress / 2.0;                  // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = hidden1.Progress / mainProgressSections; // relative to the number of impacting steps
            verifier.RunAndVerifyExecutingStep(this.progressEvents, hidden1, 0);

            // Hidden1 completes
            hidden1.ExecutionState        = StepExecutionState.Cancelled;
            verifier.ExpectedSubProgress  = 1.0 / 2.0;                  // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = 1.0 / mainProgressSections; // relative to the number of impacting steps
            verifier.RunAndVerifyExecutingStep(this.progressEvents, hidden1, 0);

            // Non-impacting started to execute
            noImpacting2.Progress       = 0;
            noImpacting2.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting2, 0);

            // Non-impacting reports progress
            noImpacting2.Progress = 0.5;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting2, 0);

            // Non-impacting completes
            noImpacting2.Progress       = 1.0;
            noImpacting2.ExecutionState = StepExecutionState.Succeeded;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, noImpacting2, 0);

            // Visible1 starts
            visible1.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, visible1, 0);

            // Visible1 reports progress
            visible1.Progress             = 1.0;
            verifier.ExpectedSubProgress  = 2.0 / 2.0;                  // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = 2.0 / mainProgressSections; // relative to the number of impacting steps
            verifier.RunAndVerifyExecutingStep(this.progressEvents, visible1, 0);

            // Visible1 completes
            visible1.ExecutionState       = StepExecutionState.Failed;
            verifier.ExpectedSubProgress  = 1.0;
            verifier.ExpectedMainProgress = 2.0 / mainProgressSections; // relative to the number of impacting steps
            verifier.RunAndVerifyExecutingStep(this.progressEvents, visible1, 0);

            // Visible2 completes
            visible2.ExecutionState       = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress  = 1.0 / 2.0; // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = 3.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, visible2, 1);

            // Hidden2 completes
            hidden2.ExecutionState        = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress  = 2.0 / 2.0; // relative to the number of sub steps in group
            verifier.ExpectedMainProgress = 4.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, hidden2, 1);
        }
        public void ProgressObserver_ProgressUpdate_DeterminateIndeterminate()
        {
            // Setup
            ConfigurableProgressTestOperation determinate1 = CreateRandomStep(visible: true, indeterminate: false, impacting: true);
            determinate1.Progress = 0;
            determinate1.ExecutionState = StepExecutionState.NotStarted;

            ConfigurableProgressTestOperation indeterminate1 = CreateRandomStep(visible: true, indeterminate: true, impacting: true);
            indeterminate1.Progress = ProgressControllerHelper.Indeterminate;
            indeterminate1.ExecutionState = StepExecutionState.NotStarted;

            ConfigurableProgressTestOperation determinate2 = CreateRandomStep(visible: true, indeterminate: false, impacting: true);
            determinate2.Progress = 0;
            determinate2.ExecutionState = StepExecutionState.NotStarted;

            ConfigurableProgressTestOperation indeterminate2 = CreateRandomStep(visible: true, indeterminate: true, impacting: true);
            indeterminate2.Progress = ProgressControllerHelper.Indeterminate;
            indeterminate2.ExecutionState = StepExecutionState.NotStarted;

            this.progressEvents.Steps = new[] { determinate1, indeterminate1, determinate2, indeterminate2 };
            this.CreateTestSubject();
            double mainProgressSections = this.progressEvents.Steps.Count(s => s.ImpactsProgress);

            // Verify initial state
            VerifyProgress(this.testVisualizer, 0, null, 0);

            ExecutionVerifier verifier = new ExecutionVerifier(this.testVisualizer, this.testSubject);
            verifier.AppendStepToGroup(0, determinate1);
            verifier.AppendStepToGroup(1, indeterminate1);
            verifier.AppendStepToGroup(2, determinate2);
            verifier.AppendStepToGroup(3, indeterminate2);

            // First started to execute
            determinate1.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate1, 0);

            // First reports progress
            determinate1.Progress = 0.5;
            verifier.ExpectedSubProgress = 0.5;
            verifier.ExpectedMainProgress = 0.5 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate1, 0);

            // First completes
            determinate1.ExecutionState = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress = 1.0;
            verifier.ExpectedMainProgress = 1.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate1, 0);

            // Second starts
            indeterminate1.ExecutionState = StepExecutionState.Executing;
            verifier.ExpectedSubProgress = ProgressControllerHelper.Indeterminate;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, indeterminate1, 1);

            // Second completes
            indeterminate1.ExecutionState = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress = ProgressControllerHelper.Indeterminate;
            verifier.ExpectedMainProgress = 2.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, indeterminate1, 1);

            // Third starts
            determinate2.ExecutionState = StepExecutionState.Executing;
            verifier.ExpectedSubProgress = 0.0;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate2, 2);

            // Third reports progress
            determinate2.Progress = 0.5;
            verifier.ExpectedSubProgress = 0.5;
            verifier.ExpectedMainProgress = 2.5 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate2, 2);

            // Third reports progress
            determinate2.Progress = 1.0;
            verifier.ExpectedSubProgress = 1.0;
            verifier.ExpectedMainProgress = 3.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate2, 2);

            // Third completes
            determinate2.ExecutionState = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress = 1.0;
            verifier.ExpectedMainProgress = 3.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate2, 2);

            // Fourth completes
            indeterminate2.ExecutionState = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress = ProgressControllerHelper.Indeterminate;
            verifier.ExpectedMainProgress = 4.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, indeterminate2, 3);
        }
        public void ProgressObserver_ProgressUpdate_DeterminateIndeterminate()
        {
            // Setup
            ConfigurableProgressTestOperation determinate1 = CreateRandomStep(visible: true, indeterminate: false, impacting: true);

            determinate1.Progress       = 0;
            determinate1.ExecutionState = StepExecutionState.NotStarted;

            ConfigurableProgressTestOperation indeterminate1 = CreateRandomStep(visible: true, indeterminate: true, impacting: true);

            indeterminate1.Progress       = ProgressControllerHelper.Indeterminate;
            indeterminate1.ExecutionState = StepExecutionState.NotStarted;

            ConfigurableProgressTestOperation determinate2 = CreateRandomStep(visible: true, indeterminate: false, impacting: true);

            determinate2.Progress       = 0;
            determinate2.ExecutionState = StepExecutionState.NotStarted;

            ConfigurableProgressTestOperation indeterminate2 = CreateRandomStep(visible: true, indeterminate: true, impacting: true);

            indeterminate2.Progress       = ProgressControllerHelper.Indeterminate;
            indeterminate2.ExecutionState = StepExecutionState.NotStarted;

            this.progressEvents.Steps = new[] { determinate1, indeterminate1, determinate2, indeterminate2 };
            this.CreateTestSubject();
            double mainProgressSections = this.progressEvents.Steps.Count(s => s.ImpactsProgress);

            // Verify initial state
            VerifyProgress(this.testVisualizer, 0, null, 0);

            ExecutionVerifier verifier = new ExecutionVerifier(this.testVisualizer, this.testSubject);

            verifier.AppendStepToGroup(0, determinate1);
            verifier.AppendStepToGroup(1, indeterminate1);
            verifier.AppendStepToGroup(2, determinate2);
            verifier.AppendStepToGroup(3, indeterminate2);

            // First started to execute
            determinate1.ExecutionState = StepExecutionState.Executing;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate1, 0);

            // First reports progress
            determinate1.Progress         = 0.5;
            verifier.ExpectedSubProgress  = 0.5;
            verifier.ExpectedMainProgress = 0.5 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate1, 0);

            // First completes
            determinate1.ExecutionState   = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress  = 1.0;
            verifier.ExpectedMainProgress = 1.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate1, 0);

            // Second starts
            indeterminate1.ExecutionState = StepExecutionState.Executing;
            verifier.ExpectedSubProgress  = ProgressControllerHelper.Indeterminate;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, indeterminate1, 1);

            // Second completes
            indeterminate1.ExecutionState = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress  = ProgressControllerHelper.Indeterminate;
            verifier.ExpectedMainProgress = 2.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, indeterminate1, 1);

            // Third starts
            determinate2.ExecutionState  = StepExecutionState.Executing;
            verifier.ExpectedSubProgress = 0.0;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate2, 2);

            // Third reports progress
            determinate2.Progress         = 0.5;
            verifier.ExpectedSubProgress  = 0.5;
            verifier.ExpectedMainProgress = 2.5 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate2, 2);

            // Third reports progress
            determinate2.Progress         = 1.0;
            verifier.ExpectedSubProgress  = 1.0;
            verifier.ExpectedMainProgress = 3.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate2, 2);

            // Third completes
            determinate2.ExecutionState   = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress  = 1.0;
            verifier.ExpectedMainProgress = 3.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, determinate2, 2);

            // Fourth completes
            indeterminate2.ExecutionState = StepExecutionState.Succeeded;
            verifier.ExpectedSubProgress  = ProgressControllerHelper.Indeterminate;
            verifier.ExpectedMainProgress = 4.0 / mainProgressSections;
            verifier.RunAndVerifyExecutingStep(this.progressEvents, indeterminate2, 3);
        }