Index: Demo/Ringtoets/src/Demo.Ringtoets/Commands/AddNewDemoAssessmentSectionCommand.cs =================================================================== diff -u -rce9e1d476f00cfb42ce2a8ab6c762baf5abfd97b -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Demo/Ringtoets/src/Demo.Ringtoets/Commands/AddNewDemoAssessmentSectionCommand.cs (.../AddNewDemoAssessmentSectionCommand.cs) (revision ce9e1d476f00cfb42ce2a8ab6c762baf5abfd97b) +++ Demo/Ringtoets/src/Demo.Ringtoets/Commands/AddNewDemoAssessmentSectionCommand.cs (.../AddNewDemoAssessmentSectionCommand.cs) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -536,7 +536,7 @@ using (var embeddedResourceFileWriter = new EmbeddedResourceFileWriter(GetType().Assembly, true, "DR6.soil")) { - var soilProfilesImporter = new PipingSoilProfilesImporter(pipingFailureMechanism.StochasticSoilModels, + var soilProfilesImporter = new StochasticSoilModelImporter(pipingFailureMechanism.StochasticSoilModels, Path.Combine(embeddedResourceFileWriter.TargetFolderPath, "DR6.soil")); soilProfilesImporter.Import(); Index: Ringtoets/Integration/test/Ringtoets.Integration.TestUtils/DataImportHelper.cs =================================================================== diff -u -rce9e1d476f00cfb42ce2a8ab6c762baf5abfd97b -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Integration/test/Ringtoets.Integration.TestUtils/DataImportHelper.cs (.../DataImportHelper.cs) (revision ce9e1d476f00cfb42ce2a8ab6c762baf5abfd97b) +++ Ringtoets/Integration/test/Ringtoets.Integration.TestUtils/DataImportHelper.cs (.../DataImportHelper.cs) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -204,8 +204,8 @@ "DR6.soil")) { string filePath = Path.Combine(embeddedResourceFileWriter.TargetFolderPath, "DR6.soil"); - var activity = new FileImportActivity(new PipingSoilProfilesImporter(assessmentSection.PipingFailureMechanism.StochasticSoilModels, filePath), - "PipingSoilProfilesImporter"); + var activity = new FileImportActivity(new StochasticSoilModelImporter(assessmentSection.PipingFailureMechanism.StochasticSoilModels, filePath), + "StochasticSoilModelImporter"); activity.Run(); activity.Finish(); } Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingFailureMechanism.cs =================================================================== diff -u -r62d6426f4dc874b8e74a0c3ebe4c3491fa207af1 -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingFailureMechanism.cs (.../PipingFailureMechanism.cs) (revision 62d6426f4dc874b8e74a0c3ebe4c3491fa207af1) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingFailureMechanism.cs (.../PipingFailureMechanism.cs) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -45,7 +45,7 @@ PipingProbabilityAssessmentInput = new PipingProbabilityAssessmentInput(); GeneralInput = new GeneralPipingInput(); SurfaceLines = new ObservableList(); - StochasticSoilModels = new ObservableList(); + StochasticSoilModels = new StochasticSoilModelCollection(); CalculationsGroup = new CalculationGroup(RingtoetsCommonDataResources.FailureMechanism_Calculations_DisplayName, false); sectionResults = new List(); @@ -67,7 +67,7 @@ /// /// Gets the available stochastic soil models within the scope of the piping failure mechanism. /// - public ObservableList StochasticSoilModels { get; private set; } + public StochasticSoilModelCollection StochasticSoilModels { get; private set; } /// /// Gets the general piping calculation input parameters that apply to each piping calculation. Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj =================================================================== diff -u -r23d1e296e2da4364fbfe346e68d582dfcf966bb0 -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj (.../Ringtoets.Piping.Data.csproj) (revision 23d1e296e2da4364fbfe346e68d582dfcf966bb0) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj (.../Ringtoets.Piping.Data.csproj) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -66,6 +66,7 @@ + Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModelCollection.cs =================================================================== diff -u --- Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModelCollection.cs (revision 0) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModelCollection.cs (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -0,0 +1,37 @@ +// Copyright (C) Stichting Deltares 2016. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using Core.Common.Base; + +namespace Ringtoets.Piping.Data +{ + /// + /// A collection of that was imported from a file. + /// + public class StochasticSoilModelCollection : ObservableList + { + /// + /// Gets the last known file path from which the + /// elements were imported. + /// + public string LastKnownFilePath { get; set; } + } +} \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/PresentationObjects/StochasticSoilModelsContext.cs =================================================================== diff -u -r065af7e201b59ec19a17c42e9d772f5e86b31338 -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/PresentationObjects/StochasticSoilModelsContext.cs (.../StochasticSoilModelsContext.cs) (revision 065af7e201b59ec19a17c42e9d772f5e86b31338) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/PresentationObjects/StochasticSoilModelsContext.cs (.../StochasticSoilModelsContext.cs) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -30,7 +30,7 @@ /// /// The presentation object for . /// - public class StochasticSoilModelsContext : ObservableWrappedObjectContextBase> + public class StochasticSoilModelsContext : ObservableWrappedObjectContextBase { /// /// Creates a new instance of . @@ -39,19 +39,19 @@ /// The failure mechanism. /// The assessment section. /// Thrown when any input argument is null. - public StochasticSoilModelsContext(ObservableList wrappedStochasticSoilModels, + public StochasticSoilModelsContext(StochasticSoilModelCollection wrappedStochasticSoilModels, PipingFailureMechanism failureMechanism, IAssessmentSection assessmentSection) : base(wrappedStochasticSoilModels) { if (failureMechanism == null) { - throw new ArgumentNullException("failureMechanism"); + throw new ArgumentNullException(nameof(failureMechanism)); } if (assessmentSection == null) { - throw new ArgumentNullException("assessmentSection"); + throw new ArgumentNullException(nameof(assessmentSection)); } FailureMechanism = failureMechanism; Fisheye: Tag 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 refers to a dead (removed) revision in file `Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/PipingSoilProfilesImporter.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelImporter.cs =================================================================== diff -u --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelImporter.cs (revision 0) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelImporter.cs (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -0,0 +1,281 @@ +// Copyright (C) Stichting Deltares 2016. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using Core.Common.Base; +using Core.Common.Base.IO; +using Core.Common.IO.Exceptions; +using Core.Common.IO.Readers; +using log4net; +using Ringtoets.Piping.Data; +using Ringtoets.Piping.IO.Exceptions; +using Ringtoets.Piping.IO.SoilProfile; +using Ringtoets.Piping.Primitives; +using Ringtoets.Piping.Plugin.Properties; +using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; + +namespace Ringtoets.Piping.Plugin.FileImporter +{ + /// + /// Imports .soil files (SqlLite database files) created with the D-Soil Model application. + /// + public class StochasticSoilModelImporter : FileImporterBase + { + private readonly ILog log = LogManager.GetLogger(typeof(StochasticSoilModelImporter)); + + /// + /// Initializes a new instance of the class. + /// + /// The collection to update. + /// The path to the file to import from. + /// Thrown when is null. + public StochasticSoilModelImporter(StochasticSoilModelCollection importTarget, string filePath) + : base(filePath, importTarget) {} + + protected override bool OnImport() + { + var importSoilProfileResult = ReadSoilProfiles(); + if (importSoilProfileResult.CriticalErrorOccurred || Canceled) + { + return false; + } + + var importStochasticSoilModelResult = ReadStochasticSoilModels(); + if (importStochasticSoilModelResult.CriticalErrorOccurred || Canceled) + { + return false; + } + + AddSoilProfilesToStochasticSoilModels(importSoilProfileResult.ImportedItems, importStochasticSoilModelResult.ImportedItems); + CheckIfAllProfilesAreUsed(importSoilProfileResult.ImportedItems, importStochasticSoilModelResult.ImportedItems); + if (Canceled) + { + return false; + } + + AddImportedDataToModel(importStochasticSoilModelResult.ImportedItems); + return true; + } + + protected override void LogImportCanceledMessage() + { + log.Info(Resources.PipingSoilProfilesImporter_Import_Import_canceled); + } + + private void AddSoilProfilesToStochasticSoilModels(ICollection soilProfiles, ICollection stochasticSoilModels) + { + foreach (var stochasticSoilModel in stochasticSoilModels) + { + foreach (var stochasticSoilProfile in stochasticSoilModel.StochasticSoilProfiles) + { + var soilProfile = soilProfiles.FirstOrDefault(s => s.SoilProfileType == stochasticSoilProfile.SoilProfileType && s.PipingSoilProfileId == stochasticSoilProfile.SoilProfileId); + if (soilProfile != null) + { + stochasticSoilProfile.SoilProfile = soilProfile; + } + } + } + } + + private void CheckIfAllProfilesAreUsed(ICollection soilProfiles, ICollection stochasticSoilModels) + { + NotifyProgress(Resources.PipingSoilProfilesImporter_CheckIfAllProfilesAreUsed_Start_checking_soil_profiles, 1, 1); + foreach (var soilProfile in soilProfiles.Where(soilProfile => !PipingSoilProfileIsUsed(soilProfile, stochasticSoilModels))) + { + log.WarnFormat(Resources.PipingSoilProfilesImporter_CheckIfAllProfilesAreUsed_SoilProfile_0_is_not_used_in_any_stochastic_soil_model, soilProfile.Name); + } + } + + private static bool PipingSoilProfileIsUsed(PipingSoilProfile soilProfile, ICollection stochasticSoilModels) + { + return stochasticSoilModels.Any(stochasticSoilModel => stochasticSoilModel.StochasticSoilProfiles.Any(stochasticSoilProfile => stochasticSoilProfile.SoilProfile == soilProfile)); + } + + private void AddImportedDataToModel(ICollection readStochasticSoilModels) + { + var stochasticSoilModelCount = readStochasticSoilModels.Count; + var currentIndex = 1; + foreach (var readStochasticSoilModel in readStochasticSoilModels) + { + NotifyProgress(RingtoetsCommonIOResources.Importer_ProgressText_Adding_imported_data_to_DataModel, currentIndex++, stochasticSoilModelCount); + if (!ValidateStochasticSoilModel(readStochasticSoilModel)) + { + continue; + } + var stochasticSoilModel = ImportTarget.FirstOrDefault(ssm => ssm.Id == readStochasticSoilModel.Id); + if (stochasticSoilModel != null) + { + log.WarnFormat(Resources.PipingSoilProfilesImporter_AddImportedDataToModel_Stochastisch_soil_model_0_already_exists, stochasticSoilModel.Name); + } + ImportTarget.Add(readStochasticSoilModel); + } + ImportTarget.LastKnownFilePath = FilePath; + } + + private bool ValidateStochasticSoilModel(StochasticSoilModel stochasticSoilModel) + { + if (!stochasticSoilModel.StochasticSoilProfiles.Any()) + { + log.WarnFormat(Resources.PipingSoilProfilesImporter_ValidateStochasticSoilModel_No_profiles_found_in_stochastic_soil_model_0, + stochasticSoilModel.Name); + return false; + } + if (stochasticSoilModel.StochasticSoilProfiles.Any(ssp => ssp.SoilProfile == null)) + { + log.WarnFormat(Resources.PipingSoilProfilesImporter_ValidateStochasticSoilModel_SoilModel_0_with_stochastic_soil_profile_without_profile, + stochasticSoilModel.Name); + return false; + } + if (!IsSumOfAllProbabilitiesEqualToOne(stochasticSoilModel)) + { + log.WarnFormat(Resources.PipingSoilProfilesImporter_ValidateStochasticSoilModel_Sum_of_probabilities_of_stochastic_soil_model_0_is_not_correct, + stochasticSoilModel.Name); + } + return true; + } + + private static bool IsSumOfAllProbabilitiesEqualToOne(StochasticSoilModel stochasticSoilModel) + { + double sumOfAllScenarioProbabilities = stochasticSoilModel.StochasticSoilProfiles + .Where(s => s.SoilProfile != null) + .Sum(s => s.Probability); + return Math.Abs(sumOfAllScenarioProbabilities - 1.0) < 1e-6; + } + + private void HandleException(Exception e) + { + var message = string.Format(Resources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped, + e.Message); + log.Error(message); + } + + #region read stochastic soil models + + private ReadResult ReadStochasticSoilModels() + { + NotifyProgress(Resources.PipingSoilProfilesImporter_Reading_database, 1, 1); + try + { + using (var stochasticSoilModelReader = new StochasticSoilModelReader(FilePath)) + { + return GetStochasticSoilModelReadResult(stochasticSoilModelReader); + } + } + catch (CriticalFileReadException e) + { + HandleException(e); + } + return new ReadResult(true); + } + + private ReadResult GetStochasticSoilModelReadResult(StochasticSoilModelReader stochasticSoilModelReader) + { + var totalNumberOfSteps = stochasticSoilModelReader.PipingStochasticSoilModelCount; + var currentStep = 1; + + var soilModels = new Collection(); + while (stochasticSoilModelReader.HasNext) + { + if (Canceled) + { + return new ReadResult(false); + } + try + { + NotifyProgress(Resources.PipingSoilProfilesImporter_GetStochasticSoilModelReadResult_Reading_stochastic_soil_models_from_database, currentStep++, totalNumberOfSteps); + soilModels.Add(stochasticSoilModelReader.ReadStochasticSoilModel()); + } + catch (StochasticSoilProfileReadException e) + { + var message = string.Format(Resources.PipingSoilProfilesImporter_GetStochasticSoilModelReadResult_Error_0_stochastic_soil_model_skipped, e.Message); + log.Error(message); + } + } + return new ReadResult(false) + { + ImportedItems = soilModels + }; + } + + #endregion + + #region read soil profiles + + private ReadResult ReadSoilProfiles() + { + NotifyProgress(Resources.PipingSoilProfilesImporter_Reading_database, 1, 1); + try + { + using (var soilProfileReader = new PipingSoilProfileReader(FilePath)) + { + return GetProfileReadResult(soilProfileReader); + } + } + catch (CriticalFileReadException e) + { + HandleException(e); + } + return new ReadResult(true); + } + + private ReadResult GetProfileReadResult(PipingSoilProfileReader soilProfileReader) + { + var totalNumberOfSteps = soilProfileReader.Count; + var currentStep = 1; + + var profiles = new Collection(); + while (soilProfileReader.HasNext) + { + if (Canceled) + { + return new ReadResult(false); + } + try + { + NotifyProgress(Resources.PipingSoilProfilesImporter_ReadingSoilProfiles, currentStep++, totalNumberOfSteps); + profiles.Add(soilProfileReader.ReadProfile()); + } + catch (PipingSoilProfileReadException e) + { + var message = string.Format(Resources.PipingSoilProfilesImporter_ReadSoilProfiles_ParseErrorMessage_0_SoilProfile_skipped, + e.Message); + log.Error(message); + } + catch (CriticalFileReadException e) + { + var message = string.Format(Resources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped, + FilePath, e.Message); + log.Error(message); + return new ReadResult(true); + } + } + return new ReadResult(false) + { + ImportedItems = profiles + }; + } + + #endregion + } +} \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingPlugin.cs =================================================================== diff -u -r46a26eb2df5ad4a02467e43d8101027d5d8d42a5 -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingPlugin.cs (.../PipingPlugin.cs) (revision 46a26eb2df5ad4a02467e43d8101027d5d8d42a5) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingPlugin.cs (.../PipingPlugin.cs) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -84,9 +84,7 @@ Name = PipingFormsResources.PipingSurfaceLinesCollection_DisplayName, Category = RingtoetsCommonFormsResources.Ringtoets_Category, Image = PipingFormsResources.PipingSurfaceLineIcon, - FileFilter = string.Format("{0} {1}", - PipingFormsResources.PipingSurfaceLinesCollection_DisplayName, - RingtoetsCommonFormsResources.DataTypeDisplayName_csv_file_filter), + FileFilter = $"{PipingFormsResources.PipingSurfaceLinesCollection_DisplayName} {RingtoetsCommonFormsResources.DataTypeDisplayName_csv_file_filter}", IsEnabled = context => context.AssessmentSection.ReferenceLine != null, CreateFileImporter = (context, filePath) => new PipingSurfaceLinesCsvImporter(context.WrappedData, context.AssessmentSection.ReferenceLine, @@ -98,9 +96,9 @@ Name = PipingFormsResources.StochasticSoilModelCollection_DisplayName, Category = RingtoetsCommonFormsResources.Ringtoets_Category, Image = PipingFormsResources.PipingSoilProfileIcon, - FileFilter = string.Format("{0} (*.soil)|*.soil", PipingPluginResources.Soil_file_name), + FileFilter = $"{PipingPluginResources.Soil_file_name} (*.soil)|*.soil", IsEnabled = context => context.AssessmentSection.ReferenceLine != null, - CreateFileImporter = (context, filePath) => new PipingSoilProfilesImporter(context.WrappedData, + CreateFileImporter = (context, filePath) => new StochasticSoilModelImporter(context.WrappedData, filePath) }; } Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj =================================================================== diff -u -r05a4b5f35f68fcccf274c23bddfc05a4a7731919 -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj (.../Ringtoets.Piping.Plugin.csproj) (revision 05a4b5f35f68fcccf274c23bddfc05a4a7731919) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj (.../Ringtoets.Piping.Plugin.csproj) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -59,7 +59,7 @@ Properties\GlobalAssembly.cs - + Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj =================================================================== diff -u -r23d1e296e2da4364fbfe346e68d582dfcf966bb0 -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj (.../Ringtoets.Piping.Data.Test.csproj) (revision 23d1e296e2da4364fbfe346e68d582dfcf966bb0) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj (.../Ringtoets.Piping.Data.Test.csproj) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -75,6 +75,7 @@ + Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelCollectionTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelCollectionTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelCollectionTest.cs (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -0,0 +1,42 @@ +// Copyright (C) Stichting Deltares 2016. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using Core.Common.Base; +using NUnit.Framework; + +namespace Ringtoets.Piping.Data.Test +{ + [TestFixture] + public class StochasticSoilModelCollectionTest + { + + [Test] + public void DefaultConstructor_ReturnObservableStochasticSoilModelCollection() + { + // Call + var collection = new StochasticSoilModelCollection(); + + // Assert + Assert.IsInstanceOf>(collection); + Assert.IsNull(collection.LastKnownFilePath); + } + } +} \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PresentationObjects/StochasticSoilModelsContextTest.cs =================================================================== diff -u -rf05844909ef96f5e6ea721563a33d32e042ef5ce -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PresentationObjects/StochasticSoilModelsContextTest.cs (.../StochasticSoilModelsContextTest.cs) (revision f05844909ef96f5e6ea721563a33d32e042ef5ce) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PresentationObjects/StochasticSoilModelsContextTest.cs (.../StochasticSoilModelsContextTest.cs) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -20,7 +20,6 @@ // All rights reserved. using System; -using Core.Common.Base; using Core.Common.Controls.PresentationObjects; using NUnit.Framework; using Rhino.Mocks; @@ -47,7 +46,7 @@ var context = new StochasticSoilModelsContext(failureMechanism.StochasticSoilModels, failureMechanism, assessmentSectionMock); // Assert - Assert.IsInstanceOf>>(context); + Assert.IsInstanceOf>(context); Assert.AreSame(failureMechanism.StochasticSoilModels, context.WrappedData); Assert.AreSame(failureMechanism, context.FailureMechanism); Assert.AreSame(assessmentSectionMock, context.AssessmentSection); @@ -62,7 +61,7 @@ var assessmentSectionMock = mocks.StrictMock(); mocks.ReplayAll(); - var stochasticSoilModels = new ObservableList(); + var stochasticSoilModels = new StochasticSoilModelCollection(); // Call TestDelegate test = () => new StochasticSoilModelsContext(stochasticSoilModels, null, assessmentSectionMock); Index: Ringtoets/Piping/test/Ringtoets.Piping.Integration.Test/ImportSoilProfileFromDatabaseTest.cs =================================================================== diff -u -r587f6330c5876eb326e8bea5e82a3650866cc475 -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/test/Ringtoets.Piping.Integration.Test/ImportSoilProfileFromDatabaseTest.cs (.../ImportSoilProfileFromDatabaseTest.cs) (revision 587f6330c5876eb326e8bea5e82a3650866cc475) +++ Ringtoets/Piping/test/Ringtoets.Piping.Integration.Test/ImportSoilProfileFromDatabaseTest.cs (.../ImportSoilProfileFromDatabaseTest.cs) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -44,7 +44,7 @@ var pipingFailureMechanism = new PipingFailureMechanism(); // When - var importer = new PipingSoilProfilesImporter(pipingFailureMechanism.StochasticSoilModels, databasePath); + var importer = new StochasticSoilModelImporter(pipingFailureMechanism.StochasticSoilModels, databasePath); importer.Import(); // Then @@ -81,7 +81,7 @@ var pipingFailureMechanism = new PipingFailureMechanism(); // When - var importer = new PipingSoilProfilesImporter(pipingFailureMechanism.StochasticSoilModels, databasePath); + var importer = new StochasticSoilModelImporter(pipingFailureMechanism.StochasticSoilModels, databasePath); importer.Import(); // Then @@ -114,7 +114,7 @@ var pipingFailureMechanism = new PipingFailureMechanism(); // When - var importer = new PipingSoilProfilesImporter(pipingFailureMechanism.StochasticSoilModels, databasePath); + var importer = new StochasticSoilModelImporter(pipingFailureMechanism.StochasticSoilModels, databasePath); importer.Import(); // Then Fisheye: Tag 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 refers to a dead (removed) revision in file `Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/PipingSoilProfilesImporterTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelImporterTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelImporterTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelImporterTest.cs (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -0,0 +1,731 @@ +// Copyright (C) Stichting Deltares 2016. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Core.Common.Base.IO; +using Core.Common.TestUtil; +using Core.Common.Utils.Builders; +using NUnit.Framework; +using Ringtoets.Piping.Data; +using Ringtoets.Piping.Plugin.FileImporter; +using Ringtoets.Piping.Plugin.Properties; +using Ringtoets.Piping.Primitives; + +namespace Ringtoets.Piping.Plugin.Test.FileImporter +{ + [TestFixture] + public class StochasticSoilModelImporterTest + { + private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Piping.IO, "PipingSoilProfilesReader"); + private int progress; + + [SetUp] + public void SetUp() + { + progress = 0; + } + + [Test] + public void Constructor_ObservableListNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => new StochasticSoilModelImporter(null, ""); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("importTarget", paramName); + } + + [Test] + public void Constructor_ExpectedValues() + { + var list = new StochasticSoilModelCollection(); + + // Call + var importer = new StochasticSoilModelImporter(list, ""); + + // Assert + Assert.IsInstanceOf>(importer); + } + + [Test] + public void Import_FromNonExistingFile_LogError() + { + // Setup + var file = "nonexisting.soil"; + string validFilePath = Path.Combine(testDataPath, file); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged(IncrementProgress); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + + var importResult = true; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + TestHelper.AssertLogMessages(call, + messages => + { + string[] messageArray = messages.ToArray(); + var message = string.Format(Resources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped, string.Empty); + StringAssert.EndsWith(message, messageArray[0]); + }); + Assert.AreEqual(1, progress); + AssertUnsuccessfulImport(importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_FromInvalidFileName_LogError() + { + // Setup + var file = "/"; + string invalidFilePath = Path.Combine(testDataPath, file); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, invalidFilePath); + importer.SetProgressChanged(IncrementProgress); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + + var importResult = true; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + TestHelper.AssertLogMessages(call, + messages => + { + string[] messageArray = messages.ToArray(); + var message = string.Format(Resources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped, string.Empty); + StringAssert.EndsWith(message, messageArray[0]); + }); + Assert.AreEqual(1, progress); + AssertUnsuccessfulImport(importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_ImportingToValidTargetWithValidFile_ImportSoilModelToCollectionLastKnownFilePathSet() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "complete.soil"); + + var pipingFailureMechanism = new PipingFailureMechanism(); + + var progressChangeNotifications = new List(); + var importer = new StochasticSoilModelImporter(pipingFailureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged((description, step, steps) => progressChangeNotifications.Add(new ProgressNotification(description, step, steps))); + + // Call + var importResult = importer.Import(); + + // Assert + Assert.IsTrue(importResult); + Assert.AreEqual(validFilePath, pipingFailureMechanism.StochasticSoilModels.LastKnownFilePath); + var expectedProfiles = 26; + var expectedModels = 3; + + var expectedProgressMessages = new List + { + new ProgressNotification("Inlezen van de D-Soil Model database.", 1, 1) + }; + for (var i = 1; i <= expectedProfiles; i++) + { + expectedProgressMessages.Add(new ProgressNotification("Inlezen van de ondergrondschematisatie uit de D-Soil Model database.", i, expectedProfiles)); + } + expectedProgressMessages.Add(new ProgressNotification("Inlezen van de D-Soil Model database.", 1, 1)); + for (var i = 1; i <= expectedModels; i++) + { + expectedProgressMessages.Add(new ProgressNotification("Inlezen van de stochastische ondergrondmodellen.", i, expectedModels)); + } + expectedProgressMessages.Add(new ProgressNotification("Controleren van ondergrondschematisaties.", 1, 1)); + for (var i = 1; i <= expectedModels; i++) + { + expectedProgressMessages.Add(new ProgressNotification("Geïmporteerde data toevoegen aan het toetsspoor.", i, expectedModels)); + } + Assert.AreEqual(expectedProgressMessages.Count, progressChangeNotifications.Count); + for (var i = 0; i < expectedProgressMessages.Count; i++) + { + var notification = expectedProgressMessages[i]; + var actualNotification = progressChangeNotifications[i]; + Assert.AreEqual(notification.Text, actualNotification.Text); + Assert.AreEqual(notification.CurrentStep, actualNotification.CurrentStep); + Assert.AreEqual(notification.TotalSteps, actualNotification.TotalSteps); + } + } + + [Test] + public void Import_ImportingToValidTargetWithValidFileTwice_AddsSoilModelToCollectionLogWarning() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "complete.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged(IncrementProgress); + + var importResult = false; + + // Precondition + importer.Import(); + var alreadyImportedSoilModelNames = failureMechanism.StochasticSoilModels.Select(ssm => ssm.Name); + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + var expectedLogMessages = alreadyImportedSoilModelNames.Select(name => $"Het stochastische ondergrondmodel '{name}' bestaat al in het toetsspoor.").ToArray(); + TestHelper.AssertLogMessagesAreGenerated(call, expectedLogMessages, expectedLogMessages.Length); + Assert.AreEqual(35*2, progress); + + AssertSuccessfulImport(6, validFilePath, importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_CancelOfImportWhenReadingSoilProfiles_CancelsImportAndLogs() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "complete.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged((description, step, steps) => + { + if (description.Contains("Inlezen van de D-Soil Model database.")) + { + importer.Cancel(); + } + }); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + Assert.IsTrue(File.Exists(validFilePath)); + + var importResult = true; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + TestHelper.AssertLogMessageIsGenerated(call, "Stochastische ondergrondmodellen importeren afgebroken. Geen data ingelezen.", 1); + AssertUnsuccessfulImport(importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_CancelOfImportWhenReadingStochasticSoilModels_CancelsImportAndLogs() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "complete.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged((description, step, steps) => + { + if (description.Contains("Inlezen van de stochastische ondergrondmodellen.")) + { + importer.Cancel(); + } + }); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + Assert.IsTrue(File.Exists(validFilePath)); + + var importResult = true; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + TestHelper.AssertLogMessageIsGenerated(call, "Stochastische ondergrondmodellen importeren afgebroken. Geen data ingelezen.", 1); + AssertUnsuccessfulImport(importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_CancelOfImportWhenAddingAndCheckingSoilProfiles_CancelsImportAndLogs() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "complete.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged((description, step, steps) => + { + if (description.Contains("Controleren van ondergrondschematisaties.")) + { + importer.Cancel(); + } + }); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + Assert.IsTrue(File.Exists(validFilePath)); + + var importResult = true; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + TestHelper.AssertLogMessageIsGenerated(call, "Stochastische ondergrondmodellen importeren afgebroken. Geen data ingelezen.", 1); + AssertUnsuccessfulImport(importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_CancelOfImportWhenAddingDataToModel_ImportCompletedSuccesfullyNonetheless() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "complete.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged((description, step, steps) => + { + if (description.Contains("Geïmporteerde data toevoegen aan het toetsspoor.")) + { + importer.Cancel(); + } + }); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + Assert.IsTrue(File.Exists(validFilePath)); + + var importResult = false; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + TestHelper.AssertLogMessageIsGenerated(call, "Huidige actie was niet meer te annuleren en is daarom voortgezet.", 1); + AssertSuccessfulImport(3, validFilePath, importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_ReuseOfCanceledImportToValidTargetWithValidFile_ImportSoilModelToCollection() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "complete.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged((description, step, steps) => importer.Cancel()); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + Assert.IsTrue(File.Exists(validFilePath)); + + // Setup (second part) + bool importResult = importer.Import(); + Assert.IsFalse(importResult); + + importer.SetProgressChanged(null); + + // Call + importResult = importer.Import(); + + // Assert + AssertSuccessfulImport(3, validFilePath, importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_ImportingToValidTargetWithEmptyFile_AbortImportAndLog() + { + // Setup + string corruptPath = Path.Combine(testDataPath, "empty.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, corruptPath); + importer.SetProgressChanged(IncrementProgress); + + var importResult = true; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + var internalErrorMessage = new FileReaderErrorMessageBuilder(corruptPath).Build("Kritieke fout opgetreden bij het uitlezen van waardes uit kolommen in de database."); + var expectedLogMessage = $"{internalErrorMessage} \r\nHet bestand wordt overgeslagen."; + TestHelper.AssertLogMessageIsGenerated(call, expectedLogMessage, 1); + Assert.AreEqual(1, progress); + + AssertUnsuccessfulImport(importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_ImportingToValidTargetWithProfileContainingInvalidAtX_SkipImportAndLog() + { + // Setup + string corruptPath = Path.Combine(testDataPath, "invalidAtX2dProperty.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, corruptPath); + importer.SetProgressChanged(IncrementProgress); + + var importResult = false; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + var internalErrorMessage = new FileReaderErrorMessageBuilder(corruptPath) + .WithSubject("ondergrondschematisatie 'Profile'") + .Build("Ondergrondschematisatie bevat geen geldige waarde in kolom \'IntersectionX\'."); + var expectedLogMessages = new[] + { + $"{internalErrorMessage} \r\nDeze ondergrondschematisatie wordt overgeslagen.", + "Het stochastische ondergrondmodel \'Name\' heeft een ongespecificeerde ondergrondschematisatie. Dit model wordt overgeslagen." + }; + TestHelper.AssertLogMessagesAreGenerated(call, expectedLogMessages, 2); + Assert.AreEqual(7, progress); + + AssertSuccessfulImport(0, corruptPath, importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_ImportingToValidTargetWithProfileContainingInvalidParameterValue_ZeroForValue() + { + // Setup + string corruptPath = Path.Combine(testDataPath, "incorrectValue2dProperty.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, corruptPath); + importer.SetProgressChanged(IncrementProgress); + + // Call + var importResult = importer.Import(); + + // Assert + AssertSuccessfulImport(0, corruptPath, importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_IncorrectProfiles_SkipModelAndLog() + { + // Setup + string corruptPath = Path.Combine(testDataPath, "invalidStochasticSoilProfiles.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, corruptPath); + importer.SetProgressChanged(IncrementProgress); + + var importResult = false; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + var expectedLogMessage = + $"Fout bij het lezen van bestand '{corruptPath}': de ondergrondschematisatie verwijst naar een ongeldige waarde." + + " Dit stochastische ondergrondmodel wordt overgeslagen."; + TestHelper.AssertLogMessageIsGenerated(call, expectedLogMessage, 1); + AssertSuccessfulImport(0, corruptPath, importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_IncorrectProbability_LogAndImportSoilModelToCollection() + { + // Setup + string corruptPath = Path.Combine(testDataPath, "incorrectProbability.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, corruptPath); + importer.SetProgressChanged(IncrementProgress); + + var importResult = false; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + var expectedLogMessages = "De som van de kansen van voorkomen in het stochastich ondergrondmodel 'Name' is niet gelijk aan 100%."; + TestHelper.AssertLogMessageIsGenerated(call, expectedLogMessages, 1); + AssertSuccessfulImport(1, corruptPath, importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_TwoSoilModelsReusingSameProfile1D_ImportSoilModelsToCollection() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "reusedSoilProfile1D.soil"); + + var pipingFailureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(pipingFailureMechanism.StochasticSoilModels, validFilePath); + + // Call + var importResult = importer.Import(); + + // Assert + Assert.IsTrue(importResult); + + Assert.AreEqual(2, pipingFailureMechanism.StochasticSoilModels.Count); + StochasticSoilModel model1 = pipingFailureMechanism.StochasticSoilModels[0]; + StochasticSoilModel model2 = pipingFailureMechanism.StochasticSoilModels[1]; + + Assert.AreEqual(1, model1.StochasticSoilProfiles.Count); + Assert.AreEqual(1, model2.StochasticSoilProfiles.Count); + + StochasticSoilProfile profile1 = model1.StochasticSoilProfiles[0]; + StochasticSoilProfile profile2 = model2.StochasticSoilProfiles[0]; + Assert.AreNotSame(profile1, profile2); + Assert.AreSame(profile1.SoilProfile, profile2.SoilProfile); + + Assert.AreEqual(SoilProfileType.SoilProfile1D, profile1.SoilProfileType, + "Expected database to have 1D profiles."); + Assert.AreEqual(SoilProfileType.SoilProfile1D, profile2.SoilProfileType, + "Expected database to have 1D profiles."); + } + + [Test] + public void Import_TwoSoilModelsReusingSameProfile2D_ImportSoilModelsToCollection() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "reusedSoilProfile2D.soil"); + + var pipingFailureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(pipingFailureMechanism.StochasticSoilModels, validFilePath); + + // Call + var importResult = importer.Import(); + + // Assert + Assert.IsTrue(importResult); + + Assert.AreEqual(2, pipingFailureMechanism.StochasticSoilModels.Count); + StochasticSoilModel model1 = pipingFailureMechanism.StochasticSoilModels[0]; + StochasticSoilModel model2 = pipingFailureMechanism.StochasticSoilModels[1]; + + Assert.AreEqual(1, model1.StochasticSoilProfiles.Count); + Assert.AreEqual(1, model2.StochasticSoilProfiles.Count); + + StochasticSoilProfile profile1 = model1.StochasticSoilProfiles[0]; + StochasticSoilProfile profile2 = model2.StochasticSoilProfiles[0]; + Assert.AreNotSame(profile1, profile2); + Assert.AreSame(profile1.SoilProfile, profile2.SoilProfile); + + Assert.AreEqual(SoilProfileType.SoilProfile2D, profile1.SoilProfileType, + "Expected database to have 2D profiles."); + Assert.AreEqual(SoilProfileType.SoilProfile2D, profile2.SoilProfileType, + "Expected database to have 2D profiles."); + } + + [Test] + public void Import_ModelWithOneInvalidStochasticSoilProfileDueToMissingProfile_SkipModelAndLog() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "EmptySoilModel.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + + var importResult = false; + + // Call + Action call = () => importResult = importer.Import(); + + // Assert + var expectedLogMessage = @"Er zijn geen ondergrondschematisaties gevonden in het stochastische ondergrondmodel 'Model'. Dit model wordt overgeslagen."; + TestHelper.AssertLogMessageIsGenerated(call, expectedLogMessage, 1); + + AssertSuccessfulImport(0, validFilePath, importResult, failureMechanism.StochasticSoilModels); + } + + [Test] + public void Import_ModelWithOneStochasticSoilProfile2DWithoutLayerPropertiesSet_ImportModelToCollection() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "SingleSoilProfile2D_noLayerProperties.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged(IncrementProgress); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + Assert.IsTrue(File.Exists(validFilePath)); + + // Call + bool importResult = importer.Import(); + + // Assert + Assert.IsTrue(importResult); + Assert.AreEqual(1, failureMechanism.StochasticSoilModels.Count); + + StochasticSoilModel soilModel = failureMechanism.StochasticSoilModels[0]; + Assert.AreEqual(1, soilModel.StochasticSoilProfiles.Count); + + StochasticSoilProfile stochasticProfile = soilModel.StochasticSoilProfiles[0]; + Assert.AreEqual(100.0, stochasticProfile.Probability); + Assert.AreEqual(SoilProfileType.SoilProfile2D, stochasticProfile.SoilProfileType); + + PipingSoilProfile profile = stochasticProfile.SoilProfile; + Assert.AreEqual("AD647M30_Segment_36005_1D1", profile.Name); + Assert.AreEqual(-45.0, profile.Bottom); + Assert.AreEqual(9, profile.Layers.Count()); + var expectedLayerTops = new[] + { + 4.8899864439741778, + 3.25, + 2.75, + 1.25, + 1.0, + -2.5, + -13.0, + -17.0, + -25.0 + }; + CollectionAssert.AreEqual(expectedLayerTops, profile.Layers.Select(l => l.Top)); + int expectedNumberOfLayers = expectedLayerTops.Length; + CollectionAssert.AreEqual(Enumerable.Repeat(false, expectedNumberOfLayers), + profile.Layers.Select(l => l.IsAquifer)); + CollectionAssert.AreEqual(Enumerable.Repeat(double.NaN, expectedNumberOfLayers), + profile.Layers.Select(l => l.BelowPhreaticLevelMean)); + + Assert.AreEqual(6, progress); + } + + [Test] + public void Import_ModelWithOneStochasticSoilProfile2DWithLayerPropertiesSet_ImportModelToCollection() + { + // Setup + string validFilePath = Path.Combine(testDataPath, "SingleSoilProfile2D_withLayerProperties.soil"); + + var failureMechanism = new PipingFailureMechanism(); + var importer = new StochasticSoilModelImporter(failureMechanism.StochasticSoilModels, validFilePath); + importer.SetProgressChanged(IncrementProgress); + + // Precondition + CollectionAssert.IsEmpty(failureMechanism.StochasticSoilModels); + Assert.IsTrue(File.Exists(validFilePath)); + + // Call + bool importResult = importer.Import(); + + // Assert + Assert.IsTrue(importResult); + Assert.AreEqual(1, failureMechanism.StochasticSoilModels.Count); + + StochasticSoilModel soilModel = failureMechanism.StochasticSoilModels[0]; + Assert.AreEqual(1, soilModel.StochasticSoilProfiles.Count); + + StochasticSoilProfile stochasticProfile = soilModel.StochasticSoilProfiles[0]; + Assert.AreEqual(100.0, stochasticProfile.Probability); + Assert.AreEqual(SoilProfileType.SoilProfile2D, stochasticProfile.SoilProfileType); + + PipingSoilProfile profile = stochasticProfile.SoilProfile; + Assert.AreEqual("Test 2d profile", profile.Name); + Assert.AreEqual(-45.0, profile.Bottom); + const int expectedNumberOfLayers = 9; + Assert.AreEqual(expectedNumberOfLayers, profile.Layers.Count()); + var expectedLayerTops = new[] + { + 5.0571018353300463, + 3.25, + 2.75, + 1.25, + 1.0, + -2.5, + -13.0, + -17.0, + -25.0 + }; + var expectedIsAquiferValues = new[] + { + false, + false, + false, + true, + false, + false, + true, + false, + false + }; + CollectionAssert.AreEqual(expectedIsAquiferValues, + profile.Layers.Select(l => l.IsAquifer)); + CollectionAssert.AreEqual(expectedLayerTops, profile.Layers.Select(l => l.Top)); + var expectedBelowPhreaticLevelValues = new[] + { + 27.27, + 28.28, + 29.29, + 30.3, + 33.33, + 35.35, + 37.37, + 39.39, + 40.4 + }; + CollectionAssert.AreEqual(expectedBelowPhreaticLevelValues, + profile.Layers.Select(l => l.BelowPhreaticLevelMean)); + + Assert.AreEqual(6, progress); + } + + private static void AssertSuccessfulImport( + int expectedSoilModelCount, + string expectedFilePath, + bool actualImportResult, + StochasticSoilModelCollection actualStochasticSoilModels) + { + Assert.AreEqual(expectedSoilModelCount, actualStochasticSoilModels.Count); + Assert.AreEqual(expectedFilePath, actualStochasticSoilModels.LastKnownFilePath); + Assert.IsTrue(actualImportResult); + } + + private static void AssertUnsuccessfulImport( + bool actualImportResult, + StochasticSoilModelCollection stochasticSoilModels) + { + Assert.IsEmpty(stochasticSoilModels); + Assert.IsNull(stochasticSoilModels.LastKnownFilePath); + Assert.IsFalse(actualImportResult); + } + + private void IncrementProgress(string a, int b, int c) + { + progress++; + } + + private class ProgressNotification + { + public ProgressNotification(string description, int currentStep, int totalSteps) + { + Text = description; + CurrentStep = currentStep; + TotalSteps = totalSteps; + } + + public string Text { get; } + public int CurrentStep { get; } + public int TotalSteps { get; } + } + } +} \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj =================================================================== diff -u -rc48f16746209f799f93c6fc79a5202a9e3fd419f -r6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8 --- Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj (.../Ringtoets.Piping.Plugin.Test.csproj) (revision c48f16746209f799f93c6fc79a5202a9e3fd419f) +++ Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj (.../Ringtoets.Piping.Plugin.Test.csproj) (revision 6ddd27897f8c0d4b1e3c4b720e06df9dd855aaf8) @@ -72,7 +72,7 @@ Properties\GlobalAssembly.cs - +