Index: Riskeer/GrassCoverErosionOutwards/src/Riskeer.GrassCoverErosionOutwards.Service/GrassCoverErosionOutwardsWaveConditionsCalculationService.cs =================================================================== diff -u -ra27f6c7f9b0d3858fc7263553fe592e7e0fdb50d -r7eb22f46c5d3e37a35bc8715d9369804e4957b35 --- Riskeer/GrassCoverErosionOutwards/src/Riskeer.GrassCoverErosionOutwards.Service/GrassCoverErosionOutwardsWaveConditionsCalculationService.cs (.../GrassCoverErosionOutwardsWaveConditionsCalculationService.cs) (revision a27f6c7f9b0d3858fc7263553fe592e7e0fdb50d) +++ Riskeer/GrassCoverErosionOutwards/src/Riskeer.GrassCoverErosionOutwards.Service/GrassCoverErosionOutwardsWaveConditionsCalculationService.cs (.../GrassCoverErosionOutwardsWaveConditionsCalculationService.cs) (revision 7eb22f46c5d3e37a35bc8715d9369804e4957b35) @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using Core.Common.Base.Data; using Core.Common.Base.IO; @@ -61,6 +62,8 @@ /// the hydraulic boundary database file path contains invalid characters. /// has no (0) contribution. /// + /// Thrown when an unexpected + /// enum value is encountered. /// Thrown when: /// /// No settings database file could be found at the location of the hydraulic boundary database file path @@ -92,17 +95,19 @@ throw new ArgumentNullException(nameof(assessmentSection)); } + GrassCoverErosionOutwardsWaveConditionsInput calculationInput = calculation.InputParameters; + GrassCoverErosionOutwardsWaveConditionsCalculationType calculationType = calculationInput.CalculationType; + + ValidateCalculationType(calculationType); CalculationServiceHelper.LogCalculationBegin(); - GrassCoverErosionOutwardsWaveConditionsInput calculationInput = calculation.InputParameters; RoundedDouble assessmentLevel = failureMechanism.GetAssessmentLevel(assessmentSection, calculationInput.HydraulicBoundaryLocation, calculationInput.CategoryType); double norm = failureMechanism.GetNorm(assessmentSection, calculation.InputParameters.CategoryType); HydraulicBoundaryDatabase hydraulicBoundaryDatabase = assessmentSection.HydraulicBoundaryDatabase; - GrassCoverErosionOutwardsWaveConditionsCalculationType calculationType = calculationInput.CalculationType; int waterLevelCount = calculationInput.GetWaterLevels(assessmentLevel).Count(); TotalWaterLevelCalculations = calculationInput.CalculationType == GrassCoverErosionOutwardsWaveConditionsCalculationType.Both ? waterLevelCount * 2 @@ -142,19 +147,44 @@ } } + /// + /// Validates the input. + /// + /// Thrown when an undefined enum is used as input. + /// Thrown when a defined enum, but is unsupported is used as input. + private static void ValidateCalculationType(GrassCoverErosionOutwardsWaveConditionsCalculationType calculationType) + { + if (!Enum.IsDefined(typeof(GrassCoverErosionOutwardsWaveConditionsCalculationType), calculationType)) + { + throw new InvalidEnumArgumentException(nameof(calculationType), (int) calculationType, + typeof(GrassCoverErosionOutwardsWaveConditionsCalculationType)); + } + + if (calculationType == GrassCoverErosionOutwardsWaveConditionsCalculationType.Both + || calculationType == GrassCoverErosionOutwardsWaveConditionsCalculationType.WaveRunUp + || calculationType == GrassCoverErosionOutwardsWaveConditionsCalculationType.WaveImpact) + { + return; + } + + throw new NotSupportedException(); + } + private static GrassCoverErosionOutwardsWaveConditionsOutput CreateOutput(GrassCoverErosionOutwardsWaveConditionsCalculationType calculationType, IEnumerable waveRunUpOutput, IEnumerable waveImpactOutput) { - switch (calculationType) + if (calculationType == GrassCoverErosionOutwardsWaveConditionsCalculationType.WaveRunUp) { - case GrassCoverErosionOutwardsWaveConditionsCalculationType.WaveRunUp: - return GrassCoverErosionOutwardsWaveConditionsOutputFactory.CreateOutputWithWaveRunUp(waveRunUpOutput); - case GrassCoverErosionOutwardsWaveConditionsCalculationType.WaveImpact: - return GrassCoverErosionOutwardsWaveConditionsOutputFactory.CreateOutputWithWaveImpact(waveImpactOutput); - default: - return GrassCoverErosionOutwardsWaveConditionsOutputFactory.CreateOutputWithWaveRunUpAndWaveImpact(waveRunUpOutput, waveImpactOutput); + return GrassCoverErosionOutwardsWaveConditionsOutputFactory.CreateOutputWithWaveRunUp(waveRunUpOutput); } + + if (calculationType == GrassCoverErosionOutwardsWaveConditionsCalculationType.WaveImpact) + { + return GrassCoverErosionOutwardsWaveConditionsOutputFactory.CreateOutputWithWaveImpact(waveImpactOutput); + } + + return GrassCoverErosionOutwardsWaveConditionsOutputFactory.CreateOutputWithWaveRunUpAndWaveImpact(waveRunUpOutput, waveImpactOutput); } private IEnumerable CalculateWaveRunUp(GrassCoverErosionOutwardsWaveConditionsCalculation calculation, Index: Riskeer/GrassCoverErosionOutwards/test/Riskeer.GrassCoverErosionOutwards.Service.Test/GrassCoverErosionOutwardsWaveConditionsCalculationServiceTest.cs =================================================================== diff -u -ra27f6c7f9b0d3858fc7263553fe592e7e0fdb50d -r7eb22f46c5d3e37a35bc8715d9369804e4957b35 --- Riskeer/GrassCoverErosionOutwards/test/Riskeer.GrassCoverErosionOutwards.Service.Test/GrassCoverErosionOutwardsWaveConditionsCalculationServiceTest.cs (.../GrassCoverErosionOutwardsWaveConditionsCalculationServiceTest.cs) (revision a27f6c7f9b0d3858fc7263553fe592e7e0fdb50d) +++ Riskeer/GrassCoverErosionOutwards/test/Riskeer.GrassCoverErosionOutwards.Service.Test/GrassCoverErosionOutwardsWaveConditionsCalculationServiceTest.cs (.../GrassCoverErosionOutwardsWaveConditionsCalculationServiceTest.cs) (revision 7eb22f46c5d3e37a35bc8715d9369804e4957b35) @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Linq; using Core.Common.Base.Data; @@ -122,6 +123,38 @@ } [Test] + public void Calculate_InvalidCalculationType_ThrowsInvalidEnumArgumentException() + { + // Setup + var mockRepository = new MockRepository(); + var assessmentSection = mockRepository.Stub(); + mockRepository.ReplayAll(); + + var calculation = new GrassCoverErosionOutwardsWaveConditionsCalculation + { + InputParameters = + { + CalculationType = (GrassCoverErosionOutwardsWaveConditionsCalculationType) 99 + } + }; + + var failureMechanism = new GrassCoverErosionOutwardsFailureMechanism(); + + // Call + TestDelegate call = () => new GrassCoverErosionOutwardsWaveConditionsCalculationService().Calculate(calculation, + failureMechanism, + assessmentSection); + + // Assert + string expectedMessage = $"The value of argument 'calculationType' ({(int)calculation.InputParameters.CalculationType}) " + + $"is invalid for Enum type '{nameof(GrassCoverErosionOutwardsWaveConditionsCalculationType)}'."; + string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage) + .ParamName; + Assert.AreEqual("calculationType", paramName); + mockRepository.VerifyAll(); + } + + [Test] [TestCase(double.NegativeInfinity, TestName = "Calculate_CalculationWithForeshoreNoBreakWaterAndInvalidBreakWaterHeight_PerformAndLog(negativeInfinity)")] [TestCase(double.PositiveInfinity, TestName = "Calculate_CalculationWithForeshoreNoBreakWaterAndInvalidBreakWaterHeight_PerformAndLog(positiveInfinity)")] [TestCase(double.NaN, TestName = "Calculate_CalculationWithForeshoreAndBreakWaterNoInvalidBreakWaterHeight_PerformAndLog(NaN)")] @@ -944,7 +977,7 @@ : waterLevels.Length; var revetmentType = "golfoploop"; - if (step > waterLevels.Length + if (step > waterLevels.Length || calculationType == GrassCoverErosionOutwardsWaveConditionsCalculationType.WaveImpact) { revetmentType = "golfklap"; Index: Riskeer/StabilityStoneCover/src/Riskeer.StabilityStoneCover.Service/StabilityStoneCoverWaveConditionsCalculationService.cs =================================================================== diff -u -r7a3b191a096f1e8518570fde706d38e9caab8173 -r7eb22f46c5d3e37a35bc8715d9369804e4957b35 --- Riskeer/StabilityStoneCover/src/Riskeer.StabilityStoneCover.Service/StabilityStoneCoverWaveConditionsCalculationService.cs (.../StabilityStoneCoverWaveConditionsCalculationService.cs) (revision 7a3b191a096f1e8518570fde706d38e9caab8173) +++ Riskeer/StabilityStoneCover/src/Riskeer.StabilityStoneCover.Service/StabilityStoneCoverWaveConditionsCalculationService.cs (.../StabilityStoneCoverWaveConditionsCalculationService.cs) (revision 7eb22f46c5d3e37a35bc8715d9369804e4957b35) @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using Core.Common.Base.Data; using Core.Common.Base.IO; @@ -86,14 +87,17 @@ throw new ArgumentNullException(nameof(generalWaveConditionsInput)); } + StabilityStoneCoverWaveConditionsCalculationType calculationType = calculation.InputParameters.CalculationType; + ValidateCalculationType(calculationType); + CalculationServiceHelper.LogCalculationBegin(); double norm = assessmentSection.GetNorm(calculation.InputParameters.CategoryType); RoundedDouble assessmentLevel = assessmentSection.GetAssessmentLevel(calculation.InputParameters.HydraulicBoundaryLocation, calculation.InputParameters.CategoryType); - StabilityStoneCoverWaveConditionsCalculationType calculationType = calculation.InputParameters.CalculationType; + int waterLevelCount = calculation.InputParameters.GetWaterLevels(assessmentLevel).Count(); TotalWaterLevelCalculations = calculationType == StabilityStoneCoverWaveConditionsCalculationType.Both ? waterLevelCount * 2 @@ -158,6 +162,29 @@ calculation.Output = output; } + /// + /// Validates the input. + /// + /// Thrown when an undefined enum is used as input. + /// Thrown when a defined enum, but is unsupported is used as input. + private static void ValidateCalculationType(StabilityStoneCoverWaveConditionsCalculationType calculationType) + { + if (!Enum.IsDefined(typeof(StabilityStoneCoverWaveConditionsCalculationType), calculationType)) + { + throw new InvalidEnumArgumentException(nameof(calculationType), (int)calculationType, + typeof(StabilityStoneCoverWaveConditionsCalculationType)); + } + + if (calculationType == StabilityStoneCoverWaveConditionsCalculationType.Both + || calculationType == StabilityStoneCoverWaveConditionsCalculationType.Blocks + || calculationType == StabilityStoneCoverWaveConditionsCalculationType.Columns) + { + return; + } + + throw new NotSupportedException(); + } + private IEnumerable CalculateColumns(StabilityStoneCoverWaveConditionsCalculation calculation, IAssessmentSection assessmentSection, RoundedDouble assessmentLevel, GeneralWaveConditionsInput generalInput, double norm) Index: Riskeer/StabilityStoneCover/test/Riskeer.StabilityStoneCover.Service.Test/StabilityStoneCoverWaveConditionsCalculationServiceTest.cs =================================================================== diff -u -rf7f8971293168512f64a313a0b3a24cfa427b3d3 -r7eb22f46c5d3e37a35bc8715d9369804e4957b35 --- Riskeer/StabilityStoneCover/test/Riskeer.StabilityStoneCover.Service.Test/StabilityStoneCoverWaveConditionsCalculationServiceTest.cs (.../StabilityStoneCoverWaveConditionsCalculationServiceTest.cs) (revision f7f8971293168512f64a313a0b3a24cfa427b3d3) +++ Riskeer/StabilityStoneCover/test/Riskeer.StabilityStoneCover.Service.Test/StabilityStoneCoverWaveConditionsCalculationServiceTest.cs (.../StabilityStoneCoverWaveConditionsCalculationServiceTest.cs) (revision 7eb22f46c5d3e37a35bc8715d9369804e4957b35) @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Linq; using Core.Common.Base.Data; @@ -119,6 +120,33 @@ } [Test] + public void Calculate_InvalidCalculationType_ThrowsInvalidEnumArgumentException() + { + // Setup + var mockRepository = new MockRepository(); + var assessmentSection = mockRepository.Stub(); + mockRepository.ReplayAll(); + + StabilityStoneCoverWaveConditionsCalculation calculation = GetDefaultCalculation(new TestHydraulicBoundaryLocation()); + calculation.InputParameters.CalculationType = (StabilityStoneCoverWaveConditionsCalculationType) 99; + + var failureMechanism = new StabilityStoneCoverFailureMechanism(); + + // Call + TestDelegate call = () => new StabilityStoneCoverWaveConditionsCalculationService().Calculate(calculation, + assessmentSection, + failureMechanism.GeneralInput); + + // Assert + string expectedMessage = $"The value of argument 'calculationType' ({(int) calculation.InputParameters.CalculationType}) " + + $"is invalid for Enum type '{nameof(StabilityStoneCoverWaveConditionsCalculationType)}'."; + string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage) + .ParamName; + Assert.AreEqual("calculationType", paramName); + mockRepository.VerifyAll(); + } + + [Test] [TestCase(double.NegativeInfinity, TestName = "Calculate_CalculationWithForeshoreNoBreakWaterAndInvalidBreakWaterHeight_PerformAndLog(negativeInfinity)")] [TestCase(double.PositiveInfinity, TestName = "Calculate_CalculationWithForeshoreNoBreakWaterAndInvalidBreakWaterHeight_PerformAndLog(positiveInfinity)")] [TestCase(double.NaN, TestName = "Calculate_CalculationWithForeshoreNoBreakWaterAndInvalidBreakWaterHeight_PerformAndLog(NaN)")] @@ -321,8 +349,8 @@ // Assert RoundedDouble[] waterLevels = GetWaterLevels(calculation, assessmentSection).ToArray(); int totalSteps = calculationType == StabilityStoneCoverWaveConditionsCalculationType.Both - ? waterLevels.Length * 2 - : waterLevels.Length; + ? waterLevels.Length * 2 + : waterLevels.Length; var revetmentType = "blokken"; if (step > waterLevels.Length