Improved support for TimeZoneInfo under windows.
[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, 1000);
57                 }
58
59                 static void AreEquivalent (IEnumerable syncEnumerable, IEnumerable async_resEnumerable)
60                 {
61                         Assert.That (async_resEnumerable, new NUnit.Framework.Constraints.CollectionEquivalentConstraint (syncEnumerable));
62                 }
63                 
64                 static void AssertAreSame<T> (IEnumerable<T> expected, IEnumerable<T> actual)
65                 {
66                         if (expected == null) {
67                                 Assert.IsNull (actual);
68                                 return;
69                         }
70
71                         Assert.IsNotNull (actual);
72                         int index = -1;
73
74                         IEnumerator<T> ee = expected.GetEnumerator ();
75                         IEnumerator<T> ea = actual.GetEnumerator ();
76
77                         while (ee.MoveNext ()) {
78                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected at index '"+ ++index + "'.");
79                                 Assert.AreEqual (ee.Current, ea.Current, "at index '" + index + "'");
80                         }
81
82                         if (ea.MoveNext ())
83                                 Assert.Fail ("Unexpected element: " + ea.Current);
84                 }
85                 
86                 public static void AssertException<T> (Action action) where T : Exception
87                 {
88                         try {
89                                 action ();
90                         }
91                         catch (T) {
92                                 return;
93                         }
94                         Assert.Fail ("Expected: " + typeof (T).Name);
95                 }
96
97                 static void AssertAreSame<K, V> (K expectedKey, IEnumerable<V> expectedValues, IGrouping<K, V> actual)
98                 {
99                         if (expectedValues == null) {
100                                 Assert.IsNull (actual);
101                                 return;
102                         }
103
104                         Assert.IsNotNull (actual);
105
106                         Assert.AreEqual (expectedKey, actual.Key);
107
108                         var ee = expectedValues.GetEnumerator ();
109                         var ea = actual.GetEnumerator ();
110
111                         while (ee.MoveNext ()) {
112                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected.");
113                                 Assert.AreEqual (ee.Current, ea.Current);
114                         }
115
116                         if (ea.MoveNext ())
117                                 Assert.Fail ("Unexpected element: " + ee.Current);
118                 }
119
120                 static void AssertAreSame<K, V> (IDictionary<K, IEnumerable<V>> expected, IEnumerable<IGrouping<K, V>> actual)
121                 {
122                         if (expected == null) {
123                                 Assert.IsNull (actual);
124                                 return;
125                         }
126
127                         Assert.IsNotNull (actual);
128
129                         var ee = expected.GetEnumerator ();
130                         var ea = actual.GetEnumerator ();
131
132                         while (ee.MoveNext ()) {
133                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + "' expected.");
134                                 AssertAreSame (ee.Current.Key, ee.Current.Value, ea.Current);
135                         }
136
137                         if (ea.MoveNext ())
138                                 Assert.Fail ("Unexpected element: " + ee.Current.Key);
139                 }
140
141                 static void AssertAreSame<K, V> (IDictionary<K, IEnumerable<V>> expected, ILookup<K, V> actual)
142                 {
143                         if (expected == null) {
144                                 Assert.IsNull (actual);
145                                 return;
146                         }
147
148                         Assert.IsNotNull (actual);
149
150                         var ee = expected.GetEnumerator ();
151                         var ea = actual.GetEnumerator ();
152
153                         while (ee.MoveNext ()) {
154                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + "' expected.");
155                                 AssertAreSame (ee.Current.Key, ee.Current.Value, ea.Current);
156                         }
157
158                         if (ea.MoveNext ())
159                                 Assert.Fail ("Unexpected element: " + ee.Current.Key);
160                 }
161
162                 static void AssertAreSame<K, V> (IDictionary<K, V> expected, IDictionary<K, V> actual)
163                 {
164                         if (expected == null) {
165                                 Assert.IsNull (actual);
166                                 return;
167                         }
168
169                         Assert.IsNotNull (actual);
170
171                         var ee = expected.GetEnumerator ();
172                         var ea = actual.GetEnumerator ();
173
174                         while (ee.MoveNext ()) {
175                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + ", " + ee.Current.Value + "' expected.");
176                                 Assert.AreEqual (ee.Current.Key, ea.Current.Key);
177                                 Assert.AreEqual (ee.Current.Value, ea.Current.Value);
178                         }
179
180                         if (ea.MoveNext ())
181                                 Assert.Fail ("Unexpected element: " + ee.Current.Key + ", " + ee.Current.Value);
182                 }
183
184                 [Test]
185                 public void SelectTestCase ()
186                 {
187                         ParallelTestHelper.Repeat (() => {
188                                 IEnumerable<int> sync  = baseEnumerable.Select (i => i * i);
189                                 IEnumerable<int> async_res = baseEnumerable.AsParallel ().Select (i => i * i);
190                                 
191                                 AreEquivalent(sync, async_res);
192                         });
193                 }
194                         
195                 [Test]
196                 public void WhereTestCase ()
197                 {
198                         ParallelTestHelper.Repeat (() => {
199                                 IEnumerable<int> sync  = baseEnumerable.Where(i => i % 2 == 0);
200                                 IEnumerable<int> async_res = baseEnumerable.AsParallel().Where(i => i % 2 == 0);
201                                 
202                                 AreEquivalent(sync, async_res);
203                         });
204                 }
205                 
206                 [Test]
207                 public void CountTestCase ()
208                 {
209                         ParallelTestHelper.Repeat (() => {
210                                 int sync  = baseEnumerable.Count();
211                                 int async_res = baseEnumerable.AsParallel().Count();
212                                 
213                                 Assert.AreEqual(sync, async_res, "#1");
214                         });
215                 }
216                 
217                 [Test]
218                 public void AggregateTestCase ()
219                 {
220                         ParallelTestHelper.Repeat (() => {
221                                 ParallelQuery<int> range = ParallelEnumerable.Repeat (5, 2643);
222                                 double average = range.Aggregate(() => new double[2],
223                                                                  (acc, elem) => { acc[0] += elem; acc[1]++; return acc; },
224                                 (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; },
225                                 acc => acc[0] / acc[1]);
226                                 
227                                 Assert.AreEqual(5.0, average, "#1");
228                         });
229                 }
230                 
231                 [Test]
232                 public void TestSimpleExcept ()
233                 {
234                         ParallelTestHelper.Repeat (() => {
235                                 int [] first = {0, 1, 2, 3, 4, 5};
236                                 int [] second = {2, 4, 6};
237                                 int [] result = {0, 1, 3, 5};
238         
239                                 AreEquivalent (result, first.AsReallyParallel ().Except (second.AsParallel ()));
240                         });
241                 }
242
243                 [Test]
244                 public void TestSimpleIntersect ()
245                 {
246                         ParallelTestHelper.Repeat (() => {
247                                 int [] first = {0, 1, 2, 3, 4, 5};
248                                 int [] second = {2, 4, 6};
249                                 int [] result = {2, 4};
250         
251                                 AreEquivalent (result, first.AsReallyParallel ().Intersect (second.AsParallel ()));
252                         });
253                 }
254
255                 [Test]
256                 public void TestSimpleUnion ()
257                 {
258                         ParallelTestHelper.Repeat (() => {
259                                 int [] first = {0, 1, 2, 3, 4, 5};
260                                 int [] second = {2, 4, 6};
261                                 int [] result = {0, 1, 2, 3, 4, 5, 6};
262                                 
263                                 AreEquivalent (result, first.AsReallyParallel ().Union (second.AsParallel ()));
264                         });
265                 }
266
267                 [Test]
268                 public void TestBigUnion ()
269                 {
270                         ParallelTestHelper.Repeat (() => {
271                                 int [] first = Enumerable.Range (1, 10000).ToArray ();
272                                 int [] second = Enumerable.Range (323, 757).ToArray ();
273
274                                 var expected = first;
275                                 var actual = first.AsReallyParallel ().Union (second.AsParallel ()).ToArray ();
276                                 // Work around quadratic behavior in NUnitLite's CollectionTally class
277                                 Array.Sort (expected);
278                                 Array.Sort (actual);
279                                 AreEquivalent (expected, actual);
280                         });
281                 }
282
283                 [Test]
284                 public void TestBigIntersect ()
285                 {
286                         ParallelTestHelper.Repeat (() => {
287                                 int [] first = Enumerable.Range (1, 10000).ToArray ();
288                                 int [] second = Enumerable.Range (323, 757).ToArray ();
289
290                                 AreEquivalent (second, first.AsReallyParallel ().Intersect (second.AsParallel ()));
291                         });
292                 }
293                 
294                 class Foo {}
295                 class Bar : Foo {}
296
297                 [Test]
298                 public void TestCast ()
299                 {
300                         Bar a = new Bar ();
301                         Bar b = new Bar ();
302                         Bar c = new Bar ();
303
304                         Foo [] foos = new Foo [] {a, b, c};
305                         Bar [] result = new Bar [] {a, b, c};
306
307                         AreEquivalent (result, foos.AsReallyParallel ().Cast<Bar> ());
308                 }
309                 
310                 [Test]
311                 public void TestSkip ()
312                 {
313                         int [] data = {0, 1, 2, 3, 4, 5};
314                         int [] result = {3, 4, 5};
315
316                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Skip (3).ToArray ());
317                 }
318                 
319                 [Test]
320                 public void TestSkipIterating ()
321                 {
322                         int [] data = {0, 1, 2, 3, 4, 5};
323                         int [] result = {3, 4, 5};
324
325                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Skip (3));
326                 }
327
328                 [Test]
329                 public void TestSkipWhile ()
330                 {
331                         int [] data = {0, 1, 2, 3, 4, 5};
332                         int [] result = {3, 4, 5};
333
334                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().SkipWhile (i => i < 3));
335                 }
336
337                 [Test]
338                 public void TestTake ()
339                 {
340                         int [] data = {0, 1, 2, 3, 4, 5};
341                         int [] result = {0, 1, 2};
342
343                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Take (3));
344                 }
345
346                 [Test]
347                 public void TestTakeWhile ()
348                 {
349                         int [] data = {0, 1, 2, 3, 4, 5};
350                         int [] result = {0, 1, 2};
351
352                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().TakeWhile (i => i < 3));
353                 }
354
355                 [Test]
356                 public void SelectManyTest ()
357                 {
358                         IEnumerable<int> initial = Enumerable.Range (1, 50);
359                         IEnumerable<int> expected = initial.SelectMany ((i) => Enumerable.Range (1, i));
360
361                         ParallelTestHelper.Repeat (() => {
362                                         var actual = initial.AsReallyParallel ().SelectMany ((i) => Enumerable.Range (1, i));
363                                         AreEquivalent (expected, actual);
364                                 });
365                 }
366
367                 [Test]
368                 public void SelectManyOrderedTest ()
369                 {
370                         IEnumerable<int> initial = Enumerable.Range (1, 50);
371                         IEnumerable<int> expected = initial.SelectMany ((i) => Enumerable.Range (1, i));
372
373                         ParallelTestHelper.Repeat (() => {
374                                         var actual = initial.AsReallyParallel ().AsOrdered ().SelectMany ((i) => Enumerable.Range (1, i));
375                                         AssertAreSame (expected, actual);
376                                 });
377                 }
378                 
379                 [Test]
380                 public void TestLast ()
381                 {
382                         int [] data = {1, 2, 3};
383
384                         Assert.AreEqual (3, data.AsReallyParallel ().AsOrdered ().Last ());
385                 }
386
387                 [Test]
388                 public void TestLastOrDefault ()
389                 {
390                         int [] data = {};
391
392                         Assert.AreEqual (default (int), data.AsReallyParallel ().AsOrdered ().LastOrDefault ());
393                 }
394
395                 [Test]
396                 public void TestFirst ()
397                 {
398                         int [] data = {1, 2, 3};
399
400                         Assert.AreEqual (1, data.AsReallyParallel ().AsOrdered ().First ());
401                 }
402
403                 [Test]
404                 public void TestFirstOrDefault ()
405                 {
406                         int [] data = {};
407
408                         Assert.AreEqual (default (int), data.AsReallyParallel ().AsOrdered ().FirstOrDefault ());
409                 }
410                 
411                 [Test]
412                 public void TestReverse ()
413                 {
414                         int [] data = {0, 1, 2, 3, 4};
415                         int [] result = {4, 3, 2, 1, 0};
416
417                         AssertAreSame (result, ((IEnumerable<int>)data).Select ((i) => i).AsReallyParallel ().AsOrdered ().Reverse ());
418                         AssertAreSame (result, ParallelEnumerable.Range (0, 5).AsReallyParallel ().AsOrdered ().Reverse ());
419                 }
420                 
421                 [Test]
422                 public void TestOrderBy ()
423                 {
424                         ParallelTestHelper.Repeat (() => {
425                                 int [] array = { 14, 53, 3, 9, 11, 14, 5, 32, 2 };
426                                 
427                                 var q = array.AsReallyParallel ().OrderBy ((i) => i);
428                                 AssertIsOrdered (q, array.Length);
429                         });
430                 }
431
432                 class Baz {
433                         string name;
434                         int age;
435
436                         public string Name
437                         {
438                                 get {
439                                         if (string.IsNullOrEmpty (name))
440                                                 return Age.ToString ();
441
442                                         return name + " (" + Age + ")";
443                                 }
444                         }
445
446                         public int Age
447                         {
448                                 get { return age + 1; }
449                         }
450
451                         public Baz (string name, int age)
452                         {
453                                 this.name = name;
454                                 this.age = age;
455                         }
456
457                         public override int GetHashCode ()
458                         {
459                                 return this.Age ^ this.Name.GetHashCode ();
460                         }
461
462                         public override bool Equals (object obj)
463                         {
464                                 Baz b = obj as Baz;
465                                 if (b == null)
466                                         return false;
467
468                                 return b.Age == this.Age && b.Name == this.Name;
469                         }
470
471                         public override string ToString ()
472                         {
473                                 return this.Name;
474                         }
475                 }
476
477                 static IEnumerable<Baz> CreateBazCollection ()
478                 {
479                         return new [] {
480                                 new Baz ("jb", 25),
481                                 new Baz ("ana", 20),
482                                 new Baz ("reg", 28),
483                                 new Baz ("ro", 25),
484                                 new Baz ("jb", 7),
485                         };
486                 }
487
488                 [Test]
489                 public void TestOrderByAgeAscendingTheByNameDescending ()
490                 {
491                         ParallelTestHelper.Repeat (() => {
492                                 var q = from b in CreateBazCollection ().AsReallyParallel ()
493                                                 orderby b.Age ascending, b.Name descending
494                                                 select b;
495         
496                                 var expected = new [] {
497                                         new Baz ("jb", 7),
498                                         new Baz ("ana", 20),
499                                         new Baz ("ro", 25),
500                                         new Baz ("jb", 25),
501                                         new Baz ("reg", 28),
502                                 };
503
504                                 AssertAreSame (expected, q);
505                         });
506                 }
507
508                 class Data {
509                         public int ID { get; set; }
510                         public string Name { get; set; }
511
512                         public override string ToString ()
513                         {
514                                 return ID + " " + Name;
515                         }
516                 }
517
518                 IEnumerable<Data> CreateData ()
519                 {
520                         return new [] {
521                                 new Data { ID = 10, Name = "bcd" },
522                                 new Data { ID = 20, Name = "Abcd" },
523                                 new Data { ID = 20, Name = "Ab" },
524                                 new Data { ID = 10, Name = "Zyx" },
525                         };
526                 }
527
528                 [Test]
529                 public void TestOrderByIdDescendingThenByNameAscending ()
530                 {
531                         ParallelTestHelper.Repeat (() => {
532                                 var q = from d in CreateData ().AsReallyParallel ()
533                                         orderby d.ID descending, d.Name ascending
534                                                 select d;
535                                 
536                                 var list = new List<Data> (q);
537                                 
538                                 Assert.AreEqual ("Ab", list [0].Name);
539                                 Assert.AreEqual ("Abcd", list [1].Name);
540                                 Assert.AreEqual ("bcd", list [2].Name);
541                                 Assert.AreEqual ("Zyx", list [3].Name);
542                         });
543                 }
544
545                 static void AssertIsOrdered (IEnumerable<int> e, int count)
546                 {
547                         int f = int.MinValue;
548                         int c = 0;
549                         
550                         foreach (int i in e) {
551                                 Assert.IsTrue (f <= i, string.Format ("{0} <= {1}", f, i));
552                                 f = i;
553                                 c++;
554                         }
555                         
556                         Assert.AreEqual (count, c);
557                 }
558                 
559                 
560                 [Test]
561                 public void ElementAtTestCase()
562                 {
563                         //ParallelTestHelper.Repeat (() => {
564                                         Assert.AreEqual(1, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(0), "#1");
565                                         Assert.AreEqual(51, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(50), "#2");
566                                         Assert.AreEqual(489, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(488), "#3");
567                         //});
568                 }
569
570                 [Test]
571                 public void TestJoin ()
572                 {
573                         int num = 100;
574                         Tuple<int, int>[] outer = Enumerable.Range (1, 50).Select ((i) => Tuple.Create (i, num - 2 * i)).ToArray ();
575                         Tuple<int, int>[] inner = Enumerable.Range (1, 50).Reverse ().Select ((i) => Tuple.Create (i, 2 * i)).ToArray ();
576
577                         IEnumerable<int> expected = outer.Join (inner, (e) => e.Item1, (e) => e.Item1, (e1, e2) => e1.Item2 + e2.Item2, EqualityComparer<int>.Default);
578
579                         ParallelTestHelper.Repeat (() => {
580                                 ParallelQuery<int> actual = outer.AsReallyParallel ().Join (inner.AsParallel (),
581                                                                                             (e) => e.Item1,
582                                                                                             (e) => e.Item1,
583                                                                                             (e1, e2) => e1.Item2 + e2.Item2,
584                                                                                             EqualityComparer<int>.Default);
585                                 AreEquivalent (expected, actual);
586                         });
587                 }
588
589                 [Test]
590                 public void SmallJoinTest ()
591                 {
592                         var items = new [] { 1, 2, 3 };
593                         var items2 = new [] { 1, 2, 3, 4 };
594                         var actual = items.AsReallyParallel ().Join (items2.AsReallyParallel (), i => i, i => i, (e1, e2) => e1 + e2);
595                         AreEquivalent (new[] { 2, 4, 6 }, actual);
596                 }
597
598                 [Test]
599                 [Category ("NotWorking")] // Deadlocks randomly
600                 public void TestGroupBy ()
601                 {
602                         int num = 100;
603                         Tuple<int, int>[] source = Enumerable.Range (0, num).Select ((i) => Tuple.Create (i / 10, i)).ToArray ();
604
605                         ParallelTestHelper.Repeat (() => {
606                                 ParallelQuery<IGrouping<int, int>> actual = source.AsReallyParallel ().GroupBy ((e) => e.Item1, (e) => e.Item2, EqualityComparer<int>.Default);
607                                 foreach (var group in actual) {
608                                         Assert.IsTrue (group.Key >= 0);
609                                         Assert.IsTrue (group.Key < num / 10);
610
611                                         int count = 0;
612                                         foreach (var e in group) {
613                                                 count++;
614                                                 Assert.IsTrue (e >= group.Key * 10);
615                                                 Assert.IsTrue (e <  (group.Key + 1) * 10);
616                                         }
617
618                                         Assert.AreEqual (10, count, "count");
619                                 }
620                         });
621                 }
622                 
623                 [Test]
624                 public void TakeTestCase()
625                 {
626                         ParallelTestHelper.Repeat (() => {
627                                 ParallelQuery<int> async_res = baseEnumerable.AsReallyParallel ().AsOrdered ().Take(800);
628                                 IEnumerable<int> sync = baseEnumerable.Take(800);
629
630                                 AreEquivalent(sync, async_res);
631
632                                 async_res = baseEnumerable.AsReallyParallel ().AsOrdered ().Take(100);
633                                 sync = baseEnumerable.Take(100);
634
635                                 AreEquivalent(sync, async_res);
636                         });
637                 }
638
639                 [TestAttribute]
640                 public void UnorderedTakeTestCase()
641                 {
642                         ParallelTestHelper.Repeat (() => {
643                                 ParallelQuery<int> async_res = baseEnumerable.AsReallyParallel ().Take(800);
644                                 IEnumerable<int> sync = baseEnumerable.Take (800);
645
646                                 Assert.AreEqual (sync.Count (), async_res.Count (), "#1");
647
648                                 async_res = baseEnumerable.AsReallyParallel ().Take(100);
649                                 sync = baseEnumerable.Take(100);
650
651                                 Assert.AreEqual (sync.Count (), async_res.Count (), "#2");
652                         });
653                 }
654                 
655                 [Test]
656                 public void SkipTestCase()
657                 {
658                         ParallelTestHelper.Repeat (() => {
659                                 ParallelQuery<int> async_res = baseEnumerable.AsReallyParallel ().AsOrdered().Skip (800);
660                                 IEnumerable<int> sync = baseEnumerable.Skip (800);
661                                 
662                                 AreEquivalent (sync, async_res);
663                         });
664                 }
665
666                 [Test]
667                 public void SkipTestCaseSmall ()
668                 {
669                         ParallelTestHelper.Repeat (() => {
670                                 var async_res = baseEnumerable.AsReallyParallel ().Skip(100);
671                                 var sync = baseEnumerable.Skip(100);
672                                 
673                                 Assert.AreEqual (sync.Count (), async_res.Count ());
674                         });
675                 }
676
677                 [Test]
678                 public void ZipTestCase()
679                 {
680                         ParallelTestHelper.Repeat (() => {
681                                 ParallelQuery<int> async_res1 = ParallelEnumerable.Range(0, 10000);
682                                 ParallelQuery<int> async_res2 = ParallelEnumerable.Repeat(1, 10000).Zip(async_res1, (e1, e2) => e1 + e2);
683
684                                 int[] expected = Enumerable.Range (1, 10000).ToArray ();
685                                 var actual = Enumerable.ToArray (async_res2);
686                                 // Work around quadratic behavior in NUnitLite's CollectionTally class
687                                 Array.Sort (expected);
688                                 Array.Sort (actual);
689                                 AreEquivalent(expected, actual);
690                         });
691                 }
692                 
693                 [Test]
694                 public void Range ()
695                 {
696                         ParallelTestHelper.Repeat (() => {
697                                 IEnumerable<int> sync  = Enumerable.Range(1, 1000);
698                                 IEnumerable<int> async_res = ParallelEnumerable.Range(1, 1000);
699                                 
700                                 AreEquivalent (sync, async_res);
701                         });
702                 }
703         
704                 [Test]
705                 public void Range_StartOffset ()
706                 {
707                         ParallelTestHelper.Repeat (() => {
708                                 IEnumerable<int> sync  = Enumerable.Range (30, 10);
709                                 IEnumerable<int> async_res = ParallelEnumerable.Range (30, 10);
710                                 
711                                 AreEquivalent (sync, async_res);
712                         });
713                 }
714
715                 [Test]
716                 public void RepeatTestCase ()
717                 {
718                         ParallelTestHelper.Repeat (() => {
719                                 IEnumerable<int> sync  = Enumerable.Repeat(1, 1000);
720                                 IEnumerable<int> async_res = ParallelEnumerable.Repeat(1, 1000);
721                                 
722                                 AreEquivalent (sync, async_res);
723                         });
724                 }
725                 
726                 [Test]
727                 public void TestSum ()
728                 {
729                         int [] data = {1, 2, 3, 4};
730
731                         Assert.AreEqual (10, data.AsReallyParallel ().Sum ());
732                 }
733
734                 [Test]
735                 public void SumOnEmpty ()
736                 {
737                         int [] data = {};
738
739                         Assert.AreEqual (0, data.AsReallyParallel ().Sum ());
740                 }
741
742                 [Test]
743                 public void TestMax ()
744                 {
745                         int [] data = {1, 3, 5, 2};
746
747                         Assert.AreEqual (5, data.AsReallyParallel ().Max ());
748                 }
749
750                 [Test]
751                 public void TestMin ()
752                 {
753                         int [] data = {3, 5, 2, 6, 1, 7};
754
755                         Assert.AreEqual (1, data.AsReallyParallel ().Min ());
756                 }
757                 
758                 [Test]
759                 public void TestToListOrdered ()
760                 {
761                         int [] data = { 2, 3, 5 };
762
763                         var list = data.AsParallel().AsOrdered().WithExecutionMode (ParallelExecutionMode.ForceParallelism).ToList ();
764
765                         AssertAreSame (data, list);
766                         AssertIsOrdered (list, data.Length);
767
768                         Assert.AreEqual (typeof (List<int>), list.GetType ());
769                 }
770
771                 [Test]
772                 public void TestToArrayOrdered ()
773                 {
774                         ICollection<int> coll = new List<int> ();
775                         coll.Add (0);
776                         coll.Add (1);
777                         coll.Add (2);
778
779                         int [] result = {0, 1, 2};
780
781                         var array = coll.AsReallyParallel ().AsOrdered().ToArray ();
782
783                         AssertAreSame (result, array);
784                         AssertIsOrdered (array, result.Length);
785
786                         Assert.AreEqual (typeof (int []), array.GetType ());
787
788                         array = Enumerable.Range (1, 100).Select ((i) => i).AsReallyParallel ().AsOrdered().ToArray ();
789                         result = Enumerable.Range (1, 100).ToArray ();
790
791                         AssertAreSame (result, array);
792                         AssertIsOrdered (array, result.Length);
793
794                         Assert.AreEqual (typeof (int []), array.GetType ());
795
796                 }
797
798                 [Test]
799                 public void TestToList ()
800                 {
801                         int [] data = {3, 5, 2};
802
803                         var list = data.AsReallyParallel ().ToList ();
804
805                         AreEquivalent (data, list);
806
807                         Assert.AreEqual (typeof (List<int>), list.GetType ());
808                 }
809
810                 [Test]
811                 public void TestToArray ()
812                 {
813                         ICollection<int> coll = new List<int> ();
814                         coll.Add (0);
815                         coll.Add (1);
816                         coll.Add (2);
817
818                         int [] result = {0, 1, 2};
819
820                         var array = coll.AsReallyParallel ().ToArray ();
821
822                         AreEquivalent (result, array);
823
824                         Assert.AreEqual (typeof (int []), array.GetType ());
825                 }
826                 
827                 
828                 [Test]
829                 public void TestAverageOnInt32 ()
830                 {
831                         Assert.AreEqual (23.25, (new int [] { 24, 7, 28, 34 }).Average ());
832                 }
833
834                 [Test]
835                 public void TestAverageOnInt64 ()
836                 {
837                         Assert.AreEqual (23.25, (new long [] { 24, 7, 28, 34 }).Average ());
838                 }
839                 
840                 
841                 [Test]
842                 public void AnyArgumentNullTest ()
843                 {
844                         string [] data = { "2", "1", "5", "3", "4" };
845
846
847                         // Any<TSource> ()
848                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().Any (); });
849
850                         // Any<TSource> (Func<TSource, bool>)
851                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().Any (x => true); });
852                         AssertException<ArgumentNullException> (delegate () { data.AsReallyParallel ().Any ((Func<string, bool>) null); });
853                 }
854
855                 [Test]
856                 public void AnyTest ()
857                 {
858                         int [] data = { 5, 2, 3, 1, 6 };
859                         int [] empty = { };
860
861
862                         // Any<TSource> ()
863                         Assert.IsTrue (data.AsReallyParallel ().Any ());
864                         Assert.IsFalse (empty.AsReallyParallel ().Any ());
865
866                         // Any<TSource> (Func<TSource, bool>)
867                         Assert.IsTrue (data.AsReallyParallel ().Any (x => x == 5));
868                         Assert.IsFalse (data.AsReallyParallel ().Any (x => x == 9));
869                         Assert.IsFalse (empty.AsReallyParallel ().Any (x => true));
870                 }
871
872                 
873                 [Test]
874                 public void AllArgumentNullTest ()
875                 {
876                         string [] data = { "2", "1", "5", "3", "4" };
877
878                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().All (x => true); });
879                         AssertException<ArgumentNullException> (delegate () { data.AsReallyParallel ().All ((Func<string, bool>) null); });
880                 }
881
882                 [Test]
883                 public void AllTest ()
884                 {
885                         int [] data = { 5, 2, 3, 1, 6 };
886                         int [] empty = { };
887
888                         Assert.IsTrue (data.AsReallyParallel ().All (x => true));
889                         Assert.IsFalse (data.AsReallyParallel ().All (x => x != 1));
890                         Assert.IsTrue (empty.AsReallyParallel ().All (x => false));
891                 }
892
893                 [Test]
894                 public void SequenceEqualsTest ()
895                 {
896                         var data1 = new int[] { 1, 2, 3 };
897                         var data2 = new int[] { 1, 2, 4 };
898                         var data3 = new int[] { 1, 2, 3, 4 };
899
900                         Assert.IsTrue (data1.AsReallyParallel ().SequenceEqual (data1.AsReallyParallel ()));
901                         Assert.IsTrue (data2.AsReallyParallel ().SequenceEqual (data2.AsReallyParallel ()));
902                         Assert.IsTrue (data3.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
903                         Assert.IsFalse (data1.AsReallyParallel ().SequenceEqual (data2.AsReallyParallel ()));
904                         Assert.IsFalse (data1.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
905                         Assert.IsFalse (data2.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
906                 }
907
908                 [Test]
909                 public void ContainsTest ()
910                 {
911                         var data1 = new int[] { 1, 2, 3 };
912                         var data2 = new int[] { 1, 2, 4 };
913                         var data3 = new int[] { 1, 2, 3, 4 };
914
915                         Assert.IsTrue (data1.AsReallyParallel ().Contains (3));
916                         Assert.IsFalse (data2.AsReallyParallel ().Contains (3));
917                         Assert.IsTrue (data3.AsReallyParallel ().Contains (3));
918                         Assert.IsFalse (data3.AsReallyParallel ().Contains (5));
919                         Assert.IsTrue (data2.AsReallyParallel ().Contains (2));
920                 }
921         }
922 }
923
924 #endif