1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Collections.Generic;
6 using Xunit;
7 
8 namespace System.Linq.Parallel.Tests
9 {
10     public static partial class ParallelQueryCombinationTests
11     {
12         [Theory]
13         [MemberData(nameof(UnaryOperations))]
14         [MemberData(nameof(BinaryOperations))]
Aggregate(Labeled<Operation> operation)15         public static void Aggregate(Labeled<Operation> operation)
16         {
17             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize),
18                 operation.Item(DefaultStart, DefaultSize, DefaultSource).Aggregate((x, y) => x + y));
19         }
20 
21         [Theory]
22         [MemberData(nameof(UnaryOperations))]
23         [MemberData(nameof(BinaryOperations))]
Aggregate_Seed(Labeled<Operation> operation)24         public static void Aggregate_Seed(Labeled<Operation> operation)
25         {
26             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize),
27                 operation.Item(DefaultStart, DefaultSize, DefaultSource).Aggregate(0, (x, y) => x + y));
28         }
29 
30         [Theory]
31         [MemberData(nameof(UnaryOperations))]
32         [MemberData(nameof(BinaryOperations))]
Aggregate_Result(Labeled<Operation> operation)33         public static void Aggregate_Result(Labeled<Operation> operation)
34         {
35             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize),
36                 operation.Item(DefaultStart, DefaultSize, DefaultSource).Aggregate(0, (x, y) => x + y, r => r));
37         }
38 
39         [Theory]
40         [MemberData(nameof(UnaryOperations))]
41         [MemberData(nameof(BinaryOperations))]
Aggregate_Accumulator(Labeled<Operation> operation)42         public static void Aggregate_Accumulator(Labeled<Operation> operation)
43         {
44             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize),
45                 operation.Item(DefaultStart, DefaultSize, DefaultSource).Aggregate(0, (a, x) => a + x, (l, r) => l + r, r => r));
46         }
47 
48         [Theory]
49         [MemberData(nameof(UnaryOperations))]
50         [MemberData(nameof(BinaryOperations))]
Aggregate_SeedFactory(Labeled<Operation> operation)51         public static void Aggregate_SeedFactory(Labeled<Operation> operation)
52         {
53             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize),
54                 operation.Item(DefaultStart, DefaultSize, DefaultSource).Aggregate(() => 0, (a, x) => a + x, (l, r) => l + r, r => r));
55         }
56 
57         [Theory]
58         [MemberData(nameof(UnaryOperations))]
59         [MemberData(nameof(BinaryOperations))]
All_False(Labeled<Operation> operation)60         public static void All_False(Labeled<Operation> operation)
61         {
62             Assert.False(operation.Item(DefaultStart, DefaultSize, DefaultSource).All(x => false));
63         }
64 
65         [Theory]
66         [MemberData(nameof(UnaryOperations))]
67         [MemberData(nameof(BinaryOperations))]
All_True(Labeled<Operation> operation)68         public static void All_True(Labeled<Operation> operation)
69         {
70             IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize);
71             Assert.True(operation.Item(DefaultStart, DefaultSize, DefaultSource).All(x => seen.Add(x)));
72             seen.AssertComplete();
73         }
74 
75         [Theory]
76         [MemberData(nameof(UnaryOperations))]
77         [MemberData(nameof(BinaryOperations))]
Any_False(Labeled<Operation> operation)78         public static void Any_False(Labeled<Operation> operation)
79         {
80             IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize);
81             Assert.False(operation.Item(DefaultStart, DefaultSize, DefaultSource).Any(x => !seen.Add(x)));
82             seen.AssertComplete();
83         }
84 
85         [Theory]
86         [MemberData(nameof(UnaryOperations))]
87         [MemberData(nameof(BinaryOperations))]
Any_True(Labeled<Operation> operation)88         public static void Any_True(Labeled<Operation> operation)
89         {
90             Assert.True(operation.Item(DefaultStart, DefaultSize, DefaultSource).Any(x => true));
91         }
92 
93         [Theory]
94         [MemberData(nameof(UnaryOperations))]
95         [MemberData(nameof(BinaryOperations))]
Average(Labeled<Operation> operation)96         public static void Average(Labeled<Operation> operation)
97         {
98             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize) / (double)DefaultSize,
99                 operation.Item(DefaultStart, DefaultSize, DefaultSource).Average());
100         }
101 
102         [Theory]
103         [MemberData(nameof(UnaryOperations))]
104         [MemberData(nameof(BinaryOperations))]
Average_Nullable(Labeled<Operation> operation)105         public static void Average_Nullable(Labeled<Operation> operation)
106         {
107             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize) / (double?)DefaultSize,
108                 operation.Item(DefaultStart, DefaultSize, DefaultSource).Average(x => (int?)x));
109         }
110 
111         [Theory]
112         [MemberData(nameof(UnaryOperators))]
113         [MemberData(nameof(BinaryOperators))]
Cast(Labeled<Operation> source, Labeled<Operation> operation)114         public static void Cast(Labeled<Operation> source, Labeled<Operation> operation)
115         {
116             int seen = DefaultStart;
117             foreach (int? i in operation.Item(DefaultStart, DefaultSize, source.Item).Cast<int?>())
118             {
119                 Assert.True(i.HasValue);
120                 Assert.Equal(seen++, i.Value);
121             }
122             Assert.Equal(DefaultStart + DefaultSize, seen);
123         }
124 
125         [Theory]
126         [MemberData(nameof(UnaryOperators))]
127         [MemberData(nameof(BinaryOperators))]
Cast_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)128         public static void Cast_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
129         {
130             int seen = DefaultStart;
131             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).Cast<int?>().ToList(), x => Assert.Equal(seen++, x));
132             Assert.Equal(DefaultStart + DefaultSize, seen);
133         }
134 
135         [Theory]
136         [MemberData(nameof(UnaryOperators))]
137         [MemberData(nameof(BinaryOperators))]
Concat(Labeled<Operation> source, Labeled<Operation> operation)138         public static void Concat(Labeled<Operation> source, Labeled<Operation> operation)
139         {
140             Action<Operation, Operation> concat = (left, right) =>
141             {
142                 int seen = DefaultStart;
143                 foreach (int i in left(DefaultStart, DefaultSize / 2, source.Item)
144                     .Concat(right(DefaultStart + DefaultSize / 2, DefaultSize / 2, source.Item)))
145                 {
146                     Assert.Equal(seen++, i);
147                 }
148                 Assert.Equal(DefaultStart + DefaultSize, seen);
149             };
150             concat(operation.Item, LabeledDefaultSource.AsOrdered().Item);
151             concat(LabeledDefaultSource.AsOrdered().Item, operation.Item);
152         }
153 
154         [Theory]
155         [MemberData(nameof(UnaryOperators))]
156         [MemberData(nameof(BinaryOperators))]
Concat_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)157         public static void Concat_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
158         {
159             Action<Operation, Operation> concat = (left, right) =>
160             {
161                 int seen = DefaultStart;
162                 Assert.All(
163                     left(DefaultStart, DefaultSize / 2, source.Item)
164                         .Concat(right(DefaultStart + DefaultSize / 2, DefaultSize / 2, source.Item)).ToList(),
165                     x => Assert.Equal(seen++, x)
166                     );
167                 Assert.Equal(DefaultStart + DefaultSize, seen);
168             };
169             concat(operation.Item, LabeledDefaultSource.AsOrdered().Item);
170             concat(LabeledDefaultSource.AsOrdered().Item, operation.Item);
171         }
172 
173         [Theory]
174         [MemberData(nameof(UnaryOperations))]
175         [MemberData(nameof(BinaryOperations))]
Contains_True(Labeled<Operation> operation)176         public static void Contains_True(Labeled<Operation> operation)
177         {
178             Assert.True(operation.Item(DefaultStart, DefaultSize, DefaultSource).Contains(DefaultStart + DefaultSize / 2));
179         }
180 
181         [Theory]
182         [MemberData(nameof(UnaryOperations))]
183         [MemberData(nameof(BinaryOperations))]
Contains_False(Labeled<Operation> operation)184         public static void Contains_False(Labeled<Operation> operation)
185         {
186             Assert.False(operation.Item(DefaultStart, DefaultSize, DefaultSource).Contains(DefaultStart + DefaultSize));
187         }
188 
189         [Theory]
190         [MemberData(nameof(UnaryOperations))]
191         [MemberData(nameof(BinaryOperations))]
Count_Elements(Labeled<Operation> operation)192         public static void Count_Elements(Labeled<Operation> operation)
193         {
194             Assert.Equal(DefaultSize, operation.Item(DefaultStart, DefaultSize, DefaultSource).Count());
195         }
196 
197         [Theory]
198         [MemberData(nameof(UnaryOperations))]
199         [MemberData(nameof(BinaryOperations))]
Count_Predicate_Some(Labeled<Operation> operation)200         public static void Count_Predicate_Some(Labeled<Operation> operation)
201         {
202             Assert.Equal(DefaultSize / 2, operation.Item(DefaultStart, DefaultSize, DefaultSource).Count(x => x < DefaultStart + DefaultSize / 2));
203         }
204 
205         [Theory]
206         [MemberData(nameof(UnaryOperations))]
207         [MemberData(nameof(BinaryOperations))]
Count_Predicate_None(Labeled<Operation> operation)208         public static void Count_Predicate_None(Labeled<Operation> operation)
209         {
210             Assert.Equal(0, operation.Item(DefaultStart, DefaultSize, DefaultSource).Count(x => x < DefaultStart));
211         }
212 
213         [Theory]
214         [MemberData(nameof(UnaryOperators))]
215         [MemberData(nameof(BinaryOperators))]
DefaultIfEmpty(Labeled<Operation> source, Labeled<Operation> operation)216         public static void DefaultIfEmpty(Labeled<Operation> source, Labeled<Operation> operation)
217         {
218             int seen = DefaultStart;
219             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).DefaultIfEmpty())
220             {
221                 Assert.Equal(seen++, i);
222             }
223             Assert.Equal(DefaultStart + DefaultSize, seen);
224         }
225 
226         [Theory]
227         [MemberData(nameof(UnaryOperators))]
228         [MemberData(nameof(BinaryOperators))]
DefaultIfEmpty_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)229         public static void DefaultIfEmpty_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
230         {
231             int seen = DefaultStart;
232             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).DefaultIfEmpty().ToList(), x => Assert.Equal(seen++, x));
233             Assert.Equal(DefaultStart + DefaultSize, seen);
234         }
235 
236         [Theory]
237         [MemberData(nameof(UnaryOperators))]
238         [MemberData(nameof(BinaryOperators))]
Distinct(Labeled<Operation> source, Labeled<Operation> operation)239         public static void Distinct(Labeled<Operation> source, Labeled<Operation> operation)
240         {
241             int seen = DefaultStart;
242             ParallelQuery<int> query = operation.Item(DefaultStart * 2, DefaultSize * 2, source.Item).Select(x => x / 2).Distinct();
243             foreach (int i in query)
244             {
245                 Assert.Equal(seen++, i);
246             }
247             Assert.Equal(DefaultStart + DefaultSize, seen);
248         }
249 
250         [Theory]
251         [MemberData(nameof(UnaryOperators))]
252         [MemberData(nameof(BinaryOperators))]
Distinct_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)253         public static void Distinct_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
254         {
255             int seen = DefaultStart;
256             ParallelQuery<int> query = operation.Item(DefaultStart * 2, DefaultSize * 2, source.Item).Select(x => x / 2).Distinct();
257             Assert.All(query.ToList(), x => Assert.Equal(seen++, x));
258             Assert.Equal(DefaultStart + DefaultSize, seen);
259         }
260 
261         [Theory]
262         [MemberData(nameof(UnaryOperators))]
263         [MemberData(nameof(BinaryOperators))]
ElementAt(Labeled<Operation> source, Labeled<Operation> operation)264         public static void ElementAt(Labeled<Operation> source, Labeled<Operation> operation)
265         {
266             ParallelQuery<int> query = operation.Item(DefaultStart, DefaultSize, source.Item);
267 
268             int seen = DefaultStart;
269             for (int i = 0; i < DefaultSize; i++)
270             {
271                 Assert.Equal(seen++, query.ElementAt(i));
272             }
273             Assert.Equal(DefaultStart + DefaultSize, seen);
274         }
275 
276         [Theory]
277         [MemberData(nameof(UnaryOperators))]
278         [MemberData(nameof(BinaryOperators))]
ElementAtOrDefault(Labeled<Operation> source, Labeled<Operation> operation)279         public static void ElementAtOrDefault(Labeled<Operation> source, Labeled<Operation> operation)
280         {
281             ParallelQuery<int> query = operation.Item(DefaultStart, DefaultSize, source.Item);
282 
283             int seen = DefaultStart;
284             for (int i = 0; i < DefaultSize; i++)
285             {
286                 Assert.Equal(seen++, query.ElementAtOrDefault(i));
287             }
288             Assert.Equal(DefaultStart + DefaultSize, seen);
289             Assert.Equal(default(int), query.ElementAtOrDefault(-1));
290         }
291 
292         [Theory]
293         [MemberData(nameof(UnaryOperators))]
294         [MemberData(nameof(BinaryOperators))]
Except(Labeled<Operation> source, Labeled<Operation> operation)295         public static void Except(Labeled<Operation> source, Labeled<Operation> operation)
296         {
297             Action<Operation, Operation> except = (left, right) =>
298             {
299                 int seen = DefaultStart;
300                 ParallelQuery<int> query = left(DefaultStart, DefaultSize + DefaultSize / 2, source.Item)
301                     .Except(right(DefaultStart + DefaultSize, DefaultSize, source.Item));
302                 foreach (int i in query)
303                 {
304                     Assert.Equal(seen++, i);
305                 }
306                 Assert.Equal(DefaultStart + DefaultSize, seen);
307             };
308             except(operation.Item, DefaultSource);
309             except(LabeledDefaultSource.AsOrdered().Item, operation.Item);
310         }
311 
312         [Theory]
313         [MemberData(nameof(UnaryOperators))]
314         [MemberData(nameof(BinaryOperators))]
Except_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)315         public static void Except_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
316         {
317             Action<Operation, Operation> except = (left, right) =>
318             {
319                 int seen = DefaultStart;
320                 ParallelQuery<int> query = left(DefaultStart, DefaultSize + DefaultSize / 2, source.Item)
321                     .Except(right(DefaultStart + DefaultSize, DefaultSize, source.Item));
322                 Assert.All(query.ToList(), x => Assert.Equal(seen++, x));
323                 Assert.Equal(DefaultStart + DefaultSize, seen);
324             };
325             except(operation.Item, DefaultSource);
326             except(LabeledDefaultSource.AsOrdered().Item, operation.Item);
327         }
328 
329         [Theory]
330         [MemberData(nameof(UnaryOperators))]
331         [MemberData(nameof(BinaryOperators))]
First(Labeled<Operation> source, Labeled<Operation> operation)332         public static void First(Labeled<Operation> source, Labeled<Operation> operation)
333         {
334             Assert.Equal(DefaultStart, operation.Item(DefaultStart, DefaultSize, source.Item).First());
335         }
336 
337         [Theory]
338         [MemberData(nameof(UnaryOperators))]
339         [MemberData(nameof(BinaryOperators))]
First_Predicate(Labeled<Operation> source, Labeled<Operation> operation)340         public static void First_Predicate(Labeled<Operation> source, Labeled<Operation> operation)
341         {
342             Assert.Equal(DefaultStart + DefaultSize / 2, operation.Item(DefaultStart, DefaultSize, source.Item).First(x => x >= DefaultStart + DefaultSize / 2));
343         }
344 
345         [Theory]
346         [MemberData(nameof(UnaryOperators))]
347         [MemberData(nameof(BinaryOperators))]
FirstOrDefault(Labeled<Operation> source, Labeled<Operation> operation)348         public static void FirstOrDefault(Labeled<Operation> source, Labeled<Operation> operation)
349         {
350             Assert.Equal(DefaultStart, operation.Item(DefaultStart, DefaultSize, source.Item).FirstOrDefault());
351         }
352 
353         [Theory]
354         [MemberData(nameof(UnaryOperators))]
355         [MemberData(nameof(BinaryOperators))]
FirstOrDefault_Predicate(Labeled<Operation> source, Labeled<Operation> operation)356         public static void FirstOrDefault_Predicate(Labeled<Operation> source, Labeled<Operation> operation)
357         {
358             Assert.Equal(DefaultStart + DefaultSize / 2, operation.Item(DefaultStart, DefaultSize, source.Item).FirstOrDefault(x => x >= DefaultStart + DefaultSize / 2));
359         }
360 
361         [Theory]
362         [MemberData(nameof(UnaryOperators))]
363         [MemberData(nameof(BinaryOperators))]
FirstOrDefault_Predicate_None(Labeled<Operation> source, Labeled<Operation> operation)364         public static void FirstOrDefault_Predicate_None(Labeled<Operation> source, Labeled<Operation> operation)
365         {
366             Assert.Equal(default(int), operation.Item(DefaultStart, DefaultSize, source.Item).FirstOrDefault(x => false));
367         }
368 
369         [Theory]
370         [MemberData(nameof(UnaryOperators))]
371         [MemberData(nameof(BinaryOperators))]
ForAll(Labeled<Operation> source, Labeled<Operation> operation)372         public static void ForAll(Labeled<Operation> source, Labeled<Operation> operation)
373         {
374             IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize);
375             operation.Item(DefaultStart, DefaultSize, source.Item).ForAll(x => seen.Add(x));
376             seen.AssertComplete();
377         }
378 
379         [Theory]
380         [MemberData(nameof(UnaryOperators))]
381         [MemberData(nameof(BinaryOperators))]
GetEnumerator(Labeled<Operation> source, Labeled<Operation> operation)382         public static void GetEnumerator(Labeled<Operation> source, Labeled<Operation> operation)
383         {
384             int seen = DefaultStart;
385             IEnumerator<int> enumerator = operation.Item(DefaultStart, DefaultSize, source.Item).GetEnumerator();
386 
387             while (enumerator.MoveNext())
388             {
389                 int current = enumerator.Current;
390                 Assert.Equal(seen++, current);
391                 Assert.Equal(current, enumerator.Current);
392             }
393             Assert.Equal(DefaultStart + DefaultSize, seen);
394 
395             Assert.Throws<NotSupportedException>(() => enumerator.Reset());
396         }
397 
398         [Theory]
399         [MemberData(nameof(UnaryOperators))]
400         [MemberData(nameof(BinaryOperators))]
GroupBy(Labeled<Operation> source, Labeled<Operation> operation)401         public static void GroupBy(Labeled<Operation> source, Labeled<Operation> operation)
402         {
403             int seenKey = DefaultStart / GroupFactor;
404             foreach (IGrouping<int, int> group in operation.Item(DefaultStart, DefaultSize, source.Item).GroupBy(x => x / GroupFactor))
405             {
406                 Assert.Equal(seenKey++, group.Key);
407                 int seenElement = group.Key * GroupFactor;
408                 Assert.All(group, x => Assert.Equal(seenElement++, x));
409                 Assert.Equal(Math.Min((group.Key + 1) * GroupFactor, DefaultStart + DefaultSize), seenElement);
410             }
411             Assert.Equal((DefaultSize + (GroupFactor - 1)) / GroupFactor + 1, seenKey);
412         }
413 
414         [Theory]
415         [MemberData(nameof(UnaryOperators))]
416         [MemberData(nameof(BinaryOperators))]
GroupBy_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)417         public static void GroupBy_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
418         {
419             int seenKey = DefaultStart / GroupFactor;
420             foreach (IGrouping<int, int> group in operation.Item(DefaultStart, DefaultSize, source.Item).GroupBy(x => x / GroupFactor).ToList())
421             {
422                 Assert.Equal(seenKey++, group.Key);
423                 int seenElement = group.Key * GroupFactor;
424                 Assert.All(group, x => Assert.Equal(seenElement++, x));
425                 Assert.Equal(Math.Min((group.Key + 1) * GroupFactor, DefaultStart + DefaultSize), seenElement);
426             }
427             Assert.Equal((DefaultSize + (GroupFactor - 1)) / GroupFactor + 1, seenKey);
428         }
429 
430         [Theory]
431         [MemberData(nameof(UnaryOperators))]
432         [MemberData(nameof(BinaryOperators))]
GroupBy_ElementSelector(Labeled<Operation> source, Labeled<Operation> operation)433         public static void GroupBy_ElementSelector(Labeled<Operation> source, Labeled<Operation> operation)
434         {
435             int seenKey = DefaultStart / GroupFactor;
436             foreach (IGrouping<int, int> group in operation.Item(DefaultStart, DefaultSize, source.Item).GroupBy(x => x / GroupFactor, y => -y))
437             {
438                 Assert.Equal(seenKey++, group.Key);
439                 int seenElement = -group.Key * GroupFactor;
440                 Assert.All(group, x => Assert.Equal(seenElement--, x));
441                 Assert.Equal(-Math.Min((group.Key + 1) * GroupFactor, DefaultStart + DefaultSize), seenElement);
442             }
443             Assert.Equal((DefaultSize + (GroupFactor - 1)) / GroupFactor + 1, seenKey);
444         }
445 
446         [Theory]
447         [MemberData(nameof(UnaryOperators))]
448         [MemberData(nameof(BinaryOperators))]
GroupBy_ElementSelector_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)449         public static void GroupBy_ElementSelector_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
450         {
451             int seenKey = DefaultStart / GroupFactor;
452             foreach (IGrouping<int, int> group in operation.Item(DefaultStart, DefaultSize, source.Item).GroupBy(x => x / GroupFactor, y => -y).ToList())
453             {
454                 Assert.Equal(seenKey++, group.Key);
455                 int seenElement = -group.Key * GroupFactor;
456                 Assert.All(group, x => Assert.Equal(seenElement--, x));
457                 Assert.Equal(-Math.Min((group.Key + 1) * GroupFactor, DefaultStart + DefaultSize), seenElement);
458             }
459             Assert.Equal((DefaultSize + (GroupFactor - 1)) / GroupFactor + 1, seenKey);
460         }
461 
462         [Theory]
463         [ActiveIssue(1155)]
464         [MemberData(nameof(UnaryOperators))]
465         [MemberData(nameof(BinaryOperators))]
GroupJoin(Labeled<Operation> source, Labeled<Operation> operation)466         public static void GroupJoin(Labeled<Operation> source, Labeled<Operation> operation)
467         {
468             Action<Operation, Operation> groupJoin = (left, right) =>
469             {
470                 int seenKey = DefaultStart / GroupFactor;
471                 foreach (KeyValuePair<int, IEnumerable<int>> group in left(DefaultStart / GroupFactor, DefaultSize / GroupFactor, source.Item)
472                     .GroupJoin(right(DefaultStart, DefaultSize, source.Item), x => x, y => y / GroupFactor, (k, g) => new KeyValuePair<int, IEnumerable<int>>(k, g)))
473                 {
474                     Assert.Equal(seenKey++, group.Key);
475                     int seenElement = group.Key * GroupFactor;
476                     Assert.All(group.Value, x => Assert.Equal(seenElement++, x));
477                     Assert.Equal((group.Key + 1) * GroupFactor, seenElement);
478                 }
479                 Assert.Equal((DefaultStart + DefaultSize) / GroupFactor, seenKey);
480             };
481             groupJoin(operation.Item, LabeledDefaultSource.AsOrdered().Item);
482             groupJoin(LabeledDefaultSource.AsOrdered().Item, operation.Item);
483         }
484 
485         [Theory]
486         [ActiveIssue(1155)]
487         [MemberData(nameof(UnaryOperators))]
488         [MemberData(nameof(BinaryOperators))]
GroupJoin_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)489         public static void GroupJoin_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
490         {
491             Action<Operation, Operation> groupJoin = (left, right) =>
492             {
493                 int seenKey = DefaultStart / GroupFactor;
494                 foreach (KeyValuePair<int, IEnumerable<int>> group in left(DefaultStart / GroupFactor, DefaultSize / GroupFactor, source.Item)
495                     .GroupJoin(right(DefaultStart, DefaultSize, source.Item), x => x, y => y / GroupFactor, (k, g) => new KeyValuePair<int, IEnumerable<int>>(k, g)).ToList())
496                 {
497                     Assert.Equal(seenKey++, group.Key);
498                     int seenElement = group.Key * GroupFactor;
499                     Assert.All(group.Value, x => Assert.Equal(seenElement++, x));
500                     Assert.Equal((group.Key + 1) * GroupFactor, seenElement);
501                 }
502                 Assert.Equal((DefaultStart + DefaultSize) / GroupFactor, seenKey);
503             };
504             groupJoin(operation.Item, LabeledDefaultSource.AsOrdered().Item);
505             groupJoin(LabeledDefaultSource.AsOrdered().Item, operation.Item);
506         }
507 
508         [Theory]
509         [MemberData(nameof(UnaryOperators))]
510         [MemberData(nameof(BinaryOperators))]
Intersect(Labeled<Operation> source, Labeled<Operation> operation)511         public static void Intersect(Labeled<Operation> source, Labeled<Operation> operation)
512         {
513             Action<Operation, Operation> intersect = (left, right) =>
514             {
515                 int seen = DefaultStart;
516                 ParallelQuery<int> query = left(DefaultStart - DefaultSize / 2, DefaultSize + DefaultSize / 2, source.Item)
517                     .Intersect(right(DefaultStart, DefaultSize + DefaultSize / 2, source.Item));
518                 foreach (int i in query)
519                 {
520                     Assert.Equal(seen++, i);
521                 }
522                 Assert.Equal(DefaultStart + DefaultSize, seen);
523             };
524             intersect(operation.Item, DefaultSource);
525             intersect(LabeledDefaultSource.AsOrdered().Item, operation.Item);
526         }
527 
528         [Theory]
529         [MemberData(nameof(UnaryOperators))]
530         [MemberData(nameof(BinaryOperators))]
Intersect_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)531         public static void Intersect_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
532         {
533             Action<Operation, Operation> intersect = (left, right) =>
534             {
535                 int seen = DefaultStart;
536                 ParallelQuery<int> query = left(DefaultStart - DefaultSize / 2, DefaultSize + DefaultSize / 2, source.Item)
537                     .Intersect(right(DefaultStart, DefaultSize + DefaultSize / 2, source.Item));
538                 Assert.All(query.ToList(), x => Assert.Equal(seen++, x));
539                 Assert.Equal(DefaultStart + DefaultSize, seen);
540             };
541             intersect(operation.Item, DefaultSource);
542             intersect(LabeledDefaultSource.AsOrdered().Item, operation.Item);
543         }
544 
545         [Theory]
546         [ActiveIssue(1155)]
547         [MemberData(nameof(UnaryOperators))]
548         [MemberData(nameof(BinaryOperators))]
Join(Labeled<Operation> source, Labeled<Operation> operation)549         public static void Join(Labeled<Operation> source, Labeled<Operation> operation)
550         {
551             Action<Operation, Operation> join = (left, right) =>
552             {
553                 int seen = DefaultStart;
554                 ParallelQuery<KeyValuePair<int, int>> query = left(DefaultStart / GroupFactor, DefaultSize / GroupFactor, source.Item)
555                       .Join(right(DefaultStart, DefaultSize, source.Item), x => x, y => y / GroupFactor, (x, y) => new KeyValuePair<int, int>(x, y));
556                 foreach (KeyValuePair<int, int> p in query)
557                 {
558                     Assert.Equal(seen++, p.Value);
559                     Assert.Equal(p.Key, p.Value / GroupFactor);
560                 }
561                 Assert.Equal(DefaultStart + DefaultSize, seen);
562             };
563             join(operation.Item, LabeledDefaultSource.AsOrdered().Item);
564             join(LabeledDefaultSource.AsOrdered().Item, operation.Item);
565         }
566 
567         [Theory]
568         [ActiveIssue(1155)]
569         [MemberData(nameof(UnaryOperators))]
570         [MemberData(nameof(BinaryOperators))]
Join_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)571         public static void Join_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
572         {
573             Action<Operation, Operation> join = (left, right) =>
574             {
575                 int seen = DefaultStart;
576                 ParallelQuery<KeyValuePair<int, int>> query = left(DefaultStart / GroupFactor, DefaultSize / GroupFactor, source.Item)
577                       .Join(right(DefaultStart, DefaultSize, source.Item), x => x, y => y / GroupFactor, (x, y) => new KeyValuePair<int, int>(x, y));
578                 foreach (KeyValuePair<int, int> p in query.ToList())
579                 {
580                     Assert.Equal(seen++, p.Value);
581                     Assert.Equal(p.Key, p.Value / GroupFactor);
582                 }
583                 Assert.Equal(DefaultStart + DefaultSize, seen);
584             };
585             join(operation.Item, LabeledDefaultSource.AsOrdered().Item);
586             join(LabeledDefaultSource.AsOrdered().Item, operation.Item);
587         }
588 
589         [Theory]
590         [MemberData(nameof(UnaryOperators))]
591         [MemberData(nameof(BinaryOperators))]
Last(Labeled<Operation> source, Labeled<Operation> operation)592         public static void Last(Labeled<Operation> source, Labeled<Operation> operation)
593         {
594             Assert.Equal(DefaultStart + DefaultSize - 1, operation.Item(DefaultStart, DefaultSize, source.Item).Last());
595         }
596 
597         [Theory]
598         [MemberData(nameof(UnaryOperators))]
599         [MemberData(nameof(BinaryOperators))]
Last_Predicate(Labeled<Operation> source, Labeled<Operation> operation)600         public static void Last_Predicate(Labeled<Operation> source, Labeled<Operation> operation)
601         {
602             Assert.Equal(DefaultStart + DefaultSize / 2 - 1, operation.Item(DefaultStart, DefaultSize, source.Item).Last(x => x < DefaultStart + DefaultSize / 2));
603         }
604 
605         [Theory]
606         [MemberData(nameof(UnaryOperators))]
607         [MemberData(nameof(BinaryOperators))]
LastOrDefault(Labeled<Operation> source, Labeled<Operation> operation)608         public static void LastOrDefault(Labeled<Operation> source, Labeled<Operation> operation)
609         {
610             Assert.Equal(DefaultStart + DefaultSize - 1, operation.Item(DefaultStart, DefaultSize, source.Item).LastOrDefault());
611         }
612 
613         [Theory]
614         [MemberData(nameof(UnaryOperators))]
615         [MemberData(nameof(BinaryOperators))]
LastOrDefault_Predicate(Labeled<Operation> source, Labeled<Operation> operation)616         public static void LastOrDefault_Predicate(Labeled<Operation> source, Labeled<Operation> operation)
617         {
618             Assert.Equal(DefaultStart + DefaultSize / 2 - 1, operation.Item(DefaultStart, DefaultSize, source.Item).LastOrDefault(x => x < DefaultStart + DefaultSize / 2));
619         }
620 
621         [Theory]
622         [MemberData(nameof(UnaryOperators))]
623         [MemberData(nameof(BinaryOperators))]
LastOrDefault_Predicate_None(Labeled<Operation> source, Labeled<Operation> operation)624         public static void LastOrDefault_Predicate_None(Labeled<Operation> source, Labeled<Operation> operation)
625         {
626             Assert.Equal(default(int), operation.Item(DefaultStart, DefaultSize, source.Item).LastOrDefault(x => false));
627         }
628 
629         [Theory]
630         [MemberData(nameof(UnaryOperations))]
631         [MemberData(nameof(BinaryOperations))]
LongCount_Elements(Labeled<Operation> operation)632         public static void LongCount_Elements(Labeled<Operation> operation)
633         {
634             Assert.Equal(DefaultSize, operation.Item(DefaultStart, DefaultSize, DefaultSource).LongCount());
635         }
636 
637         [Theory]
638         [MemberData(nameof(UnaryOperations))]
639         [MemberData(nameof(BinaryOperations))]
LongCount_Predicate_Some(Labeled<Operation> operation)640         public static void LongCount_Predicate_Some(Labeled<Operation> operation)
641         {
642             Assert.Equal(DefaultSize / 2, operation.Item(DefaultStart, DefaultSize, DefaultSource).LongCount(x => x < DefaultStart + DefaultSize / 2));
643         }
644 
645         [Theory]
646         [MemberData(nameof(UnaryOperations))]
647         [MemberData(nameof(BinaryOperations))]
LongCount_Predicate_None(Labeled<Operation> operation)648         public static void LongCount_Predicate_None(Labeled<Operation> operation)
649         {
650             Assert.Equal(0, operation.Item(DefaultStart, DefaultSize, DefaultSource).LongCount(x => x < DefaultStart));
651         }
652 
653         [Theory]
654         [MemberData(nameof(UnaryOperations))]
655         [MemberData(nameof(BinaryOperations))]
Max(Labeled<Operation> operation)656         public static void Max(Labeled<Operation> operation)
657         {
658             Assert.Equal(DefaultStart + DefaultSize - 1, operation.Item(DefaultStart, DefaultSize, DefaultSource).Max());
659         }
660 
661         [Theory]
662         [MemberData(nameof(UnaryOperations))]
663         [MemberData(nameof(BinaryOperations))]
Max_Nullable(Labeled<Operation> operation)664         public static void Max_Nullable(Labeled<Operation> operation)
665         {
666             Assert.Equal(DefaultStart + DefaultSize - 1, operation.Item(DefaultStart, DefaultSize, DefaultSource).Max(x => (int?)x));
667         }
668 
669         [Theory]
670         [MemberData(nameof(UnaryOperations))]
671         [MemberData(nameof(BinaryOperations))]
Min(Labeled<Operation> operation)672         public static void Min(Labeled<Operation> operation)
673         {
674             Assert.Equal(DefaultStart, operation.Item(DefaultStart, DefaultSize, DefaultSource).Min());
675         }
676 
677         [Theory]
678         [MemberData(nameof(UnaryOperations))]
679         [MemberData(nameof(BinaryOperations))]
Min_Nullable(Labeled<Operation> operation)680         public static void Min_Nullable(Labeled<Operation> operation)
681         {
682             Assert.Equal(DefaultStart, operation.Item(DefaultStart, DefaultSize, DefaultSource).Min(x => (int?)x));
683         }
684 
685         [Theory]
686         [MemberData(nameof(UnaryOperators))]
687         [MemberData(nameof(BinaryOperators))]
OfType(Labeled<Operation> source, Labeled<Operation> operation)688         public static void OfType(Labeled<Operation> source, Labeled<Operation> operation)
689         {
690             int seen = DefaultStart;
691             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OfType<int>())
692             {
693                 Assert.Equal(seen++, i);
694             }
695             Assert.Equal(DefaultStart + DefaultSize, seen);
696         }
697 
698         [Theory]
699         [MemberData(nameof(UnaryOperators))]
700         [MemberData(nameof(BinaryOperators))]
OfType_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)701         public static void OfType_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
702         {
703             int seen = DefaultStart;
704             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OfType<int>().ToList(), x => Assert.Equal(seen++, x));
705             Assert.Equal(DefaultStart + DefaultSize, seen);
706         }
707 
708         [Theory]
709         [MemberData(nameof(UnaryOperators))]
710         [MemberData(nameof(BinaryOperators))]
OfType_Other(Labeled<Operation> source, Labeled<Operation> operation)711         public static void OfType_Other(Labeled<Operation> source, Labeled<Operation> operation)
712         {
713             Assert.Empty(operation.Item(DefaultStart, DefaultSize, source.Item).OfType<long>());
714         }
715 
716         [Theory]
717         [MemberData(nameof(UnaryOperators))]
718         [MemberData(nameof(BinaryOperators))]
OfType_Other_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)719         public static void OfType_Other_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
720         {
721             Assert.Empty(operation.Item(DefaultStart, DefaultSize, source.Item).OfType<long>().ToList());
722         }
723 
724         [Theory]
725         [MemberData(nameof(UnaryOperators))]
726         [MemberData(nameof(BinaryOperators))]
727         [MemberData(nameof(UnaryUnorderedOperators))]
728         [MemberData(nameof(BinaryUnorderedOperators))]
OrderBy_Initial(Labeled<Operation> source, Labeled<Operation> operation)729         public static void OrderBy_Initial(Labeled<Operation> source, Labeled<Operation> operation)
730         {
731             int seen = DefaultStart;
732             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => x))
733             {
734                 Assert.Equal(seen++, i);
735             }
736             Assert.Equal(DefaultStart + DefaultSize, seen);
737         }
738 
739         [Theory]
740         [MemberData(nameof(UnaryOperators))]
741         [MemberData(nameof(BinaryOperators))]
742         [MemberData(nameof(UnaryUnorderedOperators))]
743         [MemberData(nameof(BinaryUnorderedOperators))]
OrderBy_Initial_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)744         public static void OrderBy_Initial_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
745         {
746             int seen = DefaultStart;
747             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => x).ToList(), x => Assert.Equal(seen++, x));
748             Assert.Equal(DefaultStart + DefaultSize, seen);
749         }
750 
751         [Theory]
752         [MemberData(nameof(UnaryOperators))]
753         [MemberData(nameof(BinaryOperators))]
754         [MemberData(nameof(UnaryUnorderedOperators))]
755         [MemberData(nameof(BinaryUnorderedOperators))]
OrderBy_OtherDirection(Labeled<Operation> source, Labeled<Operation> operation)756         public static void OrderBy_OtherDirection(Labeled<Operation> source, Labeled<Operation> operation)
757         {
758             int seen = DefaultStart + DefaultSize;
759             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => -x))
760             {
761                 Assert.Equal(--seen, i);
762             }
763             Assert.Equal(DefaultStart, seen);
764         }
765 
766         [Theory]
767         [MemberData(nameof(UnaryOperators))]
768         [MemberData(nameof(BinaryOperators))]
769         [MemberData(nameof(UnaryUnorderedOperators))]
770         [MemberData(nameof(BinaryUnorderedOperators))]
OrderBy_OtherDirection_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)771         public static void OrderBy_OtherDirection_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
772         {
773             int seen = DefaultStart + DefaultSize;
774             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => -x).ToList(), x => Assert.Equal(--seen, x));
775             Assert.Equal(DefaultStart, seen);
776         }
777 
778         [Theory]
779         [MemberData(nameof(UnaryOperators))]
780         [MemberData(nameof(BinaryOperators))]
781         [MemberData(nameof(UnaryUnorderedOperators))]
782         [MemberData(nameof(BinaryUnorderedOperators))]
OrderByDescending_Initial(Labeled<Operation> source, Labeled<Operation> operation)783         public static void OrderByDescending_Initial(Labeled<Operation> source, Labeled<Operation> operation)
784         {
785             int seen = DefaultStart;
786             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OrderByDescending(x => -x))
787             {
788                 Assert.Equal(seen++, i);
789             }
790             Assert.Equal(DefaultStart + DefaultSize, seen);
791         }
792 
793         [Theory]
794         [MemberData(nameof(UnaryOperators))]
795         [MemberData(nameof(BinaryOperators))]
796         [MemberData(nameof(UnaryUnorderedOperators))]
797         [MemberData(nameof(BinaryUnorderedOperators))]
OrderByDescending_Initial_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)798         public static void OrderByDescending_Initial_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
799         {
800             int seen = DefaultStart;
801             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OrderByDescending(x => -x).ToList(), x => Assert.Equal(seen++, x));
802             Assert.Equal(DefaultStart + DefaultSize, seen);
803         }
804 
805         [Theory]
806         [MemberData(nameof(UnaryOperators))]
807         [MemberData(nameof(BinaryOperators))]
808         [MemberData(nameof(UnaryUnorderedOperators))]
809         [MemberData(nameof(BinaryUnorderedOperators))]
OrderByDescending_OtherDirection(Labeled<Operation> source, Labeled<Operation> operation)810         public static void OrderByDescending_OtherDirection(Labeled<Operation> source, Labeled<Operation> operation)
811         {
812             int seen = DefaultStart + DefaultSize;
813             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OrderByDescending(x => x))
814             {
815                 Assert.Equal(--seen, i);
816             }
817             Assert.Equal(DefaultStart, seen);
818         }
819 
820         [Theory]
821         [MemberData(nameof(UnaryOperators))]
822         [MemberData(nameof(BinaryOperators))]
823         [MemberData(nameof(UnaryUnorderedOperators))]
824         [MemberData(nameof(BinaryUnorderedOperators))]
OrderByDescending_OtherDirection_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)825         public static void OrderByDescending_OtherDirection_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
826         {
827             int seen = DefaultStart + DefaultSize;
828             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OrderByDescending(x => x).ToList(), x => Assert.Equal(--seen, x));
829             Assert.Equal(DefaultStart, seen);
830         }
831 
832         [Theory]
833         [MemberData(nameof(UnaryOperators))]
834         [MemberData(nameof(BinaryOperators))]
Reverse(Labeled<Operation> source, Labeled<Operation> operation)835         public static void Reverse(Labeled<Operation> source, Labeled<Operation> operation)
836         {
837             int seen = DefaultStart + DefaultSize;
838             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).Reverse())
839             {
840                 Assert.Equal(--seen, i);
841             }
842             Assert.Equal(DefaultStart, seen);
843         }
844 
845         [Theory]
846         [MemberData(nameof(UnaryOperators))]
847         [MemberData(nameof(BinaryOperators))]
Reverse_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)848         public static void Reverse_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
849         {
850             int seen = DefaultStart + DefaultSize;
851             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).Reverse().ToList())
852             {
853                 Assert.Equal(--seen, i);
854             }
855             Assert.Equal(DefaultStart, seen);
856         }
857 
858         [Theory]
859         [MemberData(nameof(UnaryOperators))]
860         [MemberData(nameof(BinaryOperators))]
Select(Labeled<Operation> source, Labeled<Operation> operation)861         public static void Select(Labeled<Operation> source, Labeled<Operation> operation)
862         {
863             int seen = -DefaultStart;
864             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).Select(x => -x))
865             {
866                 Assert.Equal(seen--, i);
867             }
868             Assert.Equal(-DefaultStart - DefaultSize, seen);
869         }
870 
871         [Theory]
872         [MemberData(nameof(UnaryOperators))]
873         [MemberData(nameof(BinaryOperators))]
Select_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)874         public static void Select_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
875         {
876             int seen = -DefaultStart;
877             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).Select(x => -x).ToList(), x => Assert.Equal(seen--, x));
878             Assert.Equal(-DefaultStart - DefaultSize, seen);
879         }
880 
881         [Theory]
882         [MemberData(nameof(UnaryOperators))]
883         [MemberData(nameof(BinaryOperators))]
Select_Indexed(Labeled<Operation> source, Labeled<Operation> operation)884         public static void Select_Indexed(Labeled<Operation> source, Labeled<Operation> operation)
885         {
886             int seen = -DefaultStart;
887             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).Select((x, index) => { Assert.Equal(DefaultStart + index, x); return -x; }))
888             {
889                 Assert.Equal(seen--, i);
890             }
891             Assert.Equal(-DefaultStart - DefaultSize, seen);
892         }
893 
894         [Theory]
895         [MemberData(nameof(UnaryOperators))]
896         [MemberData(nameof(BinaryOperators))]
Select_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)897         public static void Select_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
898         {
899             int seen = -DefaultStart;
900             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).Select((x, index) => { Assert.Equal(DefaultStart + index, x); return -x; }).ToList(), x => Assert.Equal(seen--, x));
901             Assert.Equal(-DefaultStart - DefaultSize, seen);
902         }
903 
904         [Theory]
905         [MemberData(nameof(UnaryOperators))]
906         [MemberData(nameof(BinaryOperators))]
SelectMany(Labeled<Operation> source, Labeled<Operation> operation)907         public static void SelectMany(Labeled<Operation> source, Labeled<Operation> operation)
908         {
909             int seen = -DefaultStart;
910             foreach (int i in operation.Item(0, DefaultSize, source.Item).SelectMany(x => new[] { 0, -1 }.Select(y => y + -DefaultStart - 2 * x)))
911             {
912                 Assert.Equal(seen--, i);
913             }
914             Assert.Equal(-DefaultStart - DefaultSize * 2, seen);
915         }
916 
917         [Theory]
918         [MemberData(nameof(UnaryOperators))]
919         [MemberData(nameof(BinaryOperators))]
SelectMany_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)920         public static void SelectMany_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
921         {
922             int seen = -DefaultStart;
923             Assert.All(operation.Item(0, DefaultSize, source.Item).SelectMany(x => new[] { 0, -1 }.Select(y => y + -DefaultStart - 2 * x)).ToList(), x => Assert.Equal(seen--, x));
924             Assert.Equal(-DefaultStart - DefaultSize * 2, seen);
925         }
926 
927         [Theory]
928         [MemberData(nameof(UnaryOperators))]
929         [MemberData(nameof(BinaryOperators))]
SelectMany_Indexed(Labeled<Operation> source, Labeled<Operation> operation)930         public static void SelectMany_Indexed(Labeled<Operation> source, Labeled<Operation> operation)
931         {
932             int seen = -DefaultStart;
933             foreach (int i in operation.Item(0, DefaultSize, source.Item).SelectMany((x, index) => { Assert.Equal(index, x); return new[] { 0, -1 }.Select(y => y + -DefaultStart - 2 * x); }))
934             {
935                 Assert.Equal(seen--, i);
936             }
937             Assert.Equal(-DefaultStart - DefaultSize * 2, seen);
938         }
939 
940         [Theory]
941         [MemberData(nameof(UnaryOperators))]
942         [MemberData(nameof(BinaryOperators))]
SelectMany_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)943         public static void SelectMany_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
944         {
945             int seen = -DefaultStart;
946             Assert.All(operation.Item(0, DefaultSize, source.Item).SelectMany((x, index) => { Assert.Equal(index, x); return new[] { 0, -1 }.Select(y => y + -DefaultStart - 2 * x); }).ToList(), x => Assert.Equal(seen--, x));
947             Assert.Equal(-DefaultStart - DefaultSize * 2, seen);
948         }
949 
950         [Theory]
951         [MemberData(nameof(UnaryOperators))]
952         [MemberData(nameof(BinaryOperators))]
SelectMany_ResultSelector(Labeled<Operation> source, Labeled<Operation> operation)953         public static void SelectMany_ResultSelector(Labeled<Operation> source, Labeled<Operation> operation)
954         {
955             int seen = -DefaultStart;
956             foreach (int i in operation.Item(0, DefaultSize, source.Item).SelectMany(x => new[] { 0, -1 }, (x, y) => y + -DefaultStart - 2 * x))
957             {
958                 Assert.Equal(seen--, i);
959             }
960             Assert.Equal(-DefaultStart - DefaultSize * 2, seen);
961         }
962 
963         [Theory]
964         [MemberData(nameof(UnaryOperators))]
965         [MemberData(nameof(BinaryOperators))]
SelectMany_ResultSelector_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)966         public static void SelectMany_ResultSelector_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
967         {
968             int seen = -DefaultStart;
969             Assert.All(operation.Item(0, DefaultSize, source.Item).SelectMany(x => new[] { 0, -1 }, (x, y) => y + -DefaultStart - 2 * x).ToList(), x => Assert.Equal(seen--, x));
970             Assert.Equal(-DefaultStart - DefaultSize * 2, seen);
971         }
972 
973         [Theory]
974         [MemberData(nameof(UnaryOperators))]
975         [MemberData(nameof(BinaryOperators))]
SelectMany_Indexed_ResultSelector(Labeled<Operation> source, Labeled<Operation> operation)976         public static void SelectMany_Indexed_ResultSelector(Labeled<Operation> source, Labeled<Operation> operation)
977         {
978             int seen = -DefaultStart;
979             foreach (int i in operation.Item(0, DefaultSize, source.Item).SelectMany((x, index) => { Assert.Equal(index, x); return new[] { 0, -1 }; }, (x, y) => y + -DefaultStart - 2 * x))
980             {
981                 Assert.Equal(seen--, i);
982             }
983             Assert.Equal(-DefaultStart - DefaultSize * 2, seen);
984         }
985 
986         [Theory]
987         [MemberData(nameof(UnaryOperators))]
988         [MemberData(nameof(BinaryOperators))]
SelectMany_Indexed_ResultSelector_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)989         public static void SelectMany_Indexed_ResultSelector_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
990         {
991             int seen = -DefaultStart;
992             Assert.All(operation.Item(0, DefaultSize, source.Item).SelectMany((x, index) => { Assert.Equal(index, x); return new[] { 0, -1 }; }, (x, y) => y + -DefaultStart - 2 * x).ToList(), x => Assert.Equal(seen--, x));
993             Assert.Equal(-DefaultStart - DefaultSize * 2, seen);
994         }
995 
996         [Theory]
997         [MemberData(nameof(UnaryOperators))]
998         [MemberData(nameof(BinaryOperators))]
SequenceEqual(Labeled<Operation> source, Labeled<Operation> operation)999         public static void SequenceEqual(Labeled<Operation> source, Labeled<Operation> operation)
1000         {
1001             Assert.True(operation.Item(DefaultStart, DefaultSize, source.Item).SequenceEqual(ParallelEnumerable.Range(DefaultStart, DefaultSize).AsOrdered()));
1002             Assert.True(ParallelEnumerable.Range(DefaultStart, DefaultSize).AsOrdered().SequenceEqual(operation.Item(DefaultStart, DefaultSize, source.Item)));
1003         }
1004 
1005         [Theory]
1006         [MemberData(nameof(UnaryOperations))]
1007         [MemberData(nameof(BinaryOperations))]
Single(Labeled<Operation> operation)1008         public static void Single(Labeled<Operation> operation)
1009         {
1010             Assert.Equal(DefaultStart, operation.Item(DefaultStart, 1, DefaultSource).Single());
1011             Assert.Equal(DefaultStart + DefaultSize / 2, operation.Item(DefaultStart, DefaultSize, DefaultSource).Single(x => x == DefaultStart + DefaultSize / 2));
1012         }
1013 
1014         [Theory]
1015         [MemberData(nameof(UnaryOperations))]
1016         [MemberData(nameof(BinaryOperations))]
SingleOrDefault(Labeled<Operation> operation)1017         public static void SingleOrDefault(Labeled<Operation> operation)
1018         {
1019             Assert.Equal(DefaultStart, operation.Item(DefaultStart, 1, DefaultSource).SingleOrDefault());
1020             Assert.Equal(DefaultStart + DefaultSize / 2, operation.Item(DefaultStart, DefaultSize, DefaultSource).SingleOrDefault(x => x == DefaultStart + DefaultSize / 2));
1021 
1022             if (!operation.ToString().StartsWith("DefaultIfEmpty"))
1023             {
1024                 Assert.Equal(default(int), operation.Item(DefaultStart, 0, DefaultSource).SingleOrDefault());
1025                 Assert.Equal(default(int), operation.Item(DefaultStart, 0, DefaultSource).SingleOrDefault(x => x == DefaultStart + DefaultSize / 2));
1026             }
1027         }
1028 
1029         [Theory]
1030         [MemberData(nameof(UnaryOperators))]
1031         [MemberData(nameof(BinaryOperators))]
Skip(Labeled<Operation> source, Labeled<Operation> operation)1032         public static void Skip(Labeled<Operation> source, Labeled<Operation> operation)
1033         {
1034             int seen = DefaultStart + DefaultSize / 2;
1035             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).Skip(DefaultSize / 2))
1036             {
1037                 Assert.Equal(seen++, i);
1038             }
1039             Assert.Equal(DefaultStart + DefaultSize, seen);
1040         }
1041 
1042         [Theory]
1043         [MemberData(nameof(UnaryOperators))]
1044         [MemberData(nameof(BinaryOperators))]
Skip_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1045         public static void Skip_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1046         {
1047             int seen = DefaultStart + DefaultSize / 2;
1048             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).Skip(DefaultSize / 2).ToList(), x => Assert.Equal(seen++, x));
1049             Assert.Equal(DefaultStart + DefaultSize, seen);
1050         }
1051 
1052         [Theory]
1053         [MemberData(nameof(UnaryOperators))]
1054         [MemberData(nameof(BinaryOperators))]
SkipWhile(Labeled<Operation> source, Labeled<Operation> operation)1055         public static void SkipWhile(Labeled<Operation> source, Labeled<Operation> operation)
1056         {
1057             int seen = DefaultStart + DefaultSize / 2;
1058             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).SkipWhile(x => x < DefaultStart + DefaultSize / 2))
1059             {
1060                 Assert.Equal(seen++, i);
1061             }
1062             Assert.Equal(DefaultStart + DefaultSize, seen);
1063         }
1064 
1065         [Theory]
1066         [MemberData(nameof(UnaryOperators))]
1067         [MemberData(nameof(BinaryOperators))]
SkipWhile_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1068         public static void SkipWhile_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1069         {
1070             int seen = DefaultStart + DefaultSize / 2;
1071             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).SkipWhile(x => x < DefaultStart + DefaultSize / 2).ToList(), x => Assert.Equal(seen++, x));
1072             Assert.Equal(DefaultStart + DefaultSize, seen);
1073         }
1074 
1075         [Theory]
1076         [MemberData(nameof(UnaryOperators))]
1077         [MemberData(nameof(BinaryOperators))]
SkipWhile_Indexed(Labeled<Operation> source, Labeled<Operation> operation)1078         public static void SkipWhile_Indexed(Labeled<Operation> source, Labeled<Operation> operation)
1079         {
1080             int seen = DefaultStart + DefaultSize / 2;
1081             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).SkipWhile((x, index) => index < DefaultSize / 2))
1082             {
1083                 Assert.Equal(seen++, i);
1084             }
1085             Assert.Equal(DefaultStart + DefaultSize, seen);
1086         }
1087 
1088         [Theory]
1089         [MemberData(nameof(UnaryOperators))]
1090         [MemberData(nameof(BinaryOperators))]
SkipWhile_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1091         public static void SkipWhile_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1092         {
1093             int seen = DefaultStart + DefaultSize / 2;
1094             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).SkipWhile((x, index) => index < DefaultSize / 2).ToList(), x => Assert.Equal(seen++, x));
1095             Assert.Equal(DefaultStart + DefaultSize, seen);
1096         }
1097 
1098         [Theory]
1099         [MemberData(nameof(UnaryOperations))]
1100         [MemberData(nameof(BinaryOperations))]
Sum(Labeled<Operation> operation)1101         public static void Sum(Labeled<Operation> operation)
1102         {
1103             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize), operation.Item(DefaultStart, DefaultSize, DefaultSource).Sum());
1104         }
1105 
1106         [Theory]
1107         [MemberData(nameof(UnaryOperations))]
1108         [MemberData(nameof(BinaryOperations))]
Sum_Nullable(Labeled<Operation> operation)1109         public static void Sum_Nullable(Labeled<Operation> operation)
1110         {
1111             Assert.Equal(Functions.SumRange(DefaultStart, DefaultSize), operation.Item(DefaultStart, DefaultSize, DefaultSource).Sum(x => (int?)x));
1112         }
1113 
1114         [Theory]
1115         [MemberData(nameof(UnaryOperators))]
1116         [MemberData(nameof(BinaryOperators))]
Take(Labeled<Operation> source, Labeled<Operation> operation)1117         public static void Take(Labeled<Operation> source, Labeled<Operation> operation)
1118         {
1119             int seen = DefaultStart;
1120             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).Take(DefaultSize / 2))
1121             {
1122                 Assert.Equal(seen++, i);
1123             }
1124             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1125         }
1126 
1127         [Theory]
1128         [MemberData(nameof(UnaryOperators))]
1129         [MemberData(nameof(BinaryOperators))]
Take_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1130         public static void Take_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1131         {
1132             int seen = DefaultStart;
1133             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).Take(DefaultSize / 2).ToList(), x => Assert.Equal(seen++, x));
1134             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1135         }
1136 
1137         [Theory]
1138         [MemberData(nameof(UnaryOperators))]
1139         [MemberData(nameof(BinaryOperators))]
TakeWhile(Labeled<Operation> source, Labeled<Operation> operation)1140         public static void TakeWhile(Labeled<Operation> source, Labeled<Operation> operation)
1141         {
1142             int seen = DefaultStart;
1143             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).TakeWhile(x => x < DefaultStart + DefaultSize / 2))
1144             {
1145                 Assert.Equal(seen++, i);
1146             }
1147             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1148         }
1149 
1150         [Theory]
1151         [MemberData(nameof(UnaryOperators))]
1152         [MemberData(nameof(BinaryOperators))]
TakeWhile_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1153         public static void TakeWhile_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1154         {
1155             int seen = DefaultStart;
1156             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).TakeWhile(x => x < DefaultStart + DefaultSize / 2).ToList(), x => Assert.Equal(seen++, x));
1157             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1158         }
1159 
1160         [Theory]
1161         [MemberData(nameof(UnaryOperators))]
1162         [MemberData(nameof(BinaryOperators))]
TakeWhile_Indexed(Labeled<Operation> source, Labeled<Operation> operation)1163         public static void TakeWhile_Indexed(Labeled<Operation> source, Labeled<Operation> operation)
1164         {
1165             int seen = DefaultStart;
1166             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).TakeWhile((x, index) => index < DefaultSize / 2))
1167             {
1168                 Assert.Equal(seen++, i);
1169             }
1170             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1171         }
1172 
1173         [Theory]
1174         [MemberData(nameof(UnaryOperators))]
1175         [MemberData(nameof(BinaryOperators))]
TakeWhile_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1176         public static void TakeWhile_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1177         {
1178             int seen = DefaultStart;
1179             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).TakeWhile((x, index) => index < DefaultSize / 2).ToList(), x => Assert.Equal(seen++, x));
1180             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1181         }
1182 
1183         [Theory]
1184         [MemberData(nameof(UnaryOperators))]
1185         [MemberData(nameof(BinaryOperators))]
1186         [MemberData(nameof(UnaryUnorderedOperators))]
1187         [MemberData(nameof(BinaryUnorderedOperators))]
ThenBy_Initial(Labeled<Operation> source, Labeled<Operation> operation)1188         public static void ThenBy_Initial(Labeled<Operation> source, Labeled<Operation> operation)
1189         {
1190             int seen = DefaultStart;
1191             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => 0).ThenBy(x => x))
1192             {
1193                 Assert.Equal(seen++, i);
1194             }
1195             Assert.Equal(DefaultStart + DefaultSize, seen);
1196         }
1197 
1198         [Theory]
1199         [MemberData(nameof(UnaryOperators))]
1200         [MemberData(nameof(BinaryOperators))]
1201         [MemberData(nameof(UnaryUnorderedOperators))]
1202         [MemberData(nameof(BinaryUnorderedOperators))]
ThenBy_Initial_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1203         public static void ThenBy_Initial_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1204         {
1205             int seen = DefaultStart;
1206             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => 0).ThenBy(x => x).ToList(), x => Assert.Equal(seen++, x));
1207             Assert.Equal(DefaultStart + DefaultSize, seen);
1208         }
1209 
1210         [Theory]
1211         [MemberData(nameof(UnaryOperators))]
1212         [MemberData(nameof(BinaryOperators))]
1213         [MemberData(nameof(UnaryUnorderedOperators))]
1214         [MemberData(nameof(BinaryUnorderedOperators))]
ThenBy_OtherDirection(Labeled<Operation> source, Labeled<Operation> operation)1215         public static void ThenBy_OtherDirection(Labeled<Operation> source, Labeled<Operation> operation)
1216         {
1217             int seen = DefaultStart + DefaultSize;
1218             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => 0).ThenBy(x => -x))
1219             {
1220                 Assert.Equal(--seen, i);
1221             }
1222             Assert.Equal(DefaultStart, seen);
1223         }
1224 
1225         [Theory]
1226         [MemberData(nameof(UnaryOperators))]
1227         [MemberData(nameof(BinaryOperators))]
1228         [MemberData(nameof(UnaryUnorderedOperators))]
1229         [MemberData(nameof(BinaryUnorderedOperators))]
ThenBy_OtherDirection_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1230         public static void ThenBy_OtherDirection_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1231         {
1232             int seen = DefaultStart + DefaultSize;
1233             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => 0).ThenBy(x => -x).ToList(), x => Assert.Equal(--seen, x));
1234             Assert.Equal(DefaultStart, seen);
1235         }
1236 
1237         [Theory]
1238         [MemberData(nameof(UnaryOperators))]
1239         [MemberData(nameof(BinaryOperators))]
1240         [MemberData(nameof(UnaryUnorderedOperators))]
1241         [MemberData(nameof(BinaryUnorderedOperators))]
ThenByDescending_Initial(Labeled<Operation> source, Labeled<Operation> operation)1242         public static void ThenByDescending_Initial(Labeled<Operation> source, Labeled<Operation> operation)
1243         {
1244             int seen = DefaultStart;
1245             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => 0).ThenByDescending(x => -x))
1246             {
1247                 Assert.Equal(seen++, i);
1248             }
1249             Assert.Equal(DefaultStart + DefaultSize, seen);
1250         }
1251 
1252         [Theory]
1253         [MemberData(nameof(UnaryOperators))]
1254         [MemberData(nameof(BinaryOperators))]
1255         [MemberData(nameof(UnaryUnorderedOperators))]
1256         [MemberData(nameof(BinaryUnorderedOperators))]
ThenByDescending_Initial_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1257         public static void ThenByDescending_Initial_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1258         {
1259             int seen = DefaultStart;
1260             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => 0).ThenByDescending(x => -x).ToList(), x => Assert.Equal(seen++, x));
1261             Assert.Equal(DefaultStart + DefaultSize, seen);
1262         }
1263 
1264         [Theory]
1265         [MemberData(nameof(UnaryOperators))]
1266         [MemberData(nameof(BinaryOperators))]
1267         [MemberData(nameof(UnaryUnorderedOperators))]
1268         [MemberData(nameof(BinaryUnorderedOperators))]
ThenByDescending_OtherDirection(Labeled<Operation> source, Labeled<Operation> operation)1269         public static void ThenByDescending_OtherDirection(Labeled<Operation> source, Labeled<Operation> operation)
1270         {
1271             int seen = DefaultStart + DefaultSize;
1272             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => 0).ThenByDescending(x => x))
1273             {
1274                 Assert.Equal(--seen, i);
1275             }
1276             Assert.Equal(DefaultStart, seen);
1277         }
1278 
1279         [Theory]
1280         [MemberData(nameof(UnaryOperators))]
1281         [MemberData(nameof(BinaryOperators))]
1282         [MemberData(nameof(UnaryUnorderedOperators))]
1283         [MemberData(nameof(BinaryUnorderedOperators))]
ThenByDescending_OtherDirection_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1284         public static void ThenByDescending_OtherDirection_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1285         {
1286             int seen = DefaultStart + DefaultSize;
1287             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).OrderBy(x => 0).ThenByDescending(x => x).ToList(), x => Assert.Equal(--seen, x));
1288             Assert.Equal(DefaultStart, seen);
1289         }
1290 
1291         [Theory]
1292         [MemberData(nameof(UnaryOperators))]
1293         [MemberData(nameof(BinaryOperators))]
ToArray(Labeled<Operation> source, Labeled<Operation> operation)1294         public static void ToArray(Labeled<Operation> source, Labeled<Operation> operation)
1295         {
1296             int seen = DefaultStart;
1297             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).ToArray(), x => Assert.Equal(seen++, x));
1298             Assert.Equal(DefaultStart + DefaultSize, seen);
1299         }
1300 
1301         [Theory]
1302         [MemberData(nameof(UnaryOperations))]
1303         [MemberData(nameof(BinaryOperations))]
ToDictionary(Labeled<Operation> operation)1304         public static void ToDictionary(Labeled<Operation> operation)
1305         {
1306             IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize);
1307             Assert.All(operation.Item(DefaultStart, DefaultSize, DefaultSource).ToDictionary(x => x * 2),
1308                 p =>
1309                 {
1310                     seen.Add(p.Key / 2);
1311                     Assert.Equal(p.Key, p.Value * 2);
1312                 });
1313             seen.AssertComplete();
1314         }
1315 
1316         [Theory]
1317         [MemberData(nameof(UnaryOperations))]
1318         [MemberData(nameof(BinaryOperations))]
ToDictionary_ElementSelector(Labeled<Operation> operation)1319         public static void ToDictionary_ElementSelector(Labeled<Operation> operation)
1320         {
1321             IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize);
1322             Assert.All(operation.Item(DefaultStart, DefaultSize, DefaultSource).ToDictionary(x => x, y => y * 2),
1323                 p =>
1324                 {
1325                     seen.Add(p.Key);
1326                     Assert.Equal(p.Key * 2, p.Value);
1327                 });
1328             seen.AssertComplete();
1329         }
1330 
1331         [Theory]
1332         [MemberData(nameof(UnaryOperators))]
1333         [MemberData(nameof(BinaryOperators))]
ToList(Labeled<Operation> source, Labeled<Operation> operation)1334         public static void ToList(Labeled<Operation> source, Labeled<Operation> operation)
1335         {
1336             int seen = DefaultStart;
1337             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).ToList(), x => Assert.Equal(seen++, x));
1338             Assert.Equal(DefaultStart + DefaultSize, seen);
1339         }
1340 
1341         [Theory]
1342         [MemberData(nameof(UnaryOperators))]
1343         [MemberData(nameof(BinaryOperators))]
1344         [MemberData(nameof(UnaryUnorderedOperators))]
1345         [MemberData(nameof(BinaryUnorderedOperators))]
ToLookup(Labeled<Operation> source, Labeled<Operation> operation)1346         public static void ToLookup(Labeled<Operation> source, Labeled<Operation> operation)
1347         {
1348             IntegerRangeSet seenOuter = new IntegerRangeSet(0, 2);
1349             ILookup<int, int> lookup = operation.Item(DefaultStart, DefaultSize, source.Item).ToLookup(x => x % 2);
1350             Assert.All(lookup,
1351                 group =>
1352                 {
1353                     seenOuter.Add(group.Key);
1354                     IntegerRangeSet seenInner = new IntegerRangeSet(DefaultStart / 2, (DefaultSize + ((1 + group.Key) % 2)) / 2);
1355                     Assert.All(group, y => { Assert.Equal(group.Key, y % 2); seenInner.Add(y / 2); });
1356                     seenInner.AssertComplete();
1357                 });
1358             seenOuter.AssertComplete();
1359             Assert.Empty(lookup[-1]);
1360         }
1361 
1362         [Theory]
1363         [MemberData(nameof(UnaryOperators))]
1364         [MemberData(nameof(BinaryOperators))]
1365         [MemberData(nameof(UnaryUnorderedOperators))]
1366         [MemberData(nameof(BinaryUnorderedOperators))]
ToLookup_ElementSelector(Labeled<Operation> source, Labeled<Operation> operation)1367         public static void ToLookup_ElementSelector(Labeled<Operation> source, Labeled<Operation> operation)
1368         {
1369             IntegerRangeSet seenOuter = new IntegerRangeSet(0, 2);
1370             ILookup<int, int> lookup = operation.Item(DefaultStart, DefaultSize, source.Item).ToLookup(x => x % 2, y => -y);
1371             Assert.All(lookup,
1372                 group =>
1373                 {
1374                     seenOuter.Add(group.Key);
1375                     IntegerRangeSet seenInner = new IntegerRangeSet(DefaultStart / 2, (DefaultSize + ((1 + group.Key) % 2)) / 2);
1376                     Assert.All(group, y => { Assert.Equal(group.Key, -y % 2); seenInner.Add(-y / 2); });
1377                     seenInner.AssertComplete();
1378                 });
1379             seenOuter.AssertComplete();
1380             Assert.Empty(lookup[-1]);
1381         }
1382 
1383         [Theory]
1384         [MemberData(nameof(UnaryOperators))]
1385         [MemberData(nameof(BinaryOperators))]
Union(Labeled<Operation> source, Labeled<Operation> operation)1386         public static void Union(Labeled<Operation> source, Labeled<Operation> operation)
1387         {
1388             Action<Operation, Operation> union = (left, right) =>
1389             {
1390                 int seen = DefaultStart;
1391                 ParallelQuery<int> query = left(DefaultStart, DefaultSize * 3 / 4, source.Item)
1392                     .Union(right(DefaultStart + DefaultSize / 2, DefaultSize / 2, source.Item));
1393                 foreach (int i in query)
1394                 {
1395                     Assert.Equal(seen++, i);
1396                 }
1397                 Assert.Equal(DefaultStart + DefaultSize, seen);
1398             };
1399             union(operation.Item, LabeledDefaultSource.AsOrdered().Item);
1400             union(LabeledDefaultSource.AsOrdered().Item, operation.Item);
1401         }
1402 
1403         [Theory]
1404         [MemberData(nameof(UnaryOperators))]
1405         [MemberData(nameof(BinaryOperators))]
Union_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1406         public static void Union_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1407         {
1408             Action<Operation, Operation> union = (left, right) =>
1409             {
1410                 int seen = DefaultStart;
1411                 ParallelQuery<int> query = left(DefaultStart, DefaultSize * 3 / 4, source.Item)
1412                     .Union(right(DefaultStart + DefaultSize / 2, DefaultSize / 2, source.Item));
1413                 Assert.All(query.ToList(), x => Assert.Equal(seen++, x));
1414                 Assert.Equal(DefaultStart + DefaultSize, seen);
1415             };
1416             union(operation.Item, LabeledDefaultSource.AsOrdered().Item);
1417             union(LabeledDefaultSource.AsOrdered().Item, operation.Item);
1418         }
1419 
1420         [Theory]
1421         [MemberData(nameof(UnaryOperators))]
1422         [MemberData(nameof(BinaryOperators))]
Where(Labeled<Operation> source, Labeled<Operation> operation)1423         public static void Where(Labeled<Operation> source, Labeled<Operation> operation)
1424         {
1425             int seen = DefaultStart;
1426             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).Where(x => x < DefaultStart + DefaultSize / 2))
1427             {
1428                 Assert.Equal(seen++, i);
1429             }
1430             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1431         }
1432 
1433         [Theory]
1434         [MemberData(nameof(UnaryOperators))]
1435         [MemberData(nameof(BinaryOperators))]
Where_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1436         public static void Where_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1437         {
1438             int seen = DefaultStart;
1439             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).Where(x => x < DefaultStart + DefaultSize / 2).ToList(), x => Assert.Equal(seen++, x));
1440             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1441         }
1442 
1443         [Theory]
1444         [MemberData(nameof(UnaryOperators))]
1445         [MemberData(nameof(BinaryOperators))]
Where_Indexed(Labeled<Operation> source, Labeled<Operation> operation)1446         public static void Where_Indexed(Labeled<Operation> source, Labeled<Operation> operation)
1447         {
1448             int seen = DefaultStart;
1449             foreach (int i in operation.Item(DefaultStart, DefaultSize, source.Item).Where((x, index) => index < DefaultSize / 2))
1450             {
1451                 Assert.Equal(seen++, i);
1452             }
1453             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1454         }
1455 
1456         [Theory]
1457         [MemberData(nameof(UnaryOperators))]
1458         [MemberData(nameof(BinaryOperators))]
Where_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1459         public static void Where_Indexed_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1460         {
1461             int seen = DefaultStart;
1462             Assert.All(operation.Item(DefaultStart, DefaultSize, source.Item).Where((x, index) => index < DefaultSize / 2).ToList(), x => Assert.Equal(seen++, x));
1463             Assert.Equal(DefaultStart + DefaultSize / 2, seen);
1464         }
1465 
1466         [Theory]
1467         [MemberData(nameof(UnaryOperators))]
1468         [MemberData(nameof(BinaryOperators))]
Zip(Labeled<Operation> source, Labeled<Operation> operation)1469         public static void Zip(Labeled<Operation> source, Labeled<Operation> operation)
1470         {
1471             Action<Operation, Operation> zip = (left, right) =>
1472             {
1473                 int seen = DefaultStart;
1474                 ParallelQuery<int> query = left(DefaultStart * 2, DefaultSize, source.Item)
1475                     .Zip(right(0, DefaultSize, source.Item), (x, y) => (x + y) / 2);
1476                 foreach (int i in query)
1477                 {
1478                     Assert.Equal(seen++, i);
1479                 }
1480                 Assert.Equal(DefaultStart + DefaultSize, seen);
1481             };
1482             zip(operation.Item, LabeledDefaultSource.AsOrdered().Item);
1483             zip(LabeledDefaultSource.AsOrdered().Item, operation.Item);
1484         }
1485 
1486         [Theory]
1487         [MemberData(nameof(UnaryOperators))]
1488         [MemberData(nameof(BinaryOperators))]
Zip_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)1489         public static void Zip_NotPipelined(Labeled<Operation> source, Labeled<Operation> operation)
1490         {
1491             Action<Operation, Operation> zip = (left, right) =>
1492             {
1493                 int seen = DefaultStart;
1494                 ParallelQuery<int> query = left(DefaultStart * 2, DefaultSize, source.Item)
1495                     .Zip(right(0, DefaultSize, source.Item), (x, y) => (x + y) / 2);
1496                 Assert.All(query.ToList(), x => Assert.Equal(seen++, x));
1497                 Assert.Equal(DefaultStart + DefaultSize, seen);
1498             };
1499             zip(operation.Item, LabeledDefaultSource.AsOrdered().Item);
1500             zip(LabeledDefaultSource.AsOrdered().Item, operation.Item);
1501         }
1502     }
1503 }
1504