diff --git a/MoreLinq.Test/WindowLeftTest.cs b/MoreLinq.Test/WindowLeftTest.cs index a0cc4410a..c63dc071c 100644 --- a/MoreLinq.Test/WindowLeftTest.cs +++ b/MoreLinq.Test/WindowLeftTest.cs @@ -29,6 +29,51 @@ public void WindowLeftIsLazy() new BreakingSequence().WindowLeft(1); } + [Test] + public void WindowModifiedBeforeMoveNextDoesNotAffectNextWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.WindowLeft(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + window1[1] = -1; + e.MoveNext(); + var window2 = e.Current; + + Assert.That(window2[0], Is.EqualTo(1)); + } + + [Test] + public void WindowModifiedAfterMoveNextDoesNotAffectNextWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.WindowLeft(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + e.MoveNext(); + window1[1] = -1; + var window2 = e.Current; + + Assert.That(window2[0], Is.EqualTo(1)); + } + + [Test] + public void WindowModifiedDoesNotAffectPreviousWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.WindowLeft(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + e.MoveNext(); + var window2 = e.Current; + window2[0] = -1; + + Assert.That(window1[1], Is.EqualTo(1)); + } + [Test] public void WindowLeftWithNegativeWindowSize() { diff --git a/MoreLinq.Test/WindowRightTest.cs b/MoreLinq.Test/WindowRightTest.cs index d62c4fc57..d5296e307 100644 --- a/MoreLinq.Test/WindowRightTest.cs +++ b/MoreLinq.Test/WindowRightTest.cs @@ -29,6 +29,51 @@ public void WindowRightIsLazy() new BreakingSequence().WindowRight(1); } + [Test] + public void WindowModifiedBeforeMoveNextDoesNotAffectNextWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.WindowRight(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + window1[0] = -1; + e.MoveNext(); + var window2 = e.Current; + + Assert.That(window2[0], Is.EqualTo(0)); + } + + [Test] + public void WindowModifiedAfterMoveNextDoesNotAffectNextWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.WindowRight(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + e.MoveNext(); + window1[0] = -1; + var window2 = e.Current; + + Assert.That(window2[0], Is.EqualTo(0)); + } + + [Test] + public void WindowModifiedDoesNotAffectPreviousWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.WindowRight(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + e.MoveNext(); + var window2 = e.Current; + window2[0] = -1; + + Assert.That(window1[0], Is.EqualTo(0)); + } + [Test] public void WindowRightWithNegativeWindowSize() { diff --git a/MoreLinq.Test/WindowTest.cs b/MoreLinq.Test/WindowTest.cs index 7ed406dfe..2fc765be9 100644 --- a/MoreLinq.Test/WindowTest.cs +++ b/MoreLinq.Test/WindowTest.cs @@ -34,6 +34,51 @@ public void TestWindowIsLazy() new BreakingSequence().Window(1); } + [Test] + public void WindowModifiedBeforeMoveNextDoesNotAffectNextWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.Window(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + window1[1] = -1; + e.MoveNext(); + var window2 = e.Current; + + Assert.That(window2[0], Is.EqualTo(1)); + } + + [Test] + public void WindowModifiedAfterMoveNextDoesNotAffectNextWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.Window(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + e.MoveNext(); + window1[1] = -1; + var window2 = e.Current; + + Assert.That(window2[0], Is.EqualTo(1)); + } + + [Test] + public void WindowModifiedDoesNotAffectPreviousWindow() + { + var sequence = Enumerable.Range(0, 3); + using var e = sequence.Window(2).GetEnumerator(); + + e.MoveNext(); + var window1 = e.Current; + e.MoveNext(); + var window2 = e.Current; + window2[0] = -1; + + Assert.That(window1[1], Is.EqualTo(1)); + } + /// /// Verify that a negative window size results in an exception /// @@ -42,7 +87,7 @@ public void TestWindowNegativeWindowSizeException() { var sequence = Enumerable.Repeat(1, 10); - AssertThrowsArgument.OutOfRangeException("size",() => + AssertThrowsArgument.OutOfRangeException("size", () => sequence.Window(-5)); } diff --git a/MoreLinq/Window.cs b/MoreLinq/Window.cs index c377f90d3..a3c5375f6 100644 --- a/MoreLinq/Window.cs +++ b/MoreLinq/Window.cs @@ -52,21 +52,20 @@ public static IEnumerable> Window(this IEnumerable> WindowLeft(this IEnumerable(window.Skip(1)); yield return window; - window = new List(window.Skip(1)); + window = nextWindow; } while (window.Count > 0) { + // prepare next window before exposing data + var nextWindow = new List(window.Skip(1)); yield return window; - window = new List(window.Skip(1)); + window = nextWindow; } } } diff --git a/MoreLinq/WindowRight.cs b/MoreLinq/WindowRight.cs index 9f9d76a91..4172c3d6d 100644 --- a/MoreLinq/WindowRight.cs +++ b/MoreLinq/WindowRight.cs @@ -84,8 +84,11 @@ static IEnumerable> WindowRightWhile( foreach (var item in source) { window.Add(item); + + // prepare next window before exposing data + var nextWindow = new List(predicate(item, window.Count) ? window : window.Skip(1)); yield return window; - window = new List(predicate(item, window.Count) ? window : window.Skip(1)); + window = nextWindow; } } }