Index: Riskeer/Common/src/Riskeer.Common.Forms/Exceptions/RoundedDoubleParsingException.cs =================================================================== diff -u --- Riskeer/Common/src/Riskeer.Common.Forms/Exceptions/RoundedDoubleParsingException.cs (revision 0) +++ Riskeer/Common/src/Riskeer.Common.Forms/Exceptions/RoundedDoubleParsingException.cs (revision 9111b22be47e41193ab7bd5d3e1c06aa8dffee1a) @@ -0,0 +1,66 @@ +// Copyright (C) Stichting Deltares and State of the Netherlands 2023. All rights reserved. +// +// This file is part of DiKErnel. +// +// DiKErnel is free software: you can redistribute it and/or modify it under the terms of the +// GNU Lesser 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser 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.Runtime.Serialization; +using Core.Common.Base.Data; + +namespace Riskeer.Common.Forms.Exceptions +{ + /// + /// Exception thrown when the could not be parsed successfully. + /// + [Serializable] + public class RoundedDoubleParsingException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public RoundedDoubleParsingException() {} + + /// + /// Initializes a new instance of the class + /// with a specified error message. + /// + /// The message that describes the error. + public RoundedDoubleParsingException(string message) + : base(message) {} + + /// + /// Initializes a new instance of the class with a specified error message + /// and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, + /// or null if no inner exception is specified. + public RoundedDoubleParsingException(string message, Exception innerException) : base(message, innerException) {} + + /// + /// Initializes a new instance of with + /// serialized data. + /// The that holds the serialized + /// object data about the exception being thrown. + /// The that contains contextual + /// information about the source or destination. + /// The parameter is + /// null. + /// The class name is null or + /// is zero (0). + protected RoundedDoubleParsingException(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +} \ No newline at end of file Index: Riskeer/Common/src/Riskeer.Common.Forms/Helpers/ProbabilityParsingHelper.cs =================================================================== diff -u -r6e3bc0437167a40cf4a79f0f04e31dc61ef4407f -r9111b22be47e41193ab7bd5d3e1c06aa8dffee1a --- Riskeer/Common/src/Riskeer.Common.Forms/Helpers/ProbabilityParsingHelper.cs (.../ProbabilityParsingHelper.cs) (revision 6e3bc0437167a40cf4a79f0f04e31dc61ef4407f) +++ Riskeer/Common/src/Riskeer.Common.Forms/Helpers/ProbabilityParsingHelper.cs (.../ProbabilityParsingHelper.cs) (revision 9111b22be47e41193ab7bd5d3e1c06aa8dffee1a) @@ -65,7 +65,7 @@ } catch (OverflowException exception) { - throw new ProbabilityParsingException(Resources.Probability_Value_too_large, + throw new ProbabilityParsingException(Resources.ParsingHelper_Value_too_large, exception); } } Index: Riskeer/Common/src/Riskeer.Common.Forms/Helpers/RoundedDoubleParsingHelper.cs =================================================================== diff -u --- Riskeer/Common/src/Riskeer.Common.Forms/Helpers/RoundedDoubleParsingHelper.cs (revision 0) +++ Riskeer/Common/src/Riskeer.Common.Forms/Helpers/RoundedDoubleParsingHelper.cs (revision 9111b22be47e41193ab7bd5d3e1c06aa8dffee1a) @@ -0,0 +1,64 @@ +// Copyright (C) Stichting Deltares and State of the Netherlands 2023. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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 Core.Common.Base.Data; +using Riskeer.Common.Forms.Exceptions; +using Riskeer.Common.Forms.Properties; + +namespace Riskeer.Common.Forms.Helpers +{ + /// + /// Helper class to parse . + /// + public static class RoundedDoubleParsingHelper + { + /// + /// Parses a string value to a . + /// + /// The value to be parsed. + /// The number of decimals. + /// A . + /// Thrown when could not be successfully parsed as a probability. + public static RoundedDouble Parse(string value, int nrOfDecimals) + { + if (string.IsNullOrWhiteSpace(value)) + { + return RoundedDouble.NaN; + } + + try + { + return new RoundedDouble(nrOfDecimals, Convert.ToDouble(value)); + } + catch (FormatException exception) + { + throw new RoundedDoubleParsingException(Resources.Value_Could_not_parse_string_to_RoundedDouble, + exception); + } + catch (OverflowException exception) + { + throw new RoundedDoubleParsingException(Resources.ParsingHelper_Value_too_large, + exception); + } + } + } +} \ No newline at end of file Index: Riskeer/Common/src/Riskeer.Common.Forms/Properties/Resources.Designer.cs =================================================================== diff -u -rf236a73d44c019289a258dbe14885a5ffa9efc50 -r9111b22be47e41193ab7bd5d3e1c06aa8dffee1a --- Riskeer/Common/src/Riskeer.Common.Forms/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision f236a73d44c019289a258dbe14885a5ffa9efc50) +++ Riskeer/Common/src/Riskeer.Common.Forms/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 9111b22be47e41193ab7bd5d3e1c06aa8dffee1a) @@ -1,28 +1,6 @@ -// Copyright (C) Stichting Deltares and State of the Netherlands 2023. All rights reserved. -// -// This file is part of Riskeer. -// -// Riskeer 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. - -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -2565,6 +2543,15 @@ } /// + /// Looks up a localized string similar to De waarde is te groot of te klein.. + /// + public static string ParsingHelper_Value_too_large { + get { + return ResourceManager.GetString("ParsingHelper_Value_too_large", resourceCulture); + } + } + + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// public static System.Drawing.Bitmap ProbabilisticCalculationIcon { @@ -2602,15 +2589,6 @@ } /// - /// Looks up a localized string similar to De waarde is te groot of te klein.. - /// - public static string Probability_Value_too_large { - get { - return ResourceManager.GetString("Probability_Value_too_large", resourceCulture); - } - } - - /// /// Looks up a localized string similar to De kans dat het faalmechanisme optreedt voor deze berekening.. /// public static string ProbabilityAssessmentOutput_Probability_Description { @@ -3953,6 +3931,15 @@ } /// + /// Looks up a localized string similar to De waarde kon niet geïnterpreteerd worden als een kommagetal.. + /// + public static string Value_Could_not_parse_string_to_RoundedDouble { + get { + return ResourceManager.GetString("Value_Could_not_parse_string_to_RoundedDouble", resourceCulture); + } + } + + /// /// Looks up a localized string similar to {0} (Verwachtingswaarde = {1}, Variatiecoëfficiënt = {2}). /// public static string VariationCoefficientDesignVariable_0_Mean_1_CoefficientOfVariation_2 { Index: Riskeer/Common/src/Riskeer.Common.Forms/Properties/Resources.resx =================================================================== diff -u -rf236a73d44c019289a258dbe14885a5ffa9efc50 -r9111b22be47e41193ab7bd5d3e1c06aa8dffee1a --- Riskeer/Common/src/Riskeer.Common.Forms/Properties/Resources.resx (.../Resources.resx) (revision f236a73d44c019289a258dbe14885a5ffa9efc50) +++ Riskeer/Common/src/Riskeer.Common.Forms/Properties/Resources.resx (.../Resources.resx) (revision 9111b22be47e41193ab7bd5d3e1c06aa8dffee1a) @@ -765,7 +765,7 @@ De waarde kon niet geïnterpreteerd worden als een kans. - + De waarde is te groot of te klein. @@ -1550,4 +1550,7 @@ Naam van het bijbehorende HRD bestand. + + De waarde kon niet geïnterpreteerd worden als een kommagetal. + \ No newline at end of file Index: Riskeer/Common/test/Riskeer.Common.Forms.Test/Exceptions/DoubleParsingExceptionTest.cs =================================================================== diff -u --- Riskeer/Common/test/Riskeer.Common.Forms.Test/Exceptions/DoubleParsingExceptionTest.cs (revision 0) +++ Riskeer/Common/test/Riskeer.Common.Forms.Test/Exceptions/DoubleParsingExceptionTest.cs (revision 9111b22be47e41193ab7bd5d3e1c06aa8dffee1a) @@ -0,0 +1,32 @@ +// Copyright (C) Stichting Deltares and State of the Netherlands 2023. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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 Core.Common.TestUtil; +using NUnit.Framework; +using Riskeer.Common.Forms.Exceptions; + +namespace Riskeer.Common.Forms.Test.Exceptions +{ + [TestFixture] + public class DoubleParsingExceptionTest : + CustomExceptionDesignGuidelinesTestFixture {} +} \ No newline at end of file Index: Riskeer/Common/test/Riskeer.Common.Forms.Test/Helpers/ProbabilityParsingHelperTest.cs =================================================================== diff -u -r6e3bc0437167a40cf4a79f0f04e31dc61ef4407f -r9111b22be47e41193ab7bd5d3e1c06aa8dffee1a --- Riskeer/Common/test/Riskeer.Common.Forms.Test/Helpers/ProbabilityParsingHelperTest.cs (.../ProbabilityParsingHelperTest.cs) (revision 6e3bc0437167a40cf4a79f0f04e31dc61ef4407f) +++ Riskeer/Common/test/Riskeer.Common.Forms.Test/Helpers/ProbabilityParsingHelperTest.cs (.../ProbabilityParsingHelperTest.cs) (revision 9111b22be47e41193ab7bd5d3e1c06aa8dffee1a) @@ -31,6 +31,20 @@ public class ProbabilityParsingHelperTest { [Test] + [TestCase("")] + [TestCase(" ")] + [TestCase(" ")] + [TestCase(null)] + public void Parse_NullOrEmptyString_ReturnsExpectedOutput(string value) + { + // Call + double parsedValue = ProbabilityParsingHelper.Parse(value); + + // Assert + Assert.IsNaN(parsedValue); + } + + [Test] [SetCulture("nl-NL")] [TestCase("1/25", 0.04)] [TestCase("1/2,500", 0.4)] @@ -86,10 +100,10 @@ const string invalidValue = "I'm not a number!"; // Call - TestDelegate call = () => ProbabilityParsingHelper.Parse(invalidValue); + void Call() => ProbabilityParsingHelper.Parse(invalidValue); // Assert - var exception = Assert.Throws(call); + var exception = Assert.Throws(Call); Assert.IsInstanceOf(exception.InnerException); Assert.AreEqual("De waarde kon niet geïnterpreteerd worden als een kans.", exception.Message); } @@ -101,10 +115,10 @@ string invalidValue = "1" + double.MaxValue.ToString(CultureInfo.CurrentCulture); // Call - TestDelegate call = () => ProbabilityParsingHelper.Parse(invalidValue); + void Call() => ProbabilityParsingHelper.Parse(invalidValue); // Assert - var exception = Assert.Throws(call); + var exception = Assert.Throws(Call); Assert.IsInstanceOf(exception.InnerException); Assert.AreEqual("De waarde is te groot of te klein.", exception.Message); } Index: Riskeer/Common/test/Riskeer.Common.Forms.Test/Helpers/RoundedDoubleParsingHelperTest.cs =================================================================== diff -u --- Riskeer/Common/test/Riskeer.Common.Forms.Test/Helpers/RoundedDoubleParsingHelperTest.cs (revision 0) +++ Riskeer/Common/test/Riskeer.Common.Forms.Test/Helpers/RoundedDoubleParsingHelperTest.cs (revision 9111b22be47e41193ab7bd5d3e1c06aa8dffee1a) @@ -0,0 +1,133 @@ +// Copyright (C) Stichting Deltares and State of the Netherlands 2023. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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.Globalization; +using Core.Common.Base.Data; +using NUnit.Framework; +using Riskeer.Common.Data.TestUtil; +using Riskeer.Common.Forms.Exceptions; +using Riskeer.Common.Forms.Helpers; + +namespace Riskeer.Common.Forms.Test.Helpers +{ + [TestFixture] + public class RoundedDoubleParsingHelperTest + { + [Test] + [TestCase("")] + [TestCase(" ")] + [TestCase(" ")] + [TestCase(null)] + public void Parse_NullOrEmptyString_ReturnsExpectedOutput(string value) + { + // Setup + var random = new Random(21); + + // Call + double parsedValue = RoundedDoubleParsingHelper.Parse(value, random.Next()); + + // Assert + Assert.IsNaN(parsedValue); + } + + [Test] + [TestCase("13.137,371446", 13137.371)] + [TestCase("13,3701231", 13.370)] + [TestCase("1,000000001", 1.0)] + [TestCase("1e-2", 0.01)] + [TestCase("0,003", 0.003)] + [TestCase("-0,003", -0.003)] + [TestCase("-1e-2", -0.01)] + [TestCase("-1,000000001", -1.0)] + [TestCase("-13,3701231", -13.370)] + [TestCase("-13.137,37446", -13137.374)] + public void Parse_ValidStringInDutchCulture_ReturnsExpectedOutput(string value, double expectedValue) + { + // Setup + const int nrOfDecimals = 3; + + // Call + RoundedDouble parsedValue = RoundedDoubleParsingHelper.Parse(value, nrOfDecimals); + + // Assert + Assert.AreEqual(nrOfDecimals, parsedValue.NumberOfDecimalPlaces); + Assert.AreEqual(expectedValue, parsedValue, parsedValue.GetAccuracy()); + } + + [Test] + [SetCulture("en-US")] + [TestCase("13,137.371446", 13137.371)] + [TestCase("13.3701231", 13.370)] + [TestCase("1.000000001", 1.0)] + [TestCase("1e-2", 0.01)] + [TestCase("0.003", 0.003)] + [TestCase("-0.003", -0.003)] + [TestCase("-1e-2", -0.01)] + [TestCase("-1.000000001", -1.0)] + [TestCase("-13.3701231", -13.370)] + [TestCase("-13,137.37446", -13137.374)] + public void Parse_ValidStringInEnglishCulture_ReturnsExpectedOutput(string value, double expectedValue) + { + // Setup + const int nrOfDecimals = 3; + + // Call + RoundedDouble parsedValue = RoundedDoubleParsingHelper.Parse(value, nrOfDecimals); + + // Assert + Assert.AreEqual(nrOfDecimals, parsedValue.NumberOfDecimalPlaces); + Assert.AreEqual(expectedValue, parsedValue, parsedValue.GetAccuracy()); + } + + [Test] + public void Parse_ValueDoesNotRepresentRoundedDouble_ThrowsProbabilityParsingException() + { + // Setup + var random = new Random(21); + const string invalidValue = "I'm not a number!"; + + // Call + void Call() => RoundedDoubleParsingHelper.Parse(invalidValue, random.Next()); + + // Assert + var exception = Assert.Throws(Call); + Assert.IsInstanceOf(exception.InnerException); + Assert.AreEqual("De waarde kon niet geïnterpreteerd worden als een kommagetal.", exception.Message); + } + + [Test] + public void Parse_ValueTooLargeToStoreInDouble_ThrowsProbabilityParsingException() + { + // Setup + var random = new Random(21); + string invalidValue = "1" + double.MaxValue.ToString(CultureInfo.CurrentCulture); + + // Call + void Call() => RoundedDoubleParsingHelper.Parse(invalidValue, random.Next()); + + // Assert + var exception = Assert.Throws(Call); + Assert.IsInstanceOf(exception.InnerException); + Assert.AreEqual("De waarde is te groot of te klein.", exception.Message); + } + } +} \ No newline at end of file