From c0ec7ba664a3cc261ccc61ddf21d5412867765c0 Mon Sep 17 00:00:00 2001 From: Andy Ward Date: Mon, 11 Mar 2024 09:10:54 +0000 Subject: [PATCH] Fixes for edgecase testcases relating to casting, coercion and parsing integers/ reals --- .../Constraints/ValueContraintTests.cs | 55 ++++++++++++++++++- .../Values/TypeNames.cs | 2 +- .../Values/ValueConstraint.cs | 33 ++++++++++- .../Xbim.InformationSpecifications.csproj | 2 +- .../Xids.AssemblyVersion.cs | 2 +- 5 files changed, 88 insertions(+), 6 deletions(-) diff --git a/Xbim.InformationSpecifications.NewTests/Constraints/ValueContraintTests.cs b/Xbim.InformationSpecifications.NewTests/Constraints/ValueContraintTests.cs index 605c974..17de1d2 100644 --- a/Xbim.InformationSpecifications.NewTests/Constraints/ValueContraintTests.cs +++ b/Xbim.InformationSpecifications.NewTests/Constraints/ValueContraintTests.cs @@ -270,7 +270,7 @@ public void DecimalRangesAreInclusive() vc.AddAccepted(t); vc.IsSatisfiedBy(42.1).Should().BeFalse("40.1 failure"); - vc.IsSatisfiedBy(41.999999f).Should().BeFalse("41.9999 failure"); + vc.IsSatisfiedBy(41.99999f).Should().BeFalse("41.9999 failure"); // Note 41.99999f rounds to 42.0 so will satisfy vc.IsSatisfiedBy(42L).Should().BeTrue("42L failure"); vc.IsSatisfiedBy(42M).Should().BeTrue("42M failure"); vc.IsSatisfiedBy(42d).Should().BeTrue("42d failure"); @@ -461,6 +461,59 @@ public void RealHelperBoundsPrecisionTests(double value, double expectedLower, d upper.Should().BeApproximately(expectedUpper, 1e-10); } + [InlineData("42")] + [InlineData("42.0")] + [InlineData("42.")] + [InlineData("-42", -42)] + [InlineData("-42.0", -42)] + [InlineData("-42.", -42)] + [InlineData("0", 0)] + [InlineData("0.", 0)] + [InlineData("0.0", 0)] + [Theory] + public void UndefinedIntegerParsingSupportsRedundantDecimals(string intText, int expected = 42) + { + // Integer Parsing should permit specification of a zero decimal + + // from attribute/pass-integers_follow_the_same_rules_as_numbers_2_2 + // /property/pass-integer_values_are_checked_using_type_casting_3_4.ifc + var constraint = new ValueConstraint(NetTypeName.Undefined); + var exact = new ExactConstraint(intText); + constraint.AddAccepted(exact); + + constraint.IsSatisfiedBy(expected).Should().BeTrue(); + } + + [Fact] + public void TypedIntegerRangesAreSatisfiedByReals() + { + // E.g. Integer Range Constraint 0 <= x <= 10 can be satified by 5d + // from restriction/pass-a_bound_can_be_inclusive_2_3.ifc etc + + var constraint = new ValueConstraint(NetTypeName.Integer); + var exact = new RangeConstraint("0",true, "10", true); + constraint.AddAccepted(exact); + + constraint.IsSatisfiedBy(5d).Should().BeTrue("Double"); + constraint.IsSatisfiedBy(5f).Should().BeTrue("Float"); + constraint.IsSatisfiedBy(5.0m).Should().BeTrue("Decimal"); + } + + [Fact] + public void TypedRealRangesAreSatisfiedByIntegers() + { + // E.g. Real Range Constraint 0d <= x <= 10d can be satified by 5L + + var constraint = new ValueConstraint(NetTypeName.Floating); + var exact = new RangeConstraint("0", true, "10", true); + constraint.AddAccepted(exact); + + constraint.IsSatisfiedBy(5L).Should().BeTrue("Long"); + constraint.IsSatisfiedBy(5).Should().BeTrue("Int"); + // And other reals + constraint.IsSatisfiedBy(5f).Should().BeTrue("Float"); + constraint.IsSatisfiedBy(5.0m).Should().BeTrue("Decimal"); + } [Fact] diff --git a/Xbim.InformationSpecifications/Values/TypeNames.cs b/Xbim.InformationSpecifications/Values/TypeNames.cs index cd780da..69ad5cd 100644 --- a/Xbim.InformationSpecifications/Values/TypeNames.cs +++ b/Xbim.InformationSpecifications/Values/TypeNames.cs @@ -334,7 +334,7 @@ public enum Constraints return value; case NetTypeName.Integer: // TODO:Review handling of longs - if (int.TryParse(value, NumberStyles.Integer, culture, out var ival)) + if (int.TryParse(value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, culture, out var ival)) return ival; return null; case NetTypeName.Floating: diff --git a/Xbim.InformationSpecifications/Values/ValueConstraint.cs b/Xbim.InformationSpecifications/Values/ValueConstraint.cs index 325640c..545be0e 100644 --- a/Xbim.InformationSpecifications/Values/ValueConstraint.cs +++ b/Xbim.InformationSpecifications/Values/ValueConstraint.cs @@ -118,12 +118,17 @@ static private bool IsCompatible([NotNullWhen(true)] Type? destType, Type passed destType == typeof(long) // int64 ) { - if (typeof(double) == passedType) - return false; if (typeof(int) == passedType) return true; if (typeof(long) == passedType) return true; + // Reals can be compatible (sometimes). e.g. 5.0d == 5l + if (typeof(double) == passedType) + return true; + if (typeof(float) == passedType) + return true; + if (typeof(decimal) == passedType) + return true; } if (destType == typeof(decimal)) { @@ -134,6 +139,30 @@ static private bool IsCompatible([NotNullWhen(true)] Type? destType, Type passed if (typeof(long) == passedType) return true; } + if (destType == typeof(double)) + { + if (typeof(double) == passedType) + return true; + if (typeof(float) == passedType) + return true; + if (typeof(decimal) == passedType) + return true; + if (typeof(int) == passedType) + return true; + if (typeof(long) == passedType) + return true; + } + if (destType == typeof(float)) + { + if (typeof(float) == passedType) + return true; + if (typeof(decimal) == passedType) + return true; + if (typeof(int) == passedType) + return true; + if (typeof(long) == passedType) + return true; + } if (destType.IsAssignableFrom(passedType)) return true; if (destType == typeof(string)) diff --git a/Xbim.InformationSpecifications/Xbim.InformationSpecifications.csproj b/Xbim.InformationSpecifications/Xbim.InformationSpecifications.csproj index 7387511..b83565d 100644 --- a/Xbim.InformationSpecifications/Xbim.InformationSpecifications.csproj +++ b/Xbim.InformationSpecifications/Xbim.InformationSpecifications.csproj @@ -19,7 +19,7 @@ Xbim.InformationSpecifications Xbim.InformationSpecifications - 0.96.0 + 0.96.1 $(AssemblyVersion) $(AssemblyVersion) diff --git a/Xbim.InformationSpecifications/Xids.AssemblyVersion.cs b/Xbim.InformationSpecifications/Xids.AssemblyVersion.cs index aa4b0af..e252096 100644 --- a/Xbim.InformationSpecifications/Xids.AssemblyVersion.cs +++ b/Xbim.InformationSpecifications/Xids.AssemblyVersion.cs @@ -7,6 +7,6 @@ public partial class Xids /// This is useful for environments that do not allow to load information from the DLL dynamically /// (e.g. Blazor). /// - public static string AssemblyVersion => "0.96.0"; + public static string AssemblyVersion => "0.96.1"; } }