// 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 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.ComponentModel;
using System.Globalization;
using System.Linq;
using Core.Common.Base.Data;
using Core.Common.Base.TypeConverters;
using Core.Common.TestUtil;
using NUnit.Framework;
namespace Core.Common.Base.Test.Data
{
[TestFixture]
public class RoundedDoubleTest
{
[Test]
[TestCase(0)]
[TestCase(12)]
[TestCase(15)]
public void Constructor_WithoutValue_ExpectedValues(int numberOfDecimalPlaces)
{
// Call
var roundedDouble = new RoundedDouble(numberOfDecimalPlaces);
// Assert
Assert.IsInstanceOf>(roundedDouble);
Assert.IsInstanceOf>(roundedDouble);
Assert.IsInstanceOf(roundedDouble);
Assert.IsInstanceOf(roundedDouble);
Assert.IsInstanceOf>(roundedDouble);
Assert.IsInstanceOf>(roundedDouble);
Assert.AreEqual(numberOfDecimalPlaces, roundedDouble.NumberOfDecimalPlaces);
Assert.AreEqual(0.0, roundedDouble.Value);
TypeConverterAttribute[] typeAttributes = roundedDouble.GetType().GetCustomAttributes(typeof(TypeConverterAttribute), false)
.Cast()
.ToArray();
Assert.AreEqual(1, typeAttributes.Length);
Assert.AreEqual(new TypeConverterAttribute(typeof(RoundedDoubleConverter)), typeAttributes[0]);
}
[Test]
[TestCase(1.0, 2, 1.00)]
[TestCase(123456789.0, 3, 123456789.000)]
[TestCase(12345678.90, 2, 12345678.90)]
[TestCase(12345678.90, 3, 12345678.900)]
[TestCase(1234567.890, 2, 1234567.89)]
[TestCase(1234567.890, 3, 1234567.890)]
[TestCase(123456.7890, 2, 123456.79)]
[TestCase(123456.7890, 3, 123456.789)]
[TestCase(12345.67890, 2, 12345.68)]
[TestCase(12345.67890, 3, 12345.679)]
[TestCase(1234.567890, 2, 1234.57)]
[TestCase(1234.567890, 3, 1234.568)]
[TestCase(123.4567890, 2, 123.46)]
[TestCase(123.4567890, 3, 123.457)]
[TestCase(12.34567890, 2, 12.35)]
[TestCase(12.34567890, 3, 12.346)]
[TestCase(1.234567890, 2, 1.23)]
[TestCase(1.234567890, 3, 1.235)]
[TestCase(0.1234567890, 2, 0.12)]
[TestCase(0.1234567890, 3, 0.123)]
[TestCase(0.01234567890, 2, 0.01)]
[TestCase(0.01234567890, 3, 0.012)]
[TestCase(0.001234567890, 2, 0.00)]
[TestCase(0.001234567890, 3, 0.001)]
[TestCase(0.0001234567890, 2, 0.00)]
[TestCase(0.0001234567890, 3, 0.000)]
[TestCase(double.NaN, 2, double.NaN)]
[TestCase(double.PositiveInfinity, 4, double.PositiveInfinity)]
[TestCase(double.NegativeInfinity, 3, double.NegativeInfinity)]
public void Constructor_ExpectedValues(double doubleValue, int numberOfDecimalPlaces, double expectedRoundedValue)
{
// Call
var roundedDouble = new RoundedDouble(numberOfDecimalPlaces, doubleValue);
// Assert
Assert.IsInstanceOf>(roundedDouble);
Assert.IsInstanceOf>(roundedDouble);
Assert.AreEqual(numberOfDecimalPlaces, roundedDouble.NumberOfDecimalPlaces);
Assert.AreEqual(expectedRoundedValue, roundedDouble.Value);
}
[Test]
[TestCase(-45678)]
[TestCase(-1)]
[TestCase(16)]
[TestCase(34567)]
public void Constructor_InvalidNumberOfPlaces_ThrowArgumentOutOfRangeException(int invalidNumberOfPlaces)
{
// Call
TestDelegate call = () => new RoundedDouble(invalidNumberOfPlaces);
// Assert
const string expectedMessage = "Value must be in range [0, 15].";
TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage);
}
[Test]
public void NaN_ExpectedValue()
{
// Assert
Assert.IsNaN(RoundedDouble.NaN.Value);
Assert.AreEqual(RoundedDouble.MaximumNumberOfDecimalPlaces, RoundedDouble.NaN.NumberOfDecimalPlaces);
}
[Test]
[TestCase(1.0, 2, 1.00)]
[TestCase(123456789.0, 3, 123456789.000)]
[TestCase(12345678.90, 2, 12345678.90)]
[TestCase(12345678.90, 3, 12345678.900)]
[TestCase(1234567.890, 2, 1234567.89)]
[TestCase(1234567.890, 3, 1234567.890)]
[TestCase(123456.7890, 2, 123456.79)]
[TestCase(123456.7890, 3, 123456.789)]
[TestCase(12345.67890, 2, 12345.68)]
[TestCase(12345.67890, 3, 12345.679)]
[TestCase(1234.567890, 2, 1234.57)]
[TestCase(1234.567890, 3, 1234.568)]
[TestCase(123.4567890, 2, 123.46)]
[TestCase(123.4567890, 3, 123.457)]
[TestCase(12.34567890, 2, 12.35)]
[TestCase(12.34567890, 3, 12.346)]
[TestCase(1.234567890, 2, 1.23)]
[TestCase(1.234567890, 3, 1.235)]
[TestCase(0.1234567890, 2, 0.12)]
[TestCase(0.1234567890, 3, 0.123)]
[TestCase(0.01234567890, 2, 0.01)]
[TestCase(0.01234567890, 3, 0.012)]
[TestCase(0.001234567890, 2, 0.00)]
[TestCase(0.001234567890, 3, 0.001)]
[TestCase(0.0001234567890, 2, 0.00)]
[TestCase(0.0001234567890, 3, 0.000)]
[TestCase(double.NaN, 2, double.NaN)]
[TestCase(double.PositiveInfinity, 4, double.PositiveInfinity)]
[TestCase(double.NegativeInfinity, 3, double.NegativeInfinity)]
public void Value_SetNewValue_RoundValue(
double value, int numberOfDecimals, double expectedReturnValue)
{
// Setup
var roundedValue = new RoundedDouble(numberOfDecimals, value);
// Call
double returnValue = roundedValue.Value;
// Assert
Assert.AreEqual(expectedReturnValue, returnValue);
}
[Test]
[SetCulture("nl-NL")]
[TestCase(1.0, 2, "1,00")]
[TestCase(123456789.0, 3, "123456789,000")]
[TestCase(12345678.90, 2, "12345678,90")]
[TestCase(12345678.90, 3, "12345678,900")]
[TestCase(1234567.890, 2, "1234567,89")]
[TestCase(1234567.890, 3, "1234567,890")]
[TestCase(123456.7890, 2, "123456,79")]
[TestCase(123456.7890, 3, "123456,789")]
[TestCase(12345.67890, 2, "12345,68")]
[TestCase(12345.67890, 3, "12345,679")]
[TestCase(1234.567890, 2, "1234,57")]
[TestCase(1234.567890, 3, "1234,568")]
[TestCase(123.4567890, 2, "123,46")]
[TestCase(123.4567890, 3, "123,457")]
[TestCase(12.34567890, 2, "12,35")]
[TestCase(12.34567890, 3, "12,346")]
[TestCase(1.234567890, 2, "1,23")]
[TestCase(1.234567890, 3, "1,235")]
[TestCase(0.1234567890, 2, "0,12")]
[TestCase(0.1234567890, 3, "0,123")]
[TestCase(0.01234567890, 2, "0,01")]
[TestCase(0.01234567890, 3, "0,012")]
[TestCase(0.001234567890, 2, "0,00")]
[TestCase(0.001234567890, 3, "0,001")]
[TestCase(0.0001234567890, 2, "0,00")]
[TestCase(0.0001234567890, 3, "0,000")]
[TestCase(double.NaN, 2, "NaN")]
[TestCase(double.NegativeInfinity, 2, "-Oneindig")]
[TestCase(double.PositiveInfinity, 2, "Oneindig")]
public void ToString_VariousScenarios_ExpectedText(
double value, int numberOfDecimals, string expectedText)
{
// Setup
var roundedValue = new RoundedDouble(numberOfDecimals, value);
// Call
string text = roundedValue.ToString();
// Assert
Assert.AreEqual(expectedText, text);
}
[Test]
[SetCulture("nl-NL")]
[TestCase("N", 1.0, 2, "1,00")]
[TestCase("N0", 123456789.0, 3, "123.456.789")]
[TestCase("N1", 12345678.90, 2, "12.345.678,9")]
[TestCase("N1", 12345678.90, 3, "12.345.678,9")]
[TestCase("G", 1234567.890, 2, "1234567,89")]
[TestCase("G3", 1234567.890, 3, "1,23E+06")]
[TestCase("G9", 123456.7890, 2, "123456,79")]
[TestCase("P3", 12.34567890, 2, "1.235,000 %")]
[TestCase("P1", 12.34567890, 3, "1.234,6 %")]
[TestCase("P", 1.234567890, 2, "123,00 %")]
[TestCase("P3", 1.234567890, 3, "123,500 %")]
[TestCase("F1", 0.1234567890, 2, "0,1")]
[TestCase("F3", 0.1234567890, 3, "0,123")]
[TestCase("F3", 0.01234567890, 2, "0,010")]
[TestCase("F5", 0.01234567890, 3, "0,01200")]
[TestCase("F2", 0.001234567890, 2, "0,00")]
[TestCase("N0", 0.0001234567890, 2, "0")]
[TestCase("N1", 0.0001234567890, 3, "0,0")]
[TestCase("N", double.NaN, 2, "NaN")]
[TestCase("F7", double.NegativeInfinity, 2, "-Oneindig")]
[TestCase("G3", double.PositiveInfinity, 2, "Oneindig")]
public void ToString_WithFormatAndCurrentCultureVariousScenarios_ExpectedText(string format,
double value, int numberOfDecimals, string expectedText)
{
// Setup
var roundedValue = new RoundedDouble(numberOfDecimals, value);
// Call
string text = roundedValue.ToString(format, null);
// Assert
Assert.AreEqual(expectedText, text);
}
[Test]
[SetCulture("nl-NL")]
[TestCase("N", 1.0, 2, "1.00")]
[TestCase("N0", 123456789.0, 3, "123,456,789")]
[TestCase("N1", 12345678.90, 2, "12,345,678.9")]
[TestCase("N1", 12345678.90, 3, "12,345,678.9")]
[TestCase("G", 1234567.890, 2, "1234567.89")]
[TestCase("G3", 1234567.890, 3, "1.23E+06")]
[TestCase("G9", 123456.7890, 2, "123456.79")]
[TestCase("P3", 12.34567890, 2, "1,235.000 %")]
[TestCase("P1", 12.34567890, 3, "1,234.6 %")]
[TestCase("P", 1.234567890, 2, "123.00 %")]
[TestCase("P3", 1.234567890, 3, "123.500 %")]
[TestCase("F1", 0.1234567890, 2, "0.1")]
[TestCase("F3", 0.1234567890, 3, "0.123")]
[TestCase("F3", 0.01234567890, 2, "0.010")]
[TestCase("F5", 0.01234567890, 3, "0.01200")]
[TestCase("F2", 0.001234567890, 2, "0.00")]
[TestCase("N0", 0.0001234567890, 2, "0")]
[TestCase("N1", 0.0001234567890, 3, "0.0")]
[TestCase("N", double.NaN, 2, "NaN")]
[TestCase("F7", double.NegativeInfinity, 2, "-Oneindig")]
[TestCase("G3", double.PositiveInfinity, 2, "Oneindig")]
public void ToString_WithFormatAndDifferentCultureVariousScenarios_ExpectedText(string format,
double value, int numberOfDecimals, string expectedText)
{
// Setup
var roundedValue = new RoundedDouble(numberOfDecimals, value);
// Call
string text = roundedValue.ToString(format, CultureInfo.GetCultureInfo("en-GB"));
// Assert
Assert.AreEqual(expectedText, text);
}
[Test]
public void Equals_ToNull_ReturnFalse()
{
// Setup
var roundedDouble = new RoundedDouble(2);
// Call
bool isEqual = roundedDouble.Equals(null);
// Assert
Assert.IsFalse(isEqual);
}
[Test]
public void Equals_ToSameInstance_ReturnTrue()
{
// Setup
var roundedDouble = new RoundedDouble(5);
// Call
bool isEqual = roundedDouble.Equals(roundedDouble);
// Assert
Assert.IsTrue(isEqual);
}
[Test]
public void Equals_ToSameObjectInstance_ReturnTrue()
{
// Setup
var roundedDouble = new RoundedDouble(5);
// Call
bool isEqual = roundedDouble.Equals((object) roundedDouble);
// Assert
Assert.IsTrue(isEqual);
}
[Test]
public void Equals_ObjectOfSomeOtherType_ReturnFalse()
{
// Setup
var roundedDouble = new RoundedDouble(1);
object someOtherObject = new object();
// Call
bool isEqual1 = roundedDouble.Equals(someOtherObject);
bool isEqual2 = someOtherObject.Equals(roundedDouble);
// Assert
Assert.IsFalse(isEqual1);
Assert.IsFalse(isEqual2);
}
[Test]
[TestCase(3, 1.2344444)]
[TestCase(4, 1.2340444)]
[TestCase(7, 1.2340000)]
public void Equals_ToOtherEqualRoundedDouble_ReturnTrue(
int numberOfPlaces, double value)
{
// Setup
var baseRoundedDouble = new RoundedDouble(3, 1.234);
object comparisonRoundedDouble = new RoundedDouble(numberOfPlaces, value);
// Call
bool isEqual1 = baseRoundedDouble.Equals(comparisonRoundedDouble);
bool isEqual2 = comparisonRoundedDouble.Equals(baseRoundedDouble);
// Assert
Assert.IsTrue(isEqual1);
Assert.IsTrue(isEqual2);
}
[Test]
[TestCase(3, 1.2344444)]
[TestCase(4, 1.2340444)]
[TestCase(7, 1.2340000)]
public void GetHashCode_TwoEqualInstances_ReturnSameHash(
int numberOfPlaces, double value)
{
// Setup
var baseRoundedDouble = new RoundedDouble(3, 1.234);
object comparisonRoundedDouble = new RoundedDouble(numberOfPlaces, value);
// Call
int hash1 = baseRoundedDouble.GetHashCode();
int hash2 = comparisonRoundedDouble.GetHashCode();
// Assert
Assert.AreEqual(hash1, hash2);
}
[Test]
public void EqualityOperator_TwoUnequalRoundedValues_ReturnFalse()
{
// Setup
var roundedDouble1 = new RoundedDouble(2, 1.23);
var roundedDouble2 = new RoundedDouble(1, 1.2);
// Call
bool isEqual1 = roundedDouble1 == roundedDouble2;
bool isEqual2 = roundedDouble2 == roundedDouble1;
// Assert
Assert.IsFalse(isEqual1);
Assert.IsFalse(isEqual2);
}
[Test]
public void EqualityOperator_TwoEqualRoundedValues_ReturnFalse()
{
// Setup
var roundedDouble1 = new RoundedDouble(2, 1.20);
var roundedDouble2 = new RoundedDouble(1, 1.2);
// Call
bool isEqual1 = roundedDouble1 == roundedDouble2;
bool isEqual2 = roundedDouble2 == roundedDouble1;
// Assert
Assert.IsTrue(isEqual1);
Assert.IsTrue(isEqual2);
}
[Test]
public void InequalityOperator_TwoUnequalRoundedValues_ReturnTrue()
{
// Setup
var roundedDouble1 = new RoundedDouble(2, 1.23);
var roundedDouble2 = new RoundedDouble(1, 1.2);
// Precondition:
Assert.IsFalse(roundedDouble1.Equals(roundedDouble2));
// Call
bool isNotEqual1 = roundedDouble1 != roundedDouble2;
bool isNotEqual2 = roundedDouble2 != roundedDouble1;
// Assert
Assert.IsTrue(isNotEqual1);
Assert.IsTrue(isNotEqual2);
}
[Test]
public void InequalityOperator_TwoEqualRoundedValues_ReturnFalse()
{
// Setup
var roundedDouble1 = new RoundedDouble(2, 1.20);
var roundedDouble2 = new RoundedDouble(1, 1.2);
// Precondition:
Assert.IsTrue(roundedDouble1.Equals(roundedDouble2));
// Call
bool isNotEqual1 = roundedDouble1 != roundedDouble2;
bool isNotEqual2 = roundedDouble2 != roundedDouble1;
// Assert
Assert.IsFalse(isNotEqual1);
Assert.IsFalse(isNotEqual2);
}
[Test]
[TestCase(987654321.0, 5)]
[TestCase(-9876543.1200, 2)]
public void Equals_RoundedDoubleEqualToDouble_ReturnTrue(
double value, int numberOfDecimalPlaces)
{
// Setup
var roundedDouble = new RoundedDouble(numberOfDecimalPlaces, value);
// Call
bool isEqual1 = roundedDouble.Equals(value);
bool isEqual2 = value.Equals(roundedDouble);
// Assert
Assert.IsTrue(isEqual1);
Assert.IsTrue(isEqual2);
}
[Test]
[TestCase(987654321.1, 0)]
[TestCase(-9876543.1234, 2)]
public void Equals_RoundedDoubleNotEqualToDouble_ReturnFalse(
double value, int numberOfDecimalPlaces)
{
// Setup
var roundedDouble = new RoundedDouble(numberOfDecimalPlaces, value);
// Call
bool isEqual1 = roundedDouble.Equals(value);
bool isEqual2 = value.Equals(roundedDouble);
// Assert
Assert.IsFalse(isEqual1);
Assert.IsFalse(isEqual2);
}
[Test]
public void Equals_RoundedDoubleTotallyDifferentFromDouble_ReturnFalse()
{
// Setup
var roundedDouble = new RoundedDouble(2, 1.23);
double otherValue = 4.56;
// Call
bool isEqual1 = roundedDouble.Equals(otherValue);
bool isEqual2 = otherValue.Equals(roundedDouble);
// Assert
Assert.IsFalse(isEqual1);
Assert.IsFalse(isEqual2);
}
[Test]
public void GetHashCode_RoundedDoubleEqualToDouble_ReturnSameHashCode()
{
// Setup
double otherValue = 4.56;
var roundedDouble = new RoundedDouble(2, otherValue);
// Precondition:
Assert.IsTrue(otherValue.Equals(roundedDouble));
// Call
int hash1 = roundedDouble.GetHashCode();
int hash2 = otherValue.GetHashCode();
// Assert
Assert.AreEqual(hash1, hash2);
}
[Test]
public void DoubleEqualityOperator_DoubleIsEqualToRoundedDouble_ReturnTrue()
{
// Setup
double value = 1.234;
var roundedDouble = new RoundedDouble(4, value);
// Precondition
Assert.IsTrue(roundedDouble.Equals(value));
// Call
bool isEqual1 = value == roundedDouble;
bool isEqual2 = roundedDouble == value;
// Assert
Assert.IsTrue(isEqual1);
Assert.IsTrue(isEqual2);
}
[Test]
public void DoubleEqualityOperator_DoubleIsNotEqualToRoundedDouble_ReturnFalse()
{
// Setup
double value = 1.234;
var roundedDouble = new RoundedDouble(4, 3.21543);
// Precondition
Assert.IsFalse(roundedDouble.Equals(value));
// Call
bool isEqual1 = value == roundedDouble;
bool isEqual2 = roundedDouble == value;
// Assert
Assert.IsFalse(isEqual1);
Assert.IsFalse(isEqual2);
}
[Test]
public void DoubleInequalityOperator_DoubleIsEqualToRoundedDouble_ReturnFalse()
{
// Setup
double value = 1.234;
var roundedDouble = new RoundedDouble(4, value);
// Precondition
Assert.IsTrue(roundedDouble.Equals(value));
// Call
bool isEqual1 = value != roundedDouble;
bool isEqual2 = roundedDouble != value;
// Assert
Assert.IsFalse(isEqual1);
Assert.IsFalse(isEqual2);
}
[Test]
public void DoubleInequalityOperator_DoubleIsNotEqualToRoundedDouble_ReturnTrue()
{
// Setup
double value = 1.234;
var roundedDouble = new RoundedDouble(4, 3.21543);
// Precondition
Assert.IsFalse(roundedDouble.Equals(value));
// Call
bool isEqual1 = value != roundedDouble;
bool isEqual2 = roundedDouble != value;
// Assert
Assert.IsTrue(isEqual1);
Assert.IsTrue(isEqual2);
}
[Test]
public void ImplicitConversion_FromRoundedDoubleToDouble_ConvertedValueIsEqual()
{
// Setup
var roundedDouble = new RoundedDouble(4, 3.2154);
// Call
double convertedValue = roundedDouble;
// Assert
Assert.AreEqual(roundedDouble.Value, convertedValue);
}
[Test]
public void ExplicitConversion_FromDoubleToRoundedDouble_ConvertedValueIsEqual()
{
// Setup
double doubleValue = 1.23456789;
// Call
RoundedDouble roundedDoubleValue = (RoundedDouble) doubleValue;
// Assert
Assert.AreEqual(doubleValue, roundedDoubleValue.Value);
Assert.AreEqual(15, roundedDoubleValue.NumberOfDecimalPlaces);
}
[Test]
[TestCase(0, 1d)]
[TestCase(2, 1.24)]
[TestCase(3, 1.236)]
[TestCase(15, 1.236000000000000)]
public void ToPrecision_VariousScenarios_ReturnRoundedDouble(int newPrecision, double expectedValue)
{
// Setup
var original = new RoundedDouble(3, 1.236);
// Call
RoundedDouble convertedResult = original.ToPrecision(newPrecision);
// Assert
Assert.AreEqual(newPrecision, convertedResult.NumberOfDecimalPlaces);
Assert.AreEqual(expectedValue, convertedResult.Value);
}
[Test]
public void OperatorMinus_LeftHasLowestPrecision_ReturnRoundedDoubleWithDifferenceRoundedToLeastNumberOfDecimalPlaces()
{
// Setup
const int lowestNumberOfDecimalPlaces = 2;
var value1 = new RoundedDouble(lowestNumberOfDecimalPlaces, 1.12);
var value2 = new RoundedDouble(3, 3.456);
// Call
RoundedDouble diff = value1 - value2;
// Assert
Assert.AreEqual(lowestNumberOfDecimalPlaces, diff.NumberOfDecimalPlaces);
Assert.AreEqual(-2.34, diff.Value);
}
[Test]
public void OperatorMinus_RightHasLowestPrecision_ReturnRoundedDoubleWithDifferenceRoundedToLeastNumberOfDecimalPlaces()
{
// Setup
const int lowestNumberOfDecimalPlaces = 1;
var value1 = new RoundedDouble(6, 1.123456);
var value2 = new RoundedDouble(lowestNumberOfDecimalPlaces, -7.8);
// Call
RoundedDouble diff = value1 - value2;
// Assert
Assert.AreEqual(lowestNumberOfDecimalPlaces, diff.NumberOfDecimalPlaces);
Assert.AreEqual(8.9, diff.Value);
}
[Test]
public void OperatorPlus_LeftHasLowestPrecision_ReturnRoundedDoubleWithSumRoundedToLeastNumberOfDecimalPlaces()
{
// Setup
const int lowestNumberOfDecimalPlaces = 2;
var value1 = new RoundedDouble(lowestNumberOfDecimalPlaces, 1.12);
var value2 = new RoundedDouble(3, 3.456);
// Call
RoundedDouble diff = value1 + value2;
// Assert
Assert.AreEqual(lowestNumberOfDecimalPlaces, diff.NumberOfDecimalPlaces);
Assert.AreEqual(4.58, diff.Value);
}
[Test]
public void OperatorPlus_RightHasLowestPrecision_ReturnRoundedDoubleWithSumRoundedToLeastNumberOfDecimalPlaces()
{
// Setup
const int lowestNumberOfDecimalPlaces = 1;
var value1 = new RoundedDouble(6, 1.123456);
var value2 = new RoundedDouble(lowestNumberOfDecimalPlaces, -7.8);
// Call
RoundedDouble diff = value1 + value2;
// Assert
Assert.AreEqual(lowestNumberOfDecimalPlaces, diff.NumberOfDecimalPlaces);
Assert.AreEqual(-6.7, diff.Value);
}
[Test]
public void OperatorTimes_RoundedDoubleTimesDouble_ReturnResultAsRoundedDoublePreservingNumberOfDecimalPlaces()
{
// Setup
var roundedDouble = new RoundedDouble(3, 1.234);
double doubleValue = 5.67891234;
// Call
RoundedDouble result1 = roundedDouble * doubleValue;
RoundedDouble result2 = doubleValue * roundedDouble;
// Assert
Assert.AreEqual(roundedDouble.NumberOfDecimalPlaces, result1.NumberOfDecimalPlaces);
Assert.AreEqual(roundedDouble.NumberOfDecimalPlaces, result2.NumberOfDecimalPlaces);
const double expectedValue = 7.008;
Assert.AreEqual(expectedValue, result1.Value);
Assert.AreEqual(expectedValue, result2.Value);
}
[Test]
public void OperatorTimes_LeftHasLeastPrecision_ResultIsRoundedDoubleWithLeastNumberOfDecimalPlaces()
{
// Setup
var roundedDouble1 = new RoundedDouble(2, 1.23);
var roundedDouble2 = new RoundedDouble(5, -3.45678);
// Call
RoundedDouble result = roundedDouble1 * roundedDouble2;
// Assert
Assert.AreEqual(2, result.NumberOfDecimalPlaces);
Assert.AreEqual(-4.25, result.Value);
}
[Test]
public void OperatorTimes_RightHasLeastPrecision_ResultIsRoundedDoubleWithLeastNumberOfDecimalPlaces()
{
// Setup
var roundedDouble1 = new RoundedDouble(4, -4.5678);
var roundedDouble2 = new RoundedDouble(3, -9.123);
// Call
RoundedDouble result = roundedDouble1 * roundedDouble2;
// Assert
Assert.AreEqual(3, result.NumberOfDecimalPlaces);
Assert.AreEqual(41.672, result.Value);
}
[Test]
public void OperatorTimes_TwoRoundedDoubles_MultiplicationIsCommutative()
{
// Setup
var roundedDouble1 = new RoundedDouble(1, 1.1);
var roundedDouble2 = new RoundedDouble(2, 2.22);
// Call
RoundedDouble result1 = roundedDouble1 * roundedDouble2;
RoundedDouble result2 = roundedDouble2 * roundedDouble1;
// Assert
Assert.AreEqual(result1.NumberOfDecimalPlaces, result2.NumberOfDecimalPlaces);
Assert.AreEqual(result1.Value, result2.Value);
}
[Test]
public void CompareTo_Null_ReturnsExpectedResult()
{
// Setup
var roundedDouble = new RoundedDouble(1, 10);
// Call
int result = roundedDouble.CompareTo(null);
// Assert
Assert.AreEqual(1, result);
}
[Test]
public void CompareTo_Object_ThrowsArgumentException()
{
// Setup
var roundedDouble = new RoundedDouble(1, 10);
// Call
TestDelegate call = () => roundedDouble.CompareTo(new object());
// Assert
TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "Arg must be double or RoundedDouble");
}
[Test]
public void CompareTo_Itself_ReturnsZero()
{
// Setup
var roundedDouble = new RoundedDouble(1, 10);
// Call
int result = roundedDouble.CompareTo(roundedDouble);
// Assert
Assert.AreEqual(0, result);
}
[Test]
[TestCase(10, 10, 0)]
[TestCase(10.000005, 10, 0)]
[TestCase(10, -10, 1)]
[TestCase(10.05, 10, 1)]
[TestCase(-10, 10, -1)]
[TestCase(10, 10.05, -1)]
[TestCase(10, 10.000005, -1)]
[TestCase(10, double.NaN, 1)]
[TestCase(double.NaN, 10, -1)]
[TestCase(double.NaN, double.NaN, 0)]
public void CompareTo_RoundedDoubleToDouble_ReturnsExpectedResult(double roundedDoubleValue, double value,
int expectedRoundedDoubleIndex)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
int roundedDoubleResult = roundedDouble.CompareTo(value);
int doubleResult = value.CompareTo(roundedDouble);
// Assert
Assert.AreEqual(expectedRoundedDoubleIndex, roundedDoubleResult);
Assert.AreEqual(-1 * expectedRoundedDoubleIndex, doubleResult);
}
[Test]
[TestCase(10, 10, 0)]
[TestCase(10.000005, 10, 0)]
[TestCase(10, 10.000005, 0)]
[TestCase(10.005, 10, 0)]
[TestCase(10, 10.005, 0)]
[TestCase(10, -10, 1)]
[TestCase(10.05, 10, 1)]
[TestCase(-10, 10, -1)]
[TestCase(10, 10.05, -1)]
[TestCase(10, double.NaN, 1)]
[TestCase(double.NaN, 10, -1)]
[TestCase(double.NaN, double.NaN, 0)]
public void CompareTo_RoundedDoubleToRoundedDouble_ReturnsExpectedResult(double roundedDoubleValue, double roundedDoubleValue2,
int expectedRoundedDoubleIndex)
{
// Setup
var roundedDouble1 = new RoundedDouble(1, roundedDoubleValue);
var roundedDouble2 = new RoundedDouble(1, roundedDoubleValue2);
// Call
int roundedDouble1Result = roundedDouble1.CompareTo(roundedDouble2);
int roundedDouble2Result = roundedDouble2.CompareTo(roundedDouble1);
// Assert
Assert.AreEqual(expectedRoundedDoubleIndex, roundedDouble1Result);
Assert.AreEqual(-1 * expectedRoundedDoubleIndex, roundedDouble2Result);
}
[Test]
[TestCase(10, 10, 10, 0)]
[TestCase(10.005, 10, 10, 0)]
[TestCase(10, 10.005, 10, 0)]
[TestCase(10, 10, 10.005, 0)]
[TestCase(10, 11, 12, -1)]
[TestCase(12, 11, 10, 1)]
public void CompareTo_TransitiveRoundedDouble_ReturnsExpectedResult(double roundedDoubleValue1, double roundedDoubleValue2,
double roundedDoubleValue3, int expectedValue)
{
// Setup
var roundedDouble1 = new RoundedDouble(1, roundedDoubleValue1);
var roundedDouble2 = new RoundedDouble(1, roundedDoubleValue2);
var roundedDouble3 = new RoundedDouble(1, roundedDoubleValue3);
// Call
int roundedDoubleResult12 = roundedDouble1.CompareTo(roundedDouble2);
int roundedDoubleResult23 = roundedDouble2.CompareTo(roundedDouble3);
int roundedDoubleResult13 = roundedDouble1.CompareTo(roundedDouble3);
// Assert
Assert.AreEqual(expectedValue, roundedDoubleResult12);
Assert.AreEqual(expectedValue, roundedDoubleResult23);
Assert.AreEqual(expectedValue, roundedDoubleResult13);
}
[Test]
[TestCase(10, 10, 10, 0)]
[TestCase(10.005, 10, 10, 0)]
[TestCase(10, 11, 12, -1)]
[TestCase(12, 11, 10, 1)]
public void CompareTo_TransitiveDouble_ReturnsExpectedResult(double roundedDoubleValue, double value2,
double value3, int expectedValue)
{
// Setup
var roundedDouble1 = new RoundedDouble(1, roundedDoubleValue);
// Call
int roundedDoubleResult12 = roundedDouble1.CompareTo(value2);
int roundedDoubleResult23 = value2.CompareTo(value3);
int roundedDoubleResult13 = roundedDouble1.CompareTo(value3);
// Assert
Assert.AreEqual(expectedValue, roundedDoubleResult12);
Assert.AreEqual(expectedValue, roundedDoubleResult23);
Assert.AreEqual(expectedValue, roundedDoubleResult13);
}
[Test]
[TestCase(11, 10, false)]
[TestCase(10, 11, true)]
[TestCase(10.05, 10, false)]
[TestCase(10, 10.05, true)]
public void OperatorLess_VaryingDouble_ReturnsExpectedValues(double roundedDoubleValue, double value,
bool isRoundedDoubleLess)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
bool roundedDoubleIsLess = roundedDouble < value;
bool doubleIsLess = value < roundedDouble;
// Assert
Assert.AreEqual(isRoundedDoubleLess, roundedDoubleIsLess);
Assert.AreEqual(!isRoundedDoubleLess, doubleIsLess);
}
[Test]
[TestCase(10, 10)]
[TestCase(9.95, 10)]
[TestCase(10.005, 10)]
public void OperatorLess_RoundedDoubleEqualDouble_ReturnsFalse(double roundedDoubleValue, double value)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
bool roundedDoubleIsLess = roundedDouble < value;
bool doubleIsLess = value < roundedDouble;
// Assert
Assert.IsFalse(roundedDoubleIsLess);
Assert.IsFalse(doubleIsLess);
}
[Test]
[TestCase(11, 10, false)]
[TestCase(10, 11, true)]
[TestCase(10.05, 10, false)]
[TestCase(10, 10.05, true)]
public void OperatorLess_VaryingRoundedDouble_ReturnsExpectedValues(double roundedDoubleValue1, double roundedDoubleValue2,
bool isRoundedDoubleOneLess)
{
// Setup
var roundedDoubleOne = new RoundedDouble(1, roundedDoubleValue1);
var roundedDoubleTwo = new RoundedDouble(1, roundedDoubleValue2);
// Call
bool roundedDoubleIsLess = roundedDoubleOne < roundedDoubleTwo;
bool isLessDouble = roundedDoubleTwo < roundedDoubleOne;
// Assert
Assert.AreEqual(isRoundedDoubleOneLess, roundedDoubleIsLess);
Assert.AreEqual(!isRoundedDoubleOneLess, isLessDouble);
}
[Test]
[TestCase(10, 10)]
[TestCase(9.95, 10)]
[TestCase(10.04, 10)]
[TestCase(10, 9.95)]
[TestCase(10, 10.04)]
public void OperatorLess_RoundedDoubleEqualRoundedDouble_ReturnsFalse(double roundedDoubleValue1, double roundedDoubleValue2)
{
// Setup
var roundedDouble1 = new RoundedDouble(1, roundedDoubleValue1);
var roundedDouble2 = new RoundedDouble(1, roundedDoubleValue2);
// Call
bool roundedDoubleOneIsLess = roundedDouble1 < roundedDouble2;
bool roundedDoubleTwoIsLess = roundedDouble2 < roundedDouble1;
// Assert
Assert.IsFalse(roundedDoubleOneIsLess);
Assert.IsFalse(roundedDoubleTwoIsLess);
}
[Test]
[TestCase(11, 10, false)]
[TestCase(10, 11, true)]
[TestCase(10.05, 10, false)]
[TestCase(10, 10.05, true)]
public void OperatorLessOrEqual_VaryingDouble_ReturnsExpectedValues(double roundedDoubleValue, double value,
bool isRoundedDoubleLess)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
bool roundedDoubleIsLess = roundedDouble <= value;
bool doubleIsLess = value <= roundedDouble;
// Assert
Assert.AreEqual(isRoundedDoubleLess, roundedDoubleIsLess);
Assert.AreEqual(!isRoundedDoubleLess, doubleIsLess);
}
[Test]
[TestCase(10, 10)]
[TestCase(9.95, 10)]
[TestCase(10.005, 10)]
public void OperatorLessOrEqual_RoundedDoubleEqualDouble_ReturnsTrue(double roundedDoubleValue, double value)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
bool roundedDoubleIsLess = roundedDouble <= value;
bool doubleIsLess = value <= roundedDouble;
// Assert
Assert.IsTrue(roundedDoubleIsLess);
Assert.IsTrue(doubleIsLess);
}
[Test]
[TestCase(11, 10, false)]
[TestCase(10, 11, true)]
[TestCase(10.05, 10, false)]
[TestCase(10, 10.05, true)]
public void OperatorLessOrEqual_VaryingRoundedDouble_ReturnsExpectedValues(double roundedDoubleValue1, double roundedDoubleValue2,
bool isRoundedDoubleOneLess)
{
// Setup
var roundedDoubleOne = new RoundedDouble(1, roundedDoubleValue1);
var roundedDoubleTwo = new RoundedDouble(1, roundedDoubleValue2);
// Call
bool roundedDoubleIsLess = roundedDoubleOne <= roundedDoubleTwo;
bool isLessDouble = roundedDoubleTwo <= roundedDoubleOne;
// Assert
Assert.AreEqual(isRoundedDoubleOneLess, roundedDoubleIsLess);
Assert.AreEqual(!isRoundedDoubleOneLess, isLessDouble);
}
[Test]
[TestCase(10, 10)]
[TestCase(9.95, 10)]
[TestCase(10.04, 10)]
[TestCase(10, 9.95)]
[TestCase(10, 10.04)]
public void OperatorLessOrEqual_RoundedDoubleEqualRoundedDouble_ReturnsTrue(double roundedDoubleValue1, double roundedDoubleValue2)
{
// Setup
var roundedDouble1 = new RoundedDouble(1, roundedDoubleValue1);
var roundedDouble2 = new RoundedDouble(1, roundedDoubleValue2);
// Call
bool roundedDoubleOneIsLess = roundedDouble1 <= roundedDouble2;
bool roundedDoubleTwoIsLess = roundedDouble2 <= roundedDouble1;
// Assert
Assert.IsTrue(roundedDoubleOneIsLess);
Assert.IsTrue(roundedDoubleTwoIsLess);
}
[Test]
[TestCase(11, 10, true)]
[TestCase(10, 11, false)]
[TestCase(10.05, 10, true)]
[TestCase(10, 10.05, false)]
public void OperatorGreater_VaryingDouble_ReturnsExpectedValues(double roundedDoubleValue, double value,
bool isRoundedDoubleGreater)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
bool roundedDoubleIsGreater = roundedDouble > value;
bool doubleIsGreater = value > roundedDouble;
// Assert
Assert.AreEqual(isRoundedDoubleGreater, roundedDoubleIsGreater);
Assert.AreEqual(!isRoundedDoubleGreater, doubleIsGreater);
}
[Test]
[TestCase(10, 10)]
[TestCase(9.95, 10)]
[TestCase(10.005, 10)]
public void OperatorGreater_RoundedDoubleEqualDouble_ReturnsFalse(double roundedDoubleValue, double value)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
bool roundedDoubleIsLess = roundedDouble > value;
bool doubleIsLess = value > roundedDouble;
// Assert
Assert.IsFalse(roundedDoubleIsLess);
Assert.IsFalse(doubleIsLess);
}
[Test]
[TestCase(11, 10, true)]
[TestCase(10, 11, false)]
[TestCase(10.05, 10, true)]
[TestCase(10, 10.05, false)]
public void OperatorGreater_VaryingRoundedDouble_ReturnsExpectedValues(double roundedDoubleValue1, double roundedDoubleValue2,
bool isRoundedDoubleOneGreater)
{
// Setup
var roundedDoubleOne = new RoundedDouble(1, roundedDoubleValue1);
var roundedDoubleTwo = new RoundedDouble(1, roundedDoubleValue2);
// Call
bool roundedDoubleOneIsGreater = roundedDoubleOne > roundedDoubleTwo;
bool roundedDoubleTwoIsGreater = roundedDoubleTwo > roundedDoubleOne;
// Assert
Assert.AreEqual(isRoundedDoubleOneGreater, roundedDoubleOneIsGreater);
Assert.AreEqual(!isRoundedDoubleOneGreater, roundedDoubleTwoIsGreater);
}
[Test]
[TestCase(10, 10)]
[TestCase(9.95, 10)]
[TestCase(10.04, 10)]
[TestCase(10, 9.95)]
[TestCase(10, 10.04)]
public void OperatorGreater_RoundedDoubleEqualRoundedDouble_ReturnsFalse(double roundedDoubleValue1, double roundedDoubleValue2)
{
// Setup
var roundedDouble1 = new RoundedDouble(1, roundedDoubleValue1);
var roundedDouble2 = new RoundedDouble(1, roundedDoubleValue2);
// Call
bool roundedDoubleOneIsGreater = roundedDouble1 > roundedDouble2;
bool roundedDoubleTwoIsGreater = roundedDouble2 > roundedDouble1;
// Assert
Assert.IsFalse(roundedDoubleOneIsGreater);
Assert.IsFalse(roundedDoubleTwoIsGreater);
}
[Test]
[TestCase(11, 10, true)]
[TestCase(10, 11, false)]
[TestCase(10.05, 10, true)]
[TestCase(10, 10.05, false)]
public void OperatorGreaterOrEqual_VaryingDouble_ReturnsExpectedValues(double roundedDoubleValue, double value,
bool isRoundedDoubleGreater)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
bool roundedDoubleIsGreater = roundedDouble >= value;
bool doubleIsGreater = value >= roundedDouble;
// Assert
Assert.AreEqual(isRoundedDoubleGreater, roundedDoubleIsGreater);
Assert.AreEqual(!isRoundedDoubleGreater, doubleIsGreater);
}
[Test]
[TestCase(10, 10)]
[TestCase(9.95, 10)]
[TestCase(10.005, 10)]
public void OperatorGreaterOrEqual_RoundedDoubleEqualDouble_ReturnsTrue(double roundedDoubleValue, double value)
{
// Setup
var roundedDouble = new RoundedDouble(1, roundedDoubleValue);
// Call
bool roundedDoubleIsLess = roundedDouble >= value;
bool doubleIsLess = value >= roundedDouble;
// Assert
Assert.IsTrue(roundedDoubleIsLess);
Assert.IsTrue(doubleIsLess);
}
[Test]
[TestCase(11, 10, true)]
[TestCase(10, 11, false)]
[TestCase(10.05, 10, true)]
[TestCase(10, 10.05, false)]
public void OperatorGreaterOrEqual_VaryingRoundedDouble_ReturnsExpectedValues(double roundedDoubleValue1, double roundedDoubleValue2,
bool isRoundedDoubleOneGreater)
{
// Setup
var roundedDoubleOne = new RoundedDouble(1, roundedDoubleValue1);
var roundedDoubleTwo = new RoundedDouble(1, roundedDoubleValue2);
// Call
bool roundedDoubleOneIsGreater = roundedDoubleOne >= roundedDoubleTwo;
bool roundedDoubleTwoIsGreater = roundedDoubleTwo >= roundedDoubleOne;
// Assert
Assert.AreEqual(isRoundedDoubleOneGreater, roundedDoubleOneIsGreater);
Assert.AreEqual(!isRoundedDoubleOneGreater, roundedDoubleTwoIsGreater);
}
[Test]
[TestCase(10, 10)]
[TestCase(9.95, 10)]
[TestCase(10.04, 10)]
[TestCase(10, 9.95)]
[TestCase(10, 10.04)]
public void OperatorGreaterOrEqual_RoundedDoubleEqualRoundedDouble_ReturnsFalse(double roundedDoubleValue1, double roundedDoubleValue2)
{
// Setup
var roundedDouble1 = new RoundedDouble(1, roundedDoubleValue1);
var roundedDouble2 = new RoundedDouble(1, roundedDoubleValue2);
// Call
bool roundedDoubleOneIsGreater = roundedDouble1 >= roundedDouble2;
bool roundedDoubleTwoIsGreater = roundedDouble2 >= roundedDouble1;
// Assert
Assert.IsTrue(roundedDoubleOneIsGreater);
Assert.IsTrue(roundedDoubleTwoIsGreater);
}
}
}