From 3868366f3dc25b983d7ac5c1ec25ea187b7e1cb9 Mon Sep 17 00:00:00 2001 From: lipchev Date: Mon, 21 Sep 2020 04:10:36 +0300 Subject: [PATCH] Add BaseDimensions for TemperatureDelta & tests for operators - Added tests for the multiplication and division operators of all quantities: testing for a mismatch between the dimensions of the operands and the result - Operators marked as obsolete are skipped (e.g. Density / Mass ) - Added the missing BaseDimensions for TemperatureDelta (being the only unit failing the tests) --- Common/UnitDefinitions/TemperatureDelta.json | 3 + UnitsNet.Tests/GeneratedQuantityCodeTests.cs | 119 +++++++++++++++++- .../Quantities/TemperatureDelta.g.cs | 2 +- .../Quantities/TemperatureDelta.g.cs | 2 +- 4 files changed, 123 insertions(+), 3 deletions(-) diff --git a/Common/UnitDefinitions/TemperatureDelta.json b/Common/UnitDefinitions/TemperatureDelta.json index b7dd5c66b5..764065c0ed 100644 --- a/Common/UnitDefinitions/TemperatureDelta.json +++ b/Common/UnitDefinitions/TemperatureDelta.json @@ -2,6 +2,9 @@ "Name": "TemperatureDelta", "BaseUnit": "Kelvin", "XmlDoc": "Difference between two temperatures. The conversions are different than for Temperature.", + "BaseDimensions": { + "Θ": 1 + }, "Units": [ { "SingularName": "Kelvin", diff --git a/UnitsNet.Tests/GeneratedQuantityCodeTests.cs b/UnitsNet.Tests/GeneratedQuantityCodeTests.cs index 4f188897f4..d02428161f 100644 --- a/UnitsNet.Tests/GeneratedQuantityCodeTests.cs +++ b/UnitsNet.Tests/GeneratedQuantityCodeTests.cs @@ -1,4 +1,7 @@ -using Xunit; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; namespace UnitsNet.Tests { @@ -27,6 +30,120 @@ public void LengthEquals_GivenMaxError_ReturnsTrueIfWithinError() "Example of floating precision arithmetic that produces slightly different results."); Assert.True(Length.FromMeters(1 + 0.39).Equals(Length.FromMeters(1.39), smallError, ComparisonType.Relative), "But the difference is very small"); } + + [Fact] + public void HasMultiplicationOperator_GivenMassAndVolume_ReturnsFalse() + { + Assert.False(HasMultiplicationOperator(typeof(Mass), typeof(Volume))); + Assert.DoesNotContain(typeof(Volume), GetMultipliers(typeof(Mass))); + } + + [Fact] + public void HasMultiplicationOperator_GivenDensityAndVolume_ReturnsTrue() + { + Assert.True(HasMultiplicationOperator(typeof(Density), typeof(Volume))); + Assert.Contains(typeof(Volume), GetMultipliers(typeof(Density))); + Assert.Equal(typeof(Mass), GetMultiplicationResult(typeof(Density), typeof(Volume))); + } + + [Fact] + public void HasDivisionOperator_GivenDensityAndVolume_ReturnsFalse() + { + Assert.False(HasDivisionOperator(typeof(Density), typeof(Volume))); + Assert.DoesNotContain(typeof(Volume), GetDivisors(typeof(Density))); + } + + [Fact] + public void HasDivisionOperator_GivenMassAndVolume_ReturnsTrue() + { + Assert.True(HasDivisionOperator(typeof(Mass), typeof(Volume))); + Assert.Contains(typeof(Volume), GetDivisors(typeof(Mass))); + Assert.Equal(typeof(Density), GetDivisionResult(typeof(Mass), typeof(Volume))); + } + + [Fact] + public void HasMultiplicationOperator_GivenTwoQuantities_ReturnsTrueIfDimensionsMultiplicationIsValid() + { + foreach (var firstQuantity in Quantity.Infos) + { + foreach (var divisor in GetMultipliers(firstQuantity.ValueType)) + { + var secondQuantity = Quantity.Infos.FirstOrDefault(x => x.ValueType == divisor); + if (secondQuantity == null) + { + continue; // scalers + } + var resultDimensions = firstQuantity.BaseDimensions * secondQuantity.BaseDimensions; + var resultingType = GetMultiplicationResult(firstQuantity.ValueType, secondQuantity.ValueType); + var resultQuantity = Quantity.Infos.FirstOrDefault(x => x.ValueType == resultingType); + if (resultQuantity == null) + { + continue; // scalers + } + Assert.Equal(resultQuantity.BaseDimensions, resultDimensions); + } + } + } + + [Fact] + public void HasDivisionOperator_GivenTwoQuantities_ReturnsTrueIfDimensionsDivisionIsValid() + { + foreach (var firstQuantity in Quantity.Infos) + { + foreach (var divisor in GetDivisors(firstQuantity.ValueType)) + { + var secondQuantity = Quantity.Infos.FirstOrDefault(x => x.ValueType == divisor); + if (secondQuantity == null) + { + continue; // scalers + } + var resultDimensions = firstQuantity.BaseDimensions / secondQuantity.BaseDimensions; + var resultingType = GetDivisionResult(firstQuantity.ValueType, secondQuantity.ValueType); + var resultQuantity = Quantity.Infos.FirstOrDefault(x => x.ValueType == resultingType); + if (resultQuantity == null) + { + continue; // scalers + } + Assert.Equal(resultQuantity.BaseDimensions, resultDimensions); + } + } + } + + private static bool HasMultiplicationOperator(Type t, Type operandType) + { + var operation = t.GetMethod("op_Multiply", new[] { t, operandType }); + return operation != null && operation.IsSpecialName; + } + + private static bool HasDivisionOperator(Type t, Type operandType) + { + var operation = t.GetMethod("op_Division", new[] { t, operandType }); + return operation != null && operation.IsSpecialName; + } + + private static Type GetMultiplicationResult(Type t, Type operandType) + { + var operation = t.GetMethod("op_Multiply", new[] { t, operandType }); + return operation != null && operation.IsSpecialName ? operation.ReturnType : null; + } + + private static Type GetDivisionResult(Type t, Type operandType) + { + var operation = t.GetMethod("op_Division", new[] { t, operandType }); + return operation != null && operation.IsSpecialName ? operation.ReturnType : null; + } + + private static IEnumerable GetMultipliers(Type t) + { + return t.GetMethods().Where(x => x.IsSpecialName && x.Name == "op_Multiply" && x.CustomAttributes.All(a => a.AttributeType != typeof(ObsoleteAttribute))) + .SelectMany(x => x.GetParameters().Skip(1).Select(p => p.ParameterType)); + } + + private static IEnumerable GetDivisors(Type t) + { + return t.GetMethods().Where(x => x.IsSpecialName && x.Name == "op_Division" && x.CustomAttributes.All(a => a.AttributeType != typeof(ObsoleteAttribute))) + .SelectMany(x => x.GetParameters().Skip(1).Select(p => p.ParameterType)); + } } } } diff --git a/UnitsNet.WindowsRuntimeComponent/GeneratedCode/Quantities/TemperatureDelta.g.cs b/UnitsNet.WindowsRuntimeComponent/GeneratedCode/Quantities/TemperatureDelta.g.cs index 1144b0cfc6..be7718efbd 100644 --- a/UnitsNet.WindowsRuntimeComponent/GeneratedCode/Quantities/TemperatureDelta.g.cs +++ b/UnitsNet.WindowsRuntimeComponent/GeneratedCode/Quantities/TemperatureDelta.g.cs @@ -48,7 +48,7 @@ public sealed partial class TemperatureDelta : IQuantity static TemperatureDelta() { - BaseDimensions = BaseDimensions.Dimensionless; + BaseDimensions = new BaseDimensions(0, 0, 0, 0, 1, 0, 0); Info = new QuantityInfo(QuantityType.TemperatureDelta, Units.Cast().ToArray(), BaseUnit, Zero, BaseDimensions); } diff --git a/UnitsNet/GeneratedCode/Quantities/TemperatureDelta.g.cs b/UnitsNet/GeneratedCode/Quantities/TemperatureDelta.g.cs index c848c80097..fe358ebe1a 100644 --- a/UnitsNet/GeneratedCode/Quantities/TemperatureDelta.g.cs +++ b/UnitsNet/GeneratedCode/Quantities/TemperatureDelta.g.cs @@ -48,7 +48,7 @@ public partial struct TemperatureDelta : IQuantity, IEquat static TemperatureDelta() { - BaseDimensions = BaseDimensions.Dimensionless; + BaseDimensions = new BaseDimensions(0, 0, 0, 0, 1, 0, 0); Info = new QuantityInfo(QuantityType.TemperatureDelta, new UnitInfo[] {