.IndexOf() bug fixes and improvements. Tests extended & switched to use Recyclable.Collections.TestData.xUnit.
This commit is contained in:
1 parent
8a4364e0e9
commit
56c14910e0
5 files changed
+299
-153
No files matched your search
@@ -35,6 +35,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Recyclable.Collections.Pools;
|
||||
@@ -399,9 +400,18 @@ namespace Recyclable.Collections
|
||||
|
||||
public int IndexOf(T item, int index)
|
||||
{
|
||||
if (index < 0 || index >= _longCount)
|
||||
{
|
||||
ThrowHelper.ThrowArgumentOutOfRangeException_Index();
|
||||
}
|
||||
|
||||
Contract.Requires(index >= 0);
|
||||
Contract.Requires(index < _longCount);
|
||||
Contract.EndContractBlock();
|
||||
|
||||
if (_lastBlockWithData == 0)
|
||||
{
|
||||
return Array.IndexOf(_memoryBlocks[0], item, index, _longCount < _blockSize ? _nextItemIndex : _blockSize);
|
||||
return Array.IndexOf(_memoryBlocks[0], item, index, (_longCount < _blockSize ? _nextItemIndex : _blockSize) - index);
|
||||
}
|
||||
else if (_longCount == 0)
|
||||
{
|
||||
@@ -410,12 +420,12 @@ namespace Recyclable.Collections
|
||||
|
||||
int firstBlockIndex = index >> _blockSizePow2BitShift;
|
||||
int firstItemIndex = index & _blockSizeMinus1;
|
||||
int itemIndex = Array.IndexOf(_memoryBlocks[firstBlockIndex], item, firstItemIndex, (firstBlockIndex == _lastBlockWithData ? _nextItemIndex : _blockSize) - firstItemIndex);
|
||||
int itemIndex = Array.IndexOf(_memoryBlocks[firstBlockIndex], item, firstItemIndex, (firstBlockIndex == _lastBlockWithData && _nextItemIndex > 0 ? _nextItemIndex : _blockSize) - firstItemIndex);
|
||||
if (itemIndex >= 0)
|
||||
{
|
||||
return (firstBlockIndex << _blockSizePow2BitShift) + itemIndex;
|
||||
}
|
||||
else if (_longCount < RecyclableDefaults.MinItemsCountForParallelization)
|
||||
else if (_longCount < RecyclableDefaults.MinItemsCountForParallelization && firstBlockIndex + 1 <= _lastBlockWithData)
|
||||
{
|
||||
return (int)RecyclableLongList<T>.IndexOfHelpers.IndexOfSequential(this, item, firstBlockIndex + 1);
|
||||
}
|
||||
@@ -435,6 +445,20 @@ namespace Recyclable.Collections
|
||||
|
||||
public int IndexOf(T item, int index, int count)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
ThrowHelper.ThrowArgumentOutOfRangeException_Index();
|
||||
}
|
||||
|
||||
if (count + index > _longCount)
|
||||
{
|
||||
ThrowHelper.ThrowArgumentOutOfRangeException_Count();
|
||||
}
|
||||
|
||||
Contract.Requires(index >= 0);
|
||||
Contract.Requires(count + index <= _longCount);
|
||||
Contract.EndContractBlock();
|
||||
|
||||
if (_lastBlockWithData == 0)
|
||||
{
|
||||
return Array.IndexOf(_memoryBlocks[0], item, index, count);
|
||||
@@ -454,13 +478,13 @@ namespace Recyclable.Collections
|
||||
{
|
||||
return (firstBlockIndex << _blockSizePow2BitShift) + itemIndex;
|
||||
}
|
||||
else if (_longCount < RecyclableDefaults.MinItemsCountForParallelization)
|
||||
else if (_longCount < RecyclableDefaults.MinItemsCountForParallelization && firstBlockIndex + 1 <= _lastBlockWithData)
|
||||
{
|
||||
return (int)RecyclableLongList<T>.IndexOfHelpers.IndexOfSequential(this, item, firstBlockIndex + 1, count - firstBlockItemsCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_longCount > blockSize)
|
||||
if (firstBlockIndex + 1 <= _lastBlockWithData)
|
||||
{
|
||||
itemIndex = Array.IndexOf(_memoryBlocks[firstBlockIndex + 1], item, 0, (int)MathUtils.Min(blockSize, _longCount - blockSize, count - firstBlockItemsCount));
|
||||
return itemIndex >= 0 ? ((firstBlockIndex + 1) << _blockSizePow2BitShift) + itemIndex : checked((int)RecyclableLongList<T>.IndexOfHelpers.IndexOfParallel(this, item, firstBlockIndex + 2, count - firstBlockItemsCount - blockSize));
|
||||
|
||||
@@ -10,18 +10,20 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Recyclable.Collections.TestData" Version="0.0.3.3" />
|
||||
<PackageReference Include="xunit" Version="2.5.3" />
|
||||
<PackageReference Include="xunit.runner.console" Version="2.5.3">
|
||||
<PackageReference Include="Recyclable.Collections.TestData" Version="0.0.3.4" />
|
||||
<PackageReference Include="Recyclable.Collections.TestData.xUnit" Version="0.0.0.1" />
|
||||
<PackageReference Include="xunit" Version="2.6.4" />
|
||||
<PackageReference Include="xunit.runner.console" Version="2.6.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -3,6 +3,7 @@ using Recyclable.Collections;
|
||||
using Recyclable.Collections.TestData;
|
||||
using Recyclable.Collections.Linq;
|
||||
using System.Collections;
|
||||
using Recyclable.Collections.TestData.xUnit;
|
||||
|
||||
#pragma warning disable xUnit1026, RCS1163, IDE0060, RCS1235
|
||||
|
||||
@@ -29,7 +30,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void AddRangeShouldAddItemsInCorrectOrder(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -103,7 +104,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.EmptySourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(EmptySourceDataTheoryData))]
|
||||
public void AddRangeShouldDoNothingWhenSourceIsEmpty(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -177,7 +178,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void AddRangeShouldNotOverrideItems(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -268,7 +269,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void AddShouldAcceptDuplicates(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -312,7 +313,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void AddShouldAddItems(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -334,7 +335,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void AddShouldAddItemWhenAfterAddRange(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -359,7 +360,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceRefDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceRefDataTheoryData))]
|
||||
public void ClearShouldClearItemsWhenReferenceType(string testCase, IEnumerable<object> testData, int itemsCount)
|
||||
{
|
||||
//* Clearing empty list is tested in <see cref="ClearShouldSucceed"/>.
|
||||
@@ -380,7 +381,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void ClearShouldRemoveAllItems(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -398,7 +399,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void ConsecutiveDisposeShouldSucceed(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -410,7 +411,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void ConstructorShouldAcceptDuplicates(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -429,7 +430,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void ConstructorSourceShouldInitializeList(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Act
|
||||
@@ -444,7 +445,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void ContainsShouldFindAllItems(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
@@ -478,7 +479,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void ContainsShouldNotFindNonExistingItems(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
@@ -501,7 +502,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void CopyToShouldCopyAllItemsInTheCorrectOrder(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -519,7 +520,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceRefDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceRefDataTheoryData))]
|
||||
public void DisposeShouldClearItemsWhenReferenceType(string testCase, IEnumerable<object> testData, int itemsCount)
|
||||
{
|
||||
//* Disposing empty list is tested in <see cref="DisposeShouldSucceed"/>.
|
||||
@@ -561,7 +562,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void DisposeShouldSucceed(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -577,7 +578,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void EnumerateShouldYieldAllItemsInCorrectOrder(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -598,7 +599,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void GetByIndexShouldReturnCorrectItem(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -630,7 +631,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void IndexOfShouldNotFindNonExistingItems(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
@@ -652,7 +653,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void IndexOfShouldReturnCorrectIndexes(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -672,7 +673,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void IndexOfShouldReturnCorrectIndexesWhenConstrainedCount(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -692,7 +693,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void IndexOfShouldReturnCorrectIndexesWhenConstrainedIndex(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -712,7 +713,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void InitializeSortClearAddRangeRemoveShouldSucceed(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -756,7 +757,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void InsertShouldMoveItems(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -780,7 +781,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceRefDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceRefDataWithItemIndexTheoryData))]
|
||||
public void RemoveAtShouldClearItemWhenReferenceType(string testCase, IEnumerable<object> testData, int itemsCount, in long[] indexesToRemove)
|
||||
{
|
||||
// Prepare
|
||||
@@ -798,7 +799,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void RemoveAtShouldRemoveTheCorrectItem(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -819,7 +820,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceRefDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceRefDataWithItemIndexTheoryData))]
|
||||
public void RemoveShouldClearItemWhenReferenceType(string testCase, IEnumerable<object> testData, int itemsCount, in long[] indexesToRemove)
|
||||
{
|
||||
|
||||
@@ -840,7 +841,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithItemIndexTheoryData))]
|
||||
public void RemoveShouldRemoveTheCorrectItem(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -863,7 +864,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void SetByIndexShouldReturnCorrectItem(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -884,7 +885,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void ToArrayShouldReturnAllItemsInCorrectOrder(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -900,7 +901,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void VersionedEnumerateShouldRaiseExceptionWhenCollectionIsModified(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -918,7 +919,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataTheoryData))]
|
||||
public void VersionedEnumerateShouldYieldAllItemsInCorrectOrder(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
|
||||
@@ -4,6 +4,8 @@ using Recyclable.Collections.TestData;
|
||||
using Recyclable.Collections.Linq;
|
||||
using System.Collections;
|
||||
using System.Numerics;
|
||||
using Recyclable.Collections.TestData.xUnit;
|
||||
using Open.Collections;
|
||||
|
||||
#pragma warning disable xUnit1026, RCS1163, IDE0060, RCS1235
|
||||
|
||||
@@ -36,7 +38,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void AddRangeShouldAddItemsInCorrectOrder(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -109,7 +111,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.EmptySourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(EmptySourceDataTheoryData))]
|
||||
public void AddRangeShouldDoNothingWhenSourceIsEmpty(string testCase, IEnumerable<long> testData, long itemsCount)
|
||||
{
|
||||
// Prepare
|
||||
@@ -181,11 +183,11 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void AddRangeShouldNotOverrideItems(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
using var list = new RecyclableLongList<long>(minBlockSize: targetBlockSize);
|
||||
using RecyclableLongList<long> list = new(minBlockSize: targetBlockSize);
|
||||
|
||||
// Act
|
||||
if (testCase.Contains("Array[", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -269,7 +271,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void AddShouldAcceptDuplicates(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -307,7 +309,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void AddShouldAddItems(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -328,7 +330,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
//[InlineData("Debugging case", new long[1] { 1 }, 1, 2)]
|
||||
public void AddShouldAddItemWhenAfterAddRange(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
@@ -348,7 +350,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceRefDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceRefDataWithBlockSizeTheoryData))]
|
||||
public void ClearShouldClearItemsWhenReferenceType(string testCase, IEnumerable<object> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
if (itemsCount == 0)
|
||||
@@ -374,7 +376,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void ClearShouldRemoveAllItems(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -412,7 +414,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void ConsecutiveDisposeShouldSucceed(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -424,7 +426,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void ConstructorShouldAcceptDuplicates(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -441,7 +443,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void ConstructorSourceShouldInitializeList(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Act
|
||||
@@ -455,7 +457,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void ContainsShouldFindAllItems(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -470,7 +472,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.TargetDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(ItemsCountWithBlockSizeTheoryData))]
|
||||
public void ContainsShouldNotFindAnythingWhenListEmpty(long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -482,7 +484,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void ContainsShouldNotFindNonExistingItems(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -497,7 +499,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
//[InlineData("Debugging case", new[] { 1L, 2, }, 2, 2)]
|
||||
public void CopyToShouldCopyAllItemsInTheCorrectOrder(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
@@ -513,7 +515,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void CopyToShouldCopyAllItemsInTheCorrectOrderWhenConstrainedRange(string testCase, IEnumerable<long> testData, int itemsCount, int minBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -541,7 +543,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceRefDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceRefDataWithBlockSizeTheoryData))]
|
||||
public void DisposeShouldClearItemsWhenReferenceType(string testCase, IEnumerable<object> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
if (itemsCount == 0)
|
||||
@@ -585,7 +587,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void DisposeShouldSucceed(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -602,7 +604,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void EnumerateShouldYieldAllItemsInCorrectOrder(string testCase, IEnumerable<long> testData, int itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -621,7 +623,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void GetByIndexShouldReturnCorrectItem(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -635,7 +637,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void GetByIndexShouldReturnCorrectItemWhenLong(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -649,17 +651,105 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void IndexOfParallelShouldReturnCorrectIndexes(string testCase, IEnumerable<long> unusedTestData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
[ClassData(typeof(BlockSizeTheoryData))]
|
||||
public void IndexOfParallelShouldNotFindAnythingWhenBeyondRange(int blockSize)
|
||||
{
|
||||
const long ItemsCount = RecyclableDefaults.MinItemsCountForParallelization * 3;
|
||||
|
||||
// Prepare
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToArray();
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: blockSize, initialCapacity: ItemsCount);
|
||||
|
||||
var itemIndexes = RecyclableLongListTestData.CreateItemIndexVariants(ItemsCount, blockSize);
|
||||
foreach (var itemIndexForGenerator in itemIndexes)
|
||||
{
|
||||
var itemRanges = RecyclableLongListTestData.CombineItemIndexWithRange(itemIndexForGenerator, ItemsCount);
|
||||
foreach (var (itemIndex, rangedItemsCount) in itemRanges)
|
||||
{
|
||||
// Try finding the item prior the given itemIndex
|
||||
if (itemIndex > 0)
|
||||
{
|
||||
_ = list.IndexOf(testData[itemIndex - 1], (int)itemIndex, (int)rangedItemsCount).Should().Be(-1);
|
||||
}
|
||||
|
||||
// Try finding the item after the given item range
|
||||
if (itemIndex + rangedItemsCount < ItemsCount)
|
||||
{
|
||||
_ = list.IndexOf(testData[itemIndex + rangedItemsCount], (int)itemIndex, (int)rangedItemsCount).Should().Be(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(BlockSizeTheoryData))]
|
||||
public void IndexOfParallelShouldNotFindNonExistingItems(int blockSize)
|
||||
{
|
||||
const long ItemsCount = RecyclableDefaults.MinItemsCountForParallelization * 3;
|
||||
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToArray();
|
||||
// Prepare
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: targetBlockSize, initialCapacity: ItemsCount);
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToList();
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: blockSize, initialCapacity: ItemsCount);
|
||||
|
||||
// Act & Validate
|
||||
foreach (long itemIndex in itemIndexes)
|
||||
_ = list.IndexOf(0).Should().Be(-1);
|
||||
|
||||
var itemIndexes = RecyclableLongListTestData.CreateItemIndexVariants(ItemsCount, blockSize);
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
var item = -testData[(int)itemIndex];
|
||||
|
||||
// Act & Validate
|
||||
_ = list.IndexOf(item).Should().Be(-1);
|
||||
_ = list.IndexOf(item, (int)itemIndex).Should().Be(-1);
|
||||
_ = list.IndexOf(-item, (int)itemIndex, 0).Should().Be(-1);
|
||||
_ = list.IndexOf(0, (int)itemIndex).Should().Be(-1);
|
||||
_ = list.IndexOf(0, (int)itemIndex, 0).Should().Be(-1);
|
||||
_ = list.IndexOf(item, (int)ItemsCount, 0).Should().Be(-1);
|
||||
|
||||
if (itemIndex > 0)
|
||||
{
|
||||
_ = list.IndexOf(testData[(int)itemIndex - 1], (int)itemIndex).Should().Be(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(BlockSizeTheoryData))]
|
||||
public void IndexOfParallelShouldNotFindNonExistingItemsWhenConstrainedCount(int blockSize)
|
||||
{
|
||||
const long ItemsCount = RecyclableDefaults.MinItemsCountForParallelization * 3;
|
||||
|
||||
// Prepare
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToArray();
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: blockSize, initialCapacity: ItemsCount);
|
||||
|
||||
var itemIndexes = RecyclableLongListTestData.CreateItemIndexVariants(ItemsCount, blockSize);
|
||||
foreach (var itemIndexForGenerator in itemIndexes)
|
||||
{
|
||||
var itemRanges = RecyclableLongListTestData.CombineItemIndexWithRange(itemIndexForGenerator, ItemsCount);
|
||||
foreach (var (itemIndex, rangedItemsCount) in itemRanges)
|
||||
{
|
||||
// Act & Validate
|
||||
_ = list.IndexOf(-testData[itemIndex], (int)itemIndex, (int)rangedItemsCount).Should().Be(-1);
|
||||
_ = list.IndexOf(0, (int)itemIndex, (int)rangedItemsCount).Should().Be(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(BlockSizeTheoryData))]
|
||||
public void IndexOfParallelShouldReturnCorrectIndexes(int blockSize)
|
||||
{
|
||||
const long ItemsCount = RecyclableDefaults.MinItemsCountForParallelization * 3;
|
||||
|
||||
// Prepare
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToArray();
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: blockSize, initialCapacity: ItemsCount);
|
||||
|
||||
// Act & Validate
|
||||
IEnumerable<long> itemIndexes = RecyclableLongListTestData.CreateItemIndexVariants(ItemsCount, blockSize);
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
var actual = list.IndexOf(testData[itemIndex]);
|
||||
_ = actual.Should().Be((int)itemIndex);
|
||||
@@ -667,68 +757,93 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexWithRangeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void IndexOfParallelShouldReturnCorrectIndexesWhenConstrainedCount(string testCase, IEnumerable<long> unusedTestData, int itemsCount, int minBlockSize, in (long ItemIndex, long RangedItemsCount)[] itemRanges)
|
||||
[ClassData(typeof(BlockSizeTheoryData))]
|
||||
public void IndexOfParallelShouldReturnCorrectIndexesWhenConstrainedCount(int blockSize)
|
||||
{
|
||||
const long ItemsCount = RecyclableDefaults.MinItemsCountForParallelization * 3;
|
||||
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToArray();
|
||||
// Prepare
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: minBlockSize, initialCapacity: ItemsCount);
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToArray();
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: blockSize, initialCapacity: ItemsCount);
|
||||
|
||||
// Act & Validate
|
||||
foreach (var (itemIndex, rangedItemsCount) in itemRanges)
|
||||
var itemIndexes = RecyclableLongListTestData.CreateItemIndexVariants(ItemsCount, blockSize);
|
||||
foreach (var itemIndexForGenerator in itemIndexes)
|
||||
{
|
||||
TestWith(list, (int)itemIndex, (int)rangedItemsCount);
|
||||
TestWith(list, (int)(itemIndex - 1), 3);
|
||||
TestWith(list, (int)(itemIndex - 1), (int)(itemIndex + 1));
|
||||
TestWith(list, (int)Math.Max(0, itemIndex - RecyclableDefaults.MinItemsCountForParallelization), (int)Math.Min(ItemsCount - itemIndex + RecyclableDefaults.MinItemsCountForParallelization, itemIndex + RecyclableDefaults.MinItemsCountForParallelization));
|
||||
}
|
||||
|
||||
static void TestWith(RecyclableLongList<long> list, int index, int count)
|
||||
{
|
||||
index = Math.Max(0, index);
|
||||
count = Math.Min(count, list.Count - index);
|
||||
_ = list.IndexOf(list[index], index, count).Should().Be(count > 0 ? index : -1);
|
||||
_ = list.IndexOf(list[index], Math.Max(0, index - 1), 3).Should().Be(index);
|
||||
_ = list.IndexOf(list[Math.Max(0, index + count - 1)], index, count).Should().Be(count > 0 ? Math.Max(0, index + count - 1) : -1);
|
||||
_ = list.IndexOf(0, index, count).Should().Be(-1);
|
||||
|
||||
if (index > 0)
|
||||
var itemRanges = RecyclableLongListTestData.CombineItemIndexWithRange(itemIndexForGenerator, ItemsCount);
|
||||
foreach (var (itemIndex, rangedItemsCount) in itemRanges)
|
||||
{
|
||||
_ = list.IndexOf(list[index - 1], index, count).Should().Be(-1);
|
||||
// Act & Validate
|
||||
if (rangedItemsCount > 0)
|
||||
{
|
||||
// Find first item in range
|
||||
_ = list.IndexOf(testData[itemIndex], (int)itemIndex, (int)rangedItemsCount).Should().Be((int)itemIndex);
|
||||
|
||||
// Find last item in range
|
||||
_ = list.IndexOf(testData[itemIndex + rangedItemsCount - 1], (int)itemIndex, (int)rangedItemsCount).Should().Be((int)(itemIndex + rangedItemsCount - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void IndexOfParallelShouldReturnCorrectIndexesWhenConstrainedIndex(string testCase, IEnumerable<long> unusedTestData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
[ClassData(typeof(BlockSizeTheoryData))]
|
||||
public void IndexOfParallelShouldReturnCorrectIndexesWhenConstrainedIndex(int blockSize)
|
||||
{
|
||||
const long ItemsCount = RecyclableDefaults.MinItemsCountForParallelization * 3;
|
||||
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToArray();
|
||||
// Prepare
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: targetBlockSize, initialCapacity: ItemsCount);
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToArray();
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: blockSize, initialCapacity: ItemsCount);
|
||||
|
||||
// Act & Validate
|
||||
foreach(var itemIndex in itemIndexes)
|
||||
var itemIndexes = RecyclableLongListTestData.CreateItemIndexVariants(ItemsCount, blockSize);
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
TestWith(list, (int)Math.Max(itemIndex - 1, 0));
|
||||
TestWith(list, (int)Math.Max(0, itemIndex - RecyclableDefaults.MinItemsCountForParallelization));
|
||||
_ = list.IndexOf(testData[itemIndex], (int)itemIndex).Should().Be((int)itemIndex);
|
||||
_ = list.IndexOf(testData[^1], (int)itemIndex).Should().Be(list.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void TestWith(RecyclableLongList<long> list, int index)
|
||||
[Theory]
|
||||
[ClassData(typeof(BlockSizeTheoryData))]
|
||||
public void IndexOfParallelShouldThrowWhenInvalidRange(int blockSize)
|
||||
{
|
||||
const long ItemsCount = RecyclableDefaults.MinItemsCountForParallelization * 3;
|
||||
|
||||
// Prepare
|
||||
var testData = RecyclableLongListTestData.CreateTestData(ItemsCount).ToList();
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: blockSize, initialCapacity: ItemsCount);
|
||||
|
||||
var item = testData[0];
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => testData.IndexOf(item, -1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => list.IndexOf(item, -1));
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => testData.IndexOf(item, (int)ItemsCount + 1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => list.IndexOf(item, (int)ItemsCount + 1));
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => testData.IndexOf(item, (int)ItemsCount, 1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => list.IndexOf(item, (int)ItemsCount, 1));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexWithRangeTheoryData))]
|
||||
public void IndexOfShouldNotFindAnythingWhenBeyondRange(string testCase, IEnumerable<long> testData, int itemsCount, int minBlockSize, in (long ItemIndex, long RangedItemsCount)[] itemRanges)
|
||||
{
|
||||
// Prepare
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: minBlockSize, initialCapacity: itemsCount);
|
||||
var expectedData = testData.ToArray();
|
||||
|
||||
foreach (var (itemIndex, rangedItemsCount) in itemRanges)
|
||||
{
|
||||
var count = list.Count - 1;
|
||||
_ = list.IndexOf(list[index], index).Should().Be(index);
|
||||
_ = list.IndexOf(list[count], index).Should().Be(count);
|
||||
_ = list.IndexOf(-1, index).Should().Be(-1);
|
||||
_ = list.IndexOf(0, index).Should().Be(-1);
|
||||
|
||||
if (index > 0)
|
||||
// Try finding the item prior the given itemIndex
|
||||
if (itemIndex > 0)
|
||||
{
|
||||
_ = list.IndexOf(list[index - 1], index).Should().Be(-1);
|
||||
_ = list.IndexOf(expectedData[(int)(itemIndex - 1)], (int)itemIndex, (int)rangedItemsCount).Should().Be(-1);
|
||||
}
|
||||
|
||||
// Try finding the item after the given item range
|
||||
if (itemIndex + rangedItemsCount < itemsCount)
|
||||
{
|
||||
_ = list.IndexOf(expectedData[(int)(itemIndex + rangedItemsCount)], (int)itemIndex, (int)rangedItemsCount).Should().Be(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -745,22 +860,36 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void IndexOfShouldNotFindNonExistingItems(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: targetBlockSize, itemsCount);
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
var expectedData = testData.ToArray();
|
||||
|
||||
// Act & Validate
|
||||
_ = list.IndexOf(0).Should().Be(-1);
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
_ = list.IndexOf(-list[itemIndex]).Should().Be(-1);
|
||||
var item = -expectedData[itemIndex];
|
||||
|
||||
_ = list.IndexOf(item).Should().Be(-1);
|
||||
_ = list.IndexOf(item, (int)itemIndex).Should().Be(-1);
|
||||
_ = list.IndexOf(-item, (int)itemIndex, 0).Should().Be(-1);
|
||||
_ = list.IndexOf(0, (int)itemIndex).Should().Be(-1);
|
||||
_ = list.IndexOf(0, (int)itemIndex, 0).Should().Be(-1);
|
||||
|
||||
if (itemIndex > 0)
|
||||
{
|
||||
_ = list.IndexOf(list[itemIndex - 1], (int)itemIndex).Should().Be(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void IndexOfShouldReturnCorrectIndexes(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -769,12 +898,13 @@ namespace Recyclable.CollectionsTests
|
||||
// Act & Validate
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
_ = list.IndexOf(list[itemIndex]).Should().Be((int)itemIndex);
|
||||
int actual = list.IndexOf(list[itemIndex]);
|
||||
_ = actual.Should().Be((int)itemIndex);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexWithRangeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexWithRangeTheoryData))]
|
||||
public void IndexOfShouldReturnCorrectIndexesWhenConstrainedCount(string testCase, IEnumerable<long> testData, int itemsCount, int minBlockSize, in (long ItemIndex, long RangedItemsCount)[] itemRanges)
|
||||
{
|
||||
// Prepare
|
||||
@@ -784,46 +914,35 @@ namespace Recyclable.CollectionsTests
|
||||
// Act & Validate
|
||||
foreach (var (itemIndex, rangedItemsCount) in itemRanges)
|
||||
{
|
||||
TestWith(list, expectedData, itemIndex, rangedItemsCount, expectedData[(int)itemIndex]);
|
||||
TestWith(list, expectedData, itemIndex, (int)(itemsCount - itemIndex), expectedData[(int)itemIndex]);
|
||||
TestWith(list, expectedData, itemIndex, rangedItemsCount, expectedData[(int)Math.Max(0, itemIndex + rangedItemsCount - 1)]);
|
||||
}
|
||||
// Act & Validate
|
||||
if (rangedItemsCount > 0)
|
||||
{
|
||||
// Find first item in range
|
||||
_ = list.IndexOf(expectedData[(int)itemIndex], (int)itemIndex, (int)rangedItemsCount).Should().Be((int)itemIndex);
|
||||
|
||||
static void TestWith(RecyclableLongList<long> list, List<long> expectedData, long itemIndex, long rangedItemsCount, long item)
|
||||
{
|
||||
var expected = expectedData.IndexOf(item, (int)itemIndex, (int)rangedItemsCount);
|
||||
var actual = list.IndexOf(item, (int)itemIndex, (int)rangedItemsCount);
|
||||
|
||||
_ = actual.Should().Be(expected);
|
||||
// Find last item in range
|
||||
_ = list.IndexOf(expectedData[(int)(itemIndex + rangedItemsCount - 1)], (int)itemIndex, (int)rangedItemsCount).Should().Be((int)(itemIndex + rangedItemsCount - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void IndexOfShouldReturnCorrectIndexesWhenConstrainedIndex(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void IndexOfShouldReturnCorrectIndexesWhenConstrainedIndex(string testCase, IEnumerable<long> testData, long itemsCount, int blockSize, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
using var list = new RecyclableLongList<long>(testData, initialCapacity: itemsCount);
|
||||
using var list = new RecyclableLongList<long>(testData, minBlockSize: blockSize, initialCapacity: itemsCount);
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
TestWith(list, expectedData[(int)itemIndex], itemIndex);
|
||||
TestWith(list, expectedData[itemsCount - 1], itemIndex);
|
||||
}
|
||||
|
||||
void TestWith(RecyclableLongList<long> list, long item, long itemIndex)
|
||||
{
|
||||
var expected = expectedData.IndexOf(item, (int)itemIndex);
|
||||
// Act
|
||||
var actual = list.IndexOf(item, (int)itemIndex);
|
||||
// Validate
|
||||
_ = actual.Should().Be(expected);
|
||||
_ = list.IndexOf(expectedData[(int)itemIndex], (int)itemIndex).Should().Be((int)itemIndex);
|
||||
_ = list.IndexOf(expectedData[^1], (int)itemIndex).Should().Be(list.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void InitializeSortClearAddRangeRemoveShouldSucceed(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -867,7 +986,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void InsertShouldMoveItems(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
|
||||
@@ -895,7 +1014,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void InsertShouldMoveItemsWhenLong(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
|
||||
@@ -934,7 +1053,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void LongIndexOfShouldNotFindNonExistingItems(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -949,7 +1068,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void LongIndexOfShouldReturnCorrectIndexes(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
@@ -963,7 +1082,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceRefDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceRefDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void RemoveAtShouldClearItemWhenReferenceType(string testCase, IEnumerable<object> testData, long itemsCount, int targetBlockSize, in long[] indexesToRemove)
|
||||
{
|
||||
foreach (var indexToRemove in indexesToRemove)
|
||||
@@ -981,7 +1100,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void RemoveAtShouldRemoveTheCorrectItem(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -1003,7 +1122,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void RemoveAtShouldRemoveTheCorrectItemWhenLong(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -1025,7 +1144,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceRefDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceRefDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void RemoveShouldClearItemWhenReferenceType(string testCase, IEnumerable<object> testData, long itemsCount, int targetBlockSize, in long[] indexesToRemove)
|
||||
{
|
||||
var expectedItems = testData.ToArray();
|
||||
@@ -1046,7 +1165,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeWithItemIndexTheoryData))]
|
||||
public void RemoveShouldRemoveTheCorrectItem(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize, in long[] itemIndexes)
|
||||
{
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -1069,7 +1188,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void SetByIndexShouldReturnCorrectItem(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -1090,7 +1209,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void SetByIndexShouldReturnCorrectItemWhenLong(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -1111,7 +1230,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void VersionedEnumerateShouldRaiseExceptionWhenCollectionIsModified(string testCase, IEnumerable<long> testData, long itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
@@ -1131,7 +1250,7 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
[ClassData(typeof(SourceDataWithBlockSizeTheoryData))]
|
||||
public void VersionedEnumerateShouldYieldAllItemsInCorrectOrder(string testCase, IEnumerable<long> testData, int itemsCount, int targetBlockSize)
|
||||
{
|
||||
// Prepare
|
||||
|
||||
Reference in new issue
Block a user