Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/FileImporters/ClosingStructureReplaceDataStrategy.cs =================================================================== diff -u -r3ce69e451a97f622288b172d1dcef1ac3fbc9bc1 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/FileImporters/ClosingStructureReplaceDataStrategy.cs (.../ClosingStructureReplaceDataStrategy.cs) (revision 3ce69e451a97f622288b172d1dcef1ac3fbc9bc1) +++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/FileImporters/ClosingStructureReplaceDataStrategy.cs (.../ClosingStructureReplaceDataStrategy.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -23,26 +23,26 @@ using System.Collections.Generic; using System.Linq; using Core.Common.Base; +using Ringtoets.ClosingStructures.Data; using Ringtoets.Common.Data; +using Ringtoets.Common.Data.Structures; using Ringtoets.Common.Data.UpdateDataStrategies; using Ringtoets.Common.IO.Structures; -using Ringtoets.ClosingStructures.Data; -using Ringtoets.Common.Data.Structures; using Ringtoets.Common.Service; namespace Ringtoets.ClosingStructures.Plugin.FileImporters { /// - /// A to replace Closing - /// structures with the imported Closing structures. + /// A to replace closing + /// structures with the imported closing structures. /// public class ClosingStructureReplaceDataStrategy : ReplaceDataStrategyBase, - IStructureUpdateStrategy + IStructureUpdateStrategy { /// /// Creates a new instance of . /// - /// The failure mechanism in which the Closing structures are updated. + /// The failure mechanism in which the closing structures are updated. /// Thrown when is null. public ClosingStructureReplaceDataStrategy(ClosingStructuresFailureMechanism failureMechanism) : base(failureMechanism) {} @@ -57,8 +57,8 @@ protected override IEnumerable ClearData() { return RingtoetsCommonDataSynchronizationService.RemoveAllStructures( - FailureMechanism.Calculations.Cast>(), - FailureMechanism.ClosingStructures, + FailureMechanism.Calculations.Cast>(), + FailureMechanism.ClosingStructures, FailureMechanism.SectionResults); } } Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/FileImporters/ClosingStructureUpdateDataStrategy.cs =================================================================== diff -u -r9da080f738eb93fe40ed2a855753ea9c455063bc -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/FileImporters/ClosingStructureUpdateDataStrategy.cs (.../ClosingStructureUpdateDataStrategy.cs) (revision 9da080f738eb93fe40ed2a855753ea9c455063bc) +++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/FileImporters/ClosingStructureUpdateDataStrategy.cs (.../ClosingStructureUpdateDataStrategy.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -35,7 +35,7 @@ { /// /// An implementation for - /// updating Closing structures based on imported data. + /// updating closing structures based on imported data. /// public class ClosingStructureUpdateDataStrategy : UpdateDataStrategyBase, IStructureUpdateStrategy Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/ClosingStructuresDataSynchronizationService.cs =================================================================== diff -u -r12cec002453a1828efc68633fbd25219632c6c47 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/ClosingStructuresDataSynchronizationService.cs (.../ClosingStructuresDataSynchronizationService.cs) (revision 12cec002453a1828efc68633fbd25219632c6c47) +++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/ClosingStructuresDataSynchronizationService.cs (.../ClosingStructuresDataSynchronizationService.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -25,12 +25,10 @@ using System.Linq; using Core.Common.Base; using Ringtoets.ClosingStructures.Data; -using Ringtoets.Common.Data; using Ringtoets.Common.Data.Calculation; using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.Data.Structures; using Ringtoets.Common.Service; -using Ringtoets.Common.Utils; namespace Ringtoets.ClosingStructures.Service { Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Data.Test/ClosingStructureTest.cs =================================================================== diff -u -r98e61dd87f42755c2e08f19d921d04d9185e8f74 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Data.Test/ClosingStructureTest.cs (.../ClosingStructureTest.cs) (revision 98e61dd87f42755c2e08f19d921d04d9185e8f74) +++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Data.Test/ClosingStructureTest.cs (.../ClosingStructureTest.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -136,7 +136,7 @@ .SetName(nameof(differentIdenticalApertures)); ClosingStructure.ConstructionProperties differentInflowModelType = CreateFullyConfiguredConstructionProperties(); - differentInflowModelType.InflowModelType = ClosingStructureInflowModelType.FloodedCulvert; + differentInflowModelType.InflowModelType = ClosingStructureInflowModelType.LowSill; yield return new TestCaseData(structure, new ClosingStructure(differentInflowModelType), false) .SetName(nameof(differentInflowModelType)); @@ -556,6 +556,70 @@ Assert.AreEqual(otherStructure.WidthFlowApertures.StandardDeviation, structure.WidthFlowApertures.StandardDeviation); } + [Test] + [TestCase(null)] + [TestCase("string")] + public void Equals_ToDifferentTypeOrNull_ReturnsFalse(object other) + { + // Setup + ClosingStructure structure = CreateFullyDefinedStructure(); + + // Call + bool isEqual = structure.Equals(other); + + // Assert + Assert.IsFalse(isEqual); + } + + [Test] + public void Equals_TransitivePropertyAllPropertiesEqual_ReturnsTrue() + { + // Setup + ClosingStructure structureX = CreateFullyDefinedStructure(); + ClosingStructure structureY = CreateFullyDefinedStructure(); + ClosingStructure structureZ = CreateFullyDefinedStructure(); + + // Call + bool isXEqualToY = structureX.Equals(structureY); + bool isYEqualToZ = structureY.Equals(structureZ); + bool isXEqualToZ = structureX.Equals(structureZ); + + // Assert + Assert.IsTrue(isXEqualToY); + Assert.IsTrue(isYEqualToZ); + Assert.IsTrue(isXEqualToZ); + } + + [Test] + [TestCaseSource(nameof(StructureCombinations))] + public void Equal_DifferentProperty_RetunsIsEqual(ClosingStructure structure, + ClosingStructure otherStructure, + bool expectedToBeEqual) + { + // Call + bool isStructureEqualToOther = structure.Equals(otherStructure); + bool isOtherEqualToStructure = otherStructure.Equals(structure); + + // Assert + Assert.AreEqual(expectedToBeEqual, isStructureEqualToOther); + Assert.AreEqual(expectedToBeEqual, isOtherEqualToStructure); + } + + [Test] + public void GetHashCode_EqualStructures_ReturnsSameHashCode() + { + // Setup + ClosingStructure structureOne = CreateFullyDefinedStructure(); + ClosingStructure structureTwo = CreateFullyDefinedStructure(); + + // Call + int hashCodeOne = structureOne.GetHashCode(); + int hashCodeTwo = structureTwo.GetHashCode(); + + // Assert + Assert.AreEqual(hashCodeOne, hashCodeTwo); + } + private static ClosingStructure CreateFullyDefinedStructure() { return new ClosingStructure(CreateFullyConfiguredConstructionProperties()); Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/ClosingStructuresImporterTest.cs =================================================================== diff -u -r207fcf758cac8237b31af99f7f54278b32eba658 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/ClosingStructuresImporterTest.cs (.../ClosingStructuresImporterTest.cs) (revision 207fcf758cac8237b31af99f7f54278b32eba658) +++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/ClosingStructuresImporterTest.cs (.../ClosingStructuresImporterTest.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -138,7 +138,7 @@ "Kunstwerken.shp"); var messageProvider = mocks.Stub(); - var updateStrategy = mocks.Stub>(); + var updateStrategy = mocks.StrictMock>(); updateStrategy.Expect(u => u.UpdateStructuresWithImportedData(null, null, null)).IgnoreArguments().WhenCalled(i => { Assert.AreSame(importTarget, i.Arguments[0]); @@ -230,7 +230,7 @@ string filePath = Path.Combine(commonIoTestDataPath, "CorrectShpRandomCaseHeaderCsv", "Kunstwerken.shp"); var messageProvider = mocks.Stub(); - var updateStrategy = mocks.Stub>(); + var updateStrategy = mocks.StrictMock>(); updateStrategy.Expect(u => u.UpdateStructuresWithImportedData(null, null, null)).IgnoreArguments().WhenCalled(i => { Assert.AreSame(importTarget, i.Arguments[0]); @@ -266,7 +266,7 @@ string filePath = Path.Combine(testDataPath, nameof(ClosingStructuresImporter), "Kunstwerken.shp"); var messageProvider = mocks.Stub(); - var updateStrategy = mocks.Stub>(); + var updateStrategy = mocks.StrictMock>(); updateStrategy.Expect(u => u.UpdateStructuresWithImportedData(null, null, null)).IgnoreArguments().WhenCalled(i => { Assert.AreSame(importTarget, i.Arguments[0]); Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Plugin.Test/FileImporters/ClosingStructureReplaceDataStrategyTest.cs =================================================================== diff -u -r12cec002453a1828efc68633fbd25219632c6c47 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Plugin.Test/FileImporters/ClosingStructureReplaceDataStrategyTest.cs (.../ClosingStructureReplaceDataStrategyTest.cs) (revision 12cec002453a1828efc68633fbd25219632c6c47) +++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Plugin.Test/FileImporters/ClosingStructureReplaceDataStrategyTest.cs (.../ClosingStructureReplaceDataStrategyTest.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -31,7 +31,6 @@ using Ringtoets.Common.Data.Structures; using Ringtoets.Common.Data.TestUtil; using Ringtoets.Common.Data.UpdateDataStrategies; -using Ringtoets.Common.IO.Exceptions; using Ringtoets.Common.IO.Structures; using Ringtoets.ClosingStructures.Data; using Ringtoets.ClosingStructures.Data.TestUtil; Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Service.Test/ClosingStructureDataSynchronizationServiceTest.cs =================================================================== diff -u -r12cec002453a1828efc68633fbd25219632c6c47 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Service.Test/ClosingStructureDataSynchronizationServiceTest.cs (.../ClosingStructureDataSynchronizationServiceTest.cs) (revision 12cec002453a1828efc68633fbd25219632c6c47) +++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Service.Test/ClosingStructureDataSynchronizationServiceTest.cs (.../ClosingStructureDataSynchronizationServiceTest.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -305,76 +305,6 @@ CollectionAssert.AreEquivalent(expectedRemovedObjects, results.RemovedObjects); } - [Test] - public void RemoveClosingStructure_FullyConfiguredFailureMechanism_RemovesStructureAndClearsDependentData() - { - // Setup - ClosingStructuresFailureMechanism failureMechanism = CreateFullyConfiguredFailureMechanism(); - ClosingStructure structure = failureMechanism.ClosingStructures[0]; - StructuresCalculation[] calculationsWithStructure = failureMechanism.Calculations - .Cast>() - .Where(c => ReferenceEquals(c.InputParameters.Structure, structure)) - .ToArray(); - ClosingStructuresFailureMechanismSectionResult[] sectionResultsWithStructure = failureMechanism.SectionResults - .Where(sr => calculationsWithStructure.Contains(sr.Calculation)) - .ToArray(); - StructuresCalculation[] calculationsWithOutput = calculationsWithStructure.Where(c => c.HasOutput) - .ToArray(); - - int originalNumberOfSectionResultAssignments = failureMechanism.SectionResults.Count(sr => sr.Calculation != null); - ClosingStructuresFailureMechanismSectionResult[] sectionResults = failureMechanism.SectionResults - .Where(sr => calculationsWithStructure.Contains(sr.Calculation)) - .ToArray(); - - // Precondition - CollectionAssert.IsNotEmpty(calculationsWithOutput); - CollectionAssert.IsNotEmpty(calculationsWithStructure); - CollectionAssert.IsNotEmpty(sectionResultsWithStructure); - - // Call - IEnumerable affectedObjects = RingtoetsCommonDataSynchronizationService.RemoveStructure( - structure, - failureMechanism.Calculations.Cast>(), - failureMechanism.ClosingStructures, - failureMechanism.SectionResults); - - // Assert - // Note: To make sure the clear is performed regardless of what is done with - // the return result, no ToArray() should be called before these assertions: - CollectionAssert.DoesNotContain(failureMechanism.ClosingStructures, structure); - foreach (StructuresCalculation calculation in calculationsWithStructure) - { - Assert.IsNull(calculation.InputParameters.Structure); - } - foreach (StructuresCalculation calculation in calculationsWithOutput) - { - Assert.IsFalse(calculation.HasOutput); - } - foreach (ClosingStructuresFailureMechanismSectionResult sectionResult in sectionResultsWithStructure) - { - Assert.IsNull(sectionResult.Calculation); - } - - IObservable[] array = affectedObjects.ToArray(); - Assert.AreEqual(1 + calculationsWithOutput.Length + calculationsWithStructure.Length + sectionResultsWithStructure.Length, - array.Length); - CollectionAssert.Contains(array, failureMechanism.ClosingStructures); - foreach (StructuresCalculation calculation in calculationsWithStructure) - { - CollectionAssert.Contains(array, calculation.InputParameters); - } - foreach (StructuresCalculation calculation in calculationsWithOutput) - { - CollectionAssert.Contains(array, calculation); - } - foreach (ClosingStructuresFailureMechanismSectionResult result in sectionResultsWithStructure) - { - CollectionAssert.Contains(array, result); - } - Assert.AreEqual(originalNumberOfSectionResultAssignments - sectionResults.Length, failureMechanism.SectionResults.Count(sr => sr.Calculation != null), - "Other section results with a different calculation/structure should still have their association."); - } - private ClosingStructuresFailureMechanism CreateFullyConfiguredFailureMechanism() { var section1 = new FailureMechanismSection("A", new[] Index: Ringtoets/Common/src/Ringtoets.Common.Service/RingtoetsCommonDataSynchronizationService.cs =================================================================== diff -u -r13b638bd94679e2d79dc3d2020e2a22b86761f47 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/Common/src/Ringtoets.Common.Service/RingtoetsCommonDataSynchronizationService.cs (.../RingtoetsCommonDataSynchronizationService.cs) (revision 13b638bd94679e2d79dc3d2020e2a22b86761f47) +++ Ringtoets/Common/src/Ringtoets.Common.Service/RingtoetsCommonDataSynchronizationService.cs (.../RingtoetsCommonDataSynchronizationService.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -111,18 +111,37 @@ /// from the failure mechanism. /// /// The structure to be removed. - /// - /// - /// + /// The calculations that may have assigned. + /// The collection of structures in which is + /// contained. + /// The section results that may have an assignment to a calculation + /// based on the . /// All objects affected by the removal. + /// Thrown when any parameter is null. public static IEnumerable RemoveStructure( - TStructure structure, - IEnumerable> calculations, - StructureCollection structures, + TStructure structure, + IEnumerable> calculations, + StructureCollection structures, IEnumerable> sectionResults) where TInput : IStructuresCalculationInput, new() where TStructure : StructureBase { + if (structure == null) + { + throw new ArgumentNullException(nameof(structure)); + } + if (calculations == null) + { + throw new ArgumentNullException(nameof(calculations)); + } + if (structures == null) + { + throw new ArgumentNullException(nameof(structures)); + } + if (sectionResults == null) + { + throw new ArgumentNullException(nameof(sectionResults)); + } StructuresCalculation[] calculationWithRemovedStructure = calculations .Where(c => ReferenceEquals(c.InputParameters.Structure, structure)) .ToArray(); @@ -143,13 +162,13 @@ /// and clears all data that depends on it, /// either directly or indirectly. /// - /// Calculations to remove the structure from. + /// The calculations that may have assigned an element in + /// . /// The collection of structures to clear. - /// All the currently known section results in the failure - /// mechanism. + /// The section results that may have an assignment to a calculation + /// based on elements of . /// All objects that are affected by this operation. - /// Thrown when any parameter is - /// null. + /// Thrown when any parameter is null. public static IEnumerable RemoveAllStructures( IEnumerable> calculations, StructureCollection structures, @@ -173,7 +192,7 @@ .Where(c => c.InputParameters.Structure != null) .ToArray(); - HashSet changedObservables = ClearStructureDependentData( + ICollection changedObservables = ClearStructureDependentData( sectionResults, calculationWithRemovedStructure, calculations); @@ -185,8 +204,8 @@ } private static HashSet ClearStructureDependentData(IEnumerable> sectionResults, - IEnumerable> calculationWithRemovedStructure, - IEnumerable> structureCalculations) + IEnumerable> calculationWithRemovedStructure, + IEnumerable> structureCalculations) where T : IStructuresCalculationInput, new() { var changedObservables = new HashSet(); Index: Ringtoets/Common/test/Ringtoets.Common.Service.Test/Ringtoets.Common.Service.Test.csproj =================================================================== diff -u -r4729996da3de69c24738bc39a0ee95fb3909e0c8 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/Common/test/Ringtoets.Common.Service.Test/Ringtoets.Common.Service.Test.csproj (.../Ringtoets.Common.Service.Test.csproj) (revision 4729996da3de69c24738bc39a0ee95fb3909e0c8) +++ Ringtoets/Common/test/Ringtoets.Common.Service.Test/Ringtoets.Common.Service.Test.csproj (.../Ringtoets.Common.Service.Test.csproj) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -70,7 +70,7 @@ - + Index: Ringtoets/Common/test/Ringtoets.Common.Service.Test/RingtoetsCommonDataSynchronizationServiceTest.cs =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.Service.Test/RingtoetsCommonDataSynchronizationServiceTest.cs (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.Service.Test/RingtoetsCommonDataSynchronizationServiceTest.cs (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -0,0 +1,541 @@ +// Copyright (C) Stichting Deltares 2017. 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 Core.Common.Base; +using Core.Common.Base.Geometry; +using NUnit.Framework; +using Rhino.Mocks; +using Ringtoets.Common.Data; +using Ringtoets.Common.Data.Calculation; +using Ringtoets.Common.Data.FailureMechanism; +using Ringtoets.Common.Data.Hydraulics; +using Ringtoets.Common.Data.Probability; +using Ringtoets.Common.Data.Structures; +using Ringtoets.Common.Data.TestUtil; +using Enumerable = System.Linq.Enumerable; + +namespace Ringtoets.Common.Service.Test +{ + [TestFixture] + public class RingtoetsCommonDataSynchronizationServiceTest + { + [Test] + public void ClearHydraulicBoundaryLocationOutput_LocationsNull_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => RingtoetsCommonDataSynchronizationService.ClearHydraulicBoundaryLocationOutput(null); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("locations", exception.ParamName); + } + + [Test] + [Combinatorial] + public void ClearHydraulicBoundaryLocationOutput_LocationWithData_ClearsDataAndReturnsAffectedObjects( + [Values(3.4, double.NaN)] double designWaterLevel, + [Values(5.3, double.NaN)] double waveHeight) + { + // Setup + HydraulicBoundaryLocation location = new TestHydraulicBoundaryLocation + { + DesignWaterLevelOutput = new TestHydraulicBoundaryLocationOutput(designWaterLevel), + WaveHeightOutput = new TestHydraulicBoundaryLocationOutput(waveHeight) + }; + var locations = new ObservableList + { + location + }; + + // Call + IEnumerable affectedObjects = RingtoetsCommonDataSynchronizationService.ClearHydraulicBoundaryLocationOutput(locations); + + // Assert + Assert.IsNull(location.DesignWaterLevelOutput); + Assert.IsNull(location.WaveHeightOutput); + Assert.IsNaN(location.DesignWaterLevel); + Assert.IsNaN(location.WaveHeight); + Assert.AreEqual(CalculationConvergence.NotCalculated, location.DesignWaterLevelCalculationConvergence); + Assert.AreEqual(CalculationConvergence.NotCalculated, location.WaveHeightCalculationConvergence); + + CollectionAssert.AreEqual(new[] + { + location + }, affectedObjects); + } + + [Test] + public void ClearHydraulicBoundaryLocationOutput_HydraulicBoundaryDatabaseWithoutLocations_ReturnsNoAffectedObjects() + { + // Setup + IEnumerable locations = new ObservableList(); + + // Call + IEnumerable affectedObjects = RingtoetsCommonDataSynchronizationService.ClearHydraulicBoundaryLocationOutput(locations); + + // Assert + CollectionAssert.IsEmpty(affectedObjects); + } + + [Test] + public void ClearHydraulicBoundaryLocationOutput_LocationWithoutWaveHeightAndDesignWaterLevel_ReturnsNoAffectedObjects() + { + // Setup + var locations = new ObservableList + { + new TestHydraulicBoundaryLocation() + }; + + // Call + IEnumerable affectedObjects = RingtoetsCommonDataSynchronizationService.ClearHydraulicBoundaryLocationOutput(locations); + + // Assert + CollectionAssert.IsEmpty(affectedObjects); + } + + [Test] + public void ClearCalculationOutput_CalculationNull_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(null); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("calculation", exception.ParamName); + } + + [Test] + public void ClearCalculationOutput_WithCalculation_ClearsOutput() + { + // Setup + var mocks = new MockRepository(); + var calculation = mocks.StrictMock(); + calculation.Expect(c => c.HasOutput).Return(true); + calculation.Expect(c => c.ClearOutput()); + mocks.ReplayAll(); + + // Call + IEnumerable changedObjects = RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(calculation); + + // Assert + // Note: To make sure the clear is performed regardless of what is done with + // the return result, no ToArray() should be called before these assertions: + mocks.VerifyAll(); + + CollectionAssert.AreEqual(new[] + { + calculation + }, changedObjects); + } + + [Test] + public void ClearCalculationOutput_CalculationWithoutOutput_DoNothing() + { + // Setup + var mocks = new MockRepository(); + var calculation = mocks.StrictMock(); + calculation.Expect(c => c.HasOutput).Return(false); + mocks.ReplayAll(); + + // Call + IEnumerable changedObjects = RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(calculation); + + // Assert + CollectionAssert.IsEmpty(changedObjects); + + mocks.VerifyAll(); + } + + [Test] + public void ClearForeshoreProfile_CalculationsWithForeshoreProfile_ClearForeshoreProfileAndReturnAffectedInputs() + { + // Setup + var foreshoreProfileToBeRemoved = new TestForeshoreProfile(new Point2D(0, 0)); + var foreshoreProfile = new TestForeshoreProfile(new Point2D(1, 1)); + + var calculation1 = new StructuresCalculation + { + InputParameters = + { + ForeshoreProfile = foreshoreProfile + } + }; + var calculation2 = new StructuresCalculation + { + InputParameters = + { + ForeshoreProfile = foreshoreProfileToBeRemoved + } + }; + var calculation3 = new StructuresCalculation + { + InputParameters = + { + ForeshoreProfile = foreshoreProfileToBeRemoved + }, + Output = new ProbabilityAssessmentOutput(0, 0, 0, 0, 0) + }; + var calculations = new[] + { + calculation1, + calculation2, + calculation3 + }; + + // Call + IEnumerable affectedObjects = RingtoetsCommonDataSynchronizationService.ClearForeshoreProfile( + calculations, foreshoreProfileToBeRemoved); + + // Assert + Assert.IsNull(calculation2.InputParameters.ForeshoreProfile); + Assert.IsNull(calculation3.InputParameters.ForeshoreProfile); + Assert.IsFalse(calculation3.HasOutput); + Assert.IsNotNull(calculation1.InputParameters.ForeshoreProfile); + + CollectionAssert.AreEqual(new IObservable[] + { + calculation2.InputParameters, + calculation3, + calculation3.InputParameters + }, affectedObjects); + } + + [Test] + public void RemoveStructure_WithoutStructure_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => RingtoetsCommonDataSynchronizationService.RemoveStructure( + null, + Enumerable.Empty>(), + new StructureCollection(), + Enumerable.Empty()); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("structure", exception.ParamName); + } + + [Test] + public void RemoveStructure_WithoutCalculations_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => RingtoetsCommonDataSynchronizationService.RemoveStructure( + new TestStructure("id", new Point2D(0,0)), + null, + new StructureCollection(), + Enumerable.Empty()); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("calculations", exception.ParamName); + } + + [Test] + public void RemoveStructure_WithoutStructures_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => RingtoetsCommonDataSynchronizationService.RemoveStructure( + new TestStructure("id", new Point2D(0, 0)), + Enumerable.Empty>(), + null, + Enumerable.Empty()); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("structures", exception.ParamName); + } + + [Test] + public void RemoveStructure_WithoutSectionResults_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => RingtoetsCommonDataSynchronizationService.RemoveStructure( + new TestStructure("id", new Point2D(0, 0)), + Enumerable.Empty>(), + new StructureCollection(), + null); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("sectionResults", exception.ParamName); + } + + [Test] + public void RemoveStructure_FullyConfiguredFailureMechanism_RemovesStructureAndClearsDependentData() + { + // Setup + var locationStructureToRemove = new Point2D(0, 0); + var locationStructureToKeep = new Point2D(5, 5); + + var structureToRemove = new TestStructure("ToRemove", locationStructureToRemove); + var structureToKeep = new TestStructure("ToKeep", locationStructureToKeep); + + var structures = new StructureCollection(); + structures.AddRange(new[] + { + structureToRemove, + structureToKeep + }, "path/to/structures"); + var calculationWithOutput = new StructuresCalculation + { + Output = new ProbabilityAssessmentOutput(0, 0, 0, 0, 0) + }; + var calculationWithStructureToRemove = new StructuresCalculation + { + InputParameters = + { + Structure = structureToRemove + } + }; + var calculationWithStructureToKeepAndOutput = new StructuresCalculation + { + InputParameters = + { + Structure = structureToKeep + }, + Output = new ProbabilityAssessmentOutput(0, 0, 0, 0, 0) + }; + var calculationWithStructureToRemoveAndOutput = new StructuresCalculation + { + InputParameters = + { + Structure = structureToRemove + }, + Output = new ProbabilityAssessmentOutput(0, 0, 0, 0, 0) + }; + StructuresCalculation[] calculations = + { + calculationWithOutput, + calculationWithStructureToRemove, + calculationWithStructureToKeepAndOutput, + calculationWithStructureToRemoveAndOutput + }; + var sectionWithCalculationAtStructureToRemove = new TestSectionResult(locationStructureToRemove) + { + Calculation = calculationWithStructureToRemove + }; + var sectionWithCalculationAtStructureToKeep = new TestSectionResult(locationStructureToKeep) + { + Calculation = calculationWithStructureToKeepAndOutput + }; + StructuresFailureMechanismSectionResult[] sectionResults = + { + sectionWithCalculationAtStructureToRemove, + sectionWithCalculationAtStructureToKeep + }; + + // Call + IEnumerable affectedObjects = RingtoetsCommonDataSynchronizationService.RemoveStructure( + structureToRemove, + calculations, + structures, + sectionResults); + + // Assert + // Note: To make sure the clear is performed regardless of what is done with + // the return result, no ToArray() should be called before these assertions: + CollectionAssert.DoesNotContain(structures, structureToRemove); + Assert.IsNull(calculationWithStructureToRemove.InputParameters.Structure); + Assert.IsNull(calculationWithStructureToRemoveAndOutput.InputParameters.Structure); + Assert.IsNull(calculationWithStructureToRemoveAndOutput.Output); + Assert.IsNull(sectionWithCalculationAtStructureToRemove.Calculation); + Assert.IsNotNull(calculationWithOutput.Output); + Assert.IsNotNull(calculationWithStructureToKeepAndOutput.Output); + Assert.IsNotNull(calculationWithStructureToKeepAndOutput.InputParameters.Structure); + Assert.AreSame(sectionWithCalculationAtStructureToKeep.Calculation, calculationWithStructureToKeepAndOutput); + + IObservable[] expectedAffectedObjects = + { + calculationWithStructureToRemove.InputParameters, + calculationWithStructureToRemoveAndOutput, + calculationWithStructureToRemoveAndOutput.InputParameters, + sectionWithCalculationAtStructureToRemove, + structures + }; + CollectionAssert.AreEquivalent(expectedAffectedObjects, affectedObjects); + } + + [Test] + public void RemoveAllStructures_CalculationsNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => RingtoetsCommonDataSynchronizationService.RemoveAllStructures( + null, + new StructureCollection(), + Enumerable.Empty>()); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("calculations", paramName); + } + + [Test] + public void RemoveAllStructures_StructuresNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => RingtoetsCommonDataSynchronizationService.RemoveAllStructures( + Enumerable.Empty>(), + null, + Enumerable.Empty>()); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("structures", paramName); + } + + [Test] + public void RemoveAllStructures_SectionResultsNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => RingtoetsCommonDataSynchronizationService.RemoveAllStructures( + Enumerable.Empty>(), + new StructureCollection(), + null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("sectionResults", paramName); + } + + [Test] + public void RemoveAllStructures_FullyConfiguredFailureMechanism_RemoveAllHeightStructuresAndClearDependentData() + { + // Setup + var locationStructureA = new Point2D(0, 0); + var locationStructureB = new Point2D(5, 5); + + var structureA = new TestStructure("A", locationStructureA); + var structureB = new TestStructure("B", locationStructureB); + + var structures = new StructureCollection(); + structures.AddRange(new[] + { + structureA, + structureB + }, "path/to/structures"); + var calculationWithOutput = new StructuresCalculation + { + Output = new ProbabilityAssessmentOutput(0, 0, 0, 0, 0) + }; + var calculationWithStructureA = new StructuresCalculation + { + InputParameters = + { + Structure = structureA + } + }; + var calculationWithStructureBAndOutput = new StructuresCalculation + { + InputParameters = + { + Structure = structureB + }, + Output = new ProbabilityAssessmentOutput(0, 0, 0, 0, 0) + }; + var calculationWithStructureAAndOutput = new StructuresCalculation + { + InputParameters = + { + Structure = structureA + }, + Output = new ProbabilityAssessmentOutput(0, 0, 0, 0, 0) + }; + StructuresCalculation[] calculations = + { + calculationWithOutput, + calculationWithStructureA, + calculationWithStructureBAndOutput, + calculationWithStructureAAndOutput + }; + var sectionWithCalculationAtStructureA = new TestSectionResult(locationStructureA) + { + Calculation = calculationWithStructureA + }; + var sectionWithCalculationAtStructureB = new TestSectionResult(locationStructureB) + { + Calculation = calculationWithStructureBAndOutput + }; + StructuresFailureMechanismSectionResult[] sectionResults = + { + sectionWithCalculationAtStructureA, + sectionWithCalculationAtStructureB + }; + + // Call + IEnumerable affectedObjects = RingtoetsCommonDataSynchronizationService.RemoveAllStructures( + calculations, + structures, + sectionResults); + + // Assert + // Note: To make sure the clear is performed regardless of what is done with + // the return result, no ToArray() should be called before these assertions: + CollectionAssert.DoesNotContain(structures, structureA); + Assert.IsNull(calculationWithStructureA.InputParameters.Structure); + Assert.IsNull(calculationWithStructureAAndOutput.InputParameters.Structure); + Assert.IsNull(calculationWithStructureBAndOutput.InputParameters.Structure); + Assert.IsNull(calculationWithStructureAAndOutput.Output); + Assert.IsNull(calculationWithStructureBAndOutput.Output); + Assert.IsNull(sectionWithCalculationAtStructureA.Calculation); + Assert.IsNull(sectionWithCalculationAtStructureB.Calculation); + Assert.IsNotNull(calculationWithOutput.Output); + + IObservable[] expectedAffectedObjects = + { + calculationWithStructureA.InputParameters, + calculationWithStructureAAndOutput, + calculationWithStructureAAndOutput.InputParameters, + calculationWithStructureBAndOutput, + calculationWithStructureBAndOutput.InputParameters, + sectionWithCalculationAtStructureA, + sectionWithCalculationAtStructureB, + structures + }; + CollectionAssert.AreEquivalent(expectedAffectedObjects, affectedObjects); + } + + private class TestSectionResult : StructuresFailureMechanismSectionResult + { + public TestSectionResult(Point2D point2D) : base(new FailureMechanismSection($"Location {point2D}", new[] + { + point2D, + point2D + })) {} + } + + private class TestStructureInput : StructuresInputBase + { + protected override void UpdateStructureParameters() {} + } + + private class TestStructure : StructureBase + { + public TestStructure(string id, Point2D location) : base(new ConstructionProperties + { + Name = $"{id} name", + Id = id, + Location = location + }) {} + } + } +} \ No newline at end of file Fisheye: Tag 1010d4569cd91ef8661e423e01f833e932180fd4 refers to a dead (removed) revision in file `Ringtoets/Common/test/Ringtoets.Common.Service.Test/RingtoetsCommonDataSynchronizationServicesTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.Plugin/FileImporters/HeightStructureReplaceDataStrategy.cs =================================================================== diff -u -r12cec002453a1828efc68633fbd25219632c6c47 -r1010d4569cd91ef8661e423e01f833e932180fd4 --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.Plugin/FileImporters/HeightStructureReplaceDataStrategy.cs (.../HeightStructureReplaceDataStrategy.cs) (revision 12cec002453a1828efc68633fbd25219632c6c47) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.Plugin/FileImporters/HeightStructureReplaceDataStrategy.cs (.../HeightStructureReplaceDataStrategy.cs) (revision 1010d4569cd91ef8661e423e01f833e932180fd4) @@ -29,7 +29,6 @@ using Ringtoets.Common.IO.Structures; using Ringtoets.Common.Service; using Ringtoets.HeightStructures.Data; -using Ringtoets.HeightStructures.Service; namespace Ringtoets.HeightStructures.Plugin.FileImporters {