Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModel.cs =================================================================== diff -u -r1b6b6e221ac583d9d24ec033972acf73ffe30c56 -rc1e57c344103b0219edc5bb853da2a0ca5c41877 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModel.cs (.../StochasticSoilModel.cs) (revision 1b6b6e221ac583d9d24ec033972acf73ffe30c56) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModel.cs (.../StochasticSoilModel.cs) (revision c1e57c344103b0219edc5bb853da2a0ca5c41877) @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Core.Common.Base; using Core.Common.Base.Geometry; namespace Ringtoets.Piping.Data @@ -30,7 +31,7 @@ /// This class represents a stochastic soil model which consists out of a collection of . /// A stochastic soil model contains a segment for which the model applies. /// - public class StochasticSoilModel + public class StochasticSoilModel : Observable { /// /// Creates a new instance of . Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateDataStrategy.cs =================================================================== diff -u -ra9ab2d906323a908ed5e7a245b5813380776961a -rc1e57c344103b0219edc5bb853da2a0ca5c41877 --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateDataStrategy.cs (.../StochasticSoilModelUpdateDataStrategy.cs) (revision a9ab2d906323a908ed5e7a245b5813380776961a) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateDataStrategy.cs (.../StochasticSoilModelUpdateDataStrategy.cs) (revision c1e57c344103b0219edc5bb853da2a0ca5c41877) @@ -23,6 +23,7 @@ using System.Collections.Generic; using System.Linq; using Core.Common.Base; +using Core.Common.Utils; using Ringtoets.Piping.Data; using Ringtoets.Piping.Plugin.Properties; using Ringtoets.Piping.Service; @@ -103,17 +104,18 @@ List updatedModels = GetUpdatedExistingModels(targetCollection, readModelList).ToList(); List removedModels = GetRemovedExistingModels(targetCollection, readModelList).ToList(); - var affectedObjects = new List + var affectedObjects = new List(); + if (addedModels.Any()) { - targetCollection - }; + affectedObjects.Add(targetCollection); + } affectedObjects.AddRange(UpdateModels(updatedModels, readModelList)); affectedObjects.AddRange(RemoveModels(removedModels)); targetCollection.Clear(); targetCollection.AddRange(addedModels.Union(updatedModels), sourceFilePath); - return affectedObjects; + return affectedObjects.Distinct(new ReferenceEqualityComparer()); } private static IEnumerable GetAddedReadModels(IEnumerable existingCollection, IEnumerable readStochasticSoilModels) @@ -147,6 +149,7 @@ var affectedObjects = new List(); foreach (StochasticSoilModel updatedModel in updatedModels) { + affectedObjects.Add(updatedModel); StochasticSoilModel readModel = readModels.Single(r => r.Name.Equals(updatedModel.Name)); affectedObjects.AddRange(UpdateStochasticSoilModel(updatedModel, readModel)); } Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj =================================================================== diff -u -rf4efcc2bb58d597f4a19884d98d0ab79bab04b1c -rc1e57c344103b0219edc5bb853da2a0ca5c41877 --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj (.../Ringtoets.Piping.Plugin.csproj) (revision f4efcc2bb58d597f4a19884d98d0ab79bab04b1c) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj (.../Ringtoets.Piping.Plugin.csproj) (revision c1e57c344103b0219edc5bb853da2a0ca5c41877) @@ -103,6 +103,11 @@ Core.Common.IO False + + {F49BD8B2-332A-4C91-A196-8CCE0A2C7D98} + Core.Common.Utils + False + {2465cca1-c505-4827-9454-4fd5fd9194cd} Core.Components.Charting.Forms Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelTest.cs =================================================================== diff -u -r5e70f173b3839314912e086b6c1c784b975ee646 -rc1e57c344103b0219edc5bb853da2a0ca5c41877 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelTest.cs (.../StochasticSoilModelTest.cs) (revision 5e70f173b3839314912e086b6c1c784b975ee646) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelTest.cs (.../StochasticSoilModelTest.cs) (revision c1e57c344103b0219edc5bb853da2a0ca5c41877) @@ -20,6 +20,7 @@ // All rights reserved. using System; +using Core.Common.Base; using Core.Common.Base.Geometry; using NUnit.Framework; using Rhino.Mocks; @@ -40,7 +41,7 @@ StochasticSoilModel stochasticSoilModelSegment = new StochasticSoilModel(segmentSoilModelId, segmentSoilModelName, segmentName); // Assert - Assert.IsInstanceOf(stochasticSoilModelSegment); + Assert.IsInstanceOf(stochasticSoilModelSegment); Assert.AreEqual(segmentSoilModelId, stochasticSoilModelSegment.Id); Assert.AreEqual(segmentSoilModelName, stochasticSoilModelSegment.Name); Assert.AreEqual(segmentName, stochasticSoilModelSegment.SegmentName); Index: Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataStrategyTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataStrategyTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataStrategyTest.cs (revision c1e57c344103b0219edc5bb853da2a0ca5c41877) @@ -0,0 +1,427 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Core.Common.Base; +using NUnit.Framework; +using Ringtoets.Piping.Data; +using Ringtoets.Piping.Data.TestUtil; +using Ringtoets.Piping.KernelWrapper.TestUtil; +using Ringtoets.Piping.Plugin.FileImporter; +using Ringtoets.Piping.Primitives; + +namespace Ringtoets.Piping.Plugin.Test.FileImporter +{ + [TestFixture] + public class StochasticSoilModelUpdateDataStrategyTest + { + private const string sourceFilePath = "path"; + + [Test] + public void Constructor_WithoutCalculations_CreatesNewInstance() + { + // Call + TestDelegate test = () => new StochasticSoilModelUpdateDataStrategy(null); + + // Assert + string paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("failureMechanism", paramName); + } + + [Test] + public void Constructor_WithCalculations_CreatesNewInstance() + { + // Call + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + + // Assert + Assert.IsInstanceOf(strategy); + } + + [Test] + public void UpdateModelWithImportedData_ReadStochasticSoilModelsNull_ThrowsArgumentNullException() + { + // Setup + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + + // Call + TestDelegate test = () => strategy.UpdateModelWithImportedData(new StochasticSoilModelCollection(), null, string.Empty); + + // Assert + string paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("readStochasticSoilModels", paramName); + } + + [Test] + public void UpdateModelWithImportedData_SourceFilePathNull_ThrowsArgumentNullException() + { + // Setup + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + + // Call + TestDelegate test = () => strategy.UpdateModelWithImportedData(new StochasticSoilModelCollection(), new List(), null); + + // Assert + string paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("sourceFilePath", paramName); + } + + [Test] + public void UpdateModelWithImportedData_TargetCollectionNull_ThrowsArgumentNullException() + { + // Setup + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + + // Call + TestDelegate test = () => strategy.UpdateModelWithImportedData(null, new List(), string.Empty); + + // Assert + string paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("targetCollection", paramName); + } + + [Test] + public void UpdateModelWithImportedData_WithCurrentModelsAndImportedMultipleModelsWithSameName_ThrowsInvalidOperationException() + { + // Setup + const string nonUniqueName = "non-unique name"; + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + new TestStochasticSoilModel(nonUniqueName) + }, sourceFilePath); + + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + var importedStochasticSoilModels = new[] + { + new TestStochasticSoilModel(nonUniqueName), + new TestStochasticSoilModel(nonUniqueName) + }; + + // Call + TestDelegate test = () => strategy.UpdateModelWithImportedData(targetCollection, importedStochasticSoilModels, sourceFilePath); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("Het bijwerken van de stochastische ondrgrondmodellen is mislukt.", exception.Message); + Assert.IsInstanceOf(exception.InnerException); + } + + [Test] + public void UpdateModelWithImportedData_WithoutCurrentModelAndModelsImported_NewModelsAdded() + { + // Setup + var importedStochasticSoilModels = new[] + { + new TestStochasticSoilModel("A"), + new TestStochasticSoilModel("B") + }; + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + var targetCollection = new StochasticSoilModelCollection(); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData(targetCollection, importedStochasticSoilModels, "path"); + + // Assert + CollectionAssert.AreEqual(importedStochasticSoilModels, targetCollection); + CollectionAssert.AreEqual(new[] + { + targetCollection + }, affectedObjects); + } + + [Test] + public void UpdateModelWithImportedData_WithCurrentModelsAndImportedDataEmpty_ModelsRemoved() + { + // Setup + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + new TestStochasticSoilModel(), + new TestStochasticSoilModel() + }, sourceFilePath); + + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData(targetCollection, new List(), sourceFilePath); + + // Assert + CollectionAssert.IsEmpty(targetCollection); + CollectionAssert.AreEqual(new[] + { + targetCollection + }, affectedObjects); + } + + [Test] + public void UpdateModelWithImportedData_WithCurrentModelAndImportedModelWithOtherName_ModelReplaced() + { + // Setup + var existingModel = new TestStochasticSoilModel("existing"); + + var pipingFailureMechanism = new PipingFailureMechanism(); + pipingFailureMechanism.StochasticSoilModels.AddRange(new[] + { + existingModel, + }, sourceFilePath); + var strategy = new StochasticSoilModelUpdateDataStrategy(pipingFailureMechanism); + var readModel = new TestStochasticSoilModel("read"); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData( + pipingFailureMechanism.StochasticSoilModels, + new[] + { + readModel + }, sourceFilePath); + + // Assert + Assert.AreSame(readModel, pipingFailureMechanism.StochasticSoilModels[0]); + CollectionAssert.AreEqual(new[] + { + pipingFailureMechanism.StochasticSoilModels + }, affectedObjects); + } + + [Test] + public void UpdateModelWithImportedData_WithCurrentModelAndImportedModelWithSameName_ModelUpdated() + { + // Setup + var modelsName = "same model"; + var existingModel = new TestStochasticSoilModel(modelsName); + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + existingModel, + }, sourceFilePath); + + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + var readModel = new TestStochasticSoilModel(modelsName); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData(targetCollection, new[] + { + readModel + }, sourceFilePath); + + // Assert + Assert.AreEqual(1, targetCollection.Count); + Assert.AreSame(existingModel, targetCollection[0]); + CollectionAssert.AreEquivalent(new[] + { + existingModel + }, affectedObjects); + } + + [Test] + public void UpdateModelWithImportedData_UpdateCurrentModelWithImportedModelWithOtherProfiles_ProfilesAdded() + { + // Setup + var modelsName = "same model"; + var existingModel = new TestStochasticSoilModel(modelsName); + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + existingModel, + }, sourceFilePath); + + var strategy = new StochasticSoilModelUpdateDataStrategy(new PipingFailureMechanism()); + StochasticSoilModel readModel = CreateSimpleModel(modelsName, "new profile A", "new profile B"); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData(targetCollection, new[] + { + readModel + }, sourceFilePath); + + // Assert + Assert.AreEqual(1, targetCollection.Count); + Assert.AreSame(existingModel, targetCollection[0]); + Assert.AreEqual(2, targetCollection[0].StochasticSoilProfiles.Count); + CollectionAssert.AreEquivalent(new IObservable[] + { + existingModel + }, affectedObjects); + } + + [Test] + public void UpdateModelWithImportedData_ProfilesAssignedToCalculationsWithOneImportedModelProfileRemoved_OneProfileRemovedCalculationUpdatedAccordingly() + { + // Setup + var modelsName = "same model"; + var existingModel = new TestStochasticSoilModel(modelsName); + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + existingModel, + }, sourceFilePath); + + StochasticSoilProfile firstExistingProfile = existingModel.StochasticSoilProfiles[0]; + StochasticSoilModel readModel = CreateSimpleModel(modelsName, firstExistingProfile.SoilProfile.Name); + + var calculationWithNotUpdatedProfile = new PipingCalculationScenario(new GeneralPipingInput()); + calculationWithNotUpdatedProfile.InputParameters.StochasticSoilModel = existingModel; + calculationWithNotUpdatedProfile.InputParameters.StochasticSoilProfile = existingModel.StochasticSoilProfiles[0]; + calculationWithNotUpdatedProfile.Output = new PipingOutput(new PipingOutput.ConstructionProperties()); + + var calculationWithDeletedProfile = new PipingCalculationScenario(new GeneralPipingInput()); + calculationWithDeletedProfile.InputParameters.StochasticSoilModel = existingModel; + calculationWithDeletedProfile.InputParameters.StochasticSoilProfile = existingModel.StochasticSoilProfiles[1]; + calculationWithDeletedProfile.Output = new PipingOutput(new PipingOutput.ConstructionProperties()); + + var failureMechanism = new PipingFailureMechanism(); + failureMechanism.CalculationsGroup.Children.Add(calculationWithDeletedProfile); + failureMechanism.CalculationsGroup.Children.Add(calculationWithNotUpdatedProfile); + + var strategy = new StochasticSoilModelUpdateDataStrategy(failureMechanism); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData(targetCollection, new[] + { + readModel + }, sourceFilePath).ToArray(); + + // Assert + StochasticSoilModel firstSoilModel = targetCollection[0]; + Assert.AreSame(existingModel, firstSoilModel); + Assert.AreEqual(1, firstSoilModel.StochasticSoilProfiles.Count); + Assert.AreSame(firstExistingProfile, firstSoilModel.StochasticSoilProfiles[0]); + + Assert.IsTrue(calculationWithNotUpdatedProfile.HasOutput); + CollectionAssert.DoesNotContain(affectedObjects, calculationWithNotUpdatedProfile); + CollectionAssert.DoesNotContain(affectedObjects, calculationWithNotUpdatedProfile.InputParameters); + + Assert.IsFalse(calculationWithDeletedProfile.HasOutput); + Assert.IsNull(calculationWithDeletedProfile.InputParameters.StochasticSoilProfile); + CollectionAssert.Contains(affectedObjects, calculationWithDeletedProfile); + CollectionAssert.Contains(affectedObjects, calculationWithDeletedProfile.InputParameters); + } + + [Test] + public void UpdateModelWithImportedData_ProfilesAssignedToCalculationsOneWithNoChangeInProfile_OnlyCalculationWithChangedProfileUpdated() + { + // Setup + var modelsName = "same model"; + var existingModel = new TestStochasticSoilModel(modelsName); + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + existingModel, + }, sourceFilePath); + + StochasticSoilModel readModel = new TestStochasticSoilModel(modelsName); + StochasticSoilProfile changedProfile = CloneAndSlightlyModify(readModel.StochasticSoilProfiles.ElementAt(0)); + readModel.StochasticSoilProfiles.RemoveAt(0); + readModel.StochasticSoilProfiles.Add(changedProfile); + + var calculationWithUpdatedProfile = new PipingCalculationScenario(new GeneralPipingInput()); + calculationWithUpdatedProfile.InputParameters.StochasticSoilModel = existingModel; + calculationWithUpdatedProfile.InputParameters.StochasticSoilProfile = existingModel.StochasticSoilProfiles[0]; + calculationWithUpdatedProfile.Output = new PipingOutput(new PipingOutput.ConstructionProperties()); + + var calculationWithNotUpdatedProfile = new PipingCalculationScenario(new GeneralPipingInput()); + calculationWithNotUpdatedProfile.InputParameters.StochasticSoilModel = existingModel; + calculationWithNotUpdatedProfile.InputParameters.StochasticSoilProfile = existingModel.StochasticSoilProfiles[1]; + calculationWithNotUpdatedProfile.Output = new PipingOutput(new PipingOutput.ConstructionProperties()); + + var failureMechanism = new PipingFailureMechanism(); + failureMechanism.CalculationsGroup.Children.Add(calculationWithNotUpdatedProfile); + failureMechanism.CalculationsGroup.Children.Add(calculationWithUpdatedProfile); + + var strategy = new StochasticSoilModelUpdateDataStrategy(failureMechanism); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData(targetCollection, new[] + { + readModel + }, sourceFilePath).ToArray(); + + // Assert + StochasticSoilModel firstSoilModel = targetCollection[0]; + Assert.AreSame(existingModel, firstSoilModel); + Assert.AreEqual(2, firstSoilModel.StochasticSoilProfiles.Count); + Assert.AreSame(existingModel.StochasticSoilProfiles[0], firstSoilModel.StochasticSoilProfiles[0]); + Assert.AreSame(existingModel.StochasticSoilProfiles[1], firstSoilModel.StochasticSoilProfiles[1]); + + Assert.IsFalse(calculationWithUpdatedProfile.HasOutput); + Assert.AreSame(existingModel.StochasticSoilProfiles[0], calculationWithUpdatedProfile.InputParameters.StochasticSoilProfile); + CollectionAssert.Contains(affectedObjects, calculationWithUpdatedProfile); + CollectionAssert.Contains(affectedObjects, calculationWithUpdatedProfile.InputParameters); + + Assert.IsTrue(calculationWithNotUpdatedProfile.HasOutput); + Assert.AreSame(existingModel.StochasticSoilProfiles[1], calculationWithNotUpdatedProfile.InputParameters.StochasticSoilProfile); + CollectionAssert.DoesNotContain(affectedObjects, calculationWithNotUpdatedProfile); + CollectionAssert.DoesNotContain(affectedObjects, calculationWithNotUpdatedProfile.InputParameters); + } + + [Test] + public void UpdateModelWithImportedData_CalculationWithOutputAssignedRemovedSoilModelAndProfile_CalculationUpdatedAndCalculationAndInputReturned() + { + // Setup + var existingModel = new TestStochasticSoilModel(); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + calculation.InputParameters.StochasticSoilModel = existingModel; + calculation.InputParameters.StochasticSoilProfile = existingModel.StochasticSoilProfiles[0]; + calculation.Output = new PipingOutput(new PipingOutput.ConstructionProperties()); + + var failureMechanism = new PipingFailureMechanism(); + failureMechanism.CalculationsGroup.Children.Add(calculation); + + var strategy = new StochasticSoilModelUpdateDataStrategy(failureMechanism); + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + existingModel, + }, sourceFilePath); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData(targetCollection, new List(), sourceFilePath).ToArray(); + + // Assert + Assert.IsFalse(calculation.HasOutput); + Assert.IsNull(calculation.InputParameters.StochasticSoilModel); + Assert.IsNull(calculation.InputParameters.StochasticSoilProfile); + CollectionAssert.Contains(affectedObjects, calculation); + CollectionAssert.Contains(affectedObjects, calculation.InputParameters); + } + + /// + /// Creates a simple model with names for the model and profiles in the model set as specified. + /// + /// Name of the created model. + /// List of names for the profiles to be added to the model. + /// A new . + private StochasticSoilModel CreateSimpleModel(string modelName, params string[] profileNames) + { + var model = new StochasticSoilModel(-1, modelName, "segment name"); + foreach (string profileName in profileNames) + { + model.StochasticSoilProfiles.Add( + new StochasticSoilProfile(1.0 / profileNames.Length, SoilProfileType.SoilProfile1D, -1) + { + SoilProfile = new TestPipingSoilProfile(profileName) + }); + } + return model; + } + + private StochasticSoilProfile CloneAndSlightlyModify(StochasticSoilProfile profile) + { + return new StochasticSoilProfile(profile.Probability, profile.SoilProfileType, profile.SoilProfileId) + { + SoilProfile = new PipingSoilProfile( + profile.SoilProfile.Name, + profile.SoilProfile.Bottom - 0.2, + profile.SoilProfile.Layers, + profile.SoilProfile.SoilProfileType, + profile.SoilProfile.PipingSoilProfileId) + }; + } + } +} \ No newline at end of file Fisheye: Tag c1e57c344103b0219edc5bb853da2a0ca5c41877 refers to a dead (removed) revision in file `Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj =================================================================== diff -u -rf4efcc2bb58d597f4a19884d98d0ab79bab04b1c -rc1e57c344103b0219edc5bb853da2a0ca5c41877 --- Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj (.../Ringtoets.Piping.Plugin.Test.csproj) (revision f4efcc2bb58d597f4a19884d98d0ab79bab04b1c) +++ Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj (.../Ringtoets.Piping.Plugin.Test.csproj) (revision c1e57c344103b0219edc5bb853da2a0ca5c41877) @@ -76,7 +76,7 @@ - +