From 02ebe3afcaa183b7fd27ff96ffa7f8f18cfe88a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Feb 2026 01:46:12 +0000 Subject: [PATCH 1/3] Initial plan From 8a1ce111493949a57d63c060d9a20723e5ef4ed7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Feb 2026 01:49:21 +0000 Subject: [PATCH 2/3] Add test case demonstrating bug with empty subranges in exclusive-start parents Co-authored-by: blaze6950 <32897401+blaze6950@users.noreply.github.com> --- .../TestEmptySubrangeInOpenClosedParent.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/Intervals.NET.Data.Tests/TestEmptySubrangeInOpenClosedParent.cs diff --git a/tests/Intervals.NET.Data.Tests/TestEmptySubrangeInOpenClosedParent.cs b/tests/Intervals.NET.Data.Tests/TestEmptySubrangeInOpenClosedParent.cs new file mode 100644 index 0000000..89d090c --- /dev/null +++ b/tests/Intervals.NET.Data.Tests/TestEmptySubrangeInOpenClosedParent.cs @@ -0,0 +1,32 @@ +using Intervals.NET.Data; +using Intervals.NET.Domain.Default.Numeric; +using Range = Intervals.NET.Factories.Range; +using Xunit; + +namespace Intervals.NET.Data.Tests.TempTests; + +public class TestEmptySubrangeInOpenClosedParent +{ + private readonly IntegerFixedStepDomain _domain = new(); + + [Fact] + public void TryGet_SubRange_EmptyButContained_WithExclusiveStartParent_ShouldReturnTrue() + { + // Arrange - Parent range: (10,20] means it contains 11, 12, ..., 20 + var parentRange = Range.OpenClosed(10, 20); + var data = new[] { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; + var rangeData = new RangeData(parentRange, data, _domain); + + // Act - Sub-range (10,10] is logically empty but contained in parent + var subRange = Range.OpenClosed(10, 10); + + var success = rangeData.TryGet(subRange, out var result); + + // Assert - Should return true with empty data, not false + // This currently FAILS because endIndex becomes -1, and the negative-index guard + // returns false before the empty-range handling is reached + Assert.True(success, "TryGet should return true for an empty but contained subrange"); + Assert.NotNull(result); + Assert.Empty(result.Data); + } +} From 87941a618d6c33de0e3954b8093fedc130379882 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Feb 2026 01:51:20 +0000 Subject: [PATCH 3/3] Fix bug where empty subranges with negative indices returned false instead of empty RangeData Co-authored-by: blaze6950 <32897401+blaze6950@users.noreply.github.com> --- src/Intervals.NET.Data/RangeData.cs | 16 +++--- .../RangeDataTests.cs | 56 +++++++++++++++++++ .../TestEmptySubrangeInOpenClosedParent.cs | 32 ----------- 3 files changed, 65 insertions(+), 39 deletions(-) delete mode 100644 tests/Intervals.NET.Data.Tests/TestEmptySubrangeInOpenClosedParent.cs diff --git a/src/Intervals.NET.Data/RangeData.cs b/src/Intervals.NET.Data/RangeData.cs index e649882..2f5afe3 100644 --- a/src/Intervals.NET.Data/RangeData.cs +++ b/src/Intervals.NET.Data/RangeData.cs @@ -219,13 +219,6 @@ public bool TryGet(Range subRange, out RangeData int.MaxValue || endIndex < 0 || endIndex > int.MaxValue) - { - data = null; - return false; - } - // Calculate the count of elements to take // If adjusted indices result in startIndex > endIndex, the range is empty var count = endIndex - startIndex + 1; @@ -236,6 +229,15 @@ public bool TryGet(Range subRange, out RangeData int.MaxValue || endIndex < 0 || endIndex > int.MaxValue) + { + data = null; + return false; + } + // Guard against count overflow if (count > int.MaxValue) { diff --git a/tests/Intervals.NET.Data.Tests/RangeDataTests.cs b/tests/Intervals.NET.Data.Tests/RangeDataTests.cs index 11c375d..18ce056 100644 --- a/tests/Intervals.NET.Data.Tests/RangeDataTests.cs +++ b/tests/Intervals.NET.Data.Tests/RangeDataTests.cs @@ -325,6 +325,62 @@ public void TryGet_SubRange_WithEmptyRange_ReturnsTrueWithEmptyData() Assert.Empty(result.Data); } + [Fact] + public void TryGet_SubRange_EmptyButContained_WithExclusiveStartParent_ReturnsTrueWithEmptyData() + { + // Arrange - Parent range: (10,20] means it contains 11, 12, ..., 20 + var parentRange = Range.OpenClosed(10, 20); + var data = new[] { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; + var rangeData = new RangeData(parentRange, data, _domain); + + // Act - Sub-range (10,10] is logically empty but contained in parent + // This tests the fix for the bug where endIndex becomes -1, and the negative-index guard + // would return false before the empty-range handling was reached + var subRange = Range.OpenClosed(10, 10); + var success = rangeData.TryGet(subRange, out var result); + + // Assert - Should return true with empty data, not false + Assert.True(success); + Assert.NotNull(result); + Assert.Empty(result.Data); + } + + [Fact] + public void TryGet_SubRange_EmptyAtStartBoundary_WithClosedOpenParent_ReturnsTrueWithEmptyData() + { + // Arrange - Parent range: [10,20) means it contains 10, 11, ..., 19 + var parentRange = Range.ClosedOpen(10, 20); + var data = new[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + var rangeData = new RangeData(parentRange, data, _domain); + + // Act - Sub-range [10,10) is logically empty + var subRange = Range.ClosedOpen(10, 10); + var success = rangeData.TryGet(subRange, out var result); + + // Assert - Should return true with empty data + Assert.True(success); + Assert.NotNull(result); + Assert.Empty(result.Data); + } + + [Fact] + public void TryGet_SubRange_EmptyAtEndBoundary_WithOpenClosedParent_ReturnsTrueWithEmptyData() + { + // Arrange - Parent range: (10,20] means it contains 11, 12, ..., 20 + var parentRange = Range.OpenClosed(10, 20); + var data = new[] { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; + var rangeData = new RangeData(parentRange, data, _domain); + + // Act - Sub-range [20,20) is logically empty but at the end boundary + var subRange = Range.ClosedOpen(20, 20); + var success = rangeData.TryGet(subRange, out var result); + + // Assert - Should return true with empty data + Assert.True(success); + Assert.NotNull(result); + Assert.Empty(result.Data); + } + #endregion #region TryGet Tests - Point diff --git a/tests/Intervals.NET.Data.Tests/TestEmptySubrangeInOpenClosedParent.cs b/tests/Intervals.NET.Data.Tests/TestEmptySubrangeInOpenClosedParent.cs deleted file mode 100644 index 89d090c..0000000 --- a/tests/Intervals.NET.Data.Tests/TestEmptySubrangeInOpenClosedParent.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Intervals.NET.Data; -using Intervals.NET.Domain.Default.Numeric; -using Range = Intervals.NET.Factories.Range; -using Xunit; - -namespace Intervals.NET.Data.Tests.TempTests; - -public class TestEmptySubrangeInOpenClosedParent -{ - private readonly IntegerFixedStepDomain _domain = new(); - - [Fact] - public void TryGet_SubRange_EmptyButContained_WithExclusiveStartParent_ShouldReturnTrue() - { - // Arrange - Parent range: (10,20] means it contains 11, 12, ..., 20 - var parentRange = Range.OpenClosed(10, 20); - var data = new[] { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; - var rangeData = new RangeData(parentRange, data, _domain); - - // Act - Sub-range (10,10] is logically empty but contained in parent - var subRange = Range.OpenClosed(10, 10); - - var success = rangeData.TryGet(subRange, out var result); - - // Assert - Should return true with empty data, not false - // This currently FAILS because endIndex becomes -1, and the negative-index guard - // returns false before the empty-range handling is reached - Assert.True(success, "TryGet should return true for an empty but contained subrange"); - Assert.NotNull(result); - Assert.Empty(result.Data); - } -}