Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 83a7a9d

Browse files
committed
Add tests for bulk removal from empty collections
Immutable set and list collections have distinct behaviors in their batch remove methods. These tests describe these differences and ensure that these publicly visible behaviors do not change unknowingly.
1 parent 18ff2b0 commit 83a7a9d

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

src/System.Collections.Immutable/tests/ImmutableListTest.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,25 @@ public void RemoveNonExistentKeepsReference()
374374
Assert.Same(list, list.Remove(3));
375375
}
376376

377+
/// <summary>
378+
/// Verifies that RemoveRange does not enumerate its argument if the list is empty
379+
/// and therefore could not possibly have any elements to remove anyway.
380+
/// </summary>
381+
/// <remarks>
382+
/// While this would seem an implementation detail and simply an optimization,
383+
/// it turns out that changing this behavior now *could* represent a breaking change
384+
/// because if the enumerable were to throw an exception, that exception would not be
385+
/// observed previously, but would start to be thrown if this behavior changed.
386+
/// So this is a test to lock the behavior in place.
387+
/// </remarks>
388+
/// <seealso cref="ImmutableSetTest.ExceptDoesEnumerateSequenceIfThisIsEmpty"/>
389+
[Fact]
390+
public void RemoveRangeDoesNotEnumerateSequenceIfThisIsEmpty()
391+
{
392+
var list = ImmutableList<int>.Empty;
393+
list.RemoveRange(Enumerable.Range(1, 1).Select(n => { Assert.False(true, "Sequence should not have been enumerated."); return n; }));
394+
}
395+
377396
[Fact]
378397
public void RemoveAtTest()
379398
{

src/System.Collections.Immutable/tests/ImmutableSetTest.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,25 @@ public void ExceptTest()
5858
this.ExceptTestHelper(Empty<int>().Add(1).Add(3).Add(5).Add(7), 3, 7);
5959
}
6060

61+
/// <summary>
62+
/// Verifies that Except *does* enumerate its argument if the collection is empty.
63+
/// </summary>
64+
/// <remarks>
65+
/// While this would seem an implementation detail and simply lack of an optimization,
66+
/// it turns out that changing this behavior now *could* represent a breaking change
67+
/// because if the enumerable were to throw an exception, that exception would be
68+
/// observed previously, but would no longer be thrown if this behavior changed.
69+
/// So this is a test to lock the behavior in place or be thoughtful if adding the optimization.
70+
/// </remarks>
71+
/// <seealso cref="ImmutableListTest.RemoveRangeDoesNotEnumerateSequenceIfThisIsEmpty"/>
72+
[Fact]
73+
public void ExceptDoesEnumerateSequenceIfThisIsEmpty()
74+
{
75+
bool enumerated = false;
76+
Empty<int>().Except(Enumerable.Range(1, 1).Select(n => { enumerated = true; return n; }));
77+
Assert.True(enumerated);
78+
}
79+
6180
[Fact]
6281
public void SymmetricExceptTest()
6382
{

0 commit comments

Comments
 (0)