Skip to content

Commit c4a4a59

Browse files
authored
Merge pull request Cysharp#150 from filzrev/chore-update-systemlinq-compatibility-tests
chore: Update System.Linq.Tests tests to .NET 10 preview.2 based code
2 parents 1b87d0a + 923af5c commit c4a4a59

File tree

127 files changed

+6347
-7413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+6347
-7413
lines changed

tests/System.Linq.Tests/Stubs/System.Linq/EnumerableTests.cs

+77-17
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ protected static IEnumerable<T> FlipIsCollection<T>(IEnumerable<T> source)
247247
{
248248
return source is ICollection<T> ? ForceNotCollection(source) : new List<T>(source);
249249
}
250+
250251
protected static T[] Repeat<T>(Func<int, T> factory, int count)
251252
{
252253
T[] results = new T[count];
@@ -320,27 +321,86 @@ protected static IEnumerable<IEnumerable<T>> CreateSources<T>(IEnumerable<T> sou
320321
}
321322
}
322323

323-
// TODO: latest `dotnet/runtime` version supports more test patterns.
324-
protected static List<Func<IEnumerable<T>, IEnumerable<T>>> IdentityTransforms<T>()
324+
protected static IEnumerable<Func<IEnumerable<T>, IEnumerable<T>>> IdentityTransforms<T>()
325325
{
326-
// All of these transforms should take an enumerable and produce
327-
// another enumerable with the same contents.
328-
return new List<Func<IEnumerable<T>, IEnumerable<T>>>
326+
// Various collection types all representing the same source.
327+
List<Func<IEnumerable<T>, IEnumerable<T>>> sources =
328+
[
329+
e => e, // original
330+
e => e.ToArray(), // T[]
331+
e => e.ToList(), // List<T>
332+
e => new ReadOnlyCollection<T>(e.ToArray()), // IList<T> that's not List<T>/T[]
333+
e => new TestCollection<T>(e.ToArray()), // ICollection<T> that's not IList<T>
334+
e => new TestReadOnlyCollection<T>(e.ToArray()), // IReadOnlyCollection<T> that's not ICollection<T>
335+
e => ForceNotCollection(e), // IEnumerable<T> with no other interfaces
336+
];
337+
if (typeof(T) == typeof(char))
329338
{
330-
e => e,
331-
e => e.ToArray(),
332-
e => e.ToList(),
333-
e => e.ToList().Take(int.MaxValue),
339+
sources.Add(e => (IEnumerable<T>)(object)string.Concat((IEnumerable<char>)(object)e)); // string
340+
}
341+
342+
// Various transforms that all yield the same elements as the source.
343+
List<Func<IEnumerable<T>, IEnumerable<T>>> transforms =
344+
[
345+
// Concat
346+
e => e.Concat(ForceNotCollection<T>([])),
347+
e => ForceNotCollection<T>([]).Concat(e),
348+
349+
// Following transforms cause test failure on System.Linq tests with .NET 9
350+
#if NET10_0_OR_GREATER
351+
// Append
352+
e =>
353+
{
354+
T[] values = e.ToArray();
355+
return values.Length == 0 ? [] : values[0..^1].Append(values[^1]);
356+
},
357+
358+
// Prepend
359+
e =>
360+
{
361+
T[] values = e.ToArray();
362+
return values.Length == 0 ? [] : values[1..].Prepend(values[0]);
363+
},
364+
365+
// Reverse
366+
e => e.Reverse().Reverse(),
367+
#endif
368+
369+
// Select
334370
e => e.Select(i => i),
335-
e => e.Select(i => i).Take(int.MaxValue),
336-
e => e.Select(i => i).Where(i => true),
371+
372+
// SelectMany
373+
e => e.SelectMany<T, T>(i => [i]),
374+
375+
// Take
376+
e => e.Take(int.MaxValue),
377+
e => e.TakeLast(int.MaxValue),
378+
e => e.TakeWhile(i => true),
379+
380+
// Skip
381+
e => e.SkipWhile(i => false),
382+
383+
// Where
337384
e => e.Where(i => true),
338-
e => e.Concat(Array.Empty<T>()),
339-
e => e.Concat(ForceNotCollection(Array.Empty<T>())),
340-
e => ForceNotCollection(e),
341-
e => ForceNotCollection(e).Skip(0),
342-
e => new ReadOnlyCollection<T>(e.ToArray()),
343-
};
385+
];
386+
387+
foreach (Func<IEnumerable<T>, IEnumerable<T>> source in sources)
388+
{
389+
// Yield the source itself.
390+
yield return source;
391+
392+
foreach (Func<IEnumerable<T>, IEnumerable<T>> transform in transforms)
393+
{
394+
// Yield a single transform on the source
395+
yield return e => transform(source(e));
396+
397+
foreach (Func<IEnumerable<T>, IEnumerable<T>> transform2 in transforms)
398+
{
399+
// Yield a second transform on the first transform on the source.
400+
yield return e => transform2(transform(source(e)));
401+
}
402+
}
403+
}
344404
}
345405

