Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs =================================================================== diff -u -r69eb8c7057601ce45297368b9281ea1e60980f28 -r60d95df18eb252bf99dff07a76d9660f331c92c2 --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs (.../PipingInputContextProperties.cs) (revision 69eb8c7057601ce45297368b9281ea1e60980f28) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs (.../PipingInputContextProperties.cs) (revision 60d95df18eb252bf99dff07a76d9660f331c92c2) @@ -19,6 +19,7 @@ // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. +using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; @@ -32,8 +33,8 @@ using Ringtoets.Common.Data.Probabilistics; using Ringtoets.Common.Forms.Helpers; using Ringtoets.Common.Forms.PresentationObjects; +using Ringtoets.Common.Forms.PropertyClasses; using Ringtoets.Common.Forms.UITypeEditors; -using Ringtoets.Common.Service; using Ringtoets.Piping.Data; using Ringtoets.Piping.Forms.PresentationObjects; using Ringtoets.Piping.Forms.Properties; @@ -70,7 +71,31 @@ private const int diameter70PropertyIndex = 17; private const int saturatedVolumicWeightOfCoverageLayerPropertyIndex = 18; + private readonly ICalculationInputPropertyChangeHandler propertyChangeHandler; + /// + /// Creates a new instance of . + /// + /// The instance to show the properties for. + /// The handler responsible for handling effects of a property change. + /// Thrown when any parameter is null. + public PipingInputContextProperties(PipingInputContext data, + ICalculationInputPropertyChangeHandler handler) + { + if (data == null) + { + throw new ArgumentNullException(nameof(data)); + } + if (handler == null) + { + throw new ArgumentNullException(nameof(handler)); + } + + Data = data; + propertyChangeHandler = handler; + } + + /// /// Gets the available surface lines on . /// public IEnumerable GetAvailableSurfaceLines() @@ -125,9 +150,7 @@ /// public IEnumerable GetSelectableHydraulicBoundaryLocations() { - Point2D referencePoint = SurfaceLine == null || SurfaceLine.ReferenceLineIntersectionWorldPoint == null - ? null - : SurfaceLine.ReferenceLineIntersectionWorldPoint; + Point2D referencePoint = SurfaceLine?.ReferenceLineIntersectionWorldPoint; return SelectableHydraulicBoundaryLocationHelper.GetSortedSelectableHydraulicBoundaryLocations( data.AvailableHydraulicBoundaryLocations, referencePoint); } @@ -144,7 +167,7 @@ { get { - Point2D referencePoint = SurfaceLine != null ? SurfaceLine.ReferenceLineIntersectionWorldPoint : null; + Point2D referencePoint = SurfaceLine?.ReferenceLineIntersectionWorldPoint; return data.WrappedData.HydraulicBoundaryLocation != null ? new SelectableHydraulicBoundaryLocation(data.WrappedData.HydraulicBoundaryLocation, @@ -153,8 +176,7 @@ } set { - data.WrappedData.HydraulicBoundaryLocation = value.HydraulicBoundaryLocation; - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => input.HydraulicBoundaryLocation = v, value.HydraulicBoundaryLocation); } } @@ -171,8 +193,7 @@ } set { - data.WrappedData.AssessmentLevel = value; - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => input.AssessmentLevel = v, value); } } @@ -188,8 +209,7 @@ } set { - data.WrappedData.UseAssessmentLevelManualInput = value; - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => input.UseAssessmentLevelManualInput = v, value); } } @@ -206,8 +226,7 @@ } set { - data.WrappedData.DampingFactorExit = value.Distribution; - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => input.DampingFactorExit = v, value.Distribution); } } @@ -224,8 +243,7 @@ } set { - data.WrappedData.PhreaticLevelExit = value.Distribution; - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => input.PhreaticLevelExit = v, value.Distribution); } } @@ -260,9 +278,11 @@ { if (!ReferenceEquals(value, data.WrappedData.SurfaceLine)) { - data.WrappedData.SurfaceLine = value; - PipingInputService.SetMatchingStochasticSoilModel(data.WrappedData, GetAvailableStochasticSoilModels()); - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => + { + input.SurfaceLine = v; + PipingInputService.SetMatchingStochasticSoilModel(input, GetAvailableStochasticSoilModels()); + }, value); } } } @@ -282,9 +302,11 @@ { if (!ReferenceEquals(value, data.WrappedData.StochasticSoilModel)) { - data.WrappedData.StochasticSoilModel = value; - PipingInputService.SyncStochasticSoilProfileWithStochasticSoilModel(data.WrappedData); - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => + { + input.StochasticSoilModel = v; + PipingInputService.SyncStochasticSoilProfileWithStochasticSoilModel(input); + }, value); } } } @@ -304,8 +326,7 @@ { if (!ReferenceEquals(value, data.WrappedData.StochasticSoilProfile)) { - data.WrappedData.StochasticSoilProfile = value; - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => input.StochasticSoilProfile = v, value); } } } @@ -322,8 +343,7 @@ } set { - data.WrappedData.EntryPointL = value; - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => input.EntryPointL = v, value); } } @@ -339,8 +359,7 @@ } set { - data.WrappedData.ExitPointL = value; - ClearOutputAndNotifyPropertyChanged(); + ChangePropertyValueAndNotifyAffectedObjects((input, v) => input.ExitPointL = v, value); } } @@ -437,14 +456,26 @@ #endregion - private void ClearOutputAndNotifyPropertyChanged() + + private void ChangePropertyValueAndNotifyAffectedObjects( + SetCalculationInputPropertyValueDelegate setPropertyValue, + TValue value) { - IEnumerable affectedCalculation = RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(data.PipingCalculation); - foreach (var calculation in affectedCalculation) + IEnumerable affectedObjects = propertyChangeHandler.SetPropertyValueAfterConfirmation( + data.WrappedData, + data.PipingCalculation, + value, + setPropertyValue); + + NotifyAffectedObjects(affectedObjects); + } + + private static void NotifyAffectedObjects(IEnumerable affectedObjects) + { + foreach (var affectedObject in affectedObjects) { - calculation.NotifyObservers(); + affectedObject.NotifyObservers(); } - data.WrappedData.NotifyObservers(); } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingPlugin.cs =================================================================== diff -u -r89d34600d1408c8b1f4240020e841ba64cc26622 -r60d95df18eb252bf99dff07a76d9660f331c92c2 --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingPlugin.cs (.../PipingPlugin.cs) (revision 89d34600d1408c8b1f4240020e841ba64cc26622) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingPlugin.cs (.../PipingPlugin.cs) (revision 60d95df18eb252bf99dff07a76d9660f331c92c2) @@ -75,7 +75,10 @@ { CreateInstance = context => new PipingFailureMechanismContextProperties(context, new FailureMechanismPropertyChangeHandler()) }; - yield return new PropertyInfo(); + yield return new PropertyInfo + { + CreateInstance = context => new PipingInputContextProperties(context, new CalculationInputPropertyChangeHandler()) + }; yield return new PropertyInfo(); yield return new PropertyInfo(); yield return new PropertyInfo Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs =================================================================== diff -u -r6aaa17dbb25d6299115d68b221312aa1482d97a9 -r60d95df18eb252bf99dff07a76d9660f331c92c2 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs (.../PipingInputContextPropertiesTest.cs) (revision 6aaa17dbb25d6299115d68b221312aa1482d97a9) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs (.../PipingInputContextPropertiesTest.cs) (revision 60d95df18eb252bf99dff07a76d9660f331c92c2) @@ -34,7 +34,10 @@ using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.Data.Probabilistics; using Ringtoets.Common.Data.TestUtil; +using Ringtoets.Common.Forms.ChangeHandlers; using Ringtoets.Common.Forms.PresentationObjects; +using Ringtoets.Common.Forms.PropertyClasses; +using Ringtoets.Common.Forms.TestUtil; using Ringtoets.Common.Forms.UITypeEditors; using Ringtoets.Piping.Data; using Ringtoets.Piping.Forms.PresentationObjects; @@ -68,38 +71,106 @@ private const int expectedSaturatedVolumicWeightOfCoverageLayerPropertyIndex = 17; [Test] + public void Constructor_ContextNull_ThrowArgumentNullException() + { + // Setup + var mocks = new MockRepository(); + var handler = mocks.Stub>(); + mocks.ReplayAll(); + + // Call + TestDelegate test = () => new PipingInputContextProperties(null, handler); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("data", exception.ParamName); + mocks.VerifyAll(); + } + + [Test] + public void Constructor_HandlerNull_ThrowArgumentNullException() + { + // Setup + var mocks = new MockRepository(); + var assessmentSection = mocks.Stub(); + mocks.ReplayAll(); + + PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); + PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); + + PipingInput inputParameters = new PipingInput(new GeneralPipingInput()); + + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + // Call + TestDelegate test = () => new PipingInputContextProperties(context, null); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("handler", exception.ParamName); + mocks.VerifyAll(); + } + + [Test] public void DefaultConstructor_ExpectedValues() { + var mocks = new MockRepository(); + var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); + mocks.ReplayAll(); + + PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); + PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); + + PipingInput inputParameters = new PipingInput(new GeneralPipingInput()); + + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + // Call - PipingInputContextProperties properties = new PipingInputContextProperties(); + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); // Assert Assert.IsInstanceOf>(properties); Assert.IsInstanceOf(properties); - Assert.IsNull(properties.Data); + Assert.AreSame(context, properties.Data); + mocks.VerifyAll(); } [Test] - public void Constructor_Always_PropertiesHaveExpectedAttributesValues() + public void Constructor_ValidData_PropertiesHaveExpectedAttributesValues() { // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); mocks.ReplayAll(); + PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); PipingInput inputParameters = new PipingInput(new GeneralPipingInput()); // Call - PipingInputContextProperties properties = new PipingInputContextProperties + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + var handler = new CalculationInputPropertyChangeHandler(); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler) { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), UseAssessmentLevelManualInput = false }; @@ -257,20 +328,24 @@ var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); mocks.ReplayAll(); + PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); PipingInput inputParameters = new PipingInput(new GeneralPipingInput()); + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + var handler = new CalculationInputPropertyChangeHandler(); + // Call - PipingInputContextProperties properties = new PipingInputContextProperties + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler) { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), UseAssessmentLevelManualInput = useManualAssessmentLevelInput }; @@ -315,6 +390,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var random = new Random(22); @@ -347,16 +423,15 @@ PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection) - }; + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call & Assert Assert.AreSame(inputParameters.PhreaticLevelExit, properties.PhreaticLevelExit.Distribution); Assert.AreSame(inputParameters.DampingFactorExit, properties.DampingFactorExit.Distribution); @@ -411,16 +486,16 @@ PipingInput inputParameters = new PipingInput(new GeneralPipingInput()); - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection) - }; + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + var handler = new CalculationInputPropertyChangeHandler(); + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + const double assessmentLevel = 0.36; const double entryPointL = 0.12; const double exitPointL = 0.44; @@ -464,88 +539,111 @@ } [Test] - [TestCase(true)] - [TestCase(false)] - public void SurfaceLine_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void SurfaceLine_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.SurfaceLine = ValidSurfaceLine(0.0, 4.0)); + // Setup + RingtoetsPipingSurfaceLine newSurfaceLine = ValidSurfaceLine(0.0, 4.0); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(p => p.SurfaceLine = newSurfaceLine, newSurfaceLine, calculation); } [Test] - [TestCase(true)] - [TestCase(false)] - public void StochasticSoilModel_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void StochasticSoilModel_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.StochasticSoilModel = ValidStochasticSoilModel(0.0, 4.0)); + // Setup + StochasticSoilModel newSoilModel = ValidStochasticSoilModel(0.0, 4.0); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(properties => properties.StochasticSoilModel = newSoilModel, newSoilModel, calculation); } [Test] - [TestCase(true)] - [TestCase(false)] - public void StochasticSoilProfile_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void StochasticSoilProfile_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.StochasticSoilProfile = ValidStochasticSoilModel(0.0, 4.0).StochasticSoilProfiles.First()); + // Setup + StochasticSoilProfile newSoilProfile = ValidStochasticSoilModel(0.0, 4.0).StochasticSoilProfiles.First(); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(properties => properties.StochasticSoilProfile = newSoilProfile, newSoilProfile, calculation); } [Test] - [TestCase(true)] - [TestCase(false)] - public void AssessmentLevel_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void AssessmentLevel_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutputForCalculation( - hasOutput, - properties => properties.AssessmentLevel = new Random(21).NextRoundedDouble(), - new PipingCalculationScenario(new GeneralPipingInput()) + // Setup + var newAssessmentLevel = new Random(21).NextRoundedDouble(); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()) + { + InputParameters = { - InputParameters = - { - UseAssessmentLevelManualInput = true - } - }); + UseAssessmentLevelManualInput = true + } + }; + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(properties => properties.AssessmentLevel = newAssessmentLevel, newAssessmentLevel, calculation); } [Test] - [TestCase(true)] - [TestCase(false)] - public void DampingFactorExit_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void DampingFactorExit_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutput( - hasOutput, - properties => properties.DampingFactorExit = new LogNormalDistributionDesignVariable(new LogNormalDistribution(3))); + // Setup + var distribution = new LogNormalDistribution(3); + var newDampingFactorExit = new LogNormalDistributionDesignVariable(distribution); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(properties => properties.DampingFactorExit = newDampingFactorExit, distribution, calculation); } [Test] - [TestCase(true)] - [TestCase(false)] - public void PhreaticLevelExit_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void PhreaticLevelExit_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutput( - hasOutput, - properties => properties.PhreaticLevelExit = new NormalDistributionDesignVariable(new NormalDistribution(3))); + // Setup + var distribution = new NormalDistribution(3); + var newPhreaticLevelExit = new NormalDistributionDesignVariable(distribution); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(properties => properties.PhreaticLevelExit = newPhreaticLevelExit, distribution, calculation); } [Test] - [TestCase(true)] - [TestCase(false)] - public void EntryPoinL_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void EntryPoinL_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.EntryPointL = new Random(21).NextRoundedDouble()); + // Setup + var newEntryPointL = new Random(21).NextRoundedDouble(); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(properties => properties.EntryPointL = newEntryPointL, newEntryPointL, calculation); } [Test] - [TestCase(true)] - [TestCase(false)] - public void ExitPointL_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void ExitPointL_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.ExitPointL = new Random(21).NextRoundedDouble()); + // Setup + var newExitPointL = new Random(21).NextRoundedDouble(); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(properties => properties.ExitPointL = newExitPointL, newExitPointL, calculation); } [Test] - [TestCase(true)] - [TestCase(false)] - public void UseCustomAssessmentLevel_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + public void UseCustomAssessmentLevel_SetValidValue_SetsValueAndUpdatesObservers() { - SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.UseAssessmentLevelManualInput = true); + // Setup + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + + // Call & Assert + SetPropertyAndVerifyNotifcationsAndOutputForCalculation(properties => properties.UseAssessmentLevelManualInput = true, + true, + calculation); } [Test] @@ -559,7 +657,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var inputObserver = mocks.StrictMock(); + var inputObserver = mocks.StrictMock(); int numberOfChangedProperties = 2; inputObserver.Expect(o => o.UpdateObserver()).Repeat.Times(numberOfChangedProperties); mocks.ReplayAll(); @@ -574,19 +672,23 @@ }; inputParameters.Attach(inputObserver); - PipingInputContextProperties properties = new PipingInputContextProperties + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + var handler = new CalculationInputPropertyChangeHandler(); + + // Call + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler) { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), ExitPointL = (RoundedDouble) exitPoint, EntryPointL = (RoundedDouble) entryPoint }; - // Call & Assert + // Assert Assert.AreEqual(seepageLength, properties.SeepageLength.Distribution.Mean, 1e-6); Assert.AreEqual(properties.ExitPointL, inputParameters.ExitPointL); Assert.AreEqual(properties.SeepageLength.Distribution.Mean, inputParameters.SeepageLength.Mean); @@ -600,7 +702,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var inputObserver = mocks.StrictMock(); + var inputObserver = mocks.StrictMock(); int numberOfChangedProperties = 2; inputObserver.Expect(o => o.UpdateObserver()).Repeat.Times(numberOfChangedProperties); mocks.ReplayAll(); @@ -615,19 +717,23 @@ }; inputParameters.Attach(inputObserver); - PipingInputContextProperties properties = new PipingInputContextProperties + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + var handler = new CalculationInputPropertyChangeHandler(); + + // Call + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler) { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), EntryPointL = (RoundedDouble) 0.5, ExitPointL = (RoundedDouble) 2 }; - // Call & Assert + // Assert Assert.AreEqual(1.5, properties.SeepageLength.Distribution.Mean.Value); Assert.AreEqual(properties.ExitPointL, inputParameters.ExitPointL); Assert.AreEqual(properties.SeepageLength.Distribution.Mean, inputParameters.SeepageLength.Mean); @@ -643,7 +749,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var inputObserver = mocks.StrictMock(); + var observable = mocks.StrictMock(); mocks.ReplayAll(); RingtoetsPipingSurfaceLine surfaceLine = ValidSurfaceLine(0.0, 4.0); @@ -652,24 +758,31 @@ PipingInput inputParameters = new PipingInput(new GeneralPipingInput()) { - SurfaceLine = surfaceLine - }; - - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), + SurfaceLine = surfaceLine, EntryPointL = (RoundedDouble) 2.0 }; - inputParameters.Attach(inputObserver); + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + RoundedDouble newExitPointL = (RoundedDouble) newExitPoint; + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculationItem, + newExitPointL, + new[] + { + observable + }); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call - TestDelegate call = () => properties.ExitPointL = (RoundedDouble) newExitPoint; + TestDelegate call = () => properties.ExitPointL = newExitPointL; // Assert var expectedMessage = "Het uittredepunt moet landwaarts van het intredepunt liggen."; @@ -685,37 +798,46 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var inputObserver = mocks.StrictMock(); + var observable = mocks.StrictMock(); mocks.ReplayAll(); + RoundedDouble entryPoint = (RoundedDouble) newEntryPoint; + RingtoetsPipingSurfaceLine surfaceLine = ValidSurfaceLine(0.0, 4.0); PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); PipingInput inputParameters = new PipingInput(new GeneralPipingInput()) { - SurfaceLine = surfaceLine - }; - - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), + SurfaceLine = surfaceLine, ExitPointL = (RoundedDouble) 2.0 }; - inputParameters.Attach(inputObserver); + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculationItem, + entryPoint, + new[] + { + observable + }); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call - TestDelegate call = () => properties.EntryPointL = (RoundedDouble) newEntryPoint; + TestDelegate call = () => properties.EntryPointL = entryPoint; // Assert var expectedMessage = "Het uittredepunt moet landwaarts van het intredepunt liggen."; TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage); + Assert.IsTrue(handler.Called); mocks.VerifyAll(); // No observer notified } @@ -725,7 +847,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var inputObserver = mocks.StrictMock(); + var observable = mocks.StrictMock(); mocks.ReplayAll(); RingtoetsPipingSurfaceLine surfaceLine = ValidSurfaceLine(0.0, 4.0); @@ -734,24 +856,32 @@ PipingInput inputParameters = new PipingInput(new GeneralPipingInput()) { - SurfaceLine = surfaceLine - }; - - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), + SurfaceLine = surfaceLine, ExitPointL = (RoundedDouble) 2.0 }; - inputParameters.Attach(inputObserver); + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + RoundedDouble entryPointL = (RoundedDouble)(-15.0); + + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculationItem, + entryPointL, + new[] + { + observable + }); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call - TestDelegate call = () => properties.EntryPointL = (RoundedDouble) (-15.0); + TestDelegate call = () => properties.EntryPointL = entryPointL; // Assert const string expectedMessage = "Het gespecificeerde punt moet op het profiel liggen (bereik [0, 4])."; @@ -765,7 +895,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var inputObserver = mocks.StrictMock(); + var observable = mocks.StrictMock(); mocks.ReplayAll(); RingtoetsPipingSurfaceLine surfaceLine = ValidSurfaceLine(0.0, 4.0); @@ -774,24 +904,32 @@ PipingInput inputParameters = new PipingInput(new GeneralPipingInput()) { - SurfaceLine = surfaceLine - }; - - var properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), + SurfaceLine = surfaceLine, EntryPointL = (RoundedDouble) 2.0 }; - inputParameters.Attach(inputObserver); + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + RoundedDouble exitPointL = (RoundedDouble)10.0; + + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculationItem, + exitPointL, + new[] + { + observable + }); + + var properties = new PipingInputContextProperties(context, handler); + // Call - TestDelegate call = () => properties.ExitPointL = (RoundedDouble) 10.0; + TestDelegate call = () => properties.ExitPointL = exitPointL; // Assert const string expectedMessage = "Het gespecificeerde punt moet op het profiel liggen (bereik [0, 4])."; @@ -805,74 +943,79 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var projectObserver = mocks.StrictMock(); - projectObserver.Expect(o => o.UpdateObserver()); + var observable = mocks.StrictMock(); + observable.Expect(o => o.NotifyObservers()); mocks.ReplayAll(); - RoundedDouble assessmentLevel = (RoundedDouble) new Random(21).NextDouble(); PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); + + var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(); + var selectableHydraulicBoundaryLocation = new SelectableHydraulicBoundaryLocation(hydraulicBoundaryLocation, null); - PipingInput inputParameters = new PipingInput(new GeneralPipingInput()) - { - HydraulicBoundaryLocation = TestHydraulicBoundaryLocation.CreateDesignWaterLevelCalculated( - assessmentLevel) - }; - inputParameters.Attach(projectObserver); + var context = new PipingInputContext(calculationItem.InputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection) - }; + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + calculationItem.InputParameters, + calculationItem, + hydraulicBoundaryLocation, + new[] + { + observable + }); - var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(); - var selectableHydraulicBoundaryLocation = new SelectableHydraulicBoundaryLocation(hydraulicBoundaryLocation, null); + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); // Call properties.SelectedHydraulicBoundaryLocation = selectableHydraulicBoundaryLocation; // Assert Assert.IsNaN(properties.AssessmentLevel.Value); - mocks.VerifyAll(); } [Test] public void HydraulicBoundaryLocation_DesignWaterLevelSet_SetsAssessmentLevelToDesignWaterLevelAndNotifiesOnce() - { + { + // Setup var mocks = new MockRepository(); - var assessmentSectionMock = mocks.Stub(); - var projectObserver = mocks.StrictMock(); - projectObserver.Expect(o => o.UpdateObserver()).Repeat.Times(1); + var assessmentSection = mocks.Stub(); + var observable = mocks.StrictMock(); + observable.Expect(o => o.NotifyObservers()); mocks.ReplayAll(); - - PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); + PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); - PipingInput inputParameters = new PipingInput(new GeneralPipingInput()); - inputParameters.Attach(projectObserver); - - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSectionMock) - }; - - RoundedDouble testLevel = (RoundedDouble) new Random(21).NextDouble(); + PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); + RoundedDouble testLevel = (RoundedDouble)new Random(21).NextDouble(); HydraulicBoundaryLocation hydraulicBoundaryLocation = TestHydraulicBoundaryLocation.CreateDesignWaterLevelCalculated( testLevel); var selectableHydraulicBoundaryLocation = new SelectableHydraulicBoundaryLocation(hydraulicBoundaryLocation, null); + var context = new PipingInputContext(calculationItem.InputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + calculationItem.InputParameters, + calculationItem, + hydraulicBoundaryLocation, + new[] + { + observable + }); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call properties.SelectedHydraulicBoundaryLocation = selectableHydraulicBoundaryLocation; @@ -899,14 +1042,17 @@ HydraulicBoundaryLocation = TestHydraulicBoundaryLocation.CreateDesignWaterLevelCalculated(50) }; - PipingInputContextProperties properties = new PipingInputContextProperties + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + var handler = new CalculationInputPropertyChangeHandler(); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler) { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), UseAssessmentLevelManualInput = false }; @@ -934,8 +1080,8 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var projectObserver = mocks.StrictMock(); - projectObserver.Expect(o => o.UpdateObserver()).Repeat.Times(1); + var observable = mocks.StrictMock(); + observable.Expect(o => o.NotifyObservers()); mocks.ReplayAll(); PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); @@ -945,24 +1091,32 @@ { UseAssessmentLevelManualInput = true }; - inputParameters.Attach(projectObserver); - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection) - }; + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculationItem, + testLevel, + new [] + { + observable + }); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call properties.AssessmentLevel = (RoundedDouble) testLevel; // Assert Assert.AreEqual(2, properties.AssessmentLevel.NumberOfDecimalPlaces); Assert.AreEqual(testLevel, properties.AssessmentLevel, properties.AssessmentLevel.GetAccuracy()); + Assert.IsTrue(handler.Called); mocks.VerifyAll(); } @@ -985,16 +1139,17 @@ AssessmentLevel = (RoundedDouble) random.NextDouble() }; - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection), - }; + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + var handler = new CalculationInputPropertyChangeHandler(); + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + RoundedDouble testLevel = (RoundedDouble) random.NextDouble(); HydraulicBoundaryLocation hydraulicBoundaryLocation = TestHydraulicBoundaryLocation.CreateDesignWaterLevelCalculated( testLevel); @@ -1030,22 +1185,31 @@ PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); PipingInput inputParameters = calculationItem.InputParameters; - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection) - }; + + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + RingtoetsPipingSurfaceLine newSurfaceLine = ValidSurfaceLine(0, 2); + + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculationItem, + newSurfaceLine, + new IObservable[0]); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + inputParameters.StochasticSoilProfile = new StochasticSoilProfile(0.0, SoilProfileType.SoilProfile1D, 0) { SoilProfile = new TestPipingSoilProfile() }; // Call - properties.SurfaceLine = ValidSurfaceLine(0, 2); + properties.SurfaceLine = newSurfaceLine; // Assert Assert.IsNull(inputParameters.StochasticSoilModel); @@ -1059,6 +1223,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); RingtoetsPipingSurfaceLine testSurfaceLine = ValidSurfaceLine(0, 2); @@ -1078,19 +1243,18 @@ StochasticSoilModel = stochasticSoilModel, StochasticSoilProfile = stochasticSoilProfile }; - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - new[] - { - stochasticSoilModel - }, - failureMechanism, - assessmentSection) - }; + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + new[] + { + stochasticSoilModel + }, + failureMechanism, + assessmentSection); + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call properties.SurfaceLine = testSurfaceLine; @@ -1127,21 +1291,28 @@ PipingInput inputParameters = calculationItem.InputParameters; PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - new[] - { - stochasticSoilModel - }, - failureMechanism, - assessmentSection) - }; + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + new[] + { + stochasticSoilModel + }, + failureMechanism, + assessmentSection); + RingtoetsPipingSurfaceLine newSurfaceLine = ValidSurfaceLine(0, 2); + + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculationItem, + newSurfaceLine, + new IObservable[0]); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call - properties.SurfaceLine = ValidSurfaceLine(0, 2); + properties.SurfaceLine = newSurfaceLine; // Assert Assert.IsNull(inputParameters.StochasticSoilModel); @@ -1155,6 +1326,8 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var observable = mocks.StrictMock(); + observable.Expect(o => o.NotifyObservers()); mocks.ReplayAll(); RingtoetsPipingSurfaceLine testSurfaceLine = ValidSurfaceLine(0, 2); @@ -1181,16 +1354,24 @@ PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); - PipingInputContextProperties properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection) - }; + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculationItem, + stochasticSoilModel2, + new[] + { + observable + }); + + PipingInputContextProperties properties = new PipingInputContextProperties(context, handler); + // Call properties.StochasticSoilModel = stochasticSoilModel2; @@ -1213,15 +1394,16 @@ PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); PipingInput inputParameters = new PipingInput(new GeneralPipingInput()); - PipingInputContextProperties contextProperties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection) - }; + var context = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + var handler = new CalculationInputPropertyChangeHandler(); + + PipingInputContextProperties contextProperties = new PipingInputContextProperties(context, handler); inputParameters.HydraulicBoundaryLocation = TestHydraulicBoundaryLocation.CreateDesignWaterLevelCalculated(1.0); DesignVariable phreaticLevelExitProperty = contextProperties.PhreaticLevelExit; @@ -1247,17 +1429,15 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); var context = new PipingInputContext(calculation.InputParameters, calculation, failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); // Call IEnumerable surfaceLines = properties.GetAvailableSurfaceLines(); @@ -1273,17 +1453,15 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); var context = new PipingInputContext(calculation.InputParameters, calculation, failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); // Precondition: Assert.IsNull(calculation.InputParameters.SurfaceLine); @@ -1302,6 +1480,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var surfaceLine = new RingtoetsPipingSurfaceLine(); @@ -1361,10 +1540,7 @@ var context = new PipingInputContext(calculation.InputParameters, calculation, failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); // Precondition: Assert.IsNotNull(calculation.InputParameters.SurfaceLine); @@ -1387,17 +1563,15 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); var context = new PipingInputContext(calculation.InputParameters, calculation, failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); // Precondition Assert.IsNull(calculation.InputParameters.StochasticSoilModel); @@ -1416,6 +1590,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); @@ -1436,10 +1611,7 @@ var context = new PipingInputContext(calculation.InputParameters, calculation, failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); // Precondition Assert.IsNotNull(calculation.InputParameters.StochasticSoilModel); @@ -1458,17 +1630,15 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); var context = new PipingInputContext(calculation.InputParameters, calculation, failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); SelectableHydraulicBoundaryLocation selectedHydraulicBoundaryLocation = null; @@ -1495,29 +1665,28 @@ hydraulicBoundaryLocation } }; + var handler = mockRepository.Stub>(); mockRepository.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); + + StochasticSoilModel soilModel = ValidStochasticSoilModel(0.0, 4.0); + StochasticSoilProfile soilProfile = soilModel.StochasticSoilProfiles.First(); var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput) { InputParameters = { - HydraulicBoundaryLocation = hydraulicBoundaryLocation + HydraulicBoundaryLocation = hydraulicBoundaryLocation, + SurfaceLine = ValidSurfaceLine(0, 4.0), + StochasticSoilModel = soilModel, + StochasticSoilProfile = soilProfile } }; var context = new PipingInputContext(calculation.InputParameters, calculation, failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, failureMechanism, assessmentSection); - StochasticSoilModel soilModel = ValidStochasticSoilModel(0.0, 4.0); - StochasticSoilProfile soilProfile = soilModel.StochasticSoilProfiles.First(); - var properties = new PipingInputContextProperties - { - Data = context, - SurfaceLine = ValidSurfaceLine(0, 4.0), - StochasticSoilModel = soilModel, - StochasticSoilProfile = soilProfile - }; + var properties = new PipingInputContextProperties(context, handler); // When IEnumerable availableHydraulicBoundaryLocations = @@ -1550,17 +1719,15 @@ var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); assessmentSection.HydraulicBoundaryDatabase = hydraulicBoundaryDatabase; + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); var context = new PipingInputContext(calculation.InputParameters, calculation, failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); // Call IEnumerable selectableHydraulicBoundaryLocations = @@ -1594,20 +1761,24 @@ var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); assessmentSection.HydraulicBoundaryDatabase = hydraulicBoundaryDatabase; + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); - var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); - var context = new PipingInputContext(calculation.InputParameters, calculation, - failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, - failureMechanism, assessmentSection); + RingtoetsPipingSurfaceLine surfaceLine = ValidSurfaceLine(0.0, 4.0); surfaceLine.ReferenceLineIntersectionWorldPoint = new Point2D(0.0, 0.0); - var properties = new PipingInputContextProperties + var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput) { - Data = context, - SurfaceLine = surfaceLine + InputParameters = + { + SurfaceLine = surfaceLine + } }; + var context = new PipingInputContext(calculation.InputParameters, calculation, + failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, + failureMechanism, assessmentSection); + var properties = new PipingInputContextProperties(context, handler); // Call IEnumerable selectableHydraulicBoundaryLocations = @@ -1643,27 +1814,43 @@ var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); assessmentSection.HydraulicBoundaryDatabase = hydraulicBoundaryDatabase; + var observable = mocks.StrictMock(); + observable.Expect(o => o.NotifyObservers()); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); - var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); - var context = new PipingInputContext(calculation.InputParameters, calculation, - failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, - failureMechanism, assessmentSection); + var surfaceLine = ValidSurfaceLine(0.0, 4.0); surfaceLine.ReferenceLineIntersectionWorldPoint = new Point2D(0, 0); - var properties = new PipingInputContextProperties + var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput) { - Data = context, - SurfaceLine = surfaceLine + InputParameters = + { + SurfaceLine = surfaceLine + } }; - IEnumerable originalList = properties.GetSelectableHydraulicBoundaryLocations() - .ToList(); + var context = new PipingInputContext(calculation.InputParameters, calculation, + failureMechanism.SurfaceLines, failureMechanism.StochasticSoilModels, + failureMechanism, assessmentSection); var newSurfaceLine = ValidSurfaceLine(0.0, 5.0); newSurfaceLine.ReferenceLineIntersectionWorldPoint = new Point2D(0, 190); + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + calculation.InputParameters, + calculation, + newSurfaceLine, + new[] + { + observable + }); + + var properties = new PipingInputContextProperties(context, handler); + + IEnumerable originalList = properties.GetSelectableHydraulicBoundaryLocations() + .ToList(); + // When properties.SurfaceLine = newSurfaceLine; @@ -1691,6 +1878,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); @@ -1708,10 +1896,7 @@ Enumerable.Empty(), failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); // Call var result = properties.DynamicReadOnlyValidationMethod("AssessmentLevel"); @@ -1724,13 +1909,28 @@ public void DynamicReadOnlyValidationMethod_AnyOtherProperty_ReturnsTrue() { // Setup - var properties = new PipingInputContextProperties(); + var mocks = new MockRepository(); + var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); + mocks.ReplayAll(); + var failureMechanism = new PipingFailureMechanism(); + + var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); + + var context = new PipingInputContext(calculation.InputParameters, calculation, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, assessmentSection); + + var properties = new PipingInputContextProperties(context, handler); + // Call var result = properties.DynamicReadOnlyValidationMethod("prop"); // Assert Assert.IsTrue(result); + mocks.VerifyAll(); } [Test] @@ -1741,6 +1941,7 @@ // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); mocks.ReplayAll(); var failureMechanism = new PipingFailureMechanism(); @@ -1758,10 +1959,7 @@ Enumerable.Empty(), failureMechanism, assessmentSection); - var properties = new PipingInputContextProperties - { - Data = context - }; + var properties = new PipingInputContextProperties(context, handler); // Call var result = properties.DynamicVisibleValidationMethod("SelectedHydraulicBoundaryLocation"); @@ -1774,68 +1972,68 @@ public void DynamicVisibleValidationMethod_AnyOtherProperty_ReturnsFalse() { // Setup - var properties = new PipingInputContextProperties(); + var mocks = new MockRepository(); + var assessmentSection = mocks.Stub(); + var handler = mocks.Stub>(); + mocks.ReplayAll(); + var failureMechanism = new PipingFailureMechanism(); + + var calculation = new PipingCalculationScenario(failureMechanism.GeneralInput); + + var context = new PipingInputContext(calculation.InputParameters, calculation, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, assessmentSection); + + var properties = new PipingInputContextProperties(context, handler); + // Call var result = properties.DynamicVisibleValidationMethod("prop"); // Assert Assert.IsFalse(result); } - private void SetPropertyAndVerifyNotifcationsAndOutput(bool hasOutput, Action setProperty) - { - SetPropertyAndVerifyNotifcationsAndOutputForCalculation( - hasOutput, - setProperty, - new PipingCalculationScenario(new GeneralPipingInput())); - } - - private void SetPropertyAndVerifyNotifcationsAndOutputForCalculation( - bool hasOutput, + private void SetPropertyAndVerifyNotifcationsAndOutputForCalculation( Action setProperty, + TPropertyValue value, PipingCalculationScenario calculation) { // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - - var calculationObserver = mocks.StrictMock(); - int numberOfChangedProperties = hasOutput ? 1 : 0; - calculationObserver.Expect(o => o.UpdateObserver()).Repeat.Times(numberOfChangedProperties); - - var inputObserver = mocks.StrictMock(); - inputObserver.Expect(o => o.UpdateObserver()); - + var observable = mocks.StrictMock(); + observable.Expect(o => o.NotifyObservers()); mocks.ReplayAll(); - - if (hasOutput) - { - calculation.Output = new TestPipingOutput(); - } - calculation.Attach(calculationObserver); - + PipingInput inputParameters = calculation.InputParameters; - inputParameters.Attach(inputObserver); var failureMechanism = new PipingFailureMechanism(); - var properties = new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculation, - Enumerable.Empty(), - Enumerable.Empty(), - failureMechanism, - assessmentSection) - }; + var context = new PipingInputContext(inputParameters, + calculation, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + var handler = new CalculationInputSetPropertyValueAfterConfirmationParameterTester( + inputParameters, + calculation, + value, + new[] + { + observable + }); + + var properties = new PipingInputContextProperties(context, handler); + // Call setProperty(properties); // Assert - Assert.IsFalse(calculation.HasOutput); - + Assert.IsTrue(handler.Called); mocks.VerifyAll(); } Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/TypeConverters/LogNormalDistributionDesignVariableTypeConverterTest.cs =================================================================== diff -u -rac2a8327f9ce8b42d2e2740a0cda030385c5c63c -r60d95df18eb252bf99dff07a76d9660f331c92c2 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/TypeConverters/LogNormalDistributionDesignVariableTypeConverterTest.cs (.../LogNormalDistributionDesignVariableTypeConverterTest.cs) (revision ac2a8327f9ce8b42d2e2740a0cda030385c5c63c) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/TypeConverters/LogNormalDistributionDesignVariableTypeConverterTest.cs (.../LogNormalDistributionDesignVariableTypeConverterTest.cs) (revision 60d95df18eb252bf99dff07a76d9660f331c92c2) @@ -28,6 +28,8 @@ using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.Data.Probabilistics; +using Ringtoets.Common.Forms.ChangeHandlers; +using Ringtoets.Common.Forms.PropertyClasses; using Ringtoets.Piping.Data; using Ringtoets.Piping.Forms.PresentationObjects; using Ringtoets.Piping.Forms.PropertyClasses; @@ -79,8 +81,7 @@ var result = converter.ConvertTo(designVariable, typeof(string)); // Assert - var expectedText = string.Format("{0} (Verwachtingswaarde = {1}, Standaardafwijking = {2})", - designVariable.GetDesignValue(), distribution.Mean, distribution.StandardDeviation); + var expectedText = $"{designVariable.GetDesignValue()} (Verwachtingswaarde = {distribution.Mean}, Standaardafwijking = {distribution.StandardDeviation})"; Assert.AreEqual(expectedText, result); } @@ -226,10 +227,9 @@ failureMechanism, assessmentSectionMock); - var inputParameterContextProperties = new PipingInputContextProperties - { - Data = inputParametersContext - }; + var handler = new CalculationInputPropertyChangeHandler(); + + var inputParameterContextProperties = new PipingInputContextProperties(inputParametersContext, handler); PropertyDescriptor propertyDescriptor = TypeDescriptor.GetProperties(inputParameterContextProperties).Find("DampingFactorExit", false); var dynamicPropertyBag = new DynamicPropertyBag(inputParameterContextProperties); Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/TypeConverters/NormalDistributionDesignVariableTypeConverterTest.cs =================================================================== diff -u -rfea3ed82dfb6dfcad535eef16efcbaa9c01564ed -r60d95df18eb252bf99dff07a76d9660f331c92c2 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/TypeConverters/NormalDistributionDesignVariableTypeConverterTest.cs (.../NormalDistributionDesignVariableTypeConverterTest.cs) (revision fea3ed82dfb6dfcad535eef16efcbaa9c01564ed) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/TypeConverters/NormalDistributionDesignVariableTypeConverterTest.cs (.../NormalDistributionDesignVariableTypeConverterTest.cs) (revision 60d95df18eb252bf99dff07a76d9660f331c92c2) @@ -28,11 +28,13 @@ using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.Data.Probabilistics; +using Ringtoets.Common.Forms.PropertyClasses; using Ringtoets.Piping.Data; using Ringtoets.Piping.Forms.PresentationObjects; using Ringtoets.Piping.Forms.PropertyClasses; using Ringtoets.Piping.Forms.TypeConverters; using Ringtoets.Piping.Primitives; +using Ringtoets.Common.Forms.ChangeHandlers; namespace Ringtoets.Piping.Forms.Test.TypeConverters { @@ -224,11 +226,10 @@ Enumerable.Empty(), failureMechanism, assessmentSectionMock); - var inputParameterContextProperties = new PipingInputContextProperties - { - Data = inputParametersContext - }; + var handler = new CalculationInputPropertyChangeHandler(); + var inputParameterContextProperties = new PipingInputContextProperties(inputParametersContext, handler); + PropertyDescriptor propertyDescriptor = TypeDescriptor.GetProperties(inputParameterContextProperties).Find("PhreaticLevelExit", false); var dynamicPropertyBag = new DynamicPropertyBag(inputParameterContextProperties); Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextStochasticSoilModelSelectionEditorTest.cs =================================================================== diff -u -rf35371f467919042f47b41f84d31e8d4f47cff2a -r60d95df18eb252bf99dff07a76d9660f331c92c2 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextStochasticSoilModelSelectionEditorTest.cs (.../PipingInputContextStochasticSoilModelSelectionEditorTest.cs) (revision f35371f467919042f47b41f84d31e8d4f47cff2a) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextStochasticSoilModelSelectionEditorTest.cs (.../PipingInputContextStochasticSoilModelSelectionEditorTest.cs) (revision 60d95df18eb252bf99dff07a76d9660f331c92c2) @@ -28,6 +28,7 @@ using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; +using Ringtoets.Common.Forms.PropertyClasses; using Ringtoets.Piping.Data; using Ringtoets.Piping.Data.TestUtil; using Ringtoets.Piping.Forms.PresentationObjects; @@ -50,6 +51,7 @@ var service = mockRepository.DynamicMock(); var context = mockRepository.DynamicMock(); var assessmentSectionMock = mockRepository.StrictMock(); + var handler = mockRepository.Stub>(); var calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); var failureMechanism = new PipingFailureMechanism(); @@ -68,10 +70,7 @@ failureMechanism, assessmentSectionMock); - var properties = new PipingInputContextProperties - { - Data = pipingInputContext - }; + var properties = new PipingInputContextProperties(pipingInputContext, handler); var editor = new PipingInputContextStochasticSoilModelSelectionEditor(); var someValue = new object(); @@ -101,6 +100,7 @@ var service = mockRepository.DynamicMock(); var context = mockRepository.DynamicMock(); var assessmentSectionMock = mockRepository.StrictMock(); + var handler = mockRepository.Stub>(); var stochasticSoilProfile = new StochasticSoilProfile(1.0, SoilProfileType.SoilProfile1D, 0) { @@ -144,10 +144,7 @@ failureMechanism, assessmentSectionMock); - var properties = new PipingInputContextProperties - { - Data = inputParametersContext - }; + var properties = new PipingInputContextProperties(inputParametersContext, handler); var editor = new PipingInputContextStochasticSoilModelSelectionEditor(); var someValue = new object(); Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextStochasticSoilProfileSelectionEditorTest.cs =================================================================== diff -u -rf35371f467919042f47b41f84d31e8d4f47cff2a -r60d95df18eb252bf99dff07a76d9660f331c92c2 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextStochasticSoilProfileSelectionEditorTest.cs (.../PipingInputContextStochasticSoilProfileSelectionEditorTest.cs) (revision f35371f467919042f47b41f84d31e8d4f47cff2a) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextStochasticSoilProfileSelectionEditorTest.cs (.../PipingInputContextStochasticSoilProfileSelectionEditorTest.cs) (revision 60d95df18eb252bf99dff07a76d9660f331c92c2) @@ -28,6 +28,7 @@ using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; +using Ringtoets.Common.Forms.PropertyClasses; using Ringtoets.Piping.Data; using Ringtoets.Piping.Data.TestUtil; using Ringtoets.Piping.Forms.PresentationObjects; @@ -50,6 +51,7 @@ var service = mockRepository.DynamicMock(); var context = mockRepository.DynamicMock(); var assessmentSectionMock = mockRepository.StrictMock(); + var handler = mockRepository.Stub>(); var calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); var failureMechanism = new PipingFailureMechanism(); @@ -71,10 +73,7 @@ failureMechanism, assessmentSectionMock); - var properties = new PipingInputContextProperties - { - Data = pipingInputContext - }; + var properties = new PipingInputContextProperties(pipingInputContext, handler); var editor = new PipingInputContextStochasticSoilProfileSelectionEditor(); var someValue = new object(); @@ -104,6 +103,7 @@ var service = mockRepository.DynamicMock(); var context = mockRepository.DynamicMock(); var assessmentSectionMock = mockRepository.StrictMock(); + var handler = mockRepository.Stub>(); var stochasticSoilProfile = new StochasticSoilProfile(1.0, SoilProfileType.SoilProfile1D, 0) { @@ -147,10 +147,7 @@ failureMechanism, assessmentSectionMock); - var properties = new PipingInputContextProperties - { - Data = inputParametersContext - }; + var properties = new PipingInputContextProperties(inputParametersContext, handler); var editor = new PipingInputContextStochasticSoilProfileSelectionEditor(); var someValue = new object(); Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextSurfaceLineSelectionEditorTest.cs =================================================================== diff -u -rf35371f467919042f47b41f84d31e8d4f47cff2a -r60d95df18eb252bf99dff07a76d9660f331c92c2 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextSurfaceLineSelectionEditorTest.cs (.../PipingInputContextSurfaceLineSelectionEditorTest.cs) (revision f35371f467919042f47b41f84d31e8d4f47cff2a) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/UITypeEditors/PipingInputContextSurfaceLineSelectionEditorTest.cs (.../PipingInputContextSurfaceLineSelectionEditorTest.cs) (revision 60d95df18eb252bf99dff07a76d9660f331c92c2) @@ -28,6 +28,7 @@ using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; +using Ringtoets.Common.Forms.PropertyClasses; using Ringtoets.Piping.Data; using Ringtoets.Piping.Forms.PresentationObjects; using Ringtoets.Piping.Forms.PropertyClasses; @@ -48,6 +49,7 @@ var service = mockRepository.DynamicMock(); var context = mockRepository.DynamicMock(); var assessmentSectionMock = mockRepository.StrictMock(); + var handler = mockRepository.Stub>(); var calculationItem = new PipingCalculationScenario(new GeneralPipingInput()); var failureMechanism = new PipingFailureMechanism(); @@ -66,10 +68,7 @@ failureMechanism, assessmentSectionMock); - var properties = new PipingInputContextProperties - { - Data = inputParametersContext - }; + var properties = new PipingInputContextProperties(inputParametersContext, handler); var editor = new PipingInputContextSurfaceLineSelectionEditor(); var someValue = new object(); @@ -99,6 +98,7 @@ var service = mockRepository.DynamicMock(); var context = mockRepository.DynamicMock(); var assessmentSectionMock = mockRepository.StrictMock(); + var handler = mockRepository.Stub>(); var surfaceLine = new RingtoetsPipingSurfaceLine(); surfaceLine.SetGeometry(new[] @@ -123,10 +123,7 @@ failureMechanism, assessmentSectionMock); - var properties = new PipingInputContextProperties - { - Data = inputParametersContext - }; + var properties = new PipingInputContextProperties(inputParametersContext, handler); var editor = new PipingInputContextSurfaceLineSelectionEditor(); var someValue = new object();