Skip to content

Commit

Permalink
Implement INumber<Percentage>;
Browse files Browse the repository at this point in the history
  • Loading branch information
Corniel committed Jan 22, 2024
1 parent a14b4fa commit 10a19b6
Show file tree
Hide file tree
Showing 22 changed files with 797 additions and 849 deletions.
174 changes: 174 additions & 0 deletions specs/Qowaiv.Specs/Percentage_INumber_specs.cs
@@ -0,0 +1,174 @@
#if NET8_0_OR_GREATER

using Qowaiv.TestTools.Numerics;

namespace Percentage_specs;

public class Defines
{
[TestCase("-34%", "30%", "-4%")]
[TestCase("34%", "30%", "4%")]
[TestCase("34%", "2%", "0%")]
public void modulo(Percentage p, Percentage mod, Percentage remainder)
=> (p % mod).Should().Be(remainder);
}

public class Percentage_as_INumber
{
[Test]
public void radix_is_10()
=> Number.Radix<Percentage>().Should().Be(10);

[Test]
public void Additive_identity_Is_1_percent()
=> Number.AdditiveIdentity<Percentage>().Should().Be(1.Percent());

[Test]
public void Multiplicative_identity_is_100_percent()
=> Number.MultiplicativeIdentity<Percentage>().Should().Be(100.Percent());

[Test]
public void Is_canonical_equal_to_decimal([Random(Min, Max, Count)] double d)
{
var n = (decimal)d;
Number.IsCanonical((Percentage)n).Should().Be(Number.IsCanonical(n));
}

[Test]
public void Abs_equal_to_percentage_Abs([Random(Min, Max, Count)] double d)
{
var p = (Percentage)d;
Number.Abs(p).Should().Be(p.Abs());
}

[Test]
public void is_never_a_complex_number([Random(Min, Max, Count)] double d)
=> Number.IsComplexNumber((Percentage)d).Should().BeFalse();

[TestCase("4%", true)]
[TestCase("9%", true)]
[TestCase("1%", true)]
[TestCase("-1%", true)]
[TestCase("-2%", true)]
[TestCase("3.3%", false)]
[TestCase("-4.4%", false)]
public void is_integer(Percentage p, bool isEvenInteger)
=> Number.IsInteger(p).Should().Be(isEvenInteger);

[TestCase("4%", true)]
[TestCase("8%", true)]
[TestCase("0%", true)]
[TestCase("-2%", true)]
[TestCase("-1%", false)]
[TestCase("2.2%", false)]
public void is_even_integer(Percentage p, bool isEvenInteger)
=> Number.IsEvenInteger(p).Should().Be(isEvenInteger);

[TestCase("5%", true)]
[TestCase("9%", true)]
[TestCase("1%", true)]
[TestCase("-1%", true)]
[TestCase("-2%", false)]
[TestCase("3.3%", false)]
public void is_odd_integer(Percentage p, bool isEvenInteger)
=> Number.IsOddInteger(p).Should().Be(isEvenInteger);

[Test]
public void is_always_real([Random(Min, Max, Count)] double d)
=> Number.IsRealNumber((Percentage)d).Should().BeTrue();

[Test]
public void is_never_complex([Random(Min, Max, Count)] double d)
=> Number.IsComplexNumber((Percentage)d).Should().BeFalse();

[Test]
public void is_never_imaginary([Random(Min, Max, Count)] double d)
=> Number.IsImaginaryNumber((Percentage)d).Should().BeFalse();

[Test]
public void is_always_finate([Random(Min, Max, Count)] double d)
=> Number.IsFinite((Percentage)d).Should().BeTrue();

[Test]
public void is_never_infinite([Random(Min, Max, Count)] double d)
{
Number.IsInfinity((Percentage)d).Should().BeFalse();
Number.IsNegativeInfinity((Percentage)d).Should().BeFalse();
Number.IsPositiveInfinity((Percentage)d).Should().BeFalse();
}

[Test]
public void is_never_NaN([Random(Min, Max, Count)] double d)
=> Number.IsNaN((Percentage)d).Should().BeFalse();

[Test]
public void is_negative_equal_to_decimal([Random(Min, Max, Count)] double d)
{
var n = (decimal)d;
Number.IsNegative((Percentage)n).Should().Be(Number.IsNegative(n));
}

[Test]
public void zero_is_positive_and_not_negative()
{
Number.IsPositive(Percentage.Zero).Should().BeTrue();
Number.IsNegative(Percentage.Zero).Should().BeFalse();

Number.IsPositive(0m).Should().BeTrue();
Number.IsNegative(0m).Should().BeFalse();
}

[Test]
public void is_zero_is_false_for_all_but_zero([Random(Min, Max, Count)] double d)
{
var n = (decimal)d;
Number.IsZero((Percentage)n).Should().BeFalse();
}

[Test]
public void is_positive_equal_to_decimal([Random(Min, Max, Count)] double d)
{
var n = (decimal)d;
Number.IsPositive((Percentage)n).Should().Be(Number.IsPositive(n));
}

[Test]
public void Is_not_Normal_when_zero()
=> Number.IsNormal(Percentage.Zero).Should().BeFalse();

[Test]
public void Is_never_subnormal([Random(Min, Max, Count)] double d)
=> Number.IsSubnormal((Percentage)d).Should().BeFalse();

[Test]
public void Is_normal_when_not_zero([Random(Min, Max, Count)] double d)
{
var n = (decimal)d;
Number.IsNormal((Percentage)n).Should().BeTrue();
}

[Test]
public void max_maginiute_equal_to_decimal([Random(Min, Max, 3)] double x, [Random(Min, Max, 3)] double y)
{
var x_ = (decimal)x;
var y_ = (decimal)y;

Number.MaxMagnitude((Percentage)x_, (Percentage)y_).Should().Be((Percentage)Number.MaxMagnitude(x_, y_));
Number.MaxMagnitudeNumber((Percentage)x_, (Percentage)y_).Should().Be((Percentage)Number.MaxMagnitudeNumber(x_, y_));
}

[Test]
public void min_maginiute_equal_to_decimal([Random(Min, Max, 3)] double x, [Random(Min, Max, 3)] double y)
{
var x_ = (decimal)x;
var y_ = (decimal)y;

Number.MinMagnitude((Percentage)x_, (Percentage)y_).Should().Be((Percentage)Number.MinMagnitude(x_, y_));
Number.MinMagnitudeNumber((Percentage)x_, (Percentage)y_).Should().Be((Percentage)Number.MinMagnitudeNumber(x_, y_));
}

private const double Min = -79228162514264337593543950335d;
private const double Max = +79228162514264337593543950335d;
private const int Count = 8;
}
#endif
10 changes: 10 additions & 0 deletions specs/Qowaiv.Specs/Percentage_specs.cs
Expand Up @@ -169,6 +169,16 @@ public void with_TryParse_returns_SVO()
}
}

