Fixed handling of empty lists in RecyclableArrayList.
Some RecyclableList properties made public to allow use in RecyclableArrayList. Added support for RecyclableList in RecyclableArrayList.AddRange. Additional tests added for RecyclableArrayList.
This commit is contained in:
1 parent
e312accfe5
commit
e6224ebe44
3 files changed
+214
-128
No files matched your search
@@ -11,9 +11,9 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
protected T[] _memoryBlock;
|
protected T[] _memoryBlock;
|
||||||
|
|
||||||
private static void ThrowArgumentOutOfRangeException()
|
private static void ThrowArgumentOutOfRangeException(in string message)
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException("index");
|
throw new ArgumentOutOfRangeException(message, (Exception?)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -162,6 +162,11 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
public void AddRange(in T[] items)
|
public void AddRange(in T[] items)
|
||||||
{
|
{
|
||||||
|
if (items.LongLength == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int sourceItemsCount = items.Length;
|
int sourceItemsCount = items.Length;
|
||||||
int targetCapacity = _count + sourceItemsCount;
|
int targetCapacity = _count + sourceItemsCount;
|
||||||
if (_capacity < targetCapacity)
|
if (_capacity < targetCapacity)
|
||||||
@@ -177,6 +182,11 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
public void AddRange(List<T> items)
|
public void AddRange(List<T> items)
|
||||||
{
|
{
|
||||||
|
if (items.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var sourceItemsCount = items.Count;
|
var sourceItemsCount = items.Count;
|
||||||
var targetCapacity = _count + sourceItemsCount;
|
var targetCapacity = _count + sourceItemsCount;
|
||||||
if (_capacity < targetCapacity)
|
if (_capacity < targetCapacity)
|
||||||
@@ -190,6 +200,11 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
public void AddRange(IList<T> items)
|
public void AddRange(IList<T> items)
|
||||||
{
|
{
|
||||||
|
if (items.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var sourceItemsCount = items.Count;
|
var sourceItemsCount = items.Count;
|
||||||
var targetCapacity = _count + sourceItemsCount;
|
var targetCapacity = _count + sourceItemsCount;
|
||||||
if (_capacity < targetCapacity)
|
if (_capacity < targetCapacity)
|
||||||
@@ -203,6 +218,11 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
public void AddRange(RecyclableArrayList<T> items)
|
public void AddRange(RecyclableArrayList<T> items)
|
||||||
{
|
{
|
||||||
|
if (items.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var sourceItemsCount = items._count;
|
var sourceItemsCount = items._count;
|
||||||
var targetCapacity = _count + sourceItemsCount;
|
var targetCapacity = _count + sourceItemsCount;
|
||||||
if (_capacity < targetCapacity)
|
if (_capacity < targetCapacity)
|
||||||
@@ -216,6 +236,58 @@ namespace Recyclable.Collections
|
|||||||
_count = targetCapacity;
|
_count = targetCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddRange(RecyclableList<T> items)
|
||||||
|
{
|
||||||
|
if (items.LongCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceItemsCount = items.LongCount;
|
||||||
|
if (sourceItemsCount > int.MaxValue)
|
||||||
|
{
|
||||||
|
ThrowArgumentOutOfRangeException($"The number of items exceeds the maximum capacity of {nameof(RecyclableArrayList<T>)}, equal {int.MaxValue}, equal {int.MaxValue}. Please consider using {nameof(RecyclableList<T>)}, instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_count + sourceItemsCount > int.MaxValue)
|
||||||
|
{
|
||||||
|
ThrowArgumentOutOfRangeException($"The total number of items in source and target table exceeds the maximum capacity of {nameof(RecyclableArrayList<T>)}, equal {int.MaxValue}. Please consider using {nameof(RecyclableList<T>)}, instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
int targetCapacity = _count + (int)sourceItemsCount;
|
||||||
|
if (_capacity < targetCapacity)
|
||||||
|
{
|
||||||
|
_ = EnsureCapacity(targetCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<T> targetSpan = new Span<T>(_memoryBlock)[_count..],
|
||||||
|
itemsSpan;
|
||||||
|
|
||||||
|
int blockIndex,
|
||||||
|
sourceBlockSize = items.BlockSize,
|
||||||
|
lastBlockIndex = (int)(sourceItemsCount / sourceBlockSize) - 1;
|
||||||
|
|
||||||
|
for (blockIndex = 0; blockIndex <= lastBlockIndex; blockIndex++)
|
||||||
|
{
|
||||||
|
itemsSpan = new(items.MemoryBlocks[blockIndex], 0, sourceBlockSize);
|
||||||
|
itemsSpan.CopyTo(targetSpan);
|
||||||
|
targetSpan = targetSpan[sourceBlockSize..];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockIndex == 0)
|
||||||
|
{
|
||||||
|
itemsSpan = new(items.MemoryBlocks[blockIndex], 0, (int)sourceItemsCount);
|
||||||
|
itemsSpan.CopyTo(targetSpan);
|
||||||
|
}
|
||||||
|
else if (blockIndex < items.BlockCount)
|
||||||
|
{
|
||||||
|
itemsSpan = new(items.MemoryBlocks[blockIndex], 0, items.NextItemIndex);
|
||||||
|
itemsSpan.CopyTo(targetSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
_count = targetCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.MinPooledArrayLength)
|
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.MinPooledArrayLength)
|
||||||
{
|
{
|
||||||
if (source is T[] sourceArray)
|
if (source is T[] sourceArray)
|
||||||
@@ -375,7 +447,7 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
if (index >= oldCount)
|
if (index >= oldCount)
|
||||||
{
|
{
|
||||||
ThrowArgumentOutOfRangeException();
|
ThrowArgumentOutOfRangeException($"Argument \"{index}\" is out of range. The current version supports removing the last element, only ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ namespace Recyclable.Collections
|
|||||||
protected ArrayPool<T> _blockArrayPool;
|
protected ArrayPool<T> _blockArrayPool;
|
||||||
protected T[][] _memoryBlocks;
|
protected T[][] _memoryBlocks;
|
||||||
|
|
||||||
|
public int BlockSize => _blockSize;
|
||||||
|
public int BlockCount => _memoryBlocks.Length;
|
||||||
|
|
||||||
private long _capacity;
|
private long _capacity;
|
||||||
public long Capacity
|
public long Capacity
|
||||||
{
|
{
|
||||||
@@ -29,7 +32,8 @@ namespace Recyclable.Collections
|
|||||||
protected set => _capacity = value;
|
protected set => _capacity = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count => (int)_longCount;
|
public int Count => checked((int)_longCount);
|
||||||
|
public bool IsReadOnly { get; }
|
||||||
|
|
||||||
protected long _longCount;
|
protected long _longCount;
|
||||||
|
|
||||||
@@ -39,8 +43,8 @@ namespace Recyclable.Collections
|
|||||||
set => _longCount = value;
|
set => _longCount = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsReadOnly { get; }
|
public int LastBlockIndex => _lastBlockIndex;
|
||||||
public int BlockCount => _memoryBlocks.Length;
|
public int NextItemIndex => _nextItemIndex;
|
||||||
|
|
||||||
private static void RemoveAt(RecyclableList<T> list, long index, ArrayPool<T> blockArrayPool)
|
private static void RemoveAt(RecyclableList<T> list, long index, ArrayPool<T> blockArrayPool)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,75 +7,163 @@ namespace Recyclable.CollectionsTests
|
|||||||
{
|
{
|
||||||
private readonly static IEnumerable<int> _testData = Enumerable.Range(1, 20);
|
private readonly static IEnumerable<int> _testData = Enumerable.Range(1, 20);
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void AddCountShouldSucceed()
|
[MemberData(nameof(RecyclableListTestData.SourceDataVariants), MemberType = typeof(RecyclableListTestData))]
|
||||||
|
public void AddCountShouldSucceed(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||||
{
|
{
|
||||||
// Prepare
|
// Prepare
|
||||||
var testData = _testData.ToArray();
|
var list = new RecyclableArrayList<long>();
|
||||||
var list = new RecyclableArrayList<int>();
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
foreach (var item in testData)
|
foreach (var item in testData)
|
||||||
{
|
{
|
||||||
list.Add(item);
|
list.Add(item);
|
||||||
_ = list.Count.Should().Be(item);
|
_ = list.Count.Should().Be((int)item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
_ = list.Capacity.Should().Be(32);
|
_ = list.Capacity.Should().BeGreaterThanOrEqualTo((int)itemsCount);
|
||||||
_ = list.Should().HaveCount(testData.Length)
|
_ = list.Count.Should().Be((int)itemsCount);
|
||||||
.And.ContainInConsecutiveOrder(testData)
|
_ = list.Should().ContainInConsecutiveOrder(testData);
|
||||||
.And.BeEquivalentTo(testData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void AddRangeShouldAddItemsInCorrectOrderWhenSourceIsArray()
|
[MemberData(nameof(RecyclableListTestData.SourceDataVariants), MemberType = typeof(RecyclableListTestData))]
|
||||||
|
public void AddRangeShouldAddItemsInCorrectOrder(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||||
{
|
{
|
||||||
// Prepare
|
// Prepare
|
||||||
var testData = _testData.ToArray();
|
using var list = new RecyclableArrayList<long>();
|
||||||
var list = new RecyclableArrayList<int>();
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
list.AddRange(testData);
|
if (testData is long[] testDataArray)
|
||||||
|
{
|
||||||
// Validate
|
list.AddRange(testDataArray);
|
||||||
_ = list.Capacity.Should().Be(20, "when capacity == 0, then we allocate as much memory as needed, only");
|
}
|
||||||
_ = list.Should().HaveCount(testData.Length)
|
else if (testData is List<long> testDataList)
|
||||||
.And.ContainInConsecutiveOrder(testData)
|
{
|
||||||
.And.BeEquivalentTo(testData);
|
list.AddRange(testDataList);
|
||||||
|
}
|
||||||
|
else if (testData is RecyclableArrayList<long> testDataRecyclableArrayList)
|
||||||
|
{
|
||||||
|
list.AddRange(testDataRecyclableArrayList);
|
||||||
|
}
|
||||||
|
else if (testData is RecyclableList<long> testDataRecyclableList)
|
||||||
|
{
|
||||||
|
list.AddRange(testDataRecyclableList);
|
||||||
|
}
|
||||||
|
else if (testData is IList<long> testDataIList)
|
||||||
|
{
|
||||||
|
list.AddRange(testDataIList);
|
||||||
|
}
|
||||||
|
else if (testData is IEnumerable<long> testDataIEnumerable)
|
||||||
|
{
|
||||||
|
list.AddRange(testDataIEnumerable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidCastException("Unknown type of test data");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void AddRangeShouldAddItemsInCorrectOrderWhenSourceIsList()
|
|
||||||
{
|
|
||||||
// Prepare
|
|
||||||
var testData = _testData.ToList();
|
|
||||||
var list = new RecyclableArrayList<int>();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
list.AddRange(testData);
|
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
_ = list.Capacity.Should().Be(20, "when capacity == 0, then we allocate as much memory as needed, only");
|
_ = list.Capacity.Should().BeGreaterThanOrEqualTo((int)itemsCount, "when capacity == 0, then we should allocate as much memory as needed, only");
|
||||||
_ = list.Should().HaveCount(testData.Count)
|
_ = list.Count.Should().Be((int)itemsCount);
|
||||||
.And.ContainInConsecutiveOrder(testData)
|
_ = list.Should().ContainInConsecutiveOrder(testData);
|
||||||
.And.BeEquivalentTo(testData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void ConstructorShouldAddItemsInCorrectOrderWhenSourceIsIEnumerable()
|
[MemberData(nameof(RecyclableListTestData.SourceDataVariants), MemberType = typeof(RecyclableListTestData))]
|
||||||
|
public void AddShouldAcceptDuplicates(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||||
{
|
{
|
||||||
// Prepare
|
|
||||||
var testData = _testData;
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var list = new RecyclableArrayList<int>(testData);
|
using var list = new RecyclableArrayList<long>((int)itemsCount * 2);
|
||||||
|
foreach (var index in testData)
|
||||||
|
{
|
||||||
|
list.Add(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var index in testData)
|
||||||
|
{
|
||||||
|
list.Add(index);
|
||||||
|
}
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
_ = list.Capacity.Should().Be(32, "when we succeed in taking count without enumerating, then we allocate as much memory as needed, only");
|
_ = list.Count.Should().Be((int)itemsCount * 2);
|
||||||
_ = list.Should().HaveCount(testData.Count())
|
_ = list.Should().ContainInConsecutiveOrder(testData.Concat(testData));
|
||||||
.And.ContainInConsecutiveOrder(testData)
|
}
|
||||||
.And.BeEquivalentTo(testData);
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(RecyclableListTestData.SourceDataVariants), MemberType = typeof(RecyclableListTestData))]
|
||||||
|
public void ClearShouldRemoveAllItems(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||||
|
{
|
||||||
|
// Prepare
|
||||||
|
var list = new RecyclableArrayList<long>(testData);
|
||||||
|
_ = list.Count.Should().Be((int)itemsCount);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
list.Clear();
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
_ = list.Count.Should().Be(0);
|
||||||
|
_ = list.Should().BeEmpty();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(RecyclableListTestData.SourceDataVariants), MemberType = typeof(RecyclableListTestData))]
|
||||||
|
public void ConstructorShouldAcceptDuplicates(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
using var list = new RecyclableArrayList<long>(testData.Concat(testData), initialCapacity: (int)itemsCount * 2);
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
_ = list.Count.Should().Be((int)itemsCount * 2);
|
||||||
|
_ = list.Should().ContainInConsecutiveOrder(testData.Concat(testData));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(RecyclableListTestData.SourceDataVariants), MemberType = typeof(RecyclableListTestData))]
|
||||||
|
public void ConstructorShouldAddItemsInCorrectOrderWhenSourceIsIEnumerable(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var list = new RecyclableArrayList<long>(testData);
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
_ = list.Capacity.Should().BeGreaterThanOrEqualTo((int)itemsCount, "when we succeed in taking count without enumerating, then we allocate as much memory as needed, only");
|
||||||
|
_ = list.Count.Should().Be((int)itemsCount);
|
||||||
|
_ = list.Should().ContainInConsecutiveOrder(testData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(RecyclableListTestData.SourceDataVariants), MemberType = typeof(RecyclableListTestData))]
|
||||||
|
public void ConstructorSourceShouldInitializeList(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var list = new RecyclableArrayList<long>(testData);
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
_ = list.Count.Should().Be((int)itemsCount);
|
||||||
|
_ = list.Should().ContainInConsecutiveOrder(testData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(RecyclableListTestData.SourceDataVariants), MemberType = typeof(RecyclableListTestData))]
|
||||||
|
public void ContainsShouldFindAllItems(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||||
|
{
|
||||||
|
if (itemsCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
using var list = new RecyclableArrayList<long>(testData);
|
||||||
|
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
foreach (var item in testData)
|
||||||
|
{
|
||||||
|
// Validate
|
||||||
|
_ = list.Contains(item).Should().BeTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -203,21 +291,6 @@ namespace Recyclable.CollectionsTests
|
|||||||
_ = list.Capacity.Should().Be(20);
|
_ = list.Capacity.Should().Be(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ConstructorSourceShouldInitializeList()
|
|
||||||
{
|
|
||||||
// Prepare
|
|
||||||
var testData = _testData.ToArray();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var list = new RecyclableArrayList<int>(testData);
|
|
||||||
|
|
||||||
// Validate
|
|
||||||
_ = list.Should().HaveCount(testData.Length)
|
|
||||||
.And.ContainInConsecutiveOrder(testData)
|
|
||||||
.And.BeEquivalentTo(testData);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void EnumerateShouldYieldAllItemsInCorrectOrder()
|
public void EnumerateShouldYieldAllItemsInCorrectOrder()
|
||||||
{
|
{
|
||||||
@@ -254,22 +327,6 @@ namespace Recyclable.CollectionsTests
|
|||||||
.And.ContainInConsecutiveOrder(testData)
|
.And.ContainInConsecutiveOrder(testData)
|
||||||
.And.BeEquivalentTo(testData);
|
.And.BeEquivalentTo(testData);
|
||||||
}
|
}
|
||||||
[Fact]
|
|
||||||
public void ClearShouldRemoveAllItems()
|
|
||||||
{
|
|
||||||
// Prepare
|
|
||||||
var testData = _testData.ToArray();
|
|
||||||
var list = new RecyclableArrayList<int>(testData);
|
|
||||||
_ = list.Count.Should().NotBe(0);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
list.Clear();
|
|
||||||
|
|
||||||
// Validate
|
|
||||||
_ = list.Count.Should().Be(0);
|
|
||||||
_ = list.Should().HaveCount(0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void IndexOfShouldFindTheIndexes()
|
public void IndexOfShouldFindTheIndexes()
|
||||||
@@ -286,22 +343,6 @@ namespace Recyclable.CollectionsTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ContainsShouldFindAllItems()
|
|
||||||
{
|
|
||||||
// Prepare
|
|
||||||
var testData = _testData.ToArray();
|
|
||||||
using var list = new RecyclableArrayList<int>(testData);
|
|
||||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
|
||||||
|
|
||||||
// Act
|
|
||||||
foreach (var item in testData)
|
|
||||||
{
|
|
||||||
// Validate
|
|
||||||
_ = list.Contains(item).Should().BeTrue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ContainsShouldNotFindNonExistingItems()
|
public void ContainsShouldNotFindNonExistingItems()
|
||||||
{
|
{
|
||||||
@@ -333,36 +374,5 @@ namespace Recyclable.CollectionsTests
|
|||||||
_ = list.Contains(1).Should().BeTrue();
|
_ = list.Contains(1).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void AddShouldAcceptDuplicates()
|
|
||||||
{
|
|
||||||
// Prepare
|
|
||||||
int[] testNumbers = new[] { 1, 2, 2, 3 };
|
|
||||||
|
|
||||||
// Act
|
|
||||||
using var list = new RecyclableArrayList<int>();
|
|
||||||
foreach (var index in testNumbers)
|
|
||||||
{
|
|
||||||
list.Add(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate
|
|
||||||
_ = list.Count.Should().Be(testNumbers.Length);
|
|
||||||
_ = list.Should().BeEquivalentTo(testNumbers);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ConstructorShouldAcceptDuplicates()
|
|
||||||
{
|
|
||||||
// Prepare
|
|
||||||
int[] testNumbers = new[] { 1, 2, 2, 3 };
|
|
||||||
|
|
||||||
// Act
|
|
||||||
using var list = new RecyclableArrayList<int>(testNumbers);
|
|
||||||
|
|
||||||
// Validate
|
|
||||||
_ = list.Count.Should().Be(testNumbers.Length);
|
|
||||||
_ = list.Should().BeEquivalentTo(testNumbers);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user