From f6dde057941937352840effe35fa08b73c26cce5 Mon Sep 17 00:00:00 2001 From: Ivan Zlatev Date: Tue, 2 Aug 2016 13:03:00 +0100 Subject: [PATCH] Port of "Added support for decimals for ShouldBeCloseTo method" from #16 from meinsiedler/ShouldBeCloseTo_ForDecimals --- .../ShouldBeCloseToSpecs.cs | 237 ++++++++++++++++++ .../ShouldExtensionMethods.cs | 16 ++ 2 files changed, 253 insertions(+) create mode 100644 Machine.Specifications.Should.Specs/ShouldBeCloseToSpecs.cs diff --git a/Machine.Specifications.Should.Specs/ShouldBeCloseToSpecs.cs b/Machine.Specifications.Should.Specs/ShouldBeCloseToSpecs.cs new file mode 100644 index 0000000..0f26df9 --- /dev/null +++ b/Machine.Specifications.Should.Specs/ShouldBeCloseToSpecs.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Machine.Specifications.Should.Specs +{ + [Subject(typeof(ShouldExtensionMethods))] + public class when_asserting_that_a_value_should_be_close_to_another_value + { + static Exception Exception; + + public class and_values_are_of_type__double__ + { + static double Actual; + static double Expected; + + Establish context = () => Expected = 0; + + public class and_default_tolerance_is_used + { + public class and_actual_is_within_the_tolerance + { + Establish context = () => Actual = 0.00000005; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected)); + + It should_not_throw = () => Exception.ShouldBeNull(); + } + + public class and_actual_is_not_within_the_tolerance + { + Establish context = () => Actual = 0.00000015; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected)); + + It should_throw = () => Exception.ShouldBeOfExactType(); + } + } + + public class and_custom_tolerance_is_used + { + static double Tolerance; + + Establish context = () => Tolerance = 0.01; + + public class and_actual_is_within_the_tolerance + { + Establish context = () => Actual = 0.005; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_not_throw = () => Exception.ShouldBeNull(); + } + + public class and_actual_is_not_within_the_tolerance + { + Establish context = () => Actual = 0.015; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_throw = () => Exception.ShouldBeOfExactType(); + } + } + } + + public class and_values_are_of_type__float__ + { + static float Actual; + static float Expected; + + Establish context = () => Expected = 0f; + + public class and_default_tolerance_is_used + { + public class and_actual_is_within_the_tolerance + { + Establish context = () => Actual = 0.0000001f; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected)); + + It should_not_throw = () => Exception.ShouldBeNull(); + } + + public class and_actual_is_not_within_the_tolerance + { + Establish context = () => Actual = 0.0000002f; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected)); + + It should_throw = () => Exception.ShouldBeOfExactType(); + } + } + + public class and_custom_tolerance_is_used + { + static float Tolerance; + + Establish context = () => Tolerance = 0.01f; + + public class and_actual_is_within_the_tolerance + { + Establish context = () => Actual = 0.005f; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_not_throw = () => Exception.ShouldBeNull(); + } + + public class and_actual_is_not_within_the_tolerance + { + Establish context = () => Actual = 0.015f; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_throw = () => Exception.ShouldBeOfExactType(); + } + } + } + + public class and_values_are_of_type__decimal__ + { + static decimal Actual; + static decimal Expected; + + Establish context = () => Expected = 0m; + + public class and_default_tolerance_is_used + { + public class and_actual_is_within_the_tolerance + { + Establish context = () => Actual = 0.00000005m; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected)); + + It should_not_throw = () => Exception.ShouldBeNull(); + } + + public class and_actual_is_not_within_the_tolerance + { + Establish context = () => Actual = 0.00000015m; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected)); + + It should_throw = () => Exception.ShouldBeOfExactType(); + } + } + + public class and_custom_tolerance_is_used + { + static decimal Tolerance; + + Establish context = () => Tolerance = 0.01m; + + public class and_actual_is_within_the_tolerance + { + Establish context = () => Actual = 0.005m; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_not_throw = () => Exception.ShouldBeNull(); + } + + public class and_actual_is_not_within_the_tolerance + { + Establish context = () => Actual = 0.015m; + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_throw = () => Exception.ShouldBeOfExactType(); + } + } + } + + public class and_values_are_of_type__TimeSpan__ + { + static TimeSpan Actual; + static TimeSpan Expected; + static TimeSpan Tolerance; + + Establish context = () => + { + Expected = new TimeSpan(ticks: 1000); + Tolerance = new TimeSpan(10); + }; + + public class and_actual_is_within_the_tolerance + { + Establish context = () => Actual = new TimeSpan(1005); + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_not_throw = () => Exception.ShouldBeNull(); + } + + public class and_actual_is_not_within_the_tolerance + { + Establish context = () => Actual = new TimeSpan(1015); + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_throw = () => Exception.ShouldBeOfExactType(); + } + } + + public class and_values_are_of_type__DateTime__ + { + static DateTime Actual; + static DateTime Expected; + static TimeSpan Tolerance; + + Establish context = () => + { + Expected = new DateTime(ticks:1000); + Tolerance = new TimeSpan(10); + }; + + public class and_actual_is_within_the_tolerance + { + Establish context = () => Actual = new DateTime(1005); + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_not_throw = () => Exception.ShouldBeNull(); + } + + public class and_actual_is_not_within_the_tolerance + { + Establish context = () => Actual = new DateTime(1015); + + Because of = () => Exception = Catch.Exception(() => Actual.ShouldBeCloseTo(Expected, Tolerance)); + + It should_throw = () => Exception.ShouldBeOfExactType(); + } + } + } +} diff --git a/Machine.Specifications.Should/ShouldExtensionMethods.cs b/Machine.Specifications.Should/ShouldExtensionMethods.cs index 0f46129..5912d5b 100644 --- a/Machine.Specifications.Should/ShouldExtensionMethods.cs +++ b/Machine.Specifications.Should/ShouldExtensionMethods.cs @@ -408,6 +408,22 @@ public static void ShouldBeCloseTo(this double actual, double expected, double t } } + public static void ShouldBeCloseTo(this decimal actual, decimal expected) + { + ShouldBeCloseTo(actual, expected, 0.0000001m); + } + + public static void ShouldBeCloseTo(this decimal actual, decimal expected, decimal tolerance) + { + if (Math.Abs(actual - expected) > tolerance) + { + throw new SpecificationException(string.Format("Should be within {0} of {1} but is {2}", + tolerance.ToUsefulString(), + expected.ToUsefulString(), + actual.ToUsefulString())); + } + } + public static void ShouldBeCloseTo(this TimeSpan actual, TimeSpan expected, TimeSpan tolerance) { if (Math.Abs(actual.Ticks - expected.Ticks) > tolerance.Ticks)