aa6cd1afb0395962b93e3c44a71b2002d25d922c
[mono.git] / mcs / class / System.Core / Test / System.Linq / EnumerableTest.cs
1 //
2 // EnumerableTest.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@novell.com)
6 //
7 // (C) 2007 Novell, Inc. (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.IO;
31 using System.Collections;
32 using System.Collections.Generic;
33 using System.Linq;
34 using System.Linq.Expressions;
35
36 using NUnit.Framework;
37
38 namespace MonoTests.System.Linq {
39
40         [TestFixture]
41         public class EnumerableTest {
42
43                 [Test]
44                 public void TestSimpleExcept ()
45                 {
46                         int [] first = {0, 1, 2, 3, 4, 5};
47                         int [] second = {2, 4, 6};
48                         int [] result = {0, 1, 3, 5};
49
50                         AssertAreSame (result, first.Except (second));
51                 }
52
53                 [Test]
54                 public void TestSimpleIntersect ()
55                 {
56                         int [] first = {0, 1, 2, 3, 4, 5};
57                         int [] second = {2, 4, 6};
58                         int [] result = {2, 4};
59
60                         AssertAreSame (result, first.Intersect (second));
61                 }
62
63                 [Test]
64                 public void TestSimpleUnion ()
65                 {
66                         int [] first = {0, 1, 2, 3, 4, 5};
67                         int [] second = {2, 4, 6};
68                         int [] result = {0, 1, 2, 3, 4, 5, 6};
69
70                         AssertAreSame (result, first.Union (second));
71                 }
72
73                 class Foo {}
74                 class Bar : Foo {}
75
76                 [Test]
77                 public void TestCast ()
78                 {
79                         Bar a = new Bar ();
80                         Bar b = new Bar ();
81                         Bar c = new Bar ();
82
83                         Foo [] foos = new Foo [] {a, b, c};
84                         Bar [] result = new Bar [] {a, b, c};
85
86                         AssertAreSame (result, foos.Cast<Bar> ());
87                 }
88
89                 [Test]
90                 public void TestLast ()
91                 {
92                         int [] data = {1, 2, 3};
93
94                         Assert.AreEqual (3, data.Last ());
95                 }
96
97                 [Test]
98                 public void TestLastOrDefault ()
99                 {
100                         int [] data = {};
101
102                         Assert.AreEqual (default (int), data.LastOrDefault ());
103                 }
104
105                 [Test]
106                 public void TestFirst ()
107                 {
108                         int [] data = {1, 2, 3};
109
110                         Assert.AreEqual (1, data.First ());
111                 }
112
113                 [Test]
114                 public void TestFirstOrDefault ()
115                 {
116                         int [] data = {};
117
118                         Assert.AreEqual (default (int), data.FirstOrDefault ());
119                 }
120
121                 [Test]
122                 public void TestSequenceEqual ()
123                 {
124                         int [] first = {0, 1, 2, 3, 4, 5};
125                         int [] second = {0, 1, 2};
126                         int [] third = {0, 1, 2, 3, 4, 5};
127
128                         Assert.IsFalse (first.SequenceEqual (second));
129                         Assert.IsTrue (first.SequenceEqual (third));
130                 }
131
132                 [Test]
133                 public void TestSkip ()
134                 {
135                         int [] data = {0, 1, 2, 3, 4, 5};
136                         int [] result = {3, 4, 5};
137
138                         AssertAreSame (result, data.Skip (3));
139                 }
140
141                 [Test]
142                 public void TestSkipWhile ()
143                 {
144                         int [] data = {0, 1, 2, 3, 4, 5};
145                         int [] result = {3, 4, 5};
146
147                         AssertAreSame (result, data.SkipWhile (i => i < 3));
148                 }
149
150                 [Test]
151                 public void TestTake ()
152                 {
153                         int [] data = {0, 1, 2, 3, 4, 5};
154                         int [] result = {0, 1, 2};
155
156                         AssertAreSame (result, data.Take (3));
157                 }
158
159                 [Test]
160                 public void TestTakeWhile ()
161                 {
162                         int [] data = {0, 1, 2, 3, 4, 5};
163                         int [] result = {0, 1, 2};
164
165                         AssertAreSame (result, data.TakeWhile (i => i < 3));
166                 }
167
168                 [Test]
169                 public void TestSelect ()
170                 {
171                         int [] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
172                         int [] result = {1, 3, 5, 7, 9};
173
174                         AssertAreSame (result, data.Where (i => i % 2 != 0));
175                 }
176
177                 [Test]
178                 public void TestReverse ()
179                 {
180                         int [] data = {0, 1, 2, 3, 4};
181                         int [] result = {4, 3, 2, 1, 0};
182
183                         AssertAreSame (result, data.Reverse ());
184                         AssertAreSame (result, Enumerable.Range (0, 5).Reverse ());
185                 }
186
187                 [Test]
188                 public void TestSum ()
189                 {
190                         int [] data = {1, 2, 3, 4};
191
192                         Assert.AreEqual (10, data.Sum ());
193                 }
194
195                 [Test]
196                 public void SumOnEmpty ()
197                 {
198                         int [] data = {};
199
200                         Assert.AreEqual (0, data.Sum ());
201                 }
202
203                 [Test]
204                 public void TestMax ()
205                 {
206                         int [] data = {1, 3, 5, 2};
207
208                         Assert.AreEqual (5, data.Max ());
209                 }
210
211                 [Test]
212                 public void TestMaxNullableInt32 ()
213                 {
214                         int? [] data = { null, null, null };
215
216                         Assert.IsNull (data.Max (x => -x));
217
218                         data = new int? [] { null, 1, 2 };
219
220                         Assert.AreEqual (-1, data.Max (x => -x));
221                 }
222
223                 [Test]
224                 public void TestMin ()
225                 {
226                         int [] data = {3, 5, 2, 6, 1, 7};
227
228                         Assert.AreEqual (1, data.Min ());
229                 }
230
231                 [Test]
232                 public void TestMinNullableInt32 ()
233                 {
234                         int? [] data = { null, null, null };
235
236                         Assert.IsNull (data.Min(x => -x));
237
238                         data = new int? [] { null, 1, 2 };
239
240                         Assert.AreEqual (-2, data.Min (x => -x));
241                 }
242
243                 [Test]
244                 public void TestToList ()
245                 {
246                         int [] data = {3, 5, 2};
247
248                         var list = data.ToList ();
249
250                         AssertAreSame (data, list);
251
252                         Assert.AreEqual (typeof (List<int>), list.GetType ());
253                 }
254
255                 [Test]
256                 public void TestToArray ()
257                 {
258                         ICollection<int> coll = new List<int> ();
259                         coll.Add (0);
260                         coll.Add (1);
261                         coll.Add (2);
262
263                         int [] result = {0, 1, 2};
264
265                         var array = coll.ToArray ();
266
267                         AssertAreSame (result, array);
268
269                         Assert.AreEqual (typeof (int []), array.GetType ());
270                 }
271
272                 [Test]
273                 public void TestIntersect ()
274                 {
275                         int [] left = { 1, 1 }, right = { 1, 1 };
276                         int [] result = { 1 };
277
278                         AssertAreSame (result, left.Intersect (right));
279                 }
280
281                 [Test]
282                 public void TestAverageOnInt32 ()
283                 {
284                         Assert.AreEqual (23.25, (new int [] { 24, 7, 28, 34 }).Average ());
285                 }
286
287                 [Test]
288                 public void TestAverageOnInt64 ()
289                 {
290                         Assert.AreEqual (23.25, (new long [] { 24, 7, 28, 34 }).Average ());
291                 }
292
293                 [Test]
294                 public void TestAverageOnLongNullable ()
295                 {
296                         List<long?> list = new List<long?> ();
297                         list.Add (2);
298                         list.Add (3);
299                         Assert.AreEqual (2.5d, list.Average ());
300                 }
301
302                 [Test]
303                 public void TestRange ()
304                 {
305                         AssertAreSame (new [] {1, 2, 3, 4}, Enumerable.Range (1, 4));
306
307                         AssertAreSame (new [] {0, 1, 2, 3}, Enumerable.Range (0, 4));
308                 }
309
310                 [Test]
311                 public void TestTakeTakesProperNumberOfItems ()
312                 {
313                         var stream = new MemoryStream (new byte [] { 1, 2, 3, 4, 0 });
314
315                         Assert.AreEqual (0, stream.Position);
316
317                         foreach (byte b in AsEnumerable (stream).Take (2))
318                                 ;
319
320                         Assert.AreEqual (2, stream.Position);
321                 }
322
323                 static IEnumerable<byte> AsEnumerable (Stream stream)
324                 {
325                         byte b;
326                         while ((b = (byte) stream.ReadByte ()) >= 0)
327                                 yield return b;
328                 }
329
330                 [Test]
331                 public void TestOrderBy ()
332                 {
333                                 int [] array = { 14, 53, 3, 9, 11, 14, 5, 32, 2 };
334                                 var q = from i in array
335                                                 orderby i
336                                                 select i;
337                                 AssertIsOrdered (q);
338                 }
339
340                 class Baz {
341                         string name;
342                         int age;
343
344                         public string Name
345                         {
346                                 get {
347                                         if (string.IsNullOrEmpty (name))
348                                                 return Age.ToString ();
349
350                                         return name + " (" + Age + ")";
351                                 }
352                         }
353
354                         public int Age
355                         {
356                                 get { return age + 1; }
357                         }
358
359                         public Baz (string name, int age)
360                         {
361                                 this.name = name;
362                                 this.age = age;
363                         }
364
365                         public override int GetHashCode ()
366                         {
367                                 return this.Age ^ this.Name.GetHashCode ();
368                         }
369
370                         public override bool Equals (object obj)
371                         {
372                                 Baz b = obj as Baz;
373                                 if (b == null)
374                                         return false;
375
376                                 return b.Age == this.Age && b.Name == this.Name;
377                         }
378
379                         public override string ToString ()
380                         {
381                                 return this.Name;
382                         }
383                 }
384
385                 static IEnumerable<Baz> CreateBazCollection ()
386                 {
387                         return new [] {
388                                 new Baz ("jb", 25),
389                                 new Baz ("ana", 20),
390                                 new Baz ("reg", 28),
391                                 new Baz ("ro", 25),
392                                 new Baz ("jb", 7),
393                         };
394                 }
395
396                 [Test]
397                 public void TestOrderByAgeAscendingTheByNameDescending ()
398                 {
399                         var q = from b in CreateBazCollection ()
400                                         orderby b.Age ascending, b.Name descending
401                                         select b;
402
403                         var expected = new [] {
404                                 new Baz ("jb", 7),
405                                 new Baz ("ana", 20),
406                                 new Baz ("ro", 25),
407                                 new Baz ("jb", 25),
408                                 new Baz ("reg", 28),
409                         };
410
411                         AssertAreSame (expected, q);
412                 }
413
414                 class Data {
415                         public int ID { get; set; }
416                         public string Name { get; set; }
417
418                         public override string ToString ()
419                         {
420                                 return ID + " " + Name;
421                         }
422                 }
423
424                 IEnumerable<Data> CreateData ()
425                 {
426                         return new [] {
427                                 new Data { ID = 10, Name = "bcd" },
428                                 new Data { ID = 20, Name = "Abcd" },
429                                 new Data { ID = 20, Name = "Ab" },
430                                 new Data { ID = 10, Name = "Zyx" },
431                         };
432                 }
433
434                 [Test]
435                 public void TestOrderByIdDescendingThenByNameAscending ()
436                 {
437                         var q = from d in CreateData ()
438                                         orderby d.ID descending, d.Name ascending
439                                         select d;
440
441                         var list = new List<Data> (q);
442
443                         Assert.AreEqual ("Ab", list [0].Name);
444                         Assert.AreEqual ("Abcd", list [1].Name);
445                         Assert.AreEqual ("bcd", list [2].Name);
446                         Assert.AreEqual ("Zyx", list [3].Name);
447                 }
448
449                 static void AssertIsOrdered (IEnumerable<int> e)
450                 {
451                                 int f = int.MinValue;
452                                 foreach(int i in e) {
453                                                 Assert.IsTrue (f <= i);
454                                                 f = i;
455                                 }
456                 }
457
458                 static void AssertAreSame<T> (IEnumerable<T> expected, IEnumerable<T> actual)
459                 {
460                         if (expected == null) {
461                                 Assert.IsNull (actual);
462                                 return;
463                         }
464
465                         Assert.IsNotNull (actual);
466
467                         IEnumerator<T> ee = expected.GetEnumerator ();
468                         IEnumerator<T> ea = actual.GetEnumerator ();
469
470                         while (ee.MoveNext ()) {
471                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected.");
472                                 Assert.AreEqual (ee.Current, ea.Current);
473                         }
474
475                         if (ea.MoveNext ())
476                                 Assert.Fail ("Unexpected element: " + ea.Current);
477                 }
478         }
479 }