From 5da64c98fa32e0f91feef0e01c79b5ac2b678599 Mon Sep 17 00:00:00 2001 From: Chris Wolfgang <210299580+Chris-Wolfgang@users.noreply.github.com> Date: Mon, 1 Jun 2026 11:44:46 -0400 Subject: [PATCH] T4 follow-up: negative-int range + int.MinValue/MaxValue edge cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bulk of the T4 audit landed in #134 (custom IComparable tests + null-bound contract tests). This follow-up closes the smaller edge-case gaps the audit flagged but skipped at the time: 1. Negative integer range — every existing int Theory used positive bounds (1, 10). Added matching Theories with bounds (-10, 0) for both IsBetween and IsInRange covering below, exact-lower, mid, exact-upper, above. By construction these exercise the same code path as the positive cases, but a future refactor introducing an Abs-based shortcut or an unsigned compare would now fail. 2. int.MinValue / int.MaxValue boundaries — added four Facts covering value=int.MaxValue and value=int.MinValue against (MinValue, MaxValue) bounds for both methods. Confirms that strict bounds reject the exact extremes (IsBetween → false) and inclusive bounds accept them (IsInRange → true). 3. Money record's CompareTo(null) convention documented with a comment explaining the choice ('null < any value', per the IComparable guidance). 72 tests pass on net10.0 (58 after #134 + 14 new rows / Facts here). --- .../IComparableExtensionsTests.cs | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/Wolfgang.Extensions.IComparable.Tests.Unit/IComparableExtensionsTests.cs b/tests/Wolfgang.Extensions.IComparable.Tests.Unit/IComparableExtensionsTests.cs index 55d23c5..84e9c80 100644 --- a/tests/Wolfgang.Extensions.IComparable.Tests.Unit/IComparableExtensionsTests.cs +++ b/tests/Wolfgang.Extensions.IComparable.Tests.Unit/IComparableExtensionsTests.cs @@ -283,4 +283,73 @@ public void IsInRange_when_upperBound_is_null_defers_to_CompareTo_contract() // "m".CompareTo(null) <= 0 → 1 <= 0 → false. Assert.False("m".IsInRange("a", null!)); } + + + + // --------------------------------------------------------------- + // Edge-case integer coverage — negative bounds + value-type + // extremes. The behaviour is the same as the positive cases by + // construction, but these rows lock in that the implementation + // doesn't accidentally specialise on positive numbers (e.g. via + // an unsigned compare or an `Abs`-based shortcut introduced + // during a future refactor). + // --------------------------------------------------------------- + + [Theory] + [InlineData(-11, false)] // below the negative-to-zero range + [InlineData(-10, false)] // exact lower (strict) + [InlineData(-5, true)] // mid + [InlineData(0, false)] // exact upper (strict) + [InlineData(1, false)] // above + public void IsBetween_when_called_on_negative_integer_range_returns_expected_result(int value, bool expectedValue) + { + Assert.Equal(expectedValue, value.IsBetween(-10, 0)); + } + + + + [Theory] + [InlineData(-11, false)] // below + [InlineData(-10, true)] // exact lower (inclusive) + [InlineData(-5, true)] // mid + [InlineData(0, true)] // exact upper (inclusive) + [InlineData(1, false)] // above + public void IsInRange_when_called_on_negative_integer_range_returns_expected_result(int value, bool expectedValue) + { + Assert.Equal(expectedValue, value.IsInRange(-10, 0)); + } + + + + [Fact] + public void IsBetween_when_value_equals_int_MaxValue_against_full_range_returns_false() + { + // strict upper — MaxValue is NOT > MaxValue + Assert.False(int.MaxValue.IsBetween(int.MinValue, int.MaxValue)); + } + + + + [Fact] + public void IsBetween_when_value_equals_int_MinValue_against_full_range_returns_false() + { + // strict lower — MinValue is NOT < MinValue + Assert.False(int.MinValue.IsBetween(int.MinValue, int.MaxValue)); + } + + + + [Fact] + public void IsInRange_when_value_equals_int_MaxValue_against_full_range_returns_true() + { + Assert.True(int.MaxValue.IsInRange(int.MinValue, int.MaxValue)); + } + + + + [Fact] + public void IsInRange_when_value_equals_int_MinValue_against_full_range_returns_true() + { + Assert.True(int.MinValue.IsInRange(int.MinValue, int.MaxValue)); + } }