From f3fc74ae88c3b8341429c8f484b0e2a2298d8e41 Mon Sep 17 00:00:00 2001 From: Dejan Bratic Date: Fri, 30 Jun 2023 15:57:59 +0200 Subject: [PATCH] measurement conversion factor changed to abstract generic class; added volume conversion factor; --- src/Nox.Types/Types/Volume/Measurement.cs | 6 ++-- .../Volume/MeasurementConversionFactor.cs | 29 ++++++++-------- src/Nox.Types/Types/Volume/Volume.cs | 3 ++ .../Types/Volume/VolumeConversionFactor.cs | 19 +++++++++++ src/Nox.Types/Types/Volume/VolumeUnit.cs | 18 ++++++++++ .../MeasurementConversionFactorTests.cs | 22 ------------ .../Volume/VolumeConversionFactorTests.cs | 34 +++++++++++++++++++ .../Types/Volume/VolumeTests.cs | 3 ++ 8 files changed, 95 insertions(+), 39 deletions(-) create mode 100644 src/Nox.Types/Types/Volume/VolumeConversionFactor.cs delete mode 100644 tests/Nox.Types.Tests/Types/Volume/MeasurementConversionFactorTests.cs create mode 100644 tests/Nox.Types.Tests/Types/Volume/VolumeConversionFactorTests.cs diff --git a/src/Nox.Types/Types/Volume/Measurement.cs b/src/Nox.Types/Types/Volume/Measurement.cs index 57cd9b1..211d2eb 100644 --- a/src/Nox.Types/Types/Volume/Measurement.cs +++ b/src/Nox.Types/Types/Volume/Measurement.cs @@ -65,12 +65,14 @@ public override string ToString() public string ToString(IFormatProvider formatProvider) => $"{Value.ToString(formatProvider)} {Unit}"; - protected QuantityValue GetMeasurementIn(MeasurementUnit targetUnit) + protected QuantityValue GetMeasurementIn(TUnitType targetUnit) { - var factor = new MeasurementConversionFactor(Unit, targetUnit).Value; + 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 index 2e6ea76..72a196c 100644 --- a/src/Nox.Types/Types/Volume/MeasurementConversionFactor.cs +++ b/src/Nox.Types/Types/Volume/MeasurementConversionFactor.cs @@ -3,35 +3,34 @@ namespace Nox.Types; -public class MeasurementConversionFactor +public abstract class MeasurementConversionFactor where TUnitType : MeasurementUnit { - private static readonly Dictionary<(VolumeUnit, VolumeUnit), double> DefinedVolumeConversionFactors = new() - { - { (VolumeUnit.CubicFoot, VolumeUnit.CubicMeter), 0.0283168466 }, - { (VolumeUnit.CubicMeter, VolumeUnit.CubicFoot), 35.3146667 }, - }; + protected abstract Dictionary<(TUnitType, TUnitType), double> DefinedConversionFactors { get; } public double Value { get; } - public MeasurementConversionFactor(MeasurementUnit sourceUnit, MeasurementUnit targetUnit) + protected MeasurementConversionFactor(TUnitType sourceUnit, TUnitType targetUnit) { Value = ResolveConversionFactor(sourceUnit, targetUnit); } - private static double ResolveConversionFactor(MeasurementUnit sourceUnit, MeasurementUnit targetUnit) + private double ResolveConversionFactor(TUnitType sourceUnit, TUnitType targetUnit) { + var conversion = (sourceUnit, targetUnit); - if (sourceUnit is VolumeUnit volumeSourceUnit && targetUnit is VolumeUnit volumeTargetUnit) - { - var conversion = (volumeSourceUnit, volumeTargetUnit); + if (DefinedConversionFactors.ContainsKey(conversion)) + return DefinedConversionFactors[conversion]; - if (DefinedVolumeConversionFactors.ContainsKey(conversion)) - return DefinedVolumeConversionFactors[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/Volume.cs b/src/Nox.Types/Types/Volume/Volume.cs index 03d7c10..dc322ee 100644 --- a/src/Nox.Types/Types/Volume/Volume.cs +++ b/src/Nox.Types/Types/Volume/Volume.cs @@ -46,4 +46,7 @@ protected override IEnumerable> GetEqualityComponen { 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 index 5e1ac37..a301d4a 100644 --- a/src/Nox.Types/Types/Volume/VolumeUnit.cs +++ b/src/Nox.Types/Types/Volume/VolumeUnit.cs @@ -9,3 +9,21 @@ 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/Types/Volume/MeasurementConversionFactorTests.cs b/tests/Nox.Types.Tests/Types/Volume/MeasurementConversionFactorTests.cs deleted file mode 100644 index 90693b4..0000000 --- a/tests/Nox.Types.Tests/Types/Volume/MeasurementConversionFactorTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -using FluentAssertions; - -namespace Nox.Types.Tests.Types; - -public class MeasurementConversionFactorTests -{ - [Fact] - public void MeasurementConversionFactor_GetConversionFactor_FromCubicFootToCubicMeter_ReturnsValue() - { - var factor = new MeasurementConversionFactor(VolumeUnit.CubicFoot, VolumeUnit.CubicMeter); - - factor.Value.Should().Be(0.0283168466); - } - - [Fact] - public void MeasurementConversionFactor_GetConversionFactor_FromCubicMeterToCubicFoot_ReturnsValue() - { - var factor = new MeasurementConversionFactor(VolumeUnit.CubicMeter, VolumeUnit.CubicFoot); - - factor.Value.Should().Be(35.3146667); - } -} 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 83b0feb..f36ebc0 100644 --- a/tests/Nox.Types.Tests/Types/Volume/VolumeTests.cs +++ b/tests/Nox.Types.Tests/Types/Volume/VolumeTests.cs @@ -214,6 +214,9 @@ private static void AssertAreEquivalent(Volume expected, Volume actual) 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();