346406
protected sealed class DelegateIterator<TSource> : IEnumerable<TSource>, IEnumerator<TSource>

tests/System.Linq.Tests/Stubs/TestData/MinMaxTestData.cs

+5-53
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,39 @@
33

44
using System.Linq.Tests;
55

6-
// Original code: https://github.com/dotnet/runtime/blob/v9.0.3/src/libraries/Common/tests/System/Linq/SkipTakeData.cs
6+
// Original code:
7+
// https://github.com/dotnet/runtime/blob/v10.0.0-preview.2.25163.2/src/libraries/System.Linq/tests/MinTests.cs
8+
// https://github.com/dotnet/runtime/blob/v10.0.0-preview.2.25163.2/src/libraries/System.Linq/tests/MaxTests.cs
79

810
namespace System.Linq;
911

12+
// This class is used to share test data between System.Linq/ZLinq tests.
13+
// Note: It need to use `Shuffler.Shuffle` to show indivisual test cases on Test Explorer.
1014
public class MinMaxTestData
1115
{
1216
public static IEnumerable<object[]> Min_AllTypes_TestData()
1317
{
1418
for (int length = 2; length < 65; length++)
1519
{
1620
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (byte)i)), (byte)length };
17-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (byte)i).ToArray()), (byte)length };
1821

1922
// Unit Tests does +T.One so we should generate data up to one value below sbyte.MaxValue, otherwise the type overflows
2023
if ((length + length) < sbyte.MaxValue)
2124
{
2225
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (sbyte)i)), (sbyte)length };
23-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (sbyte)i).ToArray()), (sbyte)length };
2426
}
2527

2628
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (ushort)i)), (ushort)length };
27-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (ushort)i).ToArray()), (ushort)length };
28-
2929
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (short)i)), (short)length };
30-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (short)i).ToArray()), (short)length };
31-
3230
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (uint)i)), (uint)length };
33-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (uint)i).ToArray()), (uint)length };
34-
3531
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (int)i)), (int)length };
36-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (int)i).ToArray()), (int)length };
37-
3832
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (ulong)i)), (ulong)length };
39-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (ulong)i).ToArray()), (ulong)length };
40-
4133
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (long)i)), (long)length };
42-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (long)i).ToArray()), (long)length };
43-
4434
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (float)i)), (float)length };
45-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (float)i).ToArray()), (float)length };
46-
4735
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (double)i)), (double)length };
48-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (double)i).ToArray()), (double)length };
49-
5036
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (decimal)i)), (decimal)length };
51-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (decimal)i).ToArray()), (decimal)length };
52-
5337
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (nuint)i)), (nuint)length };
54-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (nuint)i).ToArray()), (nuint)length };
55-
5638
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (nint)i)), (nint)length };
57-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (nint)i).ToArray()), (nint)length };
5839
}
5940
}
6041

@@ -63,56 +44,27 @@ public static IEnumerable<object[]> Max_AllTypes_TestData()
6344
for (int length = 2; length < 65; length++)
6445
{
6546
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (byte)i)), (byte)(length + length - 1) };
66-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (byte)i).ToArray()), (byte)(length + length - 1) };
6747

6848
// Unit Tests does +T.One so we should generate data up to one value below sbyte.MaxValue
6949
if ((length + length) < sbyte.MaxValue)
7050
{
7151
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (sbyte)i)), (sbyte)(length + length - 1) };
72-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (sbyte)i).ToArray()), (sbyte)(length + length - 1) };
7352
}
7453

