diff --git a/Source/aweXpect/That/Numbers/ThatNumber.IsBetween.cs b/Source/aweXpect/That/Numbers/ThatNumber.IsBetween.cs index 537855df0..e781f65d6 100644 --- a/Source/aweXpect/That/Numbers/ThatNumber.IsBetween.cs +++ b/Source/aweXpect/That/Numbers/ThatNumber.IsBetween.cs @@ -12,7 +12,7 @@ public static partial class ThatNumber { #if NET8_0_OR_GREATER /// - /// Verifies that the subject is between … + /// Verifies that the subject is between the … /// public static BetweenResult>, TNumber?> IsBetween( this IThat source, TNumber? minimum) @@ -32,6 +32,28 @@ public static partial class ThatNumber source.Get().ExpectationBuilder.AddConstraint((it, grammars) => new NullableIsInRangeConstraint(it, grammars, minimum, maximum)), source)); + + /// + /// Verifies that the subject is not between the … + /// + public static BetweenResult>, TNumber?> IsNotBetween( + this IThat source, TNumber? minimum) + where TNumber : struct, INumber + => new(maximum => new AndOrResult>( + source.Get().ExpectationBuilder.AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not between the … + /// + public static BetweenResult>, TNumber?> IsNotBetween( + this IThat source, TNumber? minimum) + where TNumber : struct, INumber + => new(maximum => new AndOrResult>( + source.Get().ExpectationBuilder.AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); private sealed class IsInRangeConstraint : ConstraintResult.WithValue, IValueConstraint @@ -395,6 +417,248 @@ protected override void AppendNegatedResult(StringBuilder stringBuilder, string? new NullableIsInRangeConstraint(it, grammars, minimum, maximum)), source)); + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, byte?> IsNotBetween( + this IThat source, + byte? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, sbyte?> IsNotBetween( + this IThat source, + sbyte? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, short?> IsNotBetween( + this IThat source, + short? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, ushort?> IsNotBetween( + this IThat source, + ushort? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, int?> IsNotBetween( + this IThat source, + int? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder.AddConstraint((it, grammars) + => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, uint?> IsNotBetween( + this IThat source, + uint? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, long?> IsNotBetween( + this IThat source, + long? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, ulong?> IsNotBetween( + this IThat source, + ulong? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, float?> IsNotBetween( + this IThat source, + float? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, double?> IsNotBetween( + this IThat source, + double? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, decimal?> IsNotBetween( + this IThat source, + decimal? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new IsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, byte?> IsNotBetween( + this IThat source, + byte? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, sbyte?> IsNotBetween( + this IThat source, + sbyte? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, short?> IsNotBetween( + this IThat source, + short? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, ushort?> IsNotBetween( + this IThat source, + ushort? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, int?> IsNotBetween( + this IThat source, + int? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, uint?> IsNotBetween( + this IThat source, + uint? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, long?> IsNotBetween( + this IThat source, + long? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, ulong?> IsNotBetween( + this IThat source, + ulong? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, float?> IsNotBetween( + this IThat source, + float? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, double?> IsNotBetween( + this IThat source, + double? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + + /// + /// Verifies that the subject is not in the range between the … + /// + public static BetweenResult>, decimal?> IsNotBetween( + this IThat source, + decimal? minimum) + => new(maximum => new AndOrResult>(source.Get().ExpectationBuilder + .AddConstraint((it, grammars) => + new NullableIsInRangeConstraint(it, grammars, minimum, maximum).Invert()), + source)); + private sealed class IsInRangeConstraint : ConstraintResult.WithValue, IValueConstraint where TNumber : struct, IComparable diff --git a/Tests/aweXpect.Api.Tests/Expected/aweXpect_net8.0.txt b/Tests/aweXpect.Api.Tests/Expected/aweXpect_net8.0.txt index 1189b4733..5e64049d1 100644 --- a/Tests/aweXpect.Api.Tests/Expected/aweXpect_net8.0.txt +++ b/Tests/aweXpect.Api.Tests/Expected/aweXpect_net8.0.txt @@ -724,6 +724,10 @@ namespace aweXpect where TNumber : struct, System.Numerics.INumber { } public static aweXpect.Results.AndOrResult> IsNegative(this aweXpect.Core.IThat source) where TNumber : struct, System.Numerics.INumber { } + public static aweXpect.Results.BetweenResult>, TNumber?> IsNotBetween(this aweXpect.Core.IThat source, TNumber? minimum) + where TNumber : struct, System.Numerics.INumber { } + public static aweXpect.Results.BetweenResult>, TNumber?> IsNotBetween(this aweXpect.Core.IThat source, TNumber? minimum) + where TNumber : struct, System.Numerics.INumber { } public static aweXpect.Results.NumberToleranceResult> IsNotEqualTo(this aweXpect.Core.IThat source, TNumber? unexpected) where TNumber : struct, System.Numerics.INumber { } public static aweXpect.Results.NullableNumberToleranceResult> IsNotEqualTo(this aweXpect.Core.IThat source, TNumber? unexpected) diff --git a/Tests/aweXpect.Api.Tests/Expected/aweXpect_netstandard2.0.txt b/Tests/aweXpect.Api.Tests/Expected/aweXpect_netstandard2.0.txt index 938dd8f57..70550e098 100644 --- a/Tests/aweXpect.Api.Tests/Expected/aweXpect_netstandard2.0.txt +++ b/Tests/aweXpect.Api.Tests/Expected/aweXpect_netstandard2.0.txt @@ -652,6 +652,28 @@ namespace aweXpect public static aweXpect.Results.AndOrResult> IsNegative(this aweXpect.Core.IThat source) { } public static aweXpect.Results.AndOrResult> IsNegative(this aweXpect.Core.IThat source) { } public static aweXpect.Results.AndOrResult> IsNegative(this aweXpect.Core.IThat source) { } + public static aweXpect.Results.BetweenResult>, byte?> IsNotBetween(this aweXpect.Core.IThat source, byte? minimum) { } + public static aweXpect.Results.BetweenResult>, byte?> IsNotBetween(this aweXpect.Core.IThat source, byte? minimum) { } + public static aweXpect.Results.BetweenResult>, decimal?> IsNotBetween(this aweXpect.Core.IThat source, decimal? minimum) { } + public static aweXpect.Results.BetweenResult>, decimal?> IsNotBetween(this aweXpect.Core.IThat source, decimal? minimum) { } + public static aweXpect.Results.BetweenResult>, double?> IsNotBetween(this aweXpect.Core.IThat source, double? minimum) { } + public static aweXpect.Results.BetweenResult>, double?> IsNotBetween(this aweXpect.Core.IThat source, double? minimum) { } + public static aweXpect.Results.BetweenResult>, float?> IsNotBetween(this aweXpect.Core.IThat source, float? minimum) { } + public static aweXpect.Results.BetweenResult>, float?> IsNotBetween(this aweXpect.Core.IThat source, float? minimum) { } + public static aweXpect.Results.BetweenResult>, int?> IsNotBetween(this aweXpect.Core.IThat source, int? minimum) { } + public static aweXpect.Results.BetweenResult>, int?> IsNotBetween(this aweXpect.Core.IThat source, int? minimum) { } + public static aweXpect.Results.BetweenResult>, long?> IsNotBetween(this aweXpect.Core.IThat source, long? minimum) { } + public static aweXpect.Results.BetweenResult>, long?> IsNotBetween(this aweXpect.Core.IThat source, long? minimum) { } + public static aweXpect.Results.BetweenResult>, sbyte?> IsNotBetween(this aweXpect.Core.IThat source, sbyte? minimum) { } + public static aweXpect.Results.BetweenResult>, sbyte?> IsNotBetween(this aweXpect.Core.IThat source, sbyte? minimum) { } + public static aweXpect.Results.BetweenResult>, short?> IsNotBetween(this aweXpect.Core.IThat source, short? minimum) { } + public static aweXpect.Results.BetweenResult>, short?> IsNotBetween(this aweXpect.Core.IThat source, short? minimum) { } + public static aweXpect.Results.BetweenResult>, uint?> IsNotBetween(this aweXpect.Core.IThat source, uint? minimum) { } + public static aweXpect.Results.BetweenResult>, uint?> IsNotBetween(this aweXpect.Core.IThat source, uint? minimum) { } + public static aweXpect.Results.BetweenResult>, ulong?> IsNotBetween(this aweXpect.Core.IThat source, ulong? minimum) { } + public static aweXpect.Results.BetweenResult>, ulong?> IsNotBetween(this aweXpect.Core.IThat source, ulong? minimum) { } + public static aweXpect.Results.BetweenResult>, ushort?> IsNotBetween(this aweXpect.Core.IThat source, ushort? minimum) { } + public static aweXpect.Results.BetweenResult>, ushort?> IsNotBetween(this aweXpect.Core.IThat source, ushort? minimum) { } public static aweXpect.Results.NumberToleranceResult> IsNotEqualTo(this aweXpect.Core.IThat source, byte? unexpected) { } public static aweXpect.Results.NullableNumberToleranceResult> IsNotEqualTo(this aweXpect.Core.IThat source, byte? unexpected) { } public static aweXpect.Results.NumberToleranceResult> IsNotEqualTo(this aweXpect.Core.IThat source, decimal? unexpected) { } diff --git a/Tests/aweXpect.Tests/Numbers/ThatNumber.IsNotBetween.Tests.cs b/Tests/aweXpect.Tests/Numbers/ThatNumber.IsNotBetween.Tests.cs new file mode 100644 index 000000000..7cbfd8781 --- /dev/null +++ b/Tests/aweXpect.Tests/Numbers/ThatNumber.IsNotBetween.Tests.cs @@ -0,0 +1,1268 @@ +namespace aweXpect.Tests; + +public sealed partial class ThatNumber +{ + public sealed class IsNotBetween + { + public sealed class Tests + { + [Theory] + [InlineData(null, (byte)1)] + [InlineData((byte)1, null)] + public async Task ForByte_WhenMinimumOrMaximumIsNull_ShouldSucceed(byte? minimum, byte? maximum) + { + byte subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((byte)2, (byte)1, (byte)3)] + [InlineData((byte)2, (byte)2, (byte)4)] + [InlineData((byte)2, (byte)1, (byte)2)] + public async Task ForByte_WhenValueIsInRangeExpected_ShouldFail(byte subject, + byte? minimum, byte? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((byte)2, (byte)0, (byte)1)] + [InlineData((byte)0, (byte)1, (byte)2)] + public async Task ForByte_WhenValueIsOutsideTheRange_ShouldSucceed(byte subject, + byte? minimum, byte? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, 1.1)] + [InlineData(1.1, null)] + public async Task ForDecimal_WhenMinimumOrMaximumIsNull_ShouldSucceed(double? minimumValue, + double? maximumValue) + { + decimal subject = 2; + decimal? minimum = minimumValue is null ? null : new decimal(minimumValue.Value); + decimal? maximum = maximumValue is null ? null : new decimal(maximumValue.Value); + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2.0, 1.0, 3.0)] + [InlineData(2.0, 2.0, 4.0)] + [InlineData(2.0, 1.0, 2.0)] + public async Task ForDecimal_WhenValueIsInRangeExpected_ShouldFail( + double subjectValue, double expectedMinimum, double expectedMaximum) + { + decimal subject = new(subjectValue); + decimal? minimum = new(expectedMinimum); + decimal? maximum = new(expectedMaximum); + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData(2.0, 0.0, 1.9)] + [InlineData(0.0, 0.1, 2.0)] + public async Task ForDecimal_WhenValueIsOutsideTheRange_ShouldSucceed( + double subjectValue, double minimumValue, double maximumValue) + { + decimal subject = new(subjectValue); + decimal minimum = new(minimumValue); + decimal maximum = new(maximumValue); + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, 1.1)] + [InlineData(1.1, null)] + public async Task ForDouble_WhenMinimumOrMaximumIsNull_ShouldSucceed(double? minimum, double? maximum) + { + double subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2.0, 1.0, 3.0)] + [InlineData(2.0, 2.0, 4.0)] + [InlineData(2.0, 1.0, 2.0)] + public async Task ForDouble_WhenValueIsInRangeExpected_ShouldFail( + double subject, double minimum, double maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData(2.0, 0.0, 1.9)] + [InlineData(0.0, 0.1, 2.0)] + public async Task ForDouble_WhenValueIsOutsideTheRange_ShouldSucceed( + double subject, double minimum, double maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, 1.0F)] + [InlineData(1.0F, null)] + public async Task ForFloat_WhenMinimumOrMaximumIsNull_ShouldSucceed(float? minimum, float? maximum) + { + float subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((float)2.0, (float)1.0, (float)3.0)] + [InlineData((float)2.0, (float)2.0, (float)4.0)] + [InlineData((float)2.0, (float)1.0, (float)2.0)] + public async Task ForFloat_WhenValueIsInRangeExpected_ShouldFail( + float subject, float minimum, float maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((float)2.0, (float)0.0, (float)1.9)] + [InlineData((float)0.0, (float)0.1, (float)2.0)] + public async Task ForFloat_WhenValueIsOutsideTheRange_ShouldSucceed( + float subject, float minimum, float maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Fact] + public async Task ForInt_WhenMaximumIsSmallerThanMinimum_ShouldThrowArgumentOutOfRangeException() + { + int subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(2).And(1); + + await That(Act).Throws() + .WithParamName("maximum").And + .WithMessage("The maximum must be greater than or equal to the minimum.").AsPrefix(); + } + + [Theory] + [InlineData(null, 1)] + [InlineData(1, null)] + public async Task ForInt_WhenMinimumOrMaximumIsNull_ShouldSucceed( + int? minimum, int? maximum) + { + int subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2, 1, 3)] + [InlineData(2, 2, 4)] + [InlineData(2, 1, 2)] + public async Task ForInt_WhenValueIsInRangeExpected_ShouldFail(int subject, + int? minimum, int maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData(2, 0, 1)] + [InlineData(0, 1, 2)] + public async Task ForInt_WhenValueIsOutsideTheRange_ShouldSucceed(int subject, + int? minimum, int maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + +#if NET8_0_OR_GREATER + [Theory] + [InlineData(null, 1)] + [InlineData(1, null)] + public async Task ForInt128_WhenMinimumOrMaximumIsNull_ShouldSucceed(int? minimumValue, int? maximumValue) + { + Int128 subject = 2; + Int128? minimum = minimumValue; + Int128? maximum = maximumValue; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } +#endif + +#if NET8_0_OR_GREATER + [Theory] + [InlineData(2, 1, 3)] + [InlineData(2, 2, 4)] + [InlineData(2, 1, 2)] + public async Task ForInt128_WhenValueIsInRangeExpected_ShouldFail( + int subjectValue, int minimumValue, int maximumValue) + { + Int128 subject = subjectValue; + Int128? minimum = minimumValue; + Int128? maximum = maximumValue; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {Formatter.Format(minimum)} and {Formatter.Format(maximum)}, + but it was {Formatter.Format(subject)} + """); + } +#endif + +#if NET8_0_OR_GREATER + [Theory] + [InlineData(2, 0, 1)] + [InlineData(0, 1, 2)] + public async Task ForInt128_WhenValueIsOutsideTheRange_ShouldSucceed( + int subjectValue, int minimumValue, int maximumValue) + { + Int128 subject = subjectValue; + Int128? minimum = minimumValue; + Int128? maximum = maximumValue; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } +#endif + + [Theory] + [InlineData(null, (long)1)] + [InlineData((long)1, null)] + public async Task ForLong_WhenMinimumOrMaximumIsNull_ShouldSucceed( + long? minimum, long? maximum) + { + long subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((long)2, (long)1, (long)3)] + [InlineData((long)2, (long)2, (long)4)] + [InlineData((long)2, (long)1, (long)2)] + public async Task ForLong_WhenValueIsInRangeExpected_ShouldFail(long subject, + long? minimum, long maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((long)2, (long)0, (long)1)] + [InlineData((long)0, (long)1, (long)2)] + public async Task ForLong_WhenValueIsOutsideTheRange_ShouldSucceed(long subject, + long? minimum, long maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((byte)2, (byte)1, (byte)3)] + [InlineData((byte)2, (byte)2, (byte)4)] + [InlineData((byte)2, (byte)1, (byte)2)] + public async Task ForNullableByte_WhenValueIsInRangeExpected_ShouldFail( + byte? subject, byte? minimum, byte? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Fact] + public async Task ForNullableByte_WhenValueIsNull_ShouldSucceed() + { + byte? subject = null; + byte minimum = 1; + byte maximum = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((byte)2, (byte)0, (byte)1)] + [InlineData((byte)0, (byte)1, (byte)2)] + public async Task ForNullableByte_WhenValueIsOutsideTheRange_ShouldSucceed( + byte? subject, byte? minimum, byte? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, 1.1)] + [InlineData(1.1, null)] + public async Task ForNullableDecimal_WhenMinimumOrMaximumIsNull_ShouldSucceed(double? minimumValue, + double? maximumValue) + { + decimal subject = 2; + decimal? minimum = minimumValue == null ? null : new decimal(minimumValue.Value); + decimal? maximum = maximumValue == null ? null : new decimal(maximumValue.Value); + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2.0, 1.0, 3.0)] + [InlineData(2.0, 2.0, 4.0)] + [InlineData(2.0, 1.0, 2.0)] + public async Task ForNullableDecimal_WhenValueIsInRangeExpected_ShouldFail( + double? subjectValue, double? minimumValue, double? maximumValue) + { + decimal? subject = subjectValue == null ? null : new decimal(subjectValue.Value); + decimal? minimum = minimumValue == null ? null : new decimal(minimumValue.Value); + decimal? maximum = maximumValue == null ? null : new decimal(maximumValue.Value); + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData(2.0, 0.0, 1.9)] + [InlineData(0.0, 0.1, 2.0)] + public async Task ForNullableDecimal_WhenValueIsOutsideTheRange_ShouldSucceed( + double? subjectValue, double? minimumValue, double? maximumValue) + { + decimal? subject = subjectValue == null ? null : new decimal(subjectValue.Value); + decimal? minimum = minimumValue == null ? null : new decimal(minimumValue.Value); + decimal? maximum = maximumValue == null ? null : new decimal(maximumValue.Value); + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, 1.1)] + [InlineData(1.1, null)] + public async Task ForNullableDouble_WhenMinimumOrMaximumIsNull_ShouldSucceed(double? minimum, + double? maximum) + { + double subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2.0, 1.0, 3.0)] + [InlineData(2.0, 2.0, 4.0)] + [InlineData(2.0, 1.0, 2.0)] + public async Task ForNullableDouble_WhenValueIsInRangeExpected_ShouldFail( + double? subject, double? minimum, double? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData(2.0, 0.0, 1.9)] + [InlineData(0.0, 0.1, 2.0)] + public async Task ForNullableDouble_WhenValueIsOutsideTheRange_ShouldSucceed( + double? subject, double? minimum, double? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, 1.1F)] + [InlineData(1.1F, null)] + public async Task ForNullableFloat_WhenMinimumOrMaximumIsNull_ShouldSucceed(float? minimum, float? maximum) + { + float subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((float)2.0, (float)1.0, (float)3.0)] + [InlineData((float)2.0, (float)2.0, (float)4.0)] + [InlineData((float)2.0, (float)1.0, (float)2.0)] + public async Task ForNullableFloat_WhenValueIsInRangeExpected_ShouldFail( + float? subject, float? minimum, float? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((float)2.0, (float)0.0, (float)1.9)] + [InlineData((float)0.0, (float)0.1, (float)2.0)] + public async Task ForNullableFloat_WhenValueIsOutsideTheRange_ShouldSucceed( + float? subject, float? minimum, float? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Fact] + public async Task ForNullableInt_WhenMaximumIsSmallerThanMinimum_ShouldThrowArgumentOutOfRangeException() + { + int? subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(2).And(1); + + await That(Act).Throws() + .WithParamName("maximum").And + .WithMessage("The maximum must be greater than or equal to the minimum.").AsPrefix(); + } + + [Theory] + [InlineData(null, 1)] + [InlineData(1, null)] + public async Task ForNullableInt_WhenMinimumOrMaximumIsNull_ShouldSucceed( + int? minimum, int? maximum) + { + int? subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2, 1, 3)] + [InlineData(2, 2, 4)] + [InlineData(2, 1, 2)] + public async Task ForNullableInt_WhenValueIsInRangeExpected_ShouldFail( + int? subject, int? minimum, int? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Fact] + public async Task ForNullableInt_WhenValueIsNull_ShouldSucceed() + { + int? subject = null; + int minimum = 1; + int maximum = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2, 0, 1)] + [InlineData(0, 1, 2)] + public async Task ForNullableInt_WhenValueIsOutsideTheRange_ShouldSucceed( + int? subject, int? minimum, int? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } +#if NET8_0_OR_GREATER + [Theory] + [InlineData(null, 1)] + [InlineData(1, null)] + public async Task ForNullableInt128_WhenMinimumOrMaximumIsNull_ShouldSucceed(int? minimumValue, + int? maximumValue) + { + Int128? subject = 2; + Int128? minimum = minimumValue; + Int128? maximum = maximumValue; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } +#endif + +#if NET8_0_OR_GREATER + [Theory] + [InlineData(2, 1, 3)] + [InlineData(2, 2, 4)] + [InlineData(2, 1, 2)] + public async Task ForNullableInt128_WhenValueIsInRangeExpected_ShouldFail( + int? subjectValue, int? minimumValue, int? maximumValue) + { + Int128? subject = subjectValue; + Int128? minimum = minimumValue; + Int128? maximum = maximumValue; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {Formatter.Format(minimum)} and {Formatter.Format(maximum)}, + but it was {Formatter.Format(subject)} + """); + } +#endif + +#if NET8_0_OR_GREATER + [Theory] + [InlineData(2, 0, 1)] + [InlineData(0, 1, 2)] + public async Task ForNullableInt128_WhenValueIsOutsideTheRange_ShouldSucceed( + int? subjectValue, int? minimumValue, int? maximumValue) + { + Int128? subject = subjectValue; + Int128? minimum = minimumValue; + Int128? maximum = maximumValue; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } +#endif + + [Theory] + [InlineData(null, (long)1)] + [InlineData((long)1, null)] + public async Task ForNullableLong_WhenMinimumOrMaximumIsNull_ShouldSucceed( + long? minimum, long? maximum) + { + long? subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((long)2, (long)1, (long)3)] + [InlineData((long)2, (long)2, (long)4)] + [InlineData((long)2, (long)1, (long)2)] + public async Task ForNullableLong_WhenValueIsInRangeExpected_ShouldFail( + long? subject, long? minimum, long? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Fact] + public async Task ForNullableLong_WhenValueIsNull_ShouldSucceed() + { + long? subject = null; + long minimum = 1; + long maximum = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((long)2, (long)0, (long)1)] + [InlineData((long)0, (long)1, (long)2)] + public async Task ForNullableLong_WhenValueIsOutsideTheRange_ShouldSucceed( + long? subject, long? minimum, long? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((sbyte)2, (sbyte)1, (sbyte)3)] + [InlineData((sbyte)2, (sbyte)2, (sbyte)4)] + [InlineData((sbyte)2, (sbyte)1, (sbyte)2)] + public async Task ForNullableSbyte_WhenValueIsInRangeExpected_ShouldFail( + sbyte? subject, sbyte? minimum, sbyte? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Fact] + public async Task ForNullableSbyte_WhenValueIsNull_ShouldSucceed() + { + sbyte? subject = null; + sbyte minimum = 1; + sbyte maximum = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((sbyte)2, (sbyte)0, (sbyte)1)] + [InlineData((sbyte)0, (sbyte)1, (sbyte)2)] + public async Task ForNullableSbyte_WhenValueIsOutsideTheRange_ShouldSucceed( + sbyte? subject, sbyte? minimum, sbyte? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((short)2, (short)1, (short)3)] + [InlineData((short)2, (short)2, (short)4)] + [InlineData((short)2, (short)1, (short)2)] + public async Task ForNullableShort_WhenValueIsInRangeExpected_ShouldFail( + short? subject, short? minimum, short? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Fact] + public async Task ForNullableShort_WhenValueIsNull_ShouldSucceed() + { + short? subject = null; + short minimum = 1; + short maximum = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((short)2, (short)0, (short)1)] + [InlineData((short)0, (short)1, (short)2)] + public async Task ForNullableShort_WhenValueIsOutsideTheRange_ShouldSucceed( + short? subject, short? minimum, short? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((uint)2, (uint)1, (uint)3)] + [InlineData((uint)2, (uint)2, (uint)4)] + [InlineData((uint)2, (uint)1, (uint)2)] + public async Task ForNullableUint_WhenValueIsInRangeExpected_ShouldFail( + uint? subject, uint? minimum, uint maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Fact] + public async Task ForNullableUint_WhenValueIsNull_ShouldSucceed() + { + uint? subject = null; + uint minimum = 1; + uint maximum = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((uint)2, (uint)0, (uint)1)] + [InlineData((uint)0, (uint)1, (uint)2)] + public async Task ForNullableUint_WhenValueIsOutsideTheRange_ShouldSucceed( + uint? subject, uint? minimum, uint maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((ulong)2, (ulong)1, (ulong)3)] + [InlineData((ulong)2, (ulong)2, (ulong)4)] + [InlineData((ulong)2, (ulong)1, (ulong)2)] + public async Task ForNullableUlong_WhenValueIsInRangeExpected_ShouldFail( + ulong? subject, ulong? minimum, ulong? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Fact] + public async Task ForNullableUlong_WhenValueIsNull_ShouldSucceed() + { + ulong? subject = null; + ulong minimum = 1; + ulong maximum = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((ulong)2, (ulong)0, (ulong)1)] + [InlineData((ulong)0, (ulong)1, (ulong)2)] + public async Task ForNullableUlong_WhenValueIsOutsideTheRange_ShouldSucceed( + ulong? subject, ulong? minimum, ulong? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((ushort)2, (ushort)1, (ushort)3)] + [InlineData((ushort)2, (ushort)2, (ushort)4)] + [InlineData((ushort)2, (ushort)1, (ushort)2)] + public async Task ForNullableUshort_WhenValueIsInRangeExpected_ShouldFail( + ushort? subject, ushort? minimum, ushort? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Fact] + public async Task ForNullableUshort_WhenValueIsNull_ShouldSucceed() + { + ushort? subject = null; + ushort minimum = 1; + ushort maximum = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((ushort)2, (ushort)0, (ushort)1)] + [InlineData((ushort)0, (ushort)1, (ushort)2)] + public async Task ForNullableUshort_WhenValueIsOutsideTheRange_ShouldSucceed( + ushort? subject, ushort? minimum, ushort? maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, (sbyte)1)] + [InlineData((sbyte)1, null)] + public async Task ForSbyte_WhenMinimumOrMaximumIsNull_ShouldSucceed( + sbyte? minimum, sbyte? maximum) + { + sbyte subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((sbyte)2, (sbyte)1, (sbyte)3)] + [InlineData((sbyte)2, (sbyte)2, (sbyte)4)] + [InlineData((sbyte)2, (sbyte)1, (sbyte)2)] + public async Task ForSbyte_WhenValueIsInRangeExpected_ShouldFail(sbyte subject, + sbyte? minimum, sbyte maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((sbyte)2, (sbyte)0, (sbyte)1)] + [InlineData((sbyte)0, (sbyte)1, (sbyte)2)] + public async Task ForSbyte_WhenValueIsOutsideTheRange_ShouldSucceed(sbyte subject, + sbyte? minimum, sbyte maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, (short)1)] + [InlineData((short)1, null)] + public async Task ForShort_WhenMinimumOrMaximumIsNull_ShouldSucceed( + short? minimum, short? maximum) + { + short subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((short)2, (short)1, (short)3)] + [InlineData((short)2, (short)2, (short)4)] + [InlineData((short)2, (short)1, (short)2)] + public async Task ForShort_WhenValueIsInRangeExpected_ShouldFail(short subject, + short? minimum, short maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((short)2, (short)0, (short)1)] + [InlineData((short)0, (short)1, (short)2)] + public async Task ForShort_WhenValueIsOutsideTheRange_ShouldSucceed(short subject, + short? minimum, short maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, (uint)1)] + [InlineData((uint)1, null)] + public async Task ForUint_WhenMinimumOrMaximumIsNull_ShouldSucceed( + uint? minimum, uint? maximum) + { + uint subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((uint)2, (uint)1, (uint)3)] + [InlineData((uint)2, (uint)2, (uint)4)] + [InlineData((uint)2, (uint)1, (uint)2)] + public async Task ForUint_WhenValueIsInRangeExpected_ShouldFail(uint subject, + uint? minimum, uint maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((uint)2, (uint)0, (uint)1)] + [InlineData((uint)0, (uint)1, (uint)2)] + public async Task ForUint_WhenValueIsOutsideTheRange_ShouldSucceed(uint subject, + uint? minimum, uint maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, (ulong)1)] + [InlineData((ulong)1, null)] + public async Task ForUlong_WhenMinimumOrMaximumIsNull_ShouldSucceed( + ulong? minimum, ulong? maximum) + { + ulong subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((ulong)2, (ulong)1, (ulong)3)] + [InlineData((ulong)2, (ulong)2, (ulong)4)] + [InlineData((ulong)2, (ulong)1, (ulong)2)] + public async Task ForUlong_WhenValueIsInRangeExpected_ShouldFail(ulong subject, + ulong? minimum, ulong maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((ulong)2, (ulong)0, (ulong)1)] + [InlineData((ulong)0, (ulong)1, (ulong)2)] + public async Task ForUlong_WhenValueIsOutsideTheRange_ShouldSucceed(ulong subject, + ulong? minimum, ulong maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(null, (ushort)1)] + [InlineData((ushort)1, null)] + public async Task ForUshort_WhenMinimumOrMaximumIsNull_ShouldSucceed( + ushort? minimum, ushort? maximum) + { + ushort subject = 2; + + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData((ushort)2, (ushort)1, (ushort)3)] + [InlineData((ushort)2, (ushort)2, (ushort)4)] + [InlineData((ushort)2, (ushort)1, (ushort)2)] + public async Task ForUshort_WhenValueIsInRangeExpected_ShouldFail( + ushort subject, + ushort? minimum, ushort maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is not between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData((ushort)2, (ushort)0, (ushort)1)] + [InlineData((ushort)0, (ushort)1, (ushort)2)] + public async Task ForUshort_WhenValueIsOutsideTheRange_ShouldSucceed(ushort subject, + ushort? minimum, ushort maximum) + { + async Task Act() + => await That(subject).IsNotBetween(minimum).And(maximum); + + await That(Act).DoesNotThrow(); + } + } + + public sealed class NegatedTests + { + [Theory] + [InlineData(null, 1)] + [InlineData(1, null)] + public async Task ForInt_WhenMinimumOrMaximumIsNull_ShouldFail( + int? minimum, int? maximum) + { + int subject = 2; + + async Task Act() + => await That(subject).DoesNotComplyWith(it + => it.IsNotBetween(minimum).And(maximum)); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + + [Theory] + [InlineData(2, 1, 3)] + [InlineData(2, 2, 4)] + [InlineData(2, 1, 2)] + public async Task ForInt_WhenValueIsInRangeExpected_ShouldSucceed(int subject, + int? minimum, int maximum) + { + async Task Act() + => await That(subject).DoesNotComplyWith(it + => it.IsNotBetween(minimum).And(maximum)); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2, 0, 1)] + [InlineData(0, 1, 2)] + public async Task ForInt_WhenValueIsOutsideTheRange_ShouldFail(int subject, + int? minimum, int maximum) + { + async Task Act() + => await That(subject).DoesNotComplyWith(it + => it.IsNotBetween(minimum).And(maximum)); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + [Theory] + [InlineData(null, 1)] + [InlineData(1, null)] + public async Task ForNullableInt_WhenMinimumIsNull_ShouldFail( + int? minimum, int? maximum) + { + int subject = 2; + + async Task Act() + => await That(subject).DoesNotComplyWith(it + => it.IsNotBetween(minimum).And(maximum)); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + + + [Theory] + [InlineData(2, 1, 3)] + [InlineData(2, 2, 4)] + [InlineData(2, 1, 2)] + public async Task ForNullableInt_WhenValueIsInRangeExpected_ShouldSucceed(int? subject, + int? minimum, int maximum) + { + async Task Act() + => await That(subject).DoesNotComplyWith(it + => it.IsNotBetween(minimum).And(maximum)); + + await That(Act).DoesNotThrow(); + } + + [Theory] + [InlineData(2, 0, 1)] + [InlineData(0, 1, 2)] + public async Task ForNullableInt_WhenValueIsOutsideTheRange_ShouldFail(int? subject, + int? minimum, int maximum) + { + async Task Act() + => await That(subject).DoesNotComplyWith(it + => it.IsNotBetween(minimum).And(maximum)); + + await That(Act).Throws() + .WithMessage($""" + Expected that subject + is between {ValueFormatters.Format(Formatter, minimum)} and {ValueFormatters.Format(Formatter, maximum)}, + but it was {ValueFormatters.Format(Formatter, subject)} + """); + } + } + } +}