// 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.Linq; using Core.Common.Base.Data; using Core.Common.Base.Geometry; using Core.Common.TestUtil; using NUnit.Framework; namespace Ringtoets.GrassCoverErosionInwards.Data.Test { [TestFixture] public class DikeProfileTest { [Test] public void Constructor_Valid() { // Setup var worldCoordinate = new Point2D(1.1, 2.2); // Call var dikeProfile = new DikeProfile(worldCoordinate); // Assert Assert.IsInstanceOf(dikeProfile.Orientation); Assert.IsInstanceOf(dikeProfile.CrestLevel); Assert.IsInstanceOf(dikeProfile.X0); Assert.AreSame(worldCoordinate, dikeProfile.WorldReferencePoint); Assert.AreEqual(0.0, dikeProfile.Orientation.Value); Assert.AreEqual(2, dikeProfile.Orientation.NumberOfDecimalPlaces); Assert.AreEqual(0.0, dikeProfile.X0); Assert.AreEqual("Dijkprofiel", dikeProfile.Name); Assert.IsNull(dikeProfile.BreakWater); CollectionAssert.IsEmpty(dikeProfile.DikeGeometry); CollectionAssert.IsEmpty(dikeProfile.ForeshoreGeometry); Assert.AreEqual(0.0, dikeProfile.CrestLevel.Value); Assert.AreEqual(2, dikeProfile.CrestLevel.NumberOfDecimalPlaces); Assert.AreEqual(string.Empty, dikeProfile.Memo); } [Test] public void Constructor_WorldReferencePointIsNull_ThrowArgumentNullException() { // Call TestDelegate call = () => new DikeProfile(null); // Assert string paramName = Assert.Throws(call).ParamName; Assert.AreEqual("worldCoordinate", paramName); } [Test] public void Orientation_SetToValueWithTooManyDecimalPlaces_ValueIsRounded() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); int originalNumberOfDecimalPlaces = dikeProfile.Orientation.NumberOfDecimalPlaces; // Call dikeProfile.Orientation = new RoundedDouble(5, 1.23456); // Assert Assert.AreEqual(originalNumberOfDecimalPlaces, dikeProfile.Orientation.NumberOfDecimalPlaces); Assert.AreEqual(1.23, dikeProfile.Orientation.Value); } [Test] [TestCase(-1e-3, 0.0)] [TestCase(360 + 1e-3, 360.0)] public void Orientation_SetValueThatIsNoLongerIllegalAfterRounding_RoundedValueIsSet(double newValue, double expectedRoundedValue) { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); // Call dikeProfile.Orientation = (RoundedDouble) newValue; // Assert Assert.AreEqual(expectedRoundedValue, dikeProfile.Orientation.Value); } [Test] [TestCase(-987.65)] [TestCase(-1e-2)] [TestCase(360 + 1e-2)] [TestCase(875.12)] public void Orientation_SetIllegalValue_ThrowsArgumentOutOfRangeException(double invalidNewValue) { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); // Call TestDelegate call = () => dikeProfile.Orientation = (RoundedDouble) invalidNewValue; // Assert string expectedMessage = String.Format("De dijkprofiel oriëntatie waarde {0} moet in het interval [0, 360] liggen.", new RoundedDouble(dikeProfile.Orientation.NumberOfDecimalPlaces, invalidNewValue)); TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage); } [Test] public void X0_SetNewValue_GetsNewValue([Random(-9999.99, 9999.99, 1)] double newValue) { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); // Call dikeProfile.X0 = newValue; // Assert Assert.AreEqual(newValue, dikeProfile.X0); } [Test] public void CrestLevel_SetToValueWithTooManyDecimalPlaces_ValueIsRounded() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); int originalNumberOfDecimalPlaces = dikeProfile.CrestLevel.NumberOfDecimalPlaces; // Call dikeProfile.CrestLevel = new RoundedDouble(5, 1.23456); // Assert Assert.AreEqual(originalNumberOfDecimalPlaces, dikeProfile.CrestLevel.NumberOfDecimalPlaces); Assert.AreEqual(1.23, dikeProfile.CrestLevel.Value); } [Test] [TestCase(null)] [TestCase("")] [TestCase("Cool new name!")] public void Name_SetNewValue_GetsNewValue(string name) { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); // Call dikeProfile.Name = name; // Assert Assert.AreEqual(name, dikeProfile.Name); } [Test] [TestCase(null)] [TestCase("")] [TestCase("Very informative memo")] public void Memo_SetNewValue_GetsNewValue(string memo) { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); // Call dikeProfile.Memo = memo; // Assert Assert.AreEqual(memo, dikeProfile.Memo); } [Test] public void BreakWater_SetToNull_GetsNewlySetNull() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); // Call dikeProfile.BreakWater = null; // Assert Assert.IsNull(dikeProfile.BreakWater); } [Test] public void BreakWater_SetToNewInstance_GetsNewlySetInstance() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var newBreakWater = new BreakWater(BreakWaterType.Caisson, 1.1); // Call dikeProfile.BreakWater = newBreakWater; // Assert Assert.AreSame(newBreakWater, dikeProfile.BreakWater); } [Test] public void HasBreakWater_BreakWaterSetToNull_ReturnFalse() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)) { BreakWater = null }; // Call bool hasBreakWater = dikeProfile.HasBreakWater; // Assert Assert.IsFalse(hasBreakWater); } [Test] public void HasBreakWater_BreakWaterSetToAnInstance_ReturnTrue() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)) { BreakWater = new BreakWater(BreakWaterType.Dam, 12.34) }; // Call bool hasBreakWater = dikeProfile.HasBreakWater; // Assert Assert.IsTrue(hasBreakWater); } [Test] public void AddDikeGeometrySection_NoElementsYetInCollection_AddNewRoughnessProfileSection() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var section = new RoughnessProfileSection(new Point2D(1.1, 2.2), new Point2D(3.3, 4.4), 5.5); // Precondition CollectionAssert.IsEmpty(dikeProfile.ForeshoreGeometry); // Call dikeProfile.AddDikeGeometrySection(section); // Assert CollectionAssert.Contains(dikeProfile.DikeGeometry, section); Assert.AreEqual(1, dikeProfile.DikeGeometry.Count()); } [Test] public void AddDikeGeometrySection_CollectionHasElementsAndNewElementConnectsToStart_NewElementInsertedAtFront() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var connectedPoint = new Point2D(1.1, 2.2); var existingSection = new RoughnessProfileSection(connectedPoint, new Point2D(3.3, 4.4), 1.0); dikeProfile.AddDikeGeometrySection(existingSection); var newSection = new RoughnessProfileSection(new Point2D(0.0, 0.0), connectedPoint, 1.0); // Call dikeProfile.AddDikeGeometrySection(newSection); // Assert RoughnessProfileSection[] expectedGeometrySections = { newSection, existingSection }; CollectionAssert.AreEqual(expectedGeometrySections, dikeProfile.DikeGeometry); } [Test] public void AddDikeGeometrySection_CollectionHasElementsAndNewElementNotProperlyConnectsToStart_ThrowsArgumentException() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var connectedPoint = new Point2D(1.1, 2.2); var existingSection = new RoughnessProfileSection(connectedPoint, new Point2D(3.3, 4.4), 0.8); dikeProfile.AddDikeGeometrySection(existingSection); var newSection = new RoughnessProfileSection(connectedPoint, new Point2D(0.0, 0.0), 1.0); // Call TestDelegate call = () => dikeProfile.AddDikeGeometrySection(newSection); // Assert TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "Het nieuwe segment is wel verbonden, maar heeft een verkeerde oriëntatie (moet omgedraaid worden)."); CollectionAssert.DoesNotContain(dikeProfile.DikeGeometry, newSection); } [Test] public void AddDikeGeometrySection_CollectionHasElementAndNewElementConnectsToEnd_NewElementInsertedAtEnd() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var connectedPoint = new Point2D(4.4, 5.5); var existingSection = new RoughnessProfileSection(new Point2D(1.1, 2.2), connectedPoint, 0.5); dikeProfile.AddDikeGeometrySection(existingSection); var newSection = new RoughnessProfileSection(connectedPoint, new Point2D(12.12, 13.13), 0.6); // Call dikeProfile.AddDikeGeometrySection(newSection); // Assert RoughnessProfileSection[] expectedGeometrySections = { existingSection, newSection }; CollectionAssert.AreEqual(expectedGeometrySections, dikeProfile.DikeGeometry); } [Test] public void AddDikeGeometrySection_CollectionHasElementsAndNewElementNotProperlyConnectsToEnd_ThrowsArgumentException() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var connectedPoint = new Point2D(4.4, 5.5); var existingSection = new RoughnessProfileSection(new Point2D(1.1, 2.2), connectedPoint, 0.7); dikeProfile.AddDikeGeometrySection(existingSection); var newSection = new RoughnessProfileSection(new Point2D(12.12, 13.13), connectedPoint, 0.6); // Call TestDelegate call = () => dikeProfile.AddDikeGeometrySection(newSection); // Assert TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "Het nieuwe segment is wel verbonden, maar heeft een verkeerde oriëntatie (moet omgedraaid worden)."); CollectionAssert.DoesNotContain(dikeProfile.DikeGeometry, newSection); } [Test] public void AddDikeGeometrySection_CollectionHasElementsAndNewElementNotConnected_ThrowsArgumentException() { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var existingPoints = new[] { new Point2D(-10.10, -11.11), new Point2D(-10.10, 5.5), new Point2D(7.7, 5.5), new Point2D(7.7, -4.4), new Point2D(13.13, -2.2) }; foreach (RoughnessProfileSection existingSection in Math2D.ConvertLinePointsToLineSegments(existingPoints) .Select(segment => ConvertSegmentToRoughnessSection(segment, 0.8))) { dikeProfile.AddDikeGeometrySection(existingSection); } var random = new Random(123); var totallyDisconnectSection = new RoughnessProfileSection(new Point2D(random.NextDouble(), random.NextDouble()), new Point2D(random.NextDouble(), random.NextDouble()), 0.7); // Call TestDelegate call = () => dikeProfile.AddDikeGeometrySection(totallyDisconnectSection); // Assert TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "Het nieuwe segment is niet verbonden met de bestaande geometrie."); CollectionAssert.DoesNotContain(dikeProfile.DikeGeometry, totallyDisconnectSection); } [Test] [TestCase(1)] [TestCase(2)] public void AddDikeGeometrySection_CollectionHasElementsAndNewElementAlreadyPartOfCollection_ThrowsArgumentException(int index) { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var existingPoints = new[] { new Point2D(-10.10, -11.11), new Point2D(-10.10, 5.5), new Point2D(7.7, 5.5), new Point2D(7.7, -4.4), new Point2D(13.13, -2.2) }; RoughnessProfileSection[] roughnessProfileSections = Math2D.ConvertLinePointsToLineSegments(existingPoints) .Select(segment => ConvertSegmentToRoughnessSection(segment, 0.7)) .ToArray(); foreach (RoughnessProfileSection existingSection in roughnessProfileSections) { dikeProfile.AddDikeGeometrySection(existingSection); } RoughnessProfileSection alreadyAddedElement = dikeProfile.DikeGeometry.ElementAt(index); // Call TestDelegate call = () => dikeProfile.AddDikeGeometrySection(alreadyAddedElement); // Assert TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "Het nieuwe segment is niet verbonden met de bestaande geometrie."); Assert.AreEqual(roughnessProfileSections.Length, dikeProfile.DikeGeometry.Count()); } [Test] public void AddDikeGeometrySection_CollectionHasElementsAndIsConnectedToElementInMiddleWithFirstPoint_ThrowsArgumentException( [Range(0, 2)] int index) { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var existingPoints = new[] { new Point2D(-2.2, -2.2), new Point2D(-1.1, -1.2), new Point2D(3.3, -1.1), new Point2D(4.4, 6.7), new Point2D(7.6, 3.2) }; RoughnessProfileSection[] existingSections = Math2D.ConvertLinePointsToLineSegments(existingPoints) .Select(segment => ConvertSegmentToRoughnessSection(segment, 0.9)) .ToArray(); foreach (RoughnessProfileSection existingSection in existingSections) { dikeProfile.AddDikeGeometrySection(existingSection); } var touchingSection = new RoughnessProfileSection(existingSections[index].EndingPoint, new Point2D(999.99, 999.9), 0.6); // Call TestDelegate call = () => dikeProfile.AddDikeGeometrySection(touchingSection); // Assert TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "Het nieuwe segment is niet verbonden met de bestaande geometrie."); CollectionAssert.DoesNotContain(dikeProfile.DikeGeometry, touchingSection); } [Test] public void AddDikeGeometrySection_CollectionHasElementsAndIsConnectedToElementInMiddleWithSecondPoint_ThrowsArgumentException( [Range(1, 3)] int index) { // Setup var dikeProfile = new DikeProfile(new Point2D(0, 0)); var existingPoints = new[] { new Point2D(-2.2, -2.2), new Point2D(-1.1, -1.2), new Point2D(3.3, -1.1), new Point2D(4.4, 6.7), new Point2D(7.6, 3.2) }; RoughnessProfileSection[] existingSections = Math2D.ConvertLinePointsToLineSegments(existingPoints) .Select(segment => ConvertSegmentToRoughnessSection(segment, 0.9)) .ToArray(); foreach (RoughnessProfileSection existingSection in existingSections) { dikeProfile.AddDikeGeometrySection(existingSection); } var touchingSection = new RoughnessProfileSection(new Point2D(999.99, 999.9), existingSections[index].StartingPoint, 0.8); // Call TestDelegate call = () => dikeProfile.AddDikeGeometrySection(touchingSection); // Assert TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "Het nieuwe segment is niet verbonden met de bestaande geometrie."); CollectionAssert.DoesNotContain(dikeProfile.DikeGeometry, touchingSection); } private RoughnessProfileSection ConvertSegmentToRoughnessSection(Segment2D segment, double roughness) { return new RoughnessProfileSection(segment.FirstPoint, segment.SecondPoint, roughness); } } }