Add bigger unit test for Intersect and Union
[mono.git] / mcs / class / System.Core / Test / System.Linq / ParallelEnumerableTests.cs
1 // ParallelEnumerableTests.cs
2 //
3 // Copyright (c) 2008 Jérémie "Garuma" Laval
4 //
5 // Based on Enumerable test suite by Jb Evain (jbevain@novell.com)
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 // THE SOFTWARE.
24 //
25 //
26
27 #if NET_4_0
28
29 using System;
30 using System.Threading;
31 using System.Linq;
32
33 using System.Collections;
34 using System.Collections.Generic;
35
36 using NUnit.Framework;
37
38 namespace MonoTests.System.Linq
39 {
40         internal static class AsParallelHelper
41         {
42                 internal static ParallelQuery<T> AsReallyParallel<T> (this IEnumerable<T> source)
43                 {
44                         return source.AsParallel ().WithExecutionMode (ParallelExecutionMode.ForceParallelism);
45                 }
46         }
47
48         [TestFixtureAttribute]
49         public class ParallelEnumerableTests
50         {
51                 IEnumerable<int> baseEnumerable;
52                 
53                 [SetUpAttribute]
54                 public void Setup ()
55                 {
56                         baseEnumerable = Enumerable.Range(1, 10000);
57                 }
58                 
59                 void AreEquivalent (IEnumerable<int> syncEnumerable, IEnumerable<int> asyncEnumerable, int count)
60                 {
61                         int[] sync  = Enumerable.ToArray(syncEnumerable);
62                         int[] async = Enumerable.ToArray(asyncEnumerable);
63                         
64                         // This is not AreEquals because ParallelQuery is non-deterministic (IParallelOrderedEnumerable is)
65                         // thus the order of the initial Enumerable might not be preserved
66                         CollectionAssert.AreEquivalent(sync, async, "#" + count);
67                 }
68                 
69                 void AreEquivalent<T> (IEnumerable<T> syncEnumerable, IEnumerable<T> asyncEnumerable, int count)
70                 {
71                         T[] sync  = Enumerable.ToArray(syncEnumerable);
72                         T[] async = Enumerable.ToArray(asyncEnumerable);
73                         
74                         // This is not AreEquals because ParallelQuery is non-deterministic (IParallelOrderedEnumerable is)
75                         // thus the order of the initial Enumerable might not be preserved
76                         CollectionAssert.AreEquivalent(sync, async, "#" + count);
77                 }
78                 
79                 static void AssertAreSame<T> (IEnumerable<T> expected, IEnumerable<T> actual)
80                 {
81                         if (expected == null) {
82                                 Assert.IsNull (actual);
83                                 return;
84                         }
85
86                         Assert.IsNotNull (actual);
87                         int index = -1;
88
89                         IEnumerator<T> ee = expected.GetEnumerator ();
90                         IEnumerator<T> ea = actual.GetEnumerator ();
91
92                         while (ee.MoveNext ()) {
93                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected at index '"+ ++index + "'.");
94                                 Assert.AreEqual (ee.Current, ea.Current, "at index '" + index + "'");
95                         }
96
97                         if (ea.MoveNext ())
98                                 Assert.Fail ("Unexpected element: " + ea.Current);
99                 }
100                 
101                 public static void AssertException<T> (Action action) where T : Exception
102                 {
103                         try {
104                                 action ();
105                         }
106                         catch (T) {
107                                 return;
108                         }
109                         Assert.Fail ("Expected: " + typeof (T).Name);
110                 }
111
112                 static void AssertAreSame<K, V> (K expectedKey, IEnumerable<V> expectedValues, IGrouping<K, V> actual)
113                 {
114                         if (expectedValues == null) {
115                                 Assert.IsNull (actual);
116                                 return;
117                         }
118
119                         Assert.IsNotNull (actual);
120
121                         Assert.AreEqual (expectedKey, actual.Key);
122
123                         var ee = expectedValues.GetEnumerator ();
124                         var ea = actual.GetEnumerator ();
125
126                         while (ee.MoveNext ()) {
127                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected.");
128                                 Assert.AreEqual (ee.Current, ea.Current);
129                         }
130
131                         if (ea.MoveNext ())
132                                 Assert.Fail ("Unexpected element: " + ee.Current);
133                 }
134
135                 static void AssertAreSame<K, V> (IDictionary<K, IEnumerable<V>> expected, IEnumerable<IGrouping<K, V>> actual)
136                 {
137                         if (expected == null) {
138                                 Assert.IsNull (actual);
139                                 return;
140                         }
141
142                         Assert.IsNotNull (actual);
143
144                         var ee = expected.GetEnumerator ();
145                         var ea = actual.GetEnumerator ();
146
147                         while (ee.MoveNext ()) {
148                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + "' expected.");
149                                 AssertAreSame (ee.Current.Key, ee.Current.Value, ea.Current);
150                         }
151
152                         if (ea.MoveNext ())
153                                 Assert.Fail ("Unexpected element: " + ee.Current.Key);
154                 }
155
156                 static void AssertAreSame<K, V> (IDictionary<K, IEnumerable<V>> expected, ILookup<K, V> actual)
157                 {
158                         if (expected == null) {
159                                 Assert.IsNull (actual);
160                                 return;
161                         }
162
163                         Assert.IsNotNull (actual);
164
165                         var ee = expected.GetEnumerator ();
166                         var ea = actual.GetEnumerator ();
167
168                         while (ee.MoveNext ()) {
169                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + "' expected.");
170                                 AssertAreSame (ee.Current.Key, ee.Current.Value, ea.Current);
171                         }
172
173                         if (ea.MoveNext ())
174                                 Assert.Fail ("Unexpected element: " + ee.Current.Key);
175                 }
176
177                 static void AssertAreSame<K, V> (IDictionary<K, V> expected, IDictionary<K, V> actual)
178                 {
179                         if (expected == null) {
180                                 Assert.IsNull (actual);
181                                 return;
182                         }
183
184                         Assert.IsNotNull (actual);
185
186                         var ee = expected.GetEnumerator ();
187                         var ea = actual.GetEnumerator ();
188
189                         while (ee.MoveNext ()) {
190                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + ", " + ee.Current.Value + "' expected.");
191                                 Assert.AreEqual (ee.Current.Key, ea.Current.Key);
192                                 Assert.AreEqual (ee.Current.Value, ea.Current.Value);
193                         }
194
195                         if (ea.MoveNext ())
196                                 Assert.Fail ("Unexpected element: " + ee.Current.Key + ", " + ee.Current.Value);
197                 }
198
199                 [Test]
200                 public void SelectTestCase ()
201                 {
202                         ParallelTestHelper.Repeat (() => {
203                                 IEnumerable<int> sync  = baseEnumerable.Select (i => i * i);
204                                 IEnumerable<int> async = baseEnumerable.AsParallel ().Select (i => i * i);
205                                 
206                                 AreEquivalent(sync, async, 1);
207                         });
208                 }
209                         
210                 [Test]
211                 public void WhereTestCase ()
212                 {
213                         ParallelTestHelper.Repeat (() => {
214                                 IEnumerable<int> sync  = baseEnumerable.Where(i => i % 2 == 0);
215                                 IEnumerable<int> async = baseEnumerable.AsParallel().Where(i => i % 2 == 0);
216                                 
217                                 AreEquivalent(sync, async, 1);
218                         });
219                 }
220                 
221                 [Test]
222                 public void CountTestCase ()
223                 {
224                         ParallelTestHelper.Repeat (() => {
225                                 int sync  = baseEnumerable.Count();
226                                 int async = baseEnumerable.AsParallel().Count();
227                                 
228                                 Assert.AreEqual(sync, async, "#1");
229                         });
230                 }
231                 
232                 [Test]
233                 public void AggregateTestCase ()
234                 {
235                         ParallelTestHelper.Repeat (() => {
236                                 ParallelQuery<int> range = ParallelEnumerable.Repeat (5, 2643);
237                                 double average = range.Aggregate(() => new double[2],
238                                                                  (acc, elem) => { acc[0] += elem; acc[1]++; return acc; },
239                                 (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; },
240                                 acc => acc[0] / acc[1]);
241                                 
242                                 Assert.AreEqual(5.0, average, "#1");
243                         });
244                 }
245                 
246                 [Test]
247                 public void TestSimpleExcept ()
248                 {
249                         ParallelTestHelper.Repeat (() => {
250                                 int [] first = {0, 1, 2, 3, 4, 5};
251                                 int [] second = {2, 4, 6};
252                                 int [] result = {0, 1, 3, 5};
253         
254                                 AreEquivalent (result, first.AsReallyParallel ().Except (second.AsParallel ()), 1);
255                         });
256                 }
257
258                 [Test]
259                 public void TestSimpleIntersect ()
260                 {
261                         ParallelTestHelper.Repeat (() => {
262                                 int [] first = {0, 1, 2, 3, 4, 5};
263                                 int [] second = {2, 4, 6};
264                                 int [] result = {2, 4};
265         
266                                 AreEquivalent (result, first.AsReallyParallel ().Intersect (second.AsParallel ()), 1);
267                         });
268                 }
269
270                 [Test]
271                 public void TestSimpleUnion ()
272                 {
273                         ParallelTestHelper.Repeat (() => {
274                                 int [] first = {0, 1, 2, 3, 4, 5};
275                                 int [] second = {2, 4, 6};
276                                 int [] result = {0, 1, 2, 3, 4, 5, 6};
277                                 
278                                 AreEquivalent (result, first.AsReallyParallel ().Union (second.AsParallel ()), 1);
279                         });
280                 }
281
282                 [Test]
283                 public void TestBigUnion ()
284                 {
285                         ParallelTestHelper.Repeat (() => {
286                                 int [] first = Enumerable.Range (1, 10000).ToArray ();
287                                 int [] second = Enumerable.Range (323, 757).ToArray ();
288
289                                 AreEquivalent (first, first.AsReallyParallel ().Union (second.AsParallel ()), 1);
290                         }, 10);
291                 }
292
293                 [Test]
294                 public void TestBigIntersect ()
295                 {
296                         ParallelTestHelper.Repeat (() => {
297                                 int [] first = Enumerable.Range (1, 10000).ToArray ();
298                                 int [] second = Enumerable.Range (323, 757).ToArray ();
299
300                                 AreEquivalent (second, first.AsReallyParallel ().Intersect (second.AsParallel ()), 1);
301                         }, 10);
302                 }
303                 
304                 class Foo {}
305                 class Bar : Foo {}
306
307                 [Test]
308                 public void TestCast ()
309                 {
310                         Bar a = new Bar ();
311                         Bar b = new Bar ();
312                         Bar c = new Bar ();
313
314                         Foo [] foos = new Foo [] {a, b, c};
315                         Bar [] result = new Bar [] {a, b, c};
316
317                         AreEquivalent (result, foos.AsReallyParallel ().Cast<Bar> (), 1);
318                 }
319                 
320                 [Test]
321                 public void TestSkip ()
322                 {
323                         int [] data = {0, 1, 2, 3, 4, 5};
324                         int [] result = {3, 4, 5};
325
326                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Skip (3).ToArray ());
327                 }
328                 
329                 [Test]
330                 public void TestSkipIterating ()
331                 {
332                         int [] data = {0, 1, 2, 3, 4, 5};
333                         int [] result = {3, 4, 5};
334
335                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Skip (3));
336                 }
337
338                 [Test]
339                 public void TestSkipWhile ()
340                 {
341                         int [] data = {0, 1, 2, 3, 4, 5};
342                         int [] result = {3, 4, 5};
343
344                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().SkipWhile (i => i < 3));
345                 }
346
347                 [Test]
348                 public void TestTake ()
349                 {
350                         int [] data = {0, 1, 2, 3, 4, 5};
351                         int [] result = {0, 1, 2};
352
353                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Take (3));
354                 }
355
356                 [Test]
357                 public void TestTakeWhile ()
358                 {
359                         int [] data = {0, 1, 2, 3, 4, 5};
360                         int [] result = {0, 1, 2};
361
362                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().TakeWhile (i => i < 3));
363                 }
364
365                 [Test]
366                 public void SelectManyTest ()
367                 {
368                         IEnumerable<int> initial = Enumerable.Range (1, 50);
369                         IEnumerable<int> expected = initial.SelectMany ((i) => Enumerable.Range (1, i));
370
371                         ParallelTestHelper.Repeat (() => {
372                                         var actual = initial.AsReallyParallel ().SelectMany ((i) => Enumerable.Range (1, i));
373                                         AreEquivalent (expected, actual, 1);
374                                 });
375                 }
376
377                 [Test]
378                 public void SelectManyOrderedTest ()
379                 {
380                         IEnumerable<int> initial = Enumerable.Range (1, 50);
381                         IEnumerable<int> expected = initial.SelectMany ((i) => Enumerable.Range (1, i));
382
383                         ParallelTestHelper.Repeat (() => {
384                                         var actual = initial.AsReallyParallel ().AsOrdered ().SelectMany ((i) => Enumerable.Range (1, i));
385                                         AssertAreSame (expected, actual);
386                                 });
387                 }
388                 
389                 [Test]
390                 public void TestLast ()
391                 {
392                         int [] data = {1, 2, 3};
393
394                         Assert.AreEqual (3, data.AsReallyParallel ().AsOrdered ().Last ());
395                 }
396
397                 [Test]
398                 public void TestLastOrDefault ()
399                 {
400                         int [] data = {};
401
402                         Assert.AreEqual (default (int), data.AsReallyParallel ().AsOrdered ().LastOrDefault ());
403                 }
404
405                 [Test]
406                 public void TestFirst ()
407                 {
408                         int [] data = {1, 2, 3};
409
410                         Assert.AreEqual (1, data.AsReallyParallel ().AsOrdered ().First ());
411                 }
412
413                 [Test]
414                 public void TestFirstOrDefault ()
415                 {
416                         int [] data = {};
417
418                         Assert.AreEqual (default (int), data.AsReallyParallel ().AsOrdered ().FirstOrDefault ());
419                 }
420                 
421                 [Test]
422                 public void TestReverse ()
423                 {
424                         int [] data = {0, 1, 2, 3, 4};
425                         int [] result = {4, 3, 2, 1, 0};
426
427                         AssertAreSame (result, ((IEnumerable<int>)data).Select ((i) => i).AsReallyParallel ().AsOrdered ().Reverse ());
428                         AssertAreSame (result, ParallelEnumerable.Range (0, 5).WithExecutionMode (ParallelExecutionMode.ForceParallelism).AsOrdered ().Reverse ());
429                 }
430                 
431                 [Test]
432                 public void TestOrderBy ()
433                 {
434                         ParallelTestHelper.Repeat (() => {
435                                 int [] array = { 14, 53, 3, 9, 11, 14, 5, 32, 2 };
436                                 
437                                 var q = array.AsReallyParallel ().OrderBy ((i) => i);
438                                 AssertIsOrdered (q, array.Length);
439                         });
440                 }
441
442                 class Baz {
443                         string name;
444                         int age;
445
446                         public string Name
447                         {
448                                 get {
449                                         if (string.IsNullOrEmpty (name))
450                                                 return Age.ToString ();
451
452                                         return name + " (" + Age + ")";
453                                 }
454                         }
455
456                         public int Age
457                         {
458                                 get { return age + 1; }
459                         }
460
461                         public Baz (string name, int age)
462                         {
463                                 this.name = name;
464                                 this.age = age;
465                         }
466
467                         public override int GetHashCode ()
468                         {
469                                 return this.Age ^ this.Name.GetHashCode ();
470                         }
471
472                         public override bool Equals (object obj)
473                         {
474                                 Baz b = obj as Baz;
475                                 if (b == null)
476                                         return false;
477
478                                 return b.Age == this.Age && b.Name == this.Name;
479                         }
480
481                         public override string ToString ()
482                         {
483                                 return this.Name;
484                         }
485                 }
486
487                 static IEnumerable<Baz> CreateBazCollection ()
488                 {
489                         return new [] {
490                                 new Baz ("jb", 25),
491                                 new Baz ("ana", 20),
492                                 new Baz ("reg", 28),
493                                 new Baz ("ro", 25),
494                                 new Baz ("jb", 7),
495                         };
496                 }
497
498                 [Test]
499                 public void TestOrderByAgeAscendingTheByNameDescending ()
500                 {
501                         ParallelTestHelper.Repeat (() => {
502                                 var q = from b in CreateBazCollection ().AsReallyParallel ()
503                                                 orderby b.Age ascending, b.Name descending
504                                                 select b;
505         
506                                 var expected = new [] {
507                                         new Baz ("jb", 7),
508                                         new Baz ("ana", 20),
509                                         new Baz ("ro", 25),
510                                         new Baz ("jb", 25),
511                                         new Baz ("reg", 28),
512                                 };
513
514                                 AssertAreSame (expected, q);
515                         });
516                 }
517
518                 class Data {
519                         public int ID { get; set; }
520                         public string Name { get; set; }
521
522                         public override string ToString ()
523                         {
524                                 return ID + " " + Name;
525                         }
526                 }
527
528                 IEnumerable<Data> CreateData ()
529                 {
530                         return new [] {
531                                 new Data { ID = 10, Name = "bcd" },
532                                 new Data { ID = 20, Name = "Abcd" },
533                                 new Data { ID = 20, Name = "Ab" },
534                                 new Data { ID = 10, Name = "Zyx" },
535                         };
536                 }
537
538                 [Test]
539                 public void TestOrderByIdDescendingThenByNameAscending ()
540                 {
541                         ParallelTestHelper.Repeat (() => {
542                                 var q = from d in CreateData ().AsReallyParallel ()
543                                         orderby d.ID descending, d.Name ascending
544                                                 select d;
545                                 
546                                 var list = new List<Data> (q);
547                                 
548                                 Assert.AreEqual ("Ab", list [0].Name);
549                                 Assert.AreEqual ("Abcd", list [1].Name);
550                                 Assert.AreEqual ("bcd", list [2].Name);
551                                 Assert.AreEqual ("Zyx", list [3].Name);
552                         });
553                 }
554
555                 static void AssertIsOrdered (IEnumerable<int> e, int count)
556                 {
557                         int f = int.MinValue;
558                         int c = 0;
559                         
560                         foreach (int i in e) {
561                                 Assert.IsTrue (f <= i, string.Format ("{0} <= {1}", f, i));
562                                 f = i;
563                                 c++;
564                         }
565                         
566                         Assert.AreEqual (count, c);
567                 }
568                 
569                 
570                 [TestAttribute]
571                 public void ElementAtTestCase()
572                 {
573                         //ParallelTestHelper.Repeat (() => {
574                                         Assert.AreEqual(1, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(0), "#1");
575                                         Assert.AreEqual(51, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(50), "#2");
576                                         Assert.AreEqual(489, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(488), "#3");
577                         //});
578                 }
579
580                 [Test]
581                 public void TestJoin ()
582                 {
583                         int num = 100;
584                         Tuple<int, int>[] outer = Enumerable.Range (1, 50).Select ((i) => Tuple.Create (i, num - 2 * i)).ToArray ();
585                         Tuple<int, int>[] inner = Enumerable.Range (1, 50).Reverse ().Select ((i) => Tuple.Create (i, 2 * i)).ToArray ();
586
587                         IEnumerable<int> expected = outer.Join (inner, (e) => e.Item1, (e) => e.Item1, (e1, e2) => e1.Item2 + e2.Item2, EqualityComparer<int>.Default);
588
589                         ParallelTestHelper.Repeat (() => {
590                                         ParallelQuery<int> actual = outer.AsReallyParallel ().Join (inner.AsParallel (), (e) => e.Item1, (e) => e.Item1, (e1, e2) => e1.Item2 + e2.Item2, EqualityComparer<int>.Default);
591
592                                         AreEquivalent (expected, actual, 1);
593                                 });
594                 }
595
596                 [Test]
597                 public void TestGroupBy ()
598                 {
599                         int num = 100;
600                         Tuple<int, int>[] source = Enumerable.Range (0, num).Select ((i) => Tuple.Create (i / 10, i)).ToArray ();
601
602                         ParallelTestHelper.Repeat (() => {
603                                         ParallelQuery<IGrouping<int, int>> actual = source.AsReallyParallel ().GroupBy ((e) => e.Item1, (e) => e.Item2, EqualityComparer<int>.Default);
604
605                                         foreach (var group in actual) {
606                                                 Assert.GreaterOrEqual (group.Key, 0);
607                                                 Assert.Less (group.Key, num / 10);
608
609                                                 int count = 0;
610                                                 foreach (var e in group) {
611                                                         count++;
612                                                         Assert.GreaterOrEqual (e, group.Key * 10);
613                                                         Assert.Less (e, (group.Key + 1) * 10);
614                                                 }
615
616                                                 Assert.AreEqual (10, count, "count");
617                                         }
618                                 });
619                 }
620                 
621                 [TestAttribute]
622                 public void TakeTestCase()
623                 {
624                         ParallelTestHelper.Repeat (() => {
625                                         ParallelQuery<int> async = baseEnumerable.AsReallyParallel ().AsOrdered ().Take(2000);
626                                         IEnumerable<int> sync = baseEnumerable.Take(2000);
627
628                                         AreEquivalent(sync, async, 1);
629
630                                         async = baseEnumerable.AsReallyParallel ().AsOrdered ().Take(100);
631                                         sync = baseEnumerable.Take(100);
632
633                                         AreEquivalent(sync, async, 2);
634                                 }, 20);
635                 }
636
637                 [TestAttribute]
638                 public void UnorderedTakeTestCase()
639                 {
640                         ParallelTestHelper.Repeat (() => {
641                                         ParallelQuery<int> async = baseEnumerable.AsReallyParallel ().Take(2000);
642                                         IEnumerable<int> sync = baseEnumerable.Take (2000);
643
644                                         Assert.AreEqual (sync.Count (), async.Count (), "#1");
645
646                                         async = baseEnumerable.AsReallyParallel ().Take(100);
647                                         sync = baseEnumerable.Take(100);
648
649                                         Assert.AreEqual (sync.Count (), async.Count (), "#2");
650                                 }, 20);
651                 }
652                 
653                 [Test]
654                 public void SkipTestCase()
655                 {
656                         ParallelTestHelper.Repeat (() => {
657                                 ParallelQuery<int> async = baseEnumerable.AsReallyParallel ().AsOrdered().Skip(2000);
658                                 IEnumerable<int> sync = baseEnumerable.Skip(2000);
659                                 
660                                 AreEquivalent(sync, async, 1);
661                         }, 20);
662                 }
663
664                 [Test]
665                 public void SkipTestCaseSmall ()
666                 {
667                         ParallelTestHelper.Repeat (() => {
668                                 var async = baseEnumerable.AsReallyParallel ().Skip(100);
669                                 var sync = baseEnumerable.Skip(100);
670                                 
671                                 Assert.AreEqual (sync.Count (), async.Count ());
672                         }, 20);
673                 }
674
675                 [Test]
676                 public void ZipTestCase()
677                 {
678                         ParallelTestHelper.Repeat (() => {
679                                 ParallelQuery<int> async1 = ParallelEnumerable.Range(0, 10000);
680                                 ParallelQuery<int> async2 = ParallelEnumerable.Repeat(1, 10000).Zip(async1, (e1, e2) => e1 + e2);
681                                 
682                                 int[] expected = Enumerable.Range (1, 10000).ToArray ();
683                                 CollectionAssert.AreEquivalent(expected, Enumerable.ToArray (async2), "#1");
684                         });
685                 }
686                 
687                 [Test]
688                 public void RangeTestCase ()
689                 {
690                         ParallelTestHelper.Repeat (() => {
691                                 IEnumerable<int> sync  = Enumerable.Range(1, 1000);
692                                 IEnumerable<int> async = ParallelEnumerable.Range(1, 1000);
693                                 
694                                 AreEquivalent (sync, async, 1);
695                         });
696                 }
697                 
698                 [Test]
699                 public void RepeatTestCase ()
700                 {
701                         ParallelTestHelper.Repeat (() => {
702                                 IEnumerable<int> sync  = Enumerable.Repeat(1, 1000);
703                                 IEnumerable<int> async = ParallelEnumerable.Repeat(1, 1000);
704                                 
705                                 AreEquivalent (sync, async, 1);
706                         });
707                 }
708                 
709                 [Test]
710                 public void TestSum ()
711                 {
712                         int [] data = {1, 2, 3, 4};
713
714                         Assert.AreEqual (10, data.AsReallyParallel ().Sum ());
715                 }
716
717                 [Test]
718                 public void SumOnEmpty ()
719                 {
720                         int [] data = {};
721
722                         Assert.AreEqual (0, data.AsReallyParallel ().Sum ());
723                 }
724
725                 [Test]
726                 public void TestMax ()
727                 {
728                         int [] data = {1, 3, 5, 2};
729
730                         Assert.AreEqual (5, data.AsReallyParallel ().Max ());
731                 }
732
733                 [Test]
734                 public void TestMin ()
735                 {
736                         int [] data = {3, 5, 2, 6, 1, 7};
737
738                         Assert.AreEqual (1, data.AsReallyParallel ().Min ());
739                 }
740                 
741                 [Test]
742                 public void TestToListOrdered ()
743                 {
744                         int [] data = { 2, 3, 5 };
745
746                         var list = data.AsParallel().AsOrdered().WithExecutionMode (ParallelExecutionMode.ForceParallelism).ToList ();
747
748                         AssertAreSame (data, list);
749                         AssertIsOrdered (list, data.Length);
750
751                         Assert.AreEqual (typeof (List<int>), list.GetType ());
752                 }
753
754                 [Test]
755                 public void TestToArrayOrdered ()
756                 {
757                         ICollection<int> coll = new List<int> ();
758                         coll.Add (0);
759                         coll.Add (1);
760                         coll.Add (2);
761
762                         int [] result = {0, 1, 2};
763
764                         var array = coll.AsReallyParallel ().AsOrdered().ToArray ();
765
766                         AssertAreSame (result, array);
767                         AssertIsOrdered (array, result.Length);
768
769                         Assert.AreEqual (typeof (int []), array.GetType ());
770
771                         array = Enumerable.Range (1, 100).Select ((i) => i).AsReallyParallel ().AsOrdered().ToArray ();
772                         result = Enumerable.Range (1, 100).ToArray ();
773
774                         AssertAreSame (result, array);
775                         AssertIsOrdered (array, result.Length);
776
777                         Assert.AreEqual (typeof (int []), array.GetType ());
778
779                 }
780
781                 [Test]
782                 public void TestToList ()
783                 {
784                         int [] data = {3, 5, 2};
785
786                         var list = data.AsReallyParallel ().ToList ();
787
788                         CollectionAssert.AreEquivalent (data, list);
789
790                         Assert.AreEqual (typeof (List<int>), list.GetType ());
791                 }
792
793                 [Test]
794                 public void TestToArray ()
795                 {
796                         ICollection<int> coll = new List<int> ();
797                         coll.Add (0);
798                         coll.Add (1);
799                         coll.Add (2);
800
801                         int [] result = {0, 1, 2};
802
803                         var array = coll.AsReallyParallel ().ToArray ();
804
805                         CollectionAssert.AreEquivalent (result, array);
806
807                         Assert.AreEqual (typeof (int []), array.GetType ());
808                 }
809                 
810                 
811                 [Test]
812                 public void TestAverageOnInt32 ()
813                 {
814                         Assert.AreEqual (23.25, (new int [] { 24, 7, 28, 34 }).Average ());
815                 }
816
817                 [Test]
818                 public void TestAverageOnInt64 ()
819                 {
820                         Assert.AreEqual (23.25, (new long [] { 24, 7, 28, 34 }).Average ());
821                 }
822                 
823                 
824                 [Test]
825                 public void AnyArgumentNullTest ()
826                 {
827                         string [] data = { "2", "1", "5", "3", "4" };
828
829
830                         // Any<TSource> ()
831                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().Any (); });
832
833                         // Any<TSource> (Func<TSource, bool>)
834                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().Any (x => true); });
835                         AssertException<ArgumentNullException> (delegate () { data.AsReallyParallel ().Any ((Func<string, bool>) null); });
836                 }
837
838                 [Test]
839                 public void AnyTest ()
840                 {
841                         int [] data = { 5, 2, 3, 1, 6 };
842                         int [] empty = { };
843
844
845                         // Any<TSource> ()
846                         Assert.IsTrue (data.AsReallyParallel ().Any ());
847                         Assert.IsFalse (empty.AsReallyParallel ().Any ());
848
849                         // Any<TSource> (Func<TSource, bool>)
850                         Assert.IsTrue (data.AsReallyParallel ().Any (x => x == 5));
851                         Assert.IsFalse (data.AsReallyParallel ().Any (x => x == 9));
852                         Assert.IsFalse (empty.AsReallyParallel ().Any (x => true));
853                 }
854
855                 
856                 [Test]
857                 public void AllArgumentNullTest ()
858                 {
859                         string [] data = { "2", "1", "5", "3", "4" };
860
861                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().All (x => true); });
862                         AssertException<ArgumentNullException> (delegate () { data.AsReallyParallel ().All ((Func<string, bool>) null); });
863                 }
864
865                 [Test]
866                 public void AllTest ()
867                 {
868                         int [] data = { 5, 2, 3, 1, 6 };
869                         int [] empty = { };
870
871                         Assert.IsTrue (data.AsReallyParallel ().All (x => true));
872                         Assert.IsFalse (data.AsReallyParallel ().All (x => x != 1));
873                         Assert.IsTrue (empty.AsReallyParallel ().All (x => false));
874                 }
875         }
876 }
877
878 #endif