public class Can_not_be_parsed
{
[TestCase(NumberStyles.HexNumber)]
[TestCase(NumberStyles.AllowExponent)]
public void using_a_number_style_other_then_Number(NumberStyles style)
=> style.Invoking(s => Percentage.TryParse("4.5%", s, CultureInfo.InvariantCulture, out _))
.Should().Throw<ArgumentOutOfRangeException>()
.WithMessage("The number style '*' is not supported.*");
}

public class Can_be_created_with_percentage_extension
{
[Test]
Expand Down
2 changes: 1 addition & 1 deletion specs/Qowaiv.Specs/SVO_contract_specs.cs
@@ -1,4 +1,4 @@
namespace SVO_contract_specs;
namespace SVO_contract_specs;

public class Implements : SingleValueObjectSpecs
{
Expand Down
@@ -1,6 +1,6 @@
namespace Qowaiv.UnitTests;
namespace Qowaiv.UnitTestsSVO_numeric_contract_specs;

public class NumericSvoTest
public class Numeric_SVOs_Define
{
internal const BindingFlags NonPublicInstance = BindingFlags.NonPublic | BindingFlags.Instance;
internal const BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance;
Expand All @@ -27,7 +27,6 @@ public void Abs(Type svo)

[TestCase(typeof(Amount))]
[TestCase(typeof(Money))]
[TestCase(typeof(Percentage))]
[TestCase(typeof(StreamSize))]
public void Plus(Type svo)
{
Expand Down Expand Up @@ -55,7 +54,6 @@ public void Plus(Type svo)

[TestCase(typeof(Amount))]
[TestCase(typeof(Money))]
[TestCase(typeof(Percentage))]
[TestCase(typeof(StreamSize))]
public void Negate(Type svo)
{
Expand Down Expand Up @@ -83,7 +81,6 @@ public void Negate(Type svo)

[TestCase(typeof(Amount))]
[TestCase(typeof(Money))]
[TestCase(typeof(Percentage))]
[TestCase(typeof(StreamSize))]
public void Increment(Type svo)
{
Expand Down Expand Up @@ -111,7 +108,6 @@ public void Increment(Type svo)

[TestCase(typeof(Amount))]
[TestCase(typeof(Money))]
[TestCase(typeof(Percentage))]
[TestCase(typeof(StreamSize))]
public void Decrement(Type svo)
{
Expand Down Expand Up @@ -139,7 +135,6 @@ public void Decrement(Type svo)

[TestCase(typeof(Amount), typeof(Amount), typeof(Percentage))]
[TestCase(typeof(Money), typeof(Money), typeof(Percentage))]
[TestCase(typeof(Percentage), typeof(Percentage))]
[TestCase(typeof(StreamSize), typeof(StreamSize), typeof(Percentage))]
public void Add(Type svo, params Type[] expected)
{
Expand Down Expand Up @@ -169,7 +164,6 @@ public void Add(Type svo, params Type[] expected)

[TestCase(typeof(Amount), typeof(Amount), typeof(Percentage))]
[TestCase(typeof(Money), typeof(Money), typeof(Percentage))]
[TestCase(typeof(Percentage), typeof(Percentage))]
[TestCase(typeof(StreamSize), typeof(StreamSize), typeof(Percentage))]
public void Subtract(Type svo, params Type[] expected)
{
Expand Down Expand Up @@ -199,7 +193,6 @@ public void Subtract(Type svo, params Type[] expected)

[TestCase(typeof(Amount), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(Percentage))]
[TestCase(typeof(Money), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(Percentage))]
[TestCase(typeof(Percentage), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(Percentage))]
[TestCase(typeof(StreamSize), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(Percentage))]
public void Multiply(Type svo, params Type[] expected)
{
Expand Down Expand Up @@ -229,7 +222,6 @@ public void Multiply(Type svo, params Type[] expected)

[TestCase(typeof(Amount), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(Percentage))]
[TestCase(typeof(Money), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(Percentage))]
[TestCase(typeof(Percentage), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(Percentage))]
[TestCase(typeof(StreamSize), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(Percentage))]
public void Divide(Type svo, params Type[] expected)
{
Expand Down

0 comments on commit 10a19b6

Please sign in to comment.