You've already forked linux-packaging-mono
Imported Upstream version 5.10.0.47
Former-commit-id: d0813289fa2d35e1f8ed77530acb4fb1df441bc0
This commit is contained in:
parent
88ff76fe28
commit
e46a49ecf1
@@ -522,69 +522,74 @@ namespace System.Linq
|
||||
internal TElement ElementAt(TElement[] elements, int count, int idx) =>
|
||||
elements[QuickSelect(ComputeMap(elements, count), count - 1, idx)];
|
||||
|
||||
private int CompareKeys(int index1, int index2) => index1 == index2 ? 0 : CompareAnyKeys(index1, index2);
|
||||
|
||||
private void QuickSort(int[] map, int left, int right)
|
||||
{
|
||||
do
|
||||
{
|
||||
int i = left;
|
||||
int j = right;
|
||||
int x = map[i + ((j - i) >> 1)];
|
||||
do
|
||||
{
|
||||
while (i < map.Length && CompareKeys(x, map[i]) > 0)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
while (j >= 0 && CompareKeys(x, map[j]) < 0)
|
||||
{
|
||||
j--;
|
||||
}
|
||||
|
||||
if (i > j)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < j)
|
||||
{
|
||||
int temp = map[i];
|
||||
map[i] = map[j];
|
||||
map[j] = temp;
|
||||
}
|
||||
|
||||
i++;
|
||||
j--;
|
||||
}
|
||||
while (i <= j);
|
||||
|
||||
if (j - left <= right - i)
|
||||
{
|
||||
if (left < j)
|
||||
{
|
||||
QuickSort(map, left, j);
|
||||
}
|
||||
|
||||
left = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i < right)
|
||||
{
|
||||
QuickSort(map, i, right);
|
||||
}
|
||||
|
||||
right = j;
|
||||
}
|
||||
}
|
||||
while (left < right);
|
||||
}
|
||||
protected abstract void QuickSort(int[] map, int left, int right);
|
||||
|
||||
// Sorts the k elements between minIdx and maxIdx without sorting all elements
|
||||
// Time complexity: O(n + k log k) best and average case. O(n^2) worse case.
|
||||
private void PartialQuickSort(int[] map, int left, int right, int minIdx, int maxIdx)
|
||||
protected abstract void PartialQuickSort(int[] map, int left, int right, int minIdx, int maxIdx);
|
||||
|
||||
// Finds the element that would be at idx if the collection was sorted.
|
||||
// Time complexity: O(n) best and average case. O(n^2) worse case.
|
||||
protected abstract int QuickSelect(int[] map, int right, int idx);
|
||||
}
|
||||
|
||||
internal sealed class EnumerableSorter<TElement, TKey> : EnumerableSorter<TElement>
|
||||
{
|
||||
private readonly Func<TElement, TKey> _keySelector;
|
||||
private readonly IComparer<TKey> _comparer;
|
||||
private readonly bool _descending;
|
||||
private readonly EnumerableSorter<TElement> _next;
|
||||
private TKey[] _keys;
|
||||
|
||||
internal EnumerableSorter(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, EnumerableSorter<TElement> next)
|
||||
{
|
||||
_keySelector = keySelector;
|
||||
_comparer = comparer;
|
||||
_descending = descending;
|
||||
_next = next;
|
||||
}
|
||||
|
||||
internal override void ComputeKeys(TElement[] elements, int count)
|
||||
{
|
||||
_keys = new TKey[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
_keys[i] = _keySelector(elements[i]);
|
||||
}
|
||||
|
||||
_next?.ComputeKeys(elements, count);
|
||||
}
|
||||
|
||||
internal override int CompareAnyKeys(int index1, int index2)
|
||||
{
|
||||
int c = _comparer.Compare(_keys[index1], _keys[index2]);
|
||||
if (c == 0)
|
||||
{
|
||||
if (_next == null)
|
||||
{
|
||||
return index1 - index2; // ensure stability of sort
|
||||
}
|
||||
|
||||
return _next.CompareAnyKeys(index1, index2);
|
||||
}
|
||||
|
||||
// -c will result in a negative value for int.MinValue (-int.MinValue == int.MinValue).
|
||||
// Flipping keys earlier is more likely to trigger something strange in a comparer,
|
||||
// particularly as it comes to the sort being stable.
|
||||
return (_descending != (c > 0)) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
private int CompareKeys(int index1, int index2) => index1 == index2 ? 0 : CompareAnyKeys(index1, index2);
|
||||
|
||||
protected override void QuickSort(int[] keys, int lo, int hi) =>
|
||||
Array.Sort(keys, lo, hi - lo + 1, Comparer<int>.Create(CompareAnyKeys)); // TODO #24115: Remove Create call when delegate-based overload is available
|
||||
|
||||
|
||||
|
||||
// Sorts the k elements between minIdx and maxIdx without sorting all elements
|
||||
// Time complexity: O(n + k log k) best and average case. O(n^2) worse case.
|
||||
protected override void PartialQuickSort(int[] map, int left, int right, int minIdx, int maxIdx)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -653,7 +658,7 @@ namespace System.Linq
|
||||
|
||||
// Finds the element that would be at idx if the collection was sorted.
|
||||
// Time complexity: O(n) best and average case. O(n^2) worse case.
|
||||
private int QuickSelect(int[] map, int right, int idx)
|
||||
protected override int QuickSelect(int[] map, int right, int idx)
|
||||
{
|
||||
int left = 0;
|
||||
do
|
||||
@@ -723,51 +728,4 @@ namespace System.Linq
|
||||
return map[idx];
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class EnumerableSorter<TElement, TKey> : EnumerableSorter<TElement>
|
||||
{
|
||||
private readonly Func<TElement, TKey> _keySelector;
|
||||
private readonly IComparer<TKey> _comparer;
|
||||
private readonly bool _descending;
|
||||
private readonly EnumerableSorter<TElement> _next;
|
||||
private TKey[] _keys;
|
||||
|
||||
internal EnumerableSorter(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, EnumerableSorter<TElement> next)
|
||||
{
|
||||
_keySelector = keySelector;
|
||||
_comparer = comparer;
|
||||
_descending = descending;
|
||||
_next = next;
|
||||
}
|
||||
|
||||
internal override void ComputeKeys(TElement[] elements, int count)
|
||||
{
|
||||
_keys = new TKey[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
_keys[i] = _keySelector(elements[i]);
|
||||
}
|
||||
|
||||
_next?.ComputeKeys(elements, count);
|
||||
}
|
||||
|
||||
internal override int CompareAnyKeys(int index1, int index2)
|
||||
{
|
||||
int c = _comparer.Compare(_keys[index1], _keys[index2]);
|
||||
if (c == 0)
|
||||
{
|
||||
if (_next == null)
|
||||
{
|
||||
return index1 - index2;
|
||||
}
|
||||
|
||||
return _next.CompareAnyKeys(index1, index2);
|
||||
}
|
||||
|
||||
// -c will result in a negative value for int.MinValue (-int.MinValue == int.MinValue).
|
||||
// Flipping keys earlier is more likely to trigger something strange in a comparer,
|
||||
// particularly as it comes to the sort being stable.
|
||||
return (_descending != (c > 0)) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,26 @@ namespace System.Linq
|
||||
throw Error.ArgumentNull(nameof(second));
|
||||
}
|
||||
|
||||
if (first is ICollection<TSource> firstCol && second is ICollection<TSource> secondCol && firstCol.Count != secondCol.Count)
|
||||
if (first is ICollection<TSource> firstCol && second is ICollection<TSource> secondCol)
|
||||
{
|
||||
return false;
|
||||
if (firstCol.Count != secondCol.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (firstCol is IList<TSource> firstList && secondCol is IList<TSource> secondList)
|
||||
{
|
||||
int count = firstCol.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (!comparer.Equals(firstList[i], secondList[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
using (IEnumerator<TSource> e1 = first.GetEnumerator())
|
||||
|
||||
@@ -116,10 +116,18 @@ namespace System.Linq
|
||||
Debug.Assert(source != null);
|
||||
Debug.Assert(count > 0);
|
||||
|
||||
var queue = new Queue<TSource>();
|
||||
Queue<TSource> queue;
|
||||
|
||||
using (IEnumerator<TSource> e = source.GetEnumerator())
|
||||
{
|
||||
if (!e.MoveNext())
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
queue = new Queue<TSource>();
|
||||
queue.Enqueue(e.Current);
|
||||
|
||||
while (e.MoveNext())
|
||||
{
|
||||
if (queue.Count < count)
|
||||
|
||||
118
external/corefx/src/System.Linq/tests/ConcatTests.cs
vendored
118
external/corefx/src/System.Linq/tests/ConcatTests.cs
vendored
@@ -421,5 +421,123 @@ namespace System.Linq.Tests
|
||||
Assert.Equal(0xf00, en.Current);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GetToArrayDataSources))]
|
||||
public void CollectionInterleavedWithLazyEnumerables_ToArray(IEnumerable<int>[] arrays)
|
||||
{
|
||||
// See https://github.com/dotnet/corefx/issues/23680
|
||||
|
||||
IEnumerable<int> concats = arrays[0];
|
||||
|
||||
for (int i = 1; i < arrays.Length; i++)
|
||||
{
|
||||
concats = concats.Concat(arrays[i]);
|
||||
}
|
||||
|
||||
int[] results = concats.ToArray();
|
||||
|
||||
for (int i = 0; i < results.Length; i++)
|
||||
{
|
||||
Assert.Equal(i, results[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<object[]> GetToArrayDataSources()
|
||||
{
|
||||
// Marker at the end
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new TestEnumerable<int>(new int[] { 0 }),
|
||||
new TestEnumerable<int>(new int[] { 1 }),
|
||||
new TestEnumerable<int>(new int[] { 2 }),
|
||||
new int[] { 3 },
|
||||
}
|
||||
};
|
||||
|
||||
// Marker at beginning
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new int[] { 0 },
|
||||
new TestEnumerable<int>(new int[] { 1 }),
|
||||
new TestEnumerable<int>(new int[] { 2 }),
|
||||
new TestEnumerable<int>(new int[] { 3 }),
|
||||
}
|
||||
};
|
||||
|
||||
// Marker in middle
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new TestEnumerable<int>(new int[] { 0 }),
|
||||
new int[] { 1 },
|
||||
new TestEnumerable<int>(new int[] { 2 }),
|
||||
}
|
||||
};
|
||||
|
||||
// Non-marker in middle
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new int[] { 0 },
|
||||
new TestEnumerable<int>(new int[] { 1 }),
|
||||
new int[] { 2 },
|
||||
}
|
||||
};
|
||||
|
||||
// Big arrays (marker in middle)
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new TestEnumerable<int>(Enumerable.Range(0, 100).ToArray()),
|
||||
Enumerable.Range(100, 100).ToArray(),
|
||||
new TestEnumerable<int>(Enumerable.Range(200, 100).ToArray()),
|
||||
}
|
||||
};
|
||||
|
||||
// Big arrays (non-marker in middle)
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
Enumerable.Range(0, 100).ToArray(),
|
||||
new TestEnumerable<int>(Enumerable.Range(100, 100).ToArray()),
|
||||
Enumerable.Range(200, 100).ToArray(),
|
||||
}
|
||||
};
|
||||
|
||||
// Interleaved (first marker)
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new int[] { 0 },
|
||||
new TestEnumerable<int>(new int[] { 1 }),
|
||||
new int[] { 2 },
|
||||
new TestEnumerable<int>(new int[] { 3 }),
|
||||
new int[] { 4 },
|
||||
}
|
||||
};
|
||||
|
||||
// Interleaved (first non-marker)
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new TestEnumerable<int>(new int[] { 0 }),
|
||||
new int[] { 1 },
|
||||
new TestEnumerable<int>(new int[] { 2 }),
|
||||
new int[] { 3 },
|
||||
new TestEnumerable<int>(new int[] { 4 }),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,5 +184,50 @@ namespace System.Linq.Tests
|
||||
Func<DateTime, int> keySelector = null;
|
||||
AssertExtensions.Throws<ArgumentNullException>("keySelector", () => Enumerable.Empty<DateTime>().OrderByDescending(keySelector));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SortsLargeAscendingEnumerableCorrectly()
|
||||
{
|
||||
const int Items = 1_000_000;
|
||||
IEnumerable<int> expected = NumberRangeGuaranteedNotCollectionType(0, Items);
|
||||
|
||||
IEnumerable<int> unordered = expected.Select(i => i);
|
||||
IOrderedEnumerable<int> ordered = unordered.OrderByDescending(i => -i);
|
||||
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SortsLargeDescendingEnumerableCorrectly()
|
||||
{
|
||||
const int Items = 1_000_000;
|
||||
IEnumerable<int> expected = NumberRangeGuaranteedNotCollectionType(0, Items);
|
||||
|
||||
IEnumerable<int> unordered = expected.Select(i => Items - i - 1);
|
||||
IOrderedEnumerable<int> ordered = unordered.OrderByDescending(i => -i);
|
||||
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
[InlineData(8)]
|
||||
[InlineData(16)]
|
||||
[InlineData(1024)]
|
||||
[InlineData(4096)]
|
||||
[InlineData(1_000_000)]
|
||||
public void SortsRandomizedEnumerableCorrectly(int items)
|
||||
{
|
||||
var r = new Random(42);
|
||||
|
||||
int[] randomized = Enumerable.Range(0, items).Select(i => r.Next()).ToArray();
|
||||
int[] ordered = ForceNotCollection(randomized).OrderByDescending(i => -i).ToArray();
|
||||
|
||||
Array.Sort(randomized, (a, b) => a - b);
|
||||
Assert.Equal(randomized, ordered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,5 +377,50 @@ namespace System.Linq.Tests
|
||||
Enumerable.Range(0, 100).Select(i => i.ToString()).OrderBy(i => i.Length).ThenBy(i => i).ToArray();
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SortsLargeAscendingEnumerableCorrectly()
|
||||
{
|
||||
const int Items = 1_000_000;
|
||||
IEnumerable<int> expected = NumberRangeGuaranteedNotCollectionType(0, Items);
|
||||
|
||||
IEnumerable<int> unordered = expected.Select(i => i);
|
||||
IOrderedEnumerable<int> ordered = unordered.OrderBy(i => i);
|
||||
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SortsLargeDescendingEnumerableCorrectly()
|
||||
{
|
||||
const int Items = 1_000_000;
|
||||
IEnumerable<int> expected = NumberRangeGuaranteedNotCollectionType(0, Items);
|
||||
|
||||
IEnumerable<int> unordered = expected.Select(i => Items - i - 1);
|
||||
IOrderedEnumerable<int> ordered = unordered.OrderBy(i => i);
|
||||
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
[InlineData(8)]
|
||||
[InlineData(16)]
|
||||
[InlineData(1024)]
|
||||
[InlineData(4096)]
|
||||
[InlineData(1_000_000)]
|
||||
public void SortsRandomizedEnumerableCorrectly(int items)
|
||||
{
|
||||
var r = new Random(42);
|
||||
|
||||
int[] randomized = Enumerable.Range(0, items).Select(i => r.Next()).ToArray();
|
||||
int[] ordered = ForceNotCollection(randomized).OrderBy(i => i).ToArray();
|
||||
|
||||
Array.Sort(randomized);
|
||||
Assert.Equal(randomized, ordered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
external/corefx/src/System.Linq/tests/Performance/Configurations.props
vendored
Normal file
8
external/corefx/src/System.Linq/tests/Performance/Configurations.props
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netcoreapp;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -477,5 +477,116 @@ namespace System.Linq.Tests
|
||||
IEnumerable<int> iterator = counts.SelectMany(c => Enumerable.Range(1, c));
|
||||
Assert.Throws<OverflowException>(() => iterator.Count());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GetToArrayDataSources))]
|
||||
public void CollectionInterleavedWithLazyEnumerables_ToArray(IEnumerable<int>[] arrays)
|
||||
{
|
||||
// See https://github.com/dotnet/corefx/issues/23680
|
||||
|
||||
int[] results = arrays.SelectMany(ar => ar).ToArray();
|
||||
|
||||
for (int i = 0; i < results.Length; i++)
|
||||
{
|
||||
Assert.Equal(i, results[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<object[]> GetToArrayDataSources()
|
||||
{
|
||||
// Marker at the end
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new TestEnumerable<int>(new int[] { 0 }),
|
||||
new TestEnumerable<int>(new int[] { 1 }),
|
||||
new TestEnumerable<int>(new int[] { 2 }),
|
||||
new int[] { 3 },
|
||||
}
|
||||
};
|
||||
|
||||
// Marker at beginning
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new int[] { 0 },
|
||||
new TestEnumerable<int>(new int[] { 1 }),
|
||||
new TestEnumerable<int>(new int[] { 2 }),
|
||||
new TestEnumerable<int>(new int[] { 3 }),
|
||||
}
|
||||
};
|
||||
|
||||
// Marker in middle
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new TestEnumerable<int>(new int[] { 0 }),
|
||||
new int[] { 1 },
|
||||
new TestEnumerable<int>(new int[] { 2 }),
|
||||
}
|
||||
};
|
||||
|
||||
// Non-marker in middle
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new int[] { 0 },
|
||||
new TestEnumerable<int>(new int[] { 1 }),
|
||||
new int[] { 2 },
|
||||
}
|
||||
};
|
||||
|
||||
// Big arrays (marker in middle)
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new TestEnumerable<int>(Enumerable.Range(0, 100).ToArray()),
|
||||
Enumerable.Range(100, 100).ToArray(),
|
||||
new TestEnumerable<int>(Enumerable.Range(200, 100).ToArray()),
|
||||
}
|
||||
};
|
||||
|
||||
// Big arrays (non-marker in middle)
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
Enumerable.Range(0, 100).ToArray(),
|
||||
new TestEnumerable<int>(Enumerable.Range(100, 100).ToArray()),
|
||||
Enumerable.Range(200, 100).ToArray(),
|
||||
}
|
||||
};
|
||||
|
||||
// Interleaved (first marker)
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new int[] { 0 },
|
||||
new TestEnumerable<int>(new int[] { 1 }),
|
||||
new int[] { 2 },
|
||||
new TestEnumerable<int>(new int[] { 3 }),
|
||||
new int[] { 4 },
|
||||
}
|
||||
};
|
||||
|
||||
// Interleaved (first non-marker)
|
||||
yield return new object[]
|
||||
{
|
||||
new IEnumerable<int>[]
|
||||
{
|
||||
new TestEnumerable<int>(new int[] { 0 }),
|
||||
new int[] { 1 },
|
||||
new TestEnumerable<int>(new int[] { 2 }),
|
||||
new int[] { 3 },
|
||||
new TestEnumerable<int>(new int[] { 4 }),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,9 +77,6 @@
|
||||
<Compile Include="UnionTests.cs" />
|
||||
<Compile Include="WhereTests.cs" />
|
||||
<Compile Include="ZipTests.cs" />
|
||||
<Compile Include="$(CommonTestPath)\System\PlatformDetection.cs">
|
||||
<Link>Common\System\PlatformDetection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)\System\Linq\SkipTakeData.cs">
|
||||
<Link>Common\System\Linq\SkipTakeData.cs</Link>
|
||||
</Compile>
|
||||
|
||||
@@ -165,5 +165,71 @@ And Immortality.".Split(new[] { ' ', '\n', '\r', '—' }, StringSplitOptions.Rem
|
||||
Func<DateTime, int> keySelector = null;
|
||||
AssertExtensions.Throws<ArgumentNullException>("keySelector", () => Enumerable.Empty<DateTime>().OrderBy(e => e).ThenByDescending(keySelector, null));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
public void SortsLargeAscendingEnumerableCorrectly(int thenBys)
|
||||
{
|
||||
const int Items = 100_000;
|
||||
IEnumerable<int> expected = NumberRangeGuaranteedNotCollectionType(0, Items);
|
||||
|
||||
IEnumerable<int> unordered = expected.Select(i => i);
|
||||
IOrderedEnumerable<int> ordered = unordered.OrderBy(_ => 0);
|
||||
switch (thenBys)
|
||||
{
|
||||
case 1: ordered = ordered.ThenByDescending(i => -i); break;
|
||||
case 2: ordered = ordered.ThenByDescending(i => 0).ThenByDescending(i => -i); break;
|
||||
case 3: ordered = ordered.ThenByDescending(i => 0).ThenByDescending(i => 0).ThenByDescending(i => -i); break;
|
||||
}
|
||||
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
public void SortsLargeDescendingEnumerableCorrectly(int thenBys)
|
||||
{
|
||||
const int Items = 100_000;
|
||||
IEnumerable<int> expected = NumberRangeGuaranteedNotCollectionType(0, Items);
|
||||
|
||||
IEnumerable<int> unordered = expected.Select(i => Items - i - 1);
|
||||
IOrderedEnumerable<int> ordered = unordered.OrderBy(_ => 0);
|
||||
switch (thenBys)
|
||||
{
|
||||
case 1: ordered = ordered.ThenByDescending(i => -i); break;
|
||||
case 2: ordered = ordered.ThenByDescending(i => 0).ThenByDescending(i => -i); break;
|
||||
case 3: ordered = ordered.ThenByDescending(i => 0).ThenByDescending(i => 0).ThenByDescending(i => -i); break;
|
||||
}
|
||||
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
public void SortsLargeRandomizedEnumerableCorrectly(int thenBys)
|
||||
{
|
||||
const int Items = 100_000;
|
||||
var r = new Random(42);
|
||||
|
||||
int[] randomized = Enumerable.Range(0, Items).Select(i => r.Next()).ToArray();
|
||||
|
||||
IOrderedEnumerable<int> orderedEnumerable = randomized.OrderBy(_ => 0);
|
||||
switch (thenBys)
|
||||
{
|
||||
case 1: orderedEnumerable = orderedEnumerable.ThenByDescending(i => -i); break;
|
||||
case 2: orderedEnumerable = orderedEnumerable.ThenByDescending(i => 0).ThenByDescending(i => -i); break;
|
||||
case 3: orderedEnumerable = orderedEnumerable.ThenByDescending(i => 0).ThenByDescending(i => 0).ThenByDescending(i => -i); break;
|
||||
}
|
||||
int[] ordered = orderedEnumerable.ToArray();
|
||||
|
||||
Array.Sort(randomized, (a, b) => a - b);
|
||||
Assert.Equal(randomized, orderedEnumerable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using Xunit;
|
||||
|
||||
namespace System.Linq.Tests
|
||||
{
|
||||
public class ThenByTests
|
||||
public class ThenByTests : EnumerableTests
|
||||
{
|
||||
[Fact]
|
||||
public void SameResultsRepeatCallsIntQuery()
|
||||
@@ -170,5 +170,71 @@ And Immortality.".Split(new[] { ' ', '\n', '\r', '—' }, StringSplitOptions.Rem
|
||||
Func<DateTime, int> keySelector = null;
|
||||
AssertExtensions.Throws<ArgumentNullException>("keySelector", () => Enumerable.Empty<DateTime>().OrderBy(e => e).ThenBy(keySelector, null));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
public void SortsLargeAscendingEnumerableCorrectly(int thenBys)
|
||||
{
|
||||
const int Items = 100_000;
|
||||
IEnumerable<int> expected = NumberRangeGuaranteedNotCollectionType(0, Items);
|
||||
|
||||
IEnumerable<int> unordered = expected.Select(i => i);
|
||||
IOrderedEnumerable<int> ordered = unordered.OrderBy(_ => 0);
|
||||
switch (thenBys)
|
||||
{
|
||||
case 1: ordered = ordered.ThenBy(i => i); break;
|
||||
case 2: ordered = ordered.ThenBy(i => 0).ThenBy(i => i); break;
|
||||
case 3: ordered = ordered.ThenBy(i => 0).ThenBy(i => 0).ThenBy(i => i); break;
|
||||
}
|
||||
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
public void SortsLargeDescendingEnumerableCorrectly(int thenBys)
|
||||
{
|
||||
const int Items = 100_000;
|
||||
IEnumerable<int> expected = NumberRangeGuaranteedNotCollectionType(0, Items);
|
||||
|
||||
IEnumerable<int> unordered = expected.Select(i => Items - i - 1);
|
||||
IOrderedEnumerable<int> ordered = unordered.OrderBy(_ => 0);
|
||||
switch (thenBys)
|
||||
{
|
||||
case 1: ordered = ordered.ThenBy(i => i); break;
|
||||
case 2: ordered = ordered.ThenBy(i => 0).ThenBy(i => i); break;
|
||||
case 3: ordered = ordered.ThenBy(i => 0).ThenBy(i => 0).ThenBy(i => i); break;
|
||||
}
|
||||
|
||||
Assert.Equal(expected, ordered);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
public void SortsLargeRandomizedEnumerableCorrectly(int thenBys)
|
||||
{
|
||||
const int Items = 100_000;
|
||||
var r = new Random(42);
|
||||
|
||||
int[] randomized = Enumerable.Range(0, Items).Select(i => r.Next()).ToArray();
|
||||
|
||||
IOrderedEnumerable<int> orderedEnumerable = randomized.OrderBy(_ => 0);
|
||||
switch (thenBys)
|
||||
{
|
||||
case 1: orderedEnumerable = orderedEnumerable.ThenBy(i => i); break;
|
||||
case 2: orderedEnumerable = orderedEnumerable.ThenBy(i => 0).ThenBy(i => i); break;
|
||||
case 3: orderedEnumerable = orderedEnumerable.ThenBy(i => 0).ThenBy(i => 0).ThenBy(i => i); break;
|
||||
}
|
||||
int[] ordered = orderedEnumerable.ToArray();
|
||||
|
||||
Array.Sort(randomized, (a, b) => a - b);
|
||||
Assert.Equal(randomized, orderedEnumerable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user