diff --git a/src/Nox.Types/Types/Area/Area.cs b/src/Nox.Types/Types/Area/Area.cs index 883bc76..7786ec8 100644 --- a/src/Nox.Types/Types/Area/Area.cs +++ b/src/Nox.Types/Types/Area/Area.cs @@ -117,7 +117,7 @@ protected override IEnumerable> GetEqualityComponen private QuantityValue GetAreaIn(AreaTypeUnit targetUnit) { - var factor = new MeasurementConversionFactor((MeasurementTypeUnit)Unit, (MeasurementTypeUnit)targetUnit).Value; + var factor = new Common.MeasurementConversionFactor((MeasurementTypeUnit)Unit, (MeasurementTypeUnit)targetUnit).Value; return Round(Value * factor); } diff --git a/src/Nox.Types/Types/Distance/Distance.cs b/src/Nox.Types/Types/Distance/Distance.cs index 57a6580..4525567 100644 --- a/src/Nox.Types/Types/Distance/Distance.cs +++ b/src/Nox.Types/Types/Distance/Distance.cs @@ -135,7 +135,7 @@ public string ToString(IFormatProvider formatProvider) private QuantityValue GetDistanceIn(DistanceTypeUnit targetUnit) { - var factor = new MeasurementConversionFactor((MeasurementTypeUnit)Unit, (MeasurementTypeUnit)targetUnit).Value; + var factor = new Common.MeasurementConversionFactor((MeasurementTypeUnit)Unit, (MeasurementTypeUnit)targetUnit).Value; return Round(Value * factor); } diff --git a/src/Nox.Types/Types/Length/Length.cs b/src/Nox.Types/Types/Length/Length.cs index 6e1307e..f70df33 100644 --- a/src/Nox.Types/Types/Length/Length.cs +++ b/src/Nox.Types/Types/Length/Length.cs @@ -117,7 +117,7 @@ public QuantityValue ToFeet() private QuantityValue GetLengthIn(LengthTypeUnit targetUnit) { - var factor = new MeasurementConversionFactor((MeasurementTypeUnit)Unit, (MeasurementTypeUnit)targetUnit).Value; + var factor = new Common.MeasurementConversionFactor((MeasurementTypeUnit)Unit, (MeasurementTypeUnit)targetUnit).Value; return Round(Value * factor); } diff --git a/src/Nox.Types/Types/Volume/Measurement.cs b/src/Nox.Types/Types/Volume/Measurement.cs new file mode 100644 index 0000000..9faae6f --- /dev/null +++ b/src/Nox.Types/Types/Volume/Measurement.cs @@ -0,0 +1,78 @@ +using System; +using System.Globalization; + +namespace Nox.Types; + +public abstract class Measurement : ValueObject + where TValueObject : Measurement, new() + where TUnitType : MeasurementUnit +{ + private const int QuantityValueDecimalPrecision = 6; + + public TUnitType Unit { get; private set; } = default!; + + protected Measurement() : base() { Value = 0; } + + /// + /// Creates a new instance of object with the specified . + /// + /// The value to create the with + /// The to create the with + /// + /// + public static TValueObject From(QuantityValue value, TUnitType unit) + { + var newObject = new TValueObject + { + Value = Round(value), + Unit = unit, + }; + + var validationResult = newObject.Validate(); + + if (!validationResult.IsValid) + { + throw new TypeValidationException(validationResult.Errors); + } + + return newObject; + } + + /// + /// Validates a object. + /// + /// true if the value is valid. + internal override ValidationResult Validate() + { + var result = Value.Validate(); + + if (Value < 0 && !double.IsNaN((double)Value) && !double.IsInfinity((double)Value)) + { + result.Errors.Add(new ValidationFailure(nameof(Value), $"Could not create a Nox {typeof(TValueObject).Name} type as negative {typeof(TValueObject).Name.ToLower()} value {Value} is not allowed.")); + } + + return result; + } + + public override string ToString() + => $"{Value.ToString($"0.{new string('#', QuantityValueDecimalPrecision)}", CultureInfo.InvariantCulture)} {Unit}"; + + /// + /// Returns a string representation of the object using the specified . + /// + /// The format provider for the measurement value. + /// A string representation of the object with the value formatted using the specified . + public string ToString(IFormatProvider formatProvider) + => $"{Value.ToString(formatProvider)} {Unit}"; + + protected QuantityValue GetMeasurementIn(TUnitType targetUnit) + { + var factor = ResolveUnitConversionFactor(Unit, targetUnit); + return Round(Value * factor); + } + + private static QuantityValue Round(QuantityValue value) + => Math.Round((double)value, QuantityValueDecimalPrecision); + + protected abstract MeasurementConversionFactor ResolveUnitConversionFactor(TUnitType sourceUnit, TUnitType targetUnit); +} diff --git a/src/Nox.Types/Types/Volume/MeasurementConversionFactor.cs b/src/Nox.Types/Types/Volume/MeasurementConversionFactor.cs new file mode 100644 index 0000000..72a196c --- /dev/null +++ b/src/Nox.Types/Types/Volume/MeasurementConversionFactor.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +namespace Nox.Types; + +public abstract class MeasurementConversionFactor where TUnitType : MeasurementUnit +{ + protected abstract Dictionary<(TUnitType, TUnitType), double> DefinedConversionFactors { get; } + + public double Value { get; } + + protected MeasurementConversionFactor(TUnitType sourceUnit, TUnitType targetUnit) + { + Value = ResolveConversionFactor(sourceUnit, targetUnit); + } + + private double ResolveConversionFactor(TUnitType sourceUnit, TUnitType targetUnit) + { + var conversion = (sourceUnit, targetUnit); + + if (DefinedConversionFactors.ContainsKey(conversion)) + return DefinedConversionFactors[conversion]; + + + if (sourceUnit == targetUnit) + return 1; + + throw new NotImplementedException($"No conversion defined from {sourceUnit?.Name} to {targetUnit?.Name}."); + } + + public static QuantityValue operator *(QuantityValue value, MeasurementConversionFactor factor) + => value * factor.Value; + + public static QuantityValue operator *(MeasurementConversionFactor factor, QuantityValue value) + => value * factor; +} \ No newline at end of file diff --git a/src/Nox.Types/Types/Volume/MeasurementUnit.cs b/src/Nox.Types/Types/Volume/MeasurementUnit.cs new file mode 100644 index 0000000..862bf65 --- /dev/null +++ b/src/Nox.Types/Types/Volume/MeasurementUnit.cs @@ -0,0 +1,53 @@ +using System; + +namespace Nox.Types; + +public abstract class MeasurementUnit : IComparable +{ + public int Id { get; } + public string Name { get; } + public string Symbol { get; } + + protected MeasurementUnit(int id, string name, string symbol) + { + Id = id; + Name = name; + Symbol = symbol; + } + + public int CompareTo(object obj) + => Id.CompareTo(((MeasurementUnit)obj).Id); + + public override bool Equals(object obj) + { + if (obj is not MeasurementUnit otherValue) + { + return false; + } + + var isEqualType = GetType().Equals(obj.GetType()); + var isEqualId = Id.Equals(otherValue.Id); + + return isEqualType && isEqualId; + } + + public override int GetHashCode() => Id.GetHashCode(); + + public override string ToString() => Symbol; + + public static bool operator ==(MeasurementUnit? a, MeasurementUnit? b) + { + if (a is null && b is null) + return true; + + if (a is null || b is null) + return false; + + return a.Equals(b); + } + + public static bool operator !=(MeasurementUnit? a, MeasurementUnit? b) + { + return !(a == b); + } +} diff --git a/src/Nox.Types/Types/Volume/Volume.cs b/src/Nox.Types/Types/Volume/Volume.cs index c62acb2..dc322ee 100644 --- a/src/Nox.Types/Types/Volume/Volume.cs +++ b/src/Nox.Types/Types/Volume/Volume.cs @@ -1,9 +1,52 @@ +using System.Collections.Generic; + namespace Nox.Types; +/// +/// Represents a Nox type and value object. +/// +public sealed class Volume : Measurement +{ + /// + /// Creates a new instance of object in cubic feet. + /// + /// The value to create the with + /// + /// + public static Volume FromCubicFeet(QuantityValue value) + => From(value, VolumeUnit.CubicFoot); + + /// + /// Creates a new instance of object in cubic meters. + /// + /// The origin value to create the with + /// + /// + public static Volume FromCubicMeters(QuantityValue value) + => From(value, VolumeUnit.CubicMeter); + /// - /// Represents a Nox type and value object. + /// Creates a new instance of object in cubic meters. /// - /// Placeholder, needs to be implemented - public sealed class Volume : ValueObject + /// The origin value to create the with + /// + /// + public new static Volume From(QuantityValue value) + => From(value, VolumeUnit.CubicMeter); + + private QuantityValue? _cubicFeet; + + public QuantityValue ToCubicFeet() => _cubicFeet ??= GetMeasurementIn(VolumeUnit.CubicFoot); + + private QuantityValue? _cubicMeters; + + public QuantityValue ToCubicMeters() => _cubicMeters ??= GetMeasurementIn(VolumeUnit.CubicMeter); + + protected override IEnumerable> GetEqualityComponents() { + yield return new KeyValuePair(nameof(Value), ToCubicMeters()); } + + protected override MeasurementConversionFactor ResolveUnitConversionFactor(VolumeUnit sourceUnit, VolumeUnit targetUnit) + => new VolumeConversionFactor(sourceUnit, targetUnit); +} \ No newline at end of file diff --git a/src/Nox.Types/Types/Volume/VolumeConversionFactor.cs b/src/Nox.Types/Types/Volume/VolumeConversionFactor.cs new file mode 100644 index 0000000..b983425 --- /dev/null +++ b/src/Nox.Types/Types/Volume/VolumeConversionFactor.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace Nox.Types; + +public class VolumeConversionFactor : MeasurementConversionFactor +{ + private static readonly Dictionary<(VolumeUnit, VolumeUnit), double> _definedVolumeConversionFactors = new() + { + { (VolumeUnit.CubicFoot, VolumeUnit.CubicMeter), 0.0283168466 }, + { (VolumeUnit.CubicMeter, VolumeUnit.CubicFoot), 35.3146667 }, + }; + + protected override Dictionary<(VolumeUnit, VolumeUnit), double> DefinedConversionFactors => _definedVolumeConversionFactors; + + public VolumeConversionFactor(VolumeUnit sourceUnit, VolumeUnit targetUnit) + : base(sourceUnit, targetUnit) + { + } +} \ No newline at end of file diff --git a/src/Nox.Types/Types/Volume/VolumeUnit.cs b/src/Nox.Types/Types/Volume/VolumeUnit.cs new file mode 100644 index 0000000..a301d4a --- /dev/null +++ b/src/Nox.Types/Types/Volume/VolumeUnit.cs @@ -0,0 +1,29 @@ +namespace Nox.Types; + +public class VolumeUnit : MeasurementUnit +{ + public static VolumeUnit CubicMeter { get; } = new VolumeUnit(1, "CubicMeter", "m³"); + public static VolumeUnit CubicFoot { get; } = new VolumeUnit(2, "CubicFoot", "ft³"); + + private VolumeUnit(int id, string name, string symbol) : base(id, name, symbol) + { + } +} + + +public class LengthUnit : MeasurementUnit +{ + public static LengthUnit Meter { get; } = new LengthUnit(1, "Meter", "m"); + public static LengthUnit Foot { get; } = new LengthUnit(2, "Foot", "ft"); + + protected LengthUnit(int id, string name, string symbol) : base(id, name, symbol) + { + } +} + +public class DistanceUnit : LengthUnit +{ + protected DistanceUnit(int id, string name, string symbol) : base(id, name, symbol) + { + } +} \ No newline at end of file diff --git a/tests/Nox.Types.Tests/Common/MeasurementConversionFactorTests.cs b/tests/Nox.Types.Tests/Common/MeasurementConversionFactorTests.cs index fa48e1f..132eed4 100644 --- a/tests/Nox.Types.Tests/Common/MeasurementConversionFactorTests.cs +++ b/tests/Nox.Types.Tests/Common/MeasurementConversionFactorTests.cs @@ -8,7 +8,7 @@ public class MeasurementConversionFactorTests [Fact] public void MeasurementUnitConverter_GetConversionFactor_FromFootToMeter_ReturnsValue() { - var factor = new MeasurementConversionFactor(MeasurementTypeUnit.Foot, MeasurementTypeUnit.Meter); + var factor = new Nox.Common.MeasurementConversionFactor(MeasurementTypeUnit.Foot, MeasurementTypeUnit.Meter); factor.Value.Should().Be(0.30480000033); } @@ -16,7 +16,7 @@ public void MeasurementUnitConverter_GetConversionFactor_FromFootToMeter_Returns [Fact] public void MeasurementUnitConverter_GetConversionFactor_FromMeterToFoot_ReturnsValue() { - var factor = new MeasurementConversionFactor(MeasurementTypeUnit.Meter, MeasurementTypeUnit.Foot); + var factor = new Nox.Common.MeasurementConversionFactor(MeasurementTypeUnit.Meter, MeasurementTypeUnit.Foot); factor.Value.Should().Be(3.28083989142); } @@ -24,7 +24,7 @@ public void MeasurementUnitConverter_GetConversionFactor_FromMeterToFoot_Returns [Fact] public void MeasurementUnitConverter_GetConversionFactor_FromKilometerToMile_ReturnsValue() { - var factor = new MeasurementConversionFactor(MeasurementTypeUnit.Kilometer, MeasurementTypeUnit.Mile); + var factor = new Nox.Common.MeasurementConversionFactor(MeasurementTypeUnit.Kilometer, MeasurementTypeUnit.Mile); factor.Value.Should().Be(0.62137119102); } @@ -32,7 +32,7 @@ public void MeasurementUnitConverter_GetConversionFactor_FromKilometerToMile_Ret [Fact] public void MeasurementUnitConverter_GetConversionFactor_FromMileToKilometer_ReturnsValue() { - var factor = new MeasurementConversionFactor(MeasurementTypeUnit.Mile, MeasurementTypeUnit.Kilometer); + var factor = new Nox.Common.MeasurementConversionFactor(MeasurementTypeUnit.Mile, MeasurementTypeUnit.Kilometer); factor.Value.Should().Be(1.60934400315); } @@ -40,7 +40,7 @@ public void MeasurementUnitConverter_GetConversionFactor_FromMileToKilometer_Ret [Fact] public void MeasurementUnitConverter_GetConversionFactor_FromSquareFootToSquareMeter_ReturnsValue() { - var factor = new MeasurementConversionFactor(MeasurementTypeUnit.SquareFoot, MeasurementTypeUnit.SquareMeter); + var factor = new Nox.Common.MeasurementConversionFactor(MeasurementTypeUnit.SquareFoot, MeasurementTypeUnit.SquareMeter); factor.Value.Should().Be(0.09290304); } @@ -48,7 +48,7 @@ public void MeasurementUnitConverter_GetConversionFactor_FromSquareFootToSquareM [Fact] public void MeasurementUnitConverter_GetConversionFactor_FromSquareMeterToSquareFoot_ReturnsValue() { - var factor = new MeasurementConversionFactor(MeasurementTypeUnit.SquareMeter, MeasurementTypeUnit.SquareFoot); + var factor = new Nox.Common.MeasurementConversionFactor(MeasurementTypeUnit.SquareMeter, MeasurementTypeUnit.SquareFoot); factor.Value.Should().Be(10.76391042); } @@ -56,7 +56,7 @@ public void MeasurementUnitConverter_GetConversionFactor_FromSquareMeterToSquare [Fact] public void MeasurementUnitConverter_GetConversionFactor_WithSameSourceAndTargetUnit_ReturnsValue() { - var factor = new MeasurementConversionFactor(MeasurementTypeUnit.Foot, MeasurementTypeUnit.Foot); + var factor = new Nox.Common.MeasurementConversionFactor(MeasurementTypeUnit.Foot, MeasurementTypeUnit.Foot); factor.Value.Should().Be(1); } @@ -64,7 +64,7 @@ public void MeasurementUnitConverter_GetConversionFactor_WithSameSourceAndTarget [Fact] public void MeasurementUnitConverter_GetConversionFactor_WithUnsupportedConversion_ThrowsException() { - var action = () => new MeasurementConversionFactor(MeasurementTypeUnit.SquareMeter, MeasurementTypeUnit.Meter); + var action = () => new Nox.Common.MeasurementConversionFactor(MeasurementTypeUnit.SquareMeter, MeasurementTypeUnit.Meter); action.Should().Throw() .WithMessage("No conversion defined from SquareMeter to Meter."); diff --git a/tests/Nox.Types.Tests/Types/Volume/VolumeConversionFactorTests.cs b/tests/Nox.Types.Tests/Types/Volume/VolumeConversionFactorTests.cs new file mode 100644 index 0000000..b2d4c5c --- /dev/null +++ b/tests/Nox.Types.Tests/Types/Volume/VolumeConversionFactorTests.cs @@ -0,0 +1,34 @@ +using FluentAssertions; + +namespace Nox.Types.Tests.Types; + +public class VolumeConversionFactorTests +{ + [Fact] + public void VolumeConversionFactor_FromCubicFootToCubicMeter_ReturnsValue() + { + var factor = new VolumeConversionFactor(VolumeUnit.CubicFoot, VolumeUnit.CubicMeter); + + factor.Value.Should().Be(0.0283168466); + } + + [Fact] + public void VolumeConversionFactor_FromCubicMeterToCubicFoot_ReturnsValue() + { + var factor = new VolumeConversionFactor(VolumeUnit.CubicMeter, VolumeUnit.CubicFoot); + + factor.Value.Should().Be(35.3146667); + } + + [Fact] + public void VolumeConversionFactor_WhenMultipliedByQuantityValue_ReturnsValue() + { + var factor = new VolumeConversionFactor(VolumeUnit.CubicMeter, VolumeUnit.CubicFoot); + + var result1 = (QuantityValue)2.5 * factor; + var result2 = factor * (QuantityValue)2.5; + + result1.Should().Be(result2); + result1.Should().Be(88.28666675); + } +} diff --git a/tests/Nox.Types.Tests/Types/Volume/VolumeTests.cs b/tests/Nox.Types.Tests/Types/Volume/VolumeTests.cs index 3d95f15..f36ebc0 100644 --- a/tests/Nox.Types.Tests/Types/Volume/VolumeTests.cs +++ b/tests/Nox.Types.Tests/Types/Volume/VolumeTests.cs @@ -1,11 +1,230 @@ // ReSharper disable once CheckNamespace +using FluentAssertions; +using System.Globalization; + namespace Nox.Types.Tests.Types; public class VolumeTests { [Fact] - public void When_Create_Should() + public void Volume_Constructor_ReturnsSameValueAndDefaultUnit() + { + var volume = Volume.From(27.1828); + + volume.Value.Should().Be(27.1828); + volume.Unit.Should().Be(VolumeUnit.CubicMeter); + } + + [Fact] + public void Volume_Constructor_ReturnsRoundedValueAndDefaultUnit() + { + var volume = Volume.From(27.18281828459045); + + volume.Value.Should().Be(27.182818); + volume.Unit.Should().Be(VolumeUnit.CubicMeter); + } + + [Fact] + public void Volume_Constructor_WithUnit_ReturnsSameValueAndUnit() + { + var volume = Volume.From(27.1828, VolumeUnit.CubicMeter); + + volume.Value.Should().Be(27.1828); + volume.Unit.Should().Be(VolumeUnit.CubicMeter); + } + + [Fact] + public void Volume_Constructor_WithUnitInCubicMeters_ReturnsSameValueAndUnit() + { + var volume = Volume.FromCubicMeters(27.1828); + + volume.Value.Should().Be(27.1828); + volume.Unit.Should().Be(VolumeUnit.CubicMeter); + } + + [Fact] + public void Volume_Constructor_WithUnitInCubicFeet_ReturnsSameValueAndUnit() + { + var volume = Volume.FromCubicFeet(959.951522); + + volume.Value.Should().Be(959.951522); + volume.Unit.Should().Be(VolumeUnit.CubicFoot); + } + + [Fact] + public void Volume_Constructor_WithNegativeValueInput_ThrowsException() + { + var action = () => Volume.From(-27.1828); + + action.Should().Throw() + .And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", "Could not create a Nox Volume type as negative volume value -27.1828 is not allowed.") }); + } + + [Fact] + public void Volume_Constructor_WithNaNValueInput_ThrowsException() + { + var action = () => Volume.From(double.NaN); + + action.Should().Throw() + .And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", "Could not create a Nox type as value NaN is not allowed.") }); + } + + [Fact] + public void Volume_Constructor_WithPositiveInfinityValueInput_ThrowsException() + { + var action = () => Volume.From(double.PositiveInfinity); + + action.Should().Throw() + .And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", "Could not create a Nox type as value Infinity is not allowed.") }); + } + + [Fact] + public void Volume_Constructor_WithNegativeInfinityValueInput_ThrowsException() + { + var action = () => Volume.From(double.NegativeInfinity); + + action.Should().Throw() + .And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", "Could not create a Nox type as value Infinity is not allowed.") }); + } + + [Fact] + public void Volume_ToCubicMeters_ReturnsValue() + { + var volume = Volume.From(27.1828); + + volume.ToCubicMeters().Should().Be(27.1828); + } + + [Fact] + public void Volume_ToCubicFeet_ReturnsValue() + { + var volume = Volume.From(27.1828); + + volume.ToCubicFeet().Should().Be(959.951522); + } + + [Theory] + [InlineData("en-US")] + [InlineData("pt-PT")] + public void Volume_ValueInCubicMeters_ToString_IsCultureIndepdendent(string culture) + { + void Test() + { + var volume = Volume.FromCubicMeters(27.1828); + volume.ToString().Should().Be("27.1828 m³"); + } + + TestUtility.RunInCulture(Test, culture); + } + + [Theory] + [InlineData("en-US", "27.1828 m³")] + [InlineData("pt-PT", "27,1828 m³")] + public void Volume_ValueInCubicMeters_ToString_IsCultureDependent(string culture, string expected) + { + void Test() + { + var volume = Volume.FromCubicMeters(27.1828); + volume.ToString(new CultureInfo(culture)).Should().Be(expected); + } + + TestUtility.RunInCulture(Test, culture); + } + + [Theory] + [InlineData("en-US")] + [InlineData("pt-PT")] + public void Volume_ValueInCubicFeet_ToString_IsCultureIndependent(string culture) + { + void Test() + { + var volume = Volume.FromCubicFeet(959.951522); + volume.ToString().Should().Be("959.951522 ft³"); + } + + TestUtility.RunInCulture(Test, culture); + } + + [Theory] + [InlineData("en-US", "959.951522 ft³")] + [InlineData("pt-PT", "959,951522 ft³")] + public void Volume_ValueInCubicFeet_ToString_IsCultureDependent(string culture, string expected) + { + void Test() + { + var volume = Volume.FromCubicFeet(959.951522); + volume.ToString(new CultureInfo(culture)).Should().Be(expected); + } + + TestUtility.RunInCulture(Test, culture); + } + + [Fact] + public void Volume_Equality_WithSameVolumeUnit_Tests() { + var volume1 = Volume.From(27.1828, VolumeUnit.CubicMeter); + + var volume2 = Volume.From(27.1828, VolumeUnit.CubicMeter); + + AssertAreEquivalent(volume1, volume2); + } + + [Fact] + public void Volume_Equality_WithDifferentVolumeUnit_Tests() + { + var volume1 = Volume.From(27.1828, VolumeUnit.CubicMeter); + + var volume2 = Volume.From(959.951522, VolumeUnit.CubicFoot); + + AssertAreEquivalent(volume1, volume2); + } + + [Fact] + public void Volume_NonEquality_SpecifyingVolumeUnit_WithSameUnit_Tests() + { + var volume1 = Volume.From(27.1828, VolumeUnit.CubicMeter); + + var volume2 = Volume.From(959.951522, VolumeUnit.CubicMeter); + + AssertAreNotEquivalent(volume1, volume2); + } + + [Fact] + public void Volume_NonEquality_SpecifyingVolumeUnit_WithDifferentUnit_Tests() + { + var volume1 = Volume.From(27.1828, VolumeUnit.CubicMeter); + + var volume2 = Volume.From(27.1828, VolumeUnit.CubicFoot); + + AssertAreNotEquivalent(volume1, volume2); + } + + private static void AssertAreEquivalent(Volume expected, Volume actual) + { + actual.Should().Be(expected); + + expected.Equals(actual).Should().BeTrue(); + + actual.Equals(expected).Should().BeTrue(); + + (expected == actual).Should().BeTrue(); + + (expected != actual).Should().BeFalse(); + } + + private static void AssertAreNotEquivalent(Volume expected, Volume actual) + { + var a =LengthUnit.Foot; + var b = DistanceUnit.Foot; + + actual.Should().NotBe(expected); + + expected.Equals(actual).Should().BeFalse(); + + actual.Equals(expected).Should().BeFalse(); + + (expected == actual).Should().BeFalse(); + (expected != actual).Should().BeTrue(); } } \ No newline at end of file diff --git a/tests/Nox.Types.Tests/Types/Volume/VolumeUnitTests.cs b/tests/Nox.Types.Tests/Types/Volume/VolumeUnitTests.cs new file mode 100644 index 0000000..311b8d0 --- /dev/null +++ b/tests/Nox.Types.Tests/Types/Volume/VolumeUnitTests.cs @@ -0,0 +1,26 @@ +using FluentAssertions; + +namespace Nox.Types.Tests.Types; + +public class VolumeUnitTests +{ + [Fact] + public void VolumeUnit_CubicMeter_ReturnsValidIdNameAndSymbol() + { + var cubicMeter = VolumeUnit.CubicMeter; + + cubicMeter.Id.Should().Be(1); + cubicMeter.Name.Should().Be("CubicMeter"); + cubicMeter.Symbol.Should().Be("m³"); + } + + [Fact] + public void VolumeUnit_CubicFoot_ReturnsValidIdNameAndSymbol() + { + var cubicMeter = VolumeUnit.CubicFoot; + + cubicMeter.Id.Should().Be(2); + cubicMeter.Name.Should().Be("CubicFoot"); + cubicMeter.Symbol.Should().Be("ft³"); + } +}