Index: Core/Common/test/Core.Common.TestUtil.Test/RandomExtensionsTest.cs =================================================================== diff -u -rff061b0aa2ad74d68f9dab7b20af203348913714 -r917edb0f289fcc7259995bc8da2678142c16620c --- Core/Common/test/Core.Common.TestUtil.Test/RandomExtensionsTest.cs (.../RandomExtensionsTest.cs) (revision ff061b0aa2ad74d68f9dab7b20af203348913714) +++ Core/Common/test/Core.Common.TestUtil.Test/RandomExtensionsTest.cs (.../RandomExtensionsTest.cs) (revision 917edb0f289fcc7259995bc8da2678142c16620c) @@ -20,6 +20,7 @@ // All rights reserved. using System; +using Core.Common.Base.Data; using NUnit.Framework; namespace Core.Common.TestUtil.Test @@ -94,6 +95,20 @@ } [Test] + public void NextBoolean_RandomIsNull_ThrowsArgumentNullException() + { + // Setup + var random = (Random)null; + + // Call + TestDelegate test = () => random.NextBoolean(); + + // Assert + var paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("random", paramName); + } + + [Test] [TestCase(0, true)] [TestCase(1, false)] public void NextBoolean_ReturnRandomTrueOrFalse(int seed, bool expectedFirstCallResult) @@ -109,6 +124,20 @@ } [Test] + public void NextEnumValue_RandomIsNull_ThrowsArgumentNullException() + { + // Setup + var random = (Random)null; + + // Call + TestDelegate test = () => random.NextEnumValue(); + + // Assert + var paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("random", paramName); + } + + [Test] public void NextEnumValue_TypeIsNoEnum_ThrowsArgumentException() { // Setup @@ -136,6 +165,34 @@ Assert.AreEqual(expectedFirstCallResult, result); } + [Test] + public void NextRoundedDouble_RandomIsNull_ThrowsArgumentNullException() + { + // Setup + var random = (Random)null; + + // Call + TestDelegate test = () => random.NextRoundedDouble(); + + // Assert + var paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("random", paramName); + } + + [Test] + public void NextRoundedDouble_Always_ReturnsNewRoundedDouble() + { + // Setup + var seededRandomA = new Random(21); + var seededRandomB = new Random(21); + + // Call + RoundedDouble result = seededRandomA.NextRoundedDouble(); + + // Assert + Assert.AreEqual(seededRandomB.NextDouble(), result.Value, 1e-15); + } + public enum TestEnum { ValueOne, Index: Core/Common/test/Core.Common.TestUtil/RandomExtensions.cs =================================================================== diff -u -r3e43a4363fdbbeef529387ca3c86802094532813 -r917edb0f289fcc7259995bc8da2678142c16620c --- Core/Common/test/Core.Common.TestUtil/RandomExtensions.cs (.../RandomExtensions.cs) (revision 3e43a4363fdbbeef529387ca3c86802094532813) +++ Core/Common/test/Core.Common.TestUtil/RandomExtensions.cs (.../RandomExtensions.cs) (revision 917edb0f289fcc7259995bc8da2678142c16620c) @@ -20,6 +20,7 @@ // All rights reserved. using System; +using Core.Common.Base.Data; namespace Core.Common.TestUtil { @@ -67,20 +68,48 @@ /// /// A pseudo-random number generator. /// A new random boolean value. + /// Thrown when is null. public static bool NextBoolean(this Random random) { + if (random == null) + { + throw new ArgumentNullException("random"); + } + return Convert.ToBoolean(random.Next(0, 2)); } /// + /// Returns a random value. + /// + /// A pseudo-random number generator. + /// A new random . + /// Thrown when is null. + public static RoundedDouble NextRoundedDouble(this Random random) + { + if (random == null) + { + throw new ArgumentNullException("random"); + } + + return (RoundedDouble)random.NextDouble(); + } + + /// /// Returns a random value of . /// /// The to use. /// A pseudo-random number generator. /// >A new random value of type . + /// Thrown when is null. /// Thrown when is not an . public static TEnum NextEnumValue(this Random random) { + if (random == null) + { + throw new ArgumentNullException("random"); + } + var enumValues = (TEnum[]) Enum.GetValues(typeof(TEnum)); return enumValues[random.Next(enumValues.Length)]; } Index: Ringtoets/Common/src/Ringtoets.Common.Service/RingtoetsCommonDataSynchronizationService.cs =================================================================== diff -u -r87aafc58782eb7ce49b1e06b1db2feda8cd85948 -r917edb0f289fcc7259995bc8da2678142c16620c --- Ringtoets/Common/src/Ringtoets.Common.Service/RingtoetsCommonDataSynchronizationService.cs (.../RingtoetsCommonDataSynchronizationService.cs) (revision 87aafc58782eb7ce49b1e06b1db2feda8cd85948) +++ Ringtoets/Common/src/Ringtoets.Common.Service/RingtoetsCommonDataSynchronizationService.cs (.../RingtoetsCommonDataSynchronizationService.cs) (revision 917edb0f289fcc7259995bc8da2678142c16620c) @@ -60,7 +60,7 @@ /// The to clear the output for. /// Thrown when is null. /// All objects that have been changed. - public static IEnumerable ClearCalculationOutput(StructuresCalculation calculation) where T : ICalculationInput, new() + public static IEnumerable ClearCalculationOutput(ICalculation calculation) { if (calculation == null) { Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs =================================================================== diff -u -rac582bc093c8a275cd9b5dc2148af313b5242062 -r917edb0f289fcc7259995bc8da2678142c16620c --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs (.../PipingInputContextProperties.cs) (revision ac582bc093c8a275cd9b5dc2148af313b5242062) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs (.../PipingInputContextProperties.cs) (revision 917edb0f289fcc7259995bc8da2678142c16620c) @@ -22,6 +22,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; +using Core.Common.Base; using Core.Common.Base.Data; using Core.Common.Base.Geometry; using Core.Common.Gui.Attributes; @@ -32,6 +33,7 @@ using Ringtoets.Common.Forms.Helpers; using Ringtoets.Common.Forms.PresentationObjects; using Ringtoets.Common.Forms.UITypeEditors; +using Ringtoets.Common.Service; using Ringtoets.Piping.Data; using Ringtoets.Piping.Forms.PresentationObjects; using Ringtoets.Piping.Forms.Properties; @@ -152,7 +154,7 @@ set { data.WrappedData.HydraulicBoundaryLocation = value.HydraulicBoundaryLocation; - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } @@ -170,7 +172,7 @@ set { data.WrappedData.AssessmentLevel = value; - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } @@ -187,7 +189,7 @@ set { data.WrappedData.UseAssessmentLevelManualInput = value; - data.NotifyObservers(); + NotifyPropertyChanged(); } } @@ -205,7 +207,7 @@ set { data.WrappedData.DampingFactorExit = value.Distribution; - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } @@ -223,7 +225,7 @@ set { data.WrappedData.PhreaticLevelExit = value.Distribution; - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } @@ -260,7 +262,7 @@ { data.WrappedData.SurfaceLine = value; PipingInputService.SetMatchingStochasticSoilModel(data.WrappedData, GetAvailableStochasticSoilModels()); - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } } @@ -282,7 +284,7 @@ { data.WrappedData.StochasticSoilModel = value; PipingInputService.SyncStochasticSoilProfileWithStochasticSoilModel(data.WrappedData); - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } } @@ -303,7 +305,7 @@ if (!ReferenceEquals(value, data.WrappedData.StochasticSoilProfile)) { data.WrappedData.StochasticSoilProfile = value; - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } } @@ -321,7 +323,7 @@ set { data.WrappedData.EntryPointL = value; - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } @@ -338,7 +340,7 @@ set { data.WrappedData.ExitPointL = value; - data.WrappedData.NotifyObservers(); + NotifyPropertyChanged(); } } @@ -434,5 +436,15 @@ } #endregion + + private void NotifyPropertyChanged() + { + IEnumerable affectedCalculation = RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(data.PipingCalculation); + foreach (var calculation in affectedCalculation) + { + calculation.NotifyObservers(); + } + data.WrappedData.NotifyObservers(); + } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/Ringtoets.Piping.Forms.csproj =================================================================== diff -u -r23d1e296e2da4364fbfe346e68d582dfcf966bb0 -r917edb0f289fcc7259995bc8da2678142c16620c --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/Ringtoets.Piping.Forms.csproj (.../Ringtoets.Piping.Forms.csproj) (revision 23d1e296e2da4364fbfe346e68d582dfcf966bb0) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/Ringtoets.Piping.Forms.csproj (.../Ringtoets.Piping.Forms.csproj) (revision 917edb0f289fcc7259995bc8da2678142c16620c) @@ -190,6 +190,10 @@ Ringtoets.Common.Forms False + + {D951D6DA-FE83-4920-9FDB-63BF96480B54} + Ringtoets.Common.Service + {14C6F716-64E2-4BC4-A1EF-05865FCEFA4C} Ringtoets.Piping.Primitives Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs =================================================================== diff -u -rac582bc093c8a275cd9b5dc2148af313b5242062 -r917edb0f289fcc7259995bc8da2678142c16620c --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs (.../PipingInputContextPropertiesTest.cs) (revision ac582bc093c8a275cd9b5dc2148af313b5242062) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs (.../PipingInputContextPropertiesTest.cs) (revision 917edb0f289fcc7259995bc8da2678142c16620c) @@ -408,20 +408,17 @@ } [Test] - public void SetProperties_WithData_UpdateDataAndNotifyObservers() + public void SetProperties_WithData_PropertiesOnInputSet() { // Setup var mocks = new MockRepository(); var assessmentSection = mocks.Stub(); - var projectObserver = mocks.StrictMock(); - projectObserver.Expect(o => o.UpdateObserver()); 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 { @@ -433,93 +430,131 @@ assessmentSection) }; + const double assessmentLevel = 0.36; const double entryPointL = 0.12; + const double exitPointL = 0.44; + RingtoetsPipingSurfaceLine surfaceLine = ValidSurfaceLine(0.0, 4.0); + StochasticSoilModel soilModel = ValidStochasticSoilModel(0.0, 4.0); + StochasticSoilProfile soilProfile = soilModel.StochasticSoilProfiles.First(); + var dampingFactorExit = new LogNormalDistributionDesignVariable( + new LogNormalDistribution(3) + { + Mean = (RoundedDouble) 1.55, + StandardDeviation = (RoundedDouble) 0.22 + }); + var phreaticLevelExit = new NormalDistributionDesignVariable( + new NormalDistribution(3) + { + Mean = (RoundedDouble) 1.55, + StandardDeviation = (RoundedDouble) 0.22 + }); // Call + properties.UseAssessmentLevelManualInput = true; + properties.AssessmentLevel = (RoundedDouble) assessmentLevel; + properties.SurfaceLine = surfaceLine; properties.EntryPointL = (RoundedDouble) entryPointL; + properties.ExitPointL = (RoundedDouble) exitPointL; + properties.StochasticSoilModel = soilModel; + properties.StochasticSoilProfile = soilProfile; + properties.DampingFactorExit = dampingFactorExit; + properties.PhreaticLevelExit = phreaticLevelExit; // Assert + Assert.AreEqual(assessmentLevel, inputParameters.AssessmentLevel.Value); Assert.AreEqual(entryPointL, inputParameters.EntryPointL.Value); - mocks.VerifyAll(); + Assert.AreEqual(exitPointL, inputParameters.ExitPointL.Value); + Assert.AreSame(surfaceLine, inputParameters.SurfaceLine); + Assert.AreSame(soilModel, inputParameters.StochasticSoilModel); + Assert.AreSame(soilProfile, inputParameters.StochasticSoilProfile); + DistributionAssert.AreEqual(dampingFactorExit.Distribution, inputParameters.DampingFactorExit); + DistributionAssert.AreEqual(phreaticLevelExit.Distribution, inputParameters.PhreaticLevelExit); } [Test] - public void SetProperties_IndividualProperties_UpdateDataAndNotifyObservers() + [TestCase(true)] + [TestCase(false)] + public void SetSurfaceLine_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) { - // Setup - var mocks = new MockRepository(); - var assessmentSection = mocks.Stub(); - var projectObserver = mocks.StrictMock(); - int numberOfChangedProperties = 6; - projectObserver.Expect(o => o.UpdateObserver()).Repeat.Times(numberOfChangedProperties); - mocks.ReplayAll(); + SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.SurfaceLine = ValidSurfaceLine(0.0, 4.0)); + } - PipingCalculationScenario calculationItem = new PipingCalculationScenario(new GeneralPipingInput()) - { - InputParameters = - { - SurfaceLine = ValidSurfaceLine(0.0, 4.0) - } - }; - PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); + [Test] + [TestCase(true)] + [TestCase(false)] + public void SetStochasticSoilModel_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + { - PipingInput inputParameters = calculationItem.InputParameters; - inputParameters.Attach(projectObserver); + SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.StochasticSoilModel = ValidStochasticSoilModel(0.0, 4.0)); + } - Random random = new Random(22); + [Test] + [TestCase(true)] + [TestCase(false)] + public void SetStochasticSoilProfile_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + { + SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.StochasticSoilProfile = ValidStochasticSoilModel(0.0, 4.0).StochasticSoilProfiles.First()); + } - RoundedDouble assessmentLevel = (RoundedDouble) random.NextDouble(); + [Test] + [TestCase(true)] + [TestCase(false)] + public void SetAssessmentLevel_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + { + SetPropertyAndVerifyNotifcationsAndOutputForCalculation( + hasOutput, + properties => properties.AssessmentLevel = new Random(21).NextRoundedDouble(), + new PipingCalculationScenario(new GeneralPipingInput()) + { + InputParameters = + { + UseAssessmentLevelManualInput = true + } + }); + } - LogNormalDistribution dampingFactorExit = new LogNormalDistribution(3); - NormalDistribution phreaticLevelExit = new NormalDistribution(2); + [Test] + [TestCase(true)] + [TestCase(false)] + public void SetDampingFactorExit_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + { + SetPropertyAndVerifyNotifcationsAndOutput( + hasOutput, + properties => properties.DampingFactorExit = new LogNormalDistributionDesignVariable(new LogNormalDistribution(3))); + } - RingtoetsPipingSurfaceLine surfaceLine = ValidSurfaceLine(0.0, 4.0); - StochasticSoilModel stochasticSoilModel1 = ValidStochasticSoilModel(0.0, 4.0); + [Test] + [TestCase(true)] + [TestCase(false)] + public void SetPhreaticLevelExit_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + { + SetPropertyAndVerifyNotifcationsAndOutput( + hasOutput, + properties => properties.PhreaticLevelExit = new NormalDistributionDesignVariable(new NormalDistribution(3))); + } - StochasticSoilModel stochasticSoilModel2 = ValidStochasticSoilModel(0.0, 4.0); - StochasticSoilProfile stochasticSoilProfile2 = stochasticSoilModel2.StochasticSoilProfiles.First(); - stochasticSoilModel2.StochasticSoilProfiles.Add(new StochasticSoilProfile(0.0, SoilProfileType.SoilProfile1D, 1234)); + [Test] + [TestCase(true)] + [TestCase(false)] + public void SetEntryPoinL_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + { + SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.EntryPointL = new Random(21).NextRoundedDouble()); + } - // Call - new PipingInputContextProperties - { - Data = new PipingInputContext(inputParameters, - calculationItem, - Enumerable.Empty(), - new[] - { - stochasticSoilModel1, - stochasticSoilModel2 - }, - failureMechanism, - assessmentSection), - DampingFactorExit = new LogNormalDistributionDesignVariable(dampingFactorExit), - PhreaticLevelExit = new NormalDistributionDesignVariable(phreaticLevelExit), - SurfaceLine = surfaceLine, - StochasticSoilModel = stochasticSoilModel2, - StochasticSoilProfile = stochasticSoilProfile2, - SelectedHydraulicBoundaryLocation = new SelectableHydraulicBoundaryLocation( - TestHydraulicBoundaryLocation.CreateDesignWaterLevelCalculated(assessmentLevel), null) - }; + [Test] + [TestCase(true)] + [TestCase(false)] + public void SetExitPointL_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + { + SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.ExitPointL = new Random(21).NextRoundedDouble()); + } - // Assert - Assert.AreEqual(assessmentLevel, inputParameters.AssessmentLevel, inputParameters.AssessmentLevel.GetAccuracy()); - - Assert.AreEqual(dampingFactorExit.Mean, inputParameters.DampingFactorExit.Mean, - inputParameters.DampingFactorExit.GetAccuracy()); - Assert.AreEqual(dampingFactorExit.StandardDeviation, inputParameters.DampingFactorExit.StandardDeviation, - inputParameters.DampingFactorExit.GetAccuracy()); - - Assert.AreEqual(phreaticLevelExit.Mean, inputParameters.PhreaticLevelExit.Mean, - inputParameters.PhreaticLevelExit.GetAccuracy()); - Assert.AreEqual(phreaticLevelExit.StandardDeviation, inputParameters.PhreaticLevelExit.StandardDeviation, - inputParameters.PhreaticLevelExit.GetAccuracy()); - - Assert.AreEqual(surfaceLine, inputParameters.SurfaceLine); - Assert.AreEqual(stochasticSoilModel2, inputParameters.StochasticSoilModel); - Assert.AreEqual(stochasticSoilProfile2, inputParameters.StochasticSoilModel.StochasticSoilProfiles.First()); - - mocks.VerifyAll(); + [Test] + [TestCase(true)] + [TestCase(false)] + public void SetUseCustomAssessmentLevel_WithOrWithoutOutput_HasOutputFalseInputNotifiedAndCalculationNotifiedWhenHadOutput(bool hasOutput) + { + SetPropertyAndVerifyNotifcationsAndOutput(hasOutput, properties => properties.UseAssessmentLevelManualInput = true); } [Test] @@ -1607,6 +1642,148 @@ mocks.VerifyAll(); } + [Test] + [TestCase(true)] + [TestCase(false)] + public void DynamicReadOnlyValidationMethod_AssessmentLevel_DependsOnUseCustomAssessmentLevel(bool useCustomAssessmentLevel) + { + // Setup + var mocks = new MockRepository(); + var assessmentSection = 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 + { + Data = context + }; + + calculation.InputParameters.UseAssessmentLevelManualInput = useCustomAssessmentLevel; + + // Call + var result = properties.DynamicReadOnlyValidationMethod("AssessmentLevel"); + + // Assert + Assert.AreNotEqual(useCustomAssessmentLevel, result); + } + + [Test] + public void DynamicReadOnlyValidationMethod_AnyOtherProperty_ReturnsTrue() + { + // Setup + var properties = new PipingInputContextProperties(); + + // Call + var result = properties.DynamicReadOnlyValidationMethod("prop"); + + // Assert + Assert.IsTrue(result); + } + + [Test] + [TestCase(true)] + [TestCase(false)] + public void DynamicVisibleValidationMethod_SelectedHydraulicBoundaryLocation_DependsOnUseCustomAssessmentLevel(bool useCustomAssessmentLevel) + { + // Setup + var mocks = new MockRepository(); + var assessmentSection = 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 + { + Data = context + }; + + calculation.InputParameters.UseAssessmentLevelManualInput = useCustomAssessmentLevel; + + // Call + var result = properties.DynamicVisibleValidationMethod("SelectedHydraulicBoundaryLocation"); + + // Assert + Assert.AreNotEqual(useCustomAssessmentLevel, result); + } + + [Test] + public void DynamicVisibleValidationMethod_AnyOtherProperty_ReturnsFalse() + { + // Setup + var properties = new PipingInputContextProperties(); + + // 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, + Action setProperty, + PipingCalculationScenario calculation) + { + // Setup + var mocks = new MockRepository(); + var assessmentSection = mocks.Stub(); + var calculationObserver = mocks.StrictMock(); + var inputObserver = mocks.StrictMock(); + int numberOfChangedProperties = hasOutput ? 1 : 0; + calculationObserver.Expect(o => o.UpdateObserver()).Repeat.Times(numberOfChangedProperties); + inputObserver.Expect(o => o.UpdateObserver()); + mocks.ReplayAll(); + + PipingCalculationScenario calculationItem = calculation; + if (hasOutput) + { + calculationItem.Output = new TestPipingOutput(); + } + PipingFailureMechanism failureMechanism = new PipingFailureMechanism(); + + PipingInput inputParameters = calculationItem.InputParameters; + calculationItem.Attach(calculationObserver); + inputParameters.Attach(inputObserver); + + Random random = new Random(22); + + // Call + var pipingInputContext = new PipingInputContext(inputParameters, + calculationItem, + Enumerable.Empty(), + Enumerable.Empty(), + failureMechanism, + assessmentSection); + + PipingInputContextProperties properties = new PipingInputContextProperties(); + properties.Data = pipingInputContext; + setProperty(properties); + + // Assert + Assert.IsFalse(calculationItem.HasOutput); + + mocks.VerifyAll(); + } + private static StochasticSoilModel ValidStochasticSoilModel(double xMin, double xMax) { StochasticSoilModel stochasticSoilModel = new StochasticSoilModel(0, "StochasticSoilModelName", "StochasticSoilModelSegmentName");