diff --git a/src/NUnitFramework/framework/Constraints/Tolerance.cs b/src/NUnitFramework/framework/Constraints/Tolerance.cs index afb52864aa..423e0b56c0 100644 --- a/src/NUnitFramework/framework/Constraints/Tolerance.cs +++ b/src/NUnitFramework/framework/Constraints/Tolerance.cs @@ -278,6 +278,11 @@ private Range LinearRange(object value) return new Range(v - amount, v + amount); } + if (Amount is TimeSpan interval && value is DateTime dateTime) + { + return new Range(dateTime - interval, dateTime + interval); + } + throw new InvalidOperationException("Cannot create range for a non-numeric value"); } diff --git a/src/NUnitFramework/tests/Constraints/GreaterThanConstraintTests.cs b/src/NUnitFramework/tests/Constraints/GreaterThanConstraintTests.cs index d903146e82..328b025f45 100644 --- a/src/NUnitFramework/tests/Constraints/GreaterThanConstraintTests.cs +++ b/src/NUnitFramework/tests/Constraints/GreaterThanConstraintTests.cs @@ -1,5 +1,8 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt +using System; +using System.Collections.Generic; + using NUnit.Framework.Constraints; namespace NUnit.Framework.Tests.Constraints @@ -45,16 +48,24 @@ public void CanCompareIComparablesOfInt() Assert.That(actual, Is.GreaterThan(expected)); } - [TestCase(6.0, 5.0, 0.05)] - [TestCase(5.05, 5.0, 0.05)] // upper range bound - [TestCase(5.0001, 5.0, 0.05)] - [TestCase(4.9999, 5.0, 0.05)] - [TestCase(4.9501, 5.0, 0.05)] // lower range bound + .01 - [TestCase(210, 200, 5)] - [TestCase(205, 200, 5)] // upper range bound - [TestCase(202, 200, 5)] - [TestCase(198, 200, 5)] - [TestCase(196, 200, 5)] // lower range bound + 1 + private static readonly DateTime ConstantDateTime = new(2024, 1, 1, 1, 1, 1); + + private static IEnumerable GetSimpleToleranceData() + { + yield return new object[] { 6.0, 5.0, 0.05 }; + yield return new object[] { 5.05, 5.0, 0.05 }; // upper range bound + yield return new object[] { 5.0001, 5.0, 0.05 }; + yield return new object[] { 4.9999, 5.0, 0.05 }; + yield return new object[] { 4.9501, 5.0, 0.05 }; // lower range bound + .01 + yield return new object[] { 210, 200, 5 }; + yield return new object[] { 205, 200, 5 }; // upper range bound + yield return new object[] { 202, 200, 5 }; + yield return new object[] { 198, 200, 5 }; + yield return new object[] { 196, 200, 5 }; // lower range bound + 1 + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(1), TimeSpan.FromSeconds(2) }; + } + + [TestCaseSource(nameof(GetSimpleToleranceData))] public void SimpleTolerance(object actual, object expected, object tolerance) { #pragma warning disable NUnit2042 // Comparison constraint on object @@ -62,10 +73,17 @@ public void SimpleTolerance(object actual, object expected, object tolerance) #pragma warning restore NUnit2042 // Comparison constraint on object } - [TestCase(4.95, 5.0, 0.05)] // lower range bound - [TestCase(4.9, 5.0, 0.05)] - [TestCase(195, 200, 5)] // lower range bound - [TestCase(190, 200, 5)] + private static IEnumerable GetSimpleTolerance_FailureData() + { + yield return new object[] { 4.95, 5.0, 0.05 }; // lower range bound + yield return new object[] { 4.9, 5.0, 0.05 }; + yield return new object[] { 195, 200, 5 }; // lower range bound + yield return new object[] { 190, 200, 5 }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(2), TimeSpan.FromSeconds(1) }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(2), TimeSpan.FromSeconds(2) }; + } + + [TestCaseSource(nameof(GetSimpleTolerance_FailureData))] public void SimpleTolerance_Failure(object actual, object expected, object tolerance) { #pragma warning disable NUnit2042 // Comparison constraint on object @@ -74,7 +92,7 @@ public void SimpleTolerance_Failure(object actual, object expected, object toler "Assertion should have failed"); #pragma warning restore NUnit2042 // Comparison constraint on object - Assert.That(ex?.Message, Contains.Substring("Expected: greater than " + expected)); + Assert.That(ex?.Message, Contains.Substring("Expected: greater than " + MsgUtils.FormatValue(expected))); } [TestCase(6.0, 5.0, 1)] diff --git a/src/NUnitFramework/tests/Constraints/GreaterThanOrEqualConstraintTests.cs b/src/NUnitFramework/tests/Constraints/GreaterThanOrEqualConstraintTests.cs index f4ec97c029..04b3300d27 100644 --- a/src/NUnitFramework/tests/Constraints/GreaterThanOrEqualConstraintTests.cs +++ b/src/NUnitFramework/tests/Constraints/GreaterThanOrEqualConstraintTests.cs @@ -1,5 +1,8 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt +using System; +using System.Collections.Generic; + using NUnit.Framework.Constraints; namespace NUnit.Framework.Tests.Constraints @@ -45,18 +48,27 @@ public void CanCompareIComparablesOfInt() Assert.That(actual, Is.GreaterThanOrEqualTo(expected)); } - [TestCase(6.0, 5.0, 0.05)] - [TestCase(5.05, 5.0, 0.05)] // upper range bound - [TestCase(5.0001, 5.0, 0.05)] - [TestCase(4.9999, 5.0, 0.05)] - [TestCase(4.9501, 5.0, 0.05)] // lower range bound + .01 - [TestCase(4.95, 5.0, 0.05)] // lower range bound - [TestCase(210, 200, 5)] - [TestCase(205, 200, 5)] // upper range bound - [TestCase(202, 200, 5)] - [TestCase(198, 200, 5)] - [TestCase(196, 200, 5)] // lower range bound + 1 - [TestCase(195, 200, 5)] // lower range bound + private static readonly DateTime ConstantDateTime = new(2024, 1, 1, 1, 1, 1); + + private static IEnumerable GetSimpleToleranceData() + { + yield return new object[] { 6.0, 5.0, 0.05 }; + yield return new object[] { 5.05, 5.0, 0.05 }; // upper range bound + yield return new object[] { 5.0001, 5.0, 0.05 }; + yield return new object[] { 4.9999, 5.0, 0.05 }; + yield return new object[] { 4.9501, 5.0, 0.05 }; // lower range bound + .01 + yield return new object[] { 4.95, 5.0, 0.05 }; // lower range bound + yield return new object[] { 210, 200, 5 }; + yield return new object[] { 205, 200, 5 }; // upper range bound + yield return new object[] { 202, 200, 5 }; + yield return new object[] { 198, 200, 5 }; + yield return new object[] { 196, 200, 5 }; // lower range bound + 1 + yield return new object[] { 195, 200, 5 }; // lower range bound + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(1), TimeSpan.FromSeconds(2) }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(2), TimeSpan.FromSeconds(2) }; + } + + [TestCaseSource(nameof(GetSimpleToleranceData))] public void SimpleTolerance(object actual, object expected, object tolerance) { #pragma warning disable NUnit2042 // Comparison constraint on object @@ -64,8 +76,14 @@ public void SimpleTolerance(object actual, object expected, object tolerance) #pragma warning restore NUnit2042 // Comparison constraint on object } - [TestCase(4.9, 5.0, 0.05)] - [TestCase(190, 200, 5)] + private static IEnumerable GetSimpleTolerance_FailureData() + { + yield return new object[] { 4.9, 5.0, 0.05 }; + yield return new object[] { 190, 200, 5 }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(2), TimeSpan.FromSeconds(1) }; + } + + [TestCaseSource(nameof(GetSimpleTolerance_FailureData))] public void SimpleTolerance_Failure(object actual, object expected, object tolerance) { #pragma warning disable NUnit2042 // Comparison constraint on object @@ -74,7 +92,7 @@ public void SimpleTolerance_Failure(object actual, object expected, object toler "Assertion should have failed"); #pragma warning restore NUnit2042 // Comparison constraint on object - Assert.That(ex?.Message, Contains.Substring("Expected: greater than or equal to " + expected)); + Assert.That(ex?.Message, Contains.Substring("Expected: greater than or equal to " + MsgUtils.FormatValue(expected))); } [TestCase(6.0, 5.0, 1)] diff --git a/src/NUnitFramework/tests/Constraints/LessThanConstraintTests.cs b/src/NUnitFramework/tests/Constraints/LessThanConstraintTests.cs index 63166bd150..f93d941e05 100644 --- a/src/NUnitFramework/tests/Constraints/LessThanConstraintTests.cs +++ b/src/NUnitFramework/tests/Constraints/LessThanConstraintTests.cs @@ -1,5 +1,8 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt +using System; +using System.Collections.Generic; + using NUnit.Framework.Constraints; namespace NUnit.Framework.Tests.Constraints @@ -45,16 +48,24 @@ public void CanCompareIComparablesOfInt() Assert.That(actual, Is.LessThan(expected)); } - [TestCase(4.0, 5.0, 0.05)] - [TestCase(4.95, 5.0, 0.05)] // lower range bound - [TestCase(4.9501, 5.0, 0.05)] // lower range bound + .01 - [TestCase(4.9999, 5.0, 0.05)] - [TestCase(5.0001, 5.0, 0.05)] - [TestCase(190, 200, 5)] - [TestCase(195, 200, 5)] // lower range bound - [TestCase(196, 200, 5)] // lower range bound + 1 - [TestCase(198, 200, 5)] - [TestCase(202, 200, 5)] + private static readonly DateTime ConstantDateTime = new(2024, 1, 1, 1, 1, 1); + + private static IEnumerable GetSimpleToleranceData() + { + yield return new object[] { 4.0, 5.0, 0.05 }; + yield return new object[] { 4.95, 5.0, 0.05 }; // lower range bound + yield return new object[] { 4.9501, 5.0, 0.05 }; // lower range bound + .01 + yield return new object[] { 4.9999, 5.0, 0.05 }; + yield return new object[] { 5.0001, 5.0, 0.05 }; + yield return new object[] { 190, 200, 5 }; + yield return new object[] { 195, 200, 5 }; // lower range bound + yield return new object[] { 196, 200, 5 }; // lower range bound + 1 + yield return new object[] { 198, 200, 5 }; + yield return new object[] { 202, 200, 5 }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(-1), TimeSpan.FromSeconds(2) }; + } + + [TestCaseSource(nameof(GetSimpleToleranceData))] public void SimpleTolerance(object actual, object expected, object tolerance) { #pragma warning disable NUnit2042 // Comparison constraint on object @@ -62,10 +73,17 @@ public void SimpleTolerance(object actual, object expected, object tolerance) #pragma warning restore NUnit2042 // Comparison constraint on object } - [TestCase(5.05, 5.0, 0.05)] // upper range bound - [TestCase(6.0, 5.0, 0.05)] - [TestCase(205, 200, 5)] // upper range bound - [TestCase(210, 200, 5)] + private static IEnumerable GetSimpleTolerance_FailureData() + { + yield return new object[] { 5.05, 5.0, 0.05 }; // upper range bound + yield return new object[] { 6.0, 5.0, 0.05 }; + yield return new object[] { 205, 200, 5 }; // upper range bound + yield return new object[] { 210, 200, 5 }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(-2), TimeSpan.FromSeconds(2) }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(-2), TimeSpan.FromSeconds(1) }; + } + + [TestCaseSource(nameof(GetSimpleTolerance_FailureData))] public void SimpleTolerance_Failure(object actual, object expected, object tolerance) { #pragma warning disable NUnit2042 // Comparison constraint on object diff --git a/src/NUnitFramework/tests/Constraints/LessThanOrEqualConstraintTests.cs b/src/NUnitFramework/tests/Constraints/LessThanOrEqualConstraintTests.cs index c77290f39f..2977fddec6 100644 --- a/src/NUnitFramework/tests/Constraints/LessThanOrEqualConstraintTests.cs +++ b/src/NUnitFramework/tests/Constraints/LessThanOrEqualConstraintTests.cs @@ -1,5 +1,8 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt +using System; +using System.Collections.Generic; + using NUnit.Framework.Constraints; namespace NUnit.Framework.Tests.Constraints @@ -45,18 +48,27 @@ public void CanCompareIComparablesOfInt() Assert.That(actual, Is.LessThanOrEqualTo(expected)); } - [TestCase(4.0, 5.0, 0.05)] - [TestCase(4.95, 5.0, 0.05)] // lower range bound - [TestCase(4.9501, 5.0, 0.05)] // lower range bound + .01 - [TestCase(4.9999, 5.0, 0.05)] - [TestCase(5.0001, 5.0, 0.05)] - [TestCase(5.05, 5.0, 0.05)] // upper range bound - [TestCase(190, 200, 5)] - [TestCase(195, 200, 5)] // lower range bound - [TestCase(196, 200, 5)] // lower range bound + 1 - [TestCase(198, 200, 5)] - [TestCase(202, 200, 5)] - [TestCase(205, 200, 5)] // upper range bound + private static readonly DateTime ConstantDateTime = new(2024, 1, 1, 1, 1, 1); + + private static IEnumerable GetSimpleToleranceData() + { + yield return new object[] { 4.0, 5.0, 0.05 }; + yield return new object[] { 4.95, 5.0, 0.05 }; // lower range bound + yield return new object[] { 4.9501, 5.0, 0.05 }; // lower range bound + .01 + yield return new object[] { 4.9999, 5.0, 0.05 }; + yield return new object[] { 5.0001, 5.0, 0.05 }; + yield return new object[] { 5.05, 5.0, 0.05 }; // upper range bound + yield return new object[] { 190, 200, 5 }; + yield return new object[] { 195, 200, 5 }; // lower range bound + yield return new object[] { 196, 200, 5 }; // lower range bound + 1 + yield return new object[] { 198, 200, 5 }; + yield return new object[] { 202, 200, 5 }; + yield return new object[] { 205, 200, 5 }; // upper range bound + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(-1), TimeSpan.FromSeconds(2) }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(-2), TimeSpan.FromSeconds(2) }; + } + + [TestCaseSource(nameof(GetSimpleToleranceData))] public void SimpleTolerance(object actual, object expected, object tolerance) { #pragma warning disable NUnit2042 // Comparison constraint on object @@ -64,8 +76,14 @@ public void SimpleTolerance(object actual, object expected, object tolerance) #pragma warning restore NUnit2042 // Comparison constraint on object } - [TestCase(6.0, 5.0, 0.05)] - [TestCase(210, 200, 5)] + private static IEnumerable GetSimpleTolerance_FailureData() + { + yield return new object[] { 6.0, 5.0, 0.05 }; + yield return new object[] { 210, 200, 5 }; + yield return new object[] { ConstantDateTime, ConstantDateTime.AddSeconds(-2), TimeSpan.FromSeconds(1) }; + } + + [TestCaseSource(nameof(GetSimpleTolerance_FailureData))] public void SimpleTolerance_Failure(object actual, object expected, object tolerance) { #pragma warning disable NUnit2042 // Comparison constraint on object @@ -74,7 +92,7 @@ public void SimpleTolerance_Failure(object actual, object expected, object toler "Assertion should have failed"); #pragma warning restore NUnit2042 // Comparison constraint on object - Assert.That(ex?.Message, Contains.Substring("Expected: less than or equal to " + expected)); + Assert.That(ex?.Message, Contains.Substring("Expected: less than or equal to " + MsgUtils.FormatValue(expected))); } [TestCase(4.0, 5.0, 1)]