7554
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (ushort)i)), (ushort)(length + length - 1) };
76-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (ushort)i).ToArray()), (ushort)(length + length - 1) };
77-
7855
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (short)i)), (short)(length + length - 1) };
79-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (short)i).ToArray()), (short)(length + length - 1) };
80-
8156
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (char)i)), (char)(length + length - 1) };
82-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (char)i).ToArray()), (char)(length + length - 1) };
83-
8457
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (uint)i)), (uint)(length + length - 1) };
85-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (uint)i).ToArray()), (uint)(length + length - 1) };
86-
8758
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (int)i)), (int)(length + length - 1) };
88-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (int)i).ToArray()), (int)(length + length - 1) };
89-
9059
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (ulong)i)), (ulong)(length + length - 1) };
91-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (ulong)i).ToArray()), (ulong)(length + length - 1) };
92-
9360
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (long)i)), (long)(length + length - 1) };
94-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (long)i).ToArray()), (long)(length + length - 1) };
95-
9661
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (float)i)), (float)(length + length - 1) };
97-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (float)i).ToArray()), (float)(length + length - 1) };
98-
9962
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (double)i)), (double)(length + length - 1) };
100-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (double)i).ToArray()), (double)(length + length - 1) };
101-
10263
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (decimal)i)), (decimal)(length + length - 1) };
103-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (decimal)i).ToArray()), (decimal)(length + length - 1) };
104-
10564
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (nuint)i)), (nuint)(length + length - 1) };
106-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (nuint)i).ToArray()), (nuint)(length + length - 1) };
107-
10865
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (nint)i)), (nint)(length + length - 1) };
109-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (nint)i).ToArray()), (nint)(length + length - 1) };
110-
11166
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (Int128)i)), (Int128)(length + length - 1) };
112-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (Int128)i).ToArray()), (Int128)(length + length - 1) };
113-
11467
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (UInt128)i)), (UInt128)(length + length - 1) };
115-
yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (UInt128)i).ToArray()), (UInt128)(length + length - 1) };
11668
}
11769
}
11870
}

tests/System.Linq.Tests/Stubs/TestData/SkipTakeData.cs

+11-18
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,27 @@
33

44
// Original code: https://github.com/dotnet/runtime/blob/v9.0.3/src/libraries/Common/tests/System/Linq/SkipTakeData.cs
55

6-
namespace System.Linq;
6+
namespace System.Linq.Tests;
77

88
public class SkipTakeData
99
{
10-
public static IEnumerable<object[]> EnumerableData()
10+
public static TheoryData<int[], int> EnumerableData()
1111
{
12-
IEnumerable<int> sourceCounts = new[] { 0, 1, 2, 3, 5, 8, 13, 55, 100, 250 };
12+
IEnumerable<int> sourceCounts = [0, 1, 2, 3, 5, 8, 13, 55, 100, 250];
1313

14-
IEnumerable<int> counts = new[] { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 100, 250, 500, int.MaxValue };
14+
IEnumerable<int> counts = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 100, 250, 500, int.MaxValue];
1515
counts = counts.Concat(counts.Select(c => -c)).Append(0).Append(int.MinValue);
1616

17-
return from sourceCount in sourceCounts
18-
let source = Enumerable.Range(0, sourceCount)
19-
from count in counts
20-
select new object[] { source, count };
21-
}
17+
var items = from sourceCount in sourceCounts
18+
let source = Enumerable.Range(0, sourceCount)
19+
from count in counts
20+
select new { source, count };
2221

23-
public static IEnumerable<object[]> EvaluationBehaviorData()
24-
{
25-
return Enumerable.Range(-1, 15).Select(count => new object[] { count });
22+
return new(items.Select(x => (x.source.ToArray(), x.count)));
2623
}
2724

28-
public static IEnumerable<object[]> QueryableData()
25+
public static TheoryData<int> EvaluationBehaviorData()
2926
{
30-
return EnumerableData().Select(array =>
31-
{
32-
var enumerable = (IEnumerable<int>)array[0];
33-
return new[] { enumerable.AsQueryable(), array[1] };
34-
});
27+
return new(Enumerable.Range(-1, 15).Select(count => count).ToArray());
3528
}
3629
}

tests/System.Linq.Tests/Stubs/TestUtilities/PlatformDetection.cs

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ private static bool ComputeIsLinqSizeOptimized()
4343
#endif
4444
}
4545
#else
46+
public static bool IsLinqSpeedOptimized => IsSpeedOptimized;
47+
4648
public static bool IsSpeedOptimized => !IsSizeOptimized;
4749
public static bool IsSizeOptimized => IsBrowser || IsWasi || IsAndroid || IsAppleMobile;
4850
#endif

tests/System.Linq.Tests/Stubs/xUnit/ConditionalUtils.cs

-3
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,8 @@ public static bool IsEnable(Type type, string key)
2323
case "IsDebuggerTypeProxyAttributeSupported" when PlatformDetection.IsDebuggerTypeProxyAttributeSupported:
2424
case "IsNotBuiltWithAggressiveTrimming" when PlatformDetection.IsNotBuiltWithAggressiveTrimming:
2525

26-
#if NET10_0_OR_GREATER
2726
case "IsLinqSpeedOptimized" when PlatformDetection.IsLinqSpeedOptimized:
28-
#else
2927
case "IsSpeedOptimized" when PlatformDetection.IsSpeedOptimized:
30-
#endif
3128
return true;
3229
default:
3330
return false;

0 commit comments

Comments
 (0)