Index: Riskeer/GrassCoverErosionInwards/src/Riskeer.GrassCoverErosionInwards.Forms/Views/GrassCoverErosionInwardsFailureMechanismResultView.cs =================================================================== diff -u -r26c5fd5650a79c33fd5969dc002225083d57e0f6 -r5ff5db30cf8971a12212d5b48062ab2541a356b8 --- Riskeer/GrassCoverErosionInwards/src/Riskeer.GrassCoverErosionInwards.Forms/Views/GrassCoverErosionInwardsFailureMechanismResultView.cs (.../GrassCoverErosionInwardsFailureMechanismResultView.cs) (revision 26c5fd5650a79c33fd5969dc002225083d57e0f6) +++ Riskeer/GrassCoverErosionInwards/src/Riskeer.GrassCoverErosionInwards.Forms/Views/GrassCoverErosionInwardsFailureMechanismResultView.cs (.../GrassCoverErosionInwardsFailureMechanismResultView.cs) (revision 5ff5db30cf8971a12212d5b48062ab2541a356b8) @@ -24,6 +24,7 @@ using System.Linq; using Core.Common.Base; using Riskeer.Common.Data.AssessmentSection; +using Riskeer.Common.Data.Calculation; using Riskeer.Common.Data.FailureMechanism; using Riskeer.Common.Forms; using Riskeer.Common.Forms.Builders; @@ -50,6 +51,9 @@ private const int sectionProbabilityIndex = 10; private const int sectionNIndex = 11; private const int assemblyGroupIndex = 12; + + private readonly RecursiveObserver calculationInputsObserver; + private readonly RecursiveObserver calculationGroupObserver; private readonly IAssessmentSection assessmentSection; /// @@ -71,6 +75,22 @@ } this.assessmentSection = assessmentSection; + + // The concat is needed to observe the input of calculations in child groups. + calculationInputsObserver = new RecursiveObserver( + UpdateInternalViewData, + cg => cg.Children.Concat(cg.Children + .OfType() + .Select(c => c.InputParameters))) + { + Observable = failureMechanism.CalculationsGroup + }; + calculationGroupObserver = new RecursiveObserver( + UpdateInternalViewData, + c => c.Children) + { + Observable = failureMechanism.CalculationsGroup + }; } protected override AdoptableWithProfileProbabilityFailureMechanismSectionResultRow CreateFailureMechanismSectionResultRow( @@ -102,6 +122,14 @@ }); } + protected override void Dispose(bool disposing) + { + calculationInputsObserver.Dispose(); + calculationGroupObserver.Dispose(); + + base.Dispose(disposing); + } + protected override double GetN() { return FailureMechanism.GeneralInput.N; Index: Riskeer/GrassCoverErosionInwards/test/Riskeer.GrassCoverErosionInwards.Forms.Test/Views/GrassCoverErosionInwardsFailureMechanismResultViewTest.cs =================================================================== diff -u -r26c5fd5650a79c33fd5969dc002225083d57e0f6 -r5ff5db30cf8971a12212d5b48062ab2541a356b8 --- Riskeer/GrassCoverErosionInwards/test/Riskeer.GrassCoverErosionInwards.Forms.Test/Views/GrassCoverErosionInwardsFailureMechanismResultViewTest.cs (.../GrassCoverErosionInwardsFailureMechanismResultViewTest.cs) (revision 26c5fd5650a79c33fd5969dc002225083d57e0f6) +++ Riskeer/GrassCoverErosionInwards/test/Riskeer.GrassCoverErosionInwards.Forms.Test/Views/GrassCoverErosionInwardsFailureMechanismResultViewTest.cs (.../GrassCoverErosionInwardsFailureMechanismResultViewTest.cs) (revision 5ff5db30cf8971a12212d5b48062ab2541a356b8) @@ -20,11 +20,13 @@ // All rights reserved. using System; +using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using NUnit.Extensions.Forms; using NUnit.Framework; using Rhino.Mocks; +using Riskeer.AssemblyTool.Data; using Riskeer.AssemblyTool.KernelWrapper.Calculators; using Riskeer.AssemblyTool.KernelWrapper.TestUtil.Calculators; using Riskeer.AssemblyTool.KernelWrapper.TestUtil.Calculators.Assembly; @@ -234,6 +236,92 @@ } } + [Test] + public void GivenGrassCoverErosionInwardsFailureMechanismResultView_WhenCalculationNotifiesObservers_ThenDataGridViewUpdatedAndAssemblyPerformed() + { + // Given + var failureMechanism = new GrassCoverErosionInwardsFailureMechanism(); + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection("Section 1"); + FailureMechanismTestHelper.SetSections(failureMechanism, new[] + { + section + }); + + GrassCoverErosionInwardsCalculationScenario calculationScenario = GrassCoverErosionInwardsCalculationScenarioTestFactory.CreateGrassCoverErosionInwardsCalculationScenario(section); + failureMechanism.CalculationsGroup.Children.Add(calculationScenario); + + using (new AssemblyToolCalculatorFactoryConfig()) + using (ShowFailureMechanismResultsView(failureMechanism)) + { + var testFactory = (TestAssemblyToolCalculatorFactory) AssemblyToolCalculatorFactory.Instance; + FailureMechanismSectionAssemblyCalculatorStub failureMechanismSectionAssemblyCalculator = testFactory.LastCreatedFailureMechanismSectionAssemblyCalculator; + failureMechanismSectionAssemblyCalculator.FailureMechanismSectionAssemblyResultOutput = new FailureMechanismSectionAssemblyResult(1, 1, 1, FailureMechanismSectionAssemblyGroup.III); + + FailurePathAssemblyCalculatorStub failurePathAssemblyCalculator = testFactory.LastCreatedFailurePathAssemblyCalculator; + IEnumerable initialCalculatorInput = failurePathAssemblyCalculator.SectionAssemblyResultsInput + .ToArray(); + + var rowsChanged = false; + DataGridView dataGridView = GetDataGridView(); + dataGridView.Rows.CollectionChanged += (sender, args) => rowsChanged = true; + + // Precondition + Assert.IsFalse(rowsChanged); + + // When + calculationScenario.NotifyObservers(); + + // Then + Assert.IsTrue(rowsChanged); + IEnumerable updatedCalculatorInput = failurePathAssemblyCalculator.SectionAssemblyResultsInput + .ToArray(); + CollectionAssert.AreNotEqual(initialCalculatorInput, updatedCalculatorInput); + } + } + + [Test] + public void GivenGrassCoverErosionInwardsFailureMechanismResultView_WhenCalculationInputNotifiesObservers_ThenDataGridViewUpdatedAndAssemblyPerformed() + { + // Given + var failureMechanism = new GrassCoverErosionInwardsFailureMechanism(); + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection("Section 1"); + FailureMechanismTestHelper.SetSections(failureMechanism, new[] + { + section + }); + + GrassCoverErosionInwardsCalculationScenario calculationScenario = GrassCoverErosionInwardsCalculationScenarioTestFactory.CreateGrassCoverErosionInwardsCalculationScenario(section); + failureMechanism.CalculationsGroup.Children.Add(calculationScenario); + + using (new AssemblyToolCalculatorFactoryConfig()) + using (ShowFailureMechanismResultsView(failureMechanism)) + { + var testFactory = (TestAssemblyToolCalculatorFactory) AssemblyToolCalculatorFactory.Instance; + FailureMechanismSectionAssemblyCalculatorStub failureMechanismSectionAssemblyCalculator = testFactory.LastCreatedFailureMechanismSectionAssemblyCalculator; + failureMechanismSectionAssemblyCalculator.FailureMechanismSectionAssemblyResultOutput = new FailureMechanismSectionAssemblyResult(1, 1, 1, FailureMechanismSectionAssemblyGroup.III); + + FailurePathAssemblyCalculatorStub failurePathAssemblyCalculator = testFactory.LastCreatedFailurePathAssemblyCalculator; + IEnumerable initialCalculatorInput = failurePathAssemblyCalculator.SectionAssemblyResultsInput + .ToArray(); + + var rowsChanged = false; + DataGridView dataGridView = GetDataGridView(); + dataGridView.Rows.CollectionChanged += (sender, args) => rowsChanged = true; + + // Precondition + Assert.IsFalse(rowsChanged); + + // When + calculationScenario.InputParameters.NotifyObservers(); + + // Then + Assert.IsTrue(rowsChanged); + IEnumerable updatedCalculatorInput = failurePathAssemblyCalculator.SectionAssemblyResultsInput + .ToArray(); + CollectionAssert.AreNotEqual(initialCalculatorInput, updatedCalculatorInput); + } + } + private static DataGridView GetDataGridView() { return (DataGridView) new ControlTester("dataGridView").TheObject;