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