Skip to content

Commit

Permalink
Add BaseDimensions for TemperatureDelta & tests for operators (angula…
Browse files Browse the repository at this point in the history
…rsen#840)

- 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)
  • Loading branch information
lipchev authored Sep 21, 2020
1 parent c902f0f commit f3c61d3
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Common/UnitDefinitions/TemperatureDelta.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
119 changes: 118 additions & 1 deletion UnitsNet.Tests/GeneratedQuantityCodeTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Xunit;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace UnitsNet.Tests
{
Expand Down Expand Up @@ -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<Type> 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<Type> 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));
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion UnitsNet/GeneratedCode/Quantities/TemperatureDelta.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f3c61d3

Please sign in to comment.