be1f8f92729705b768877e3376a82ebb6e1ae6f7
[mono.git] / mcs / class / corlib / Test / System.Collections.Generic / ListTest.cs
1 //
2 // MonoTests.System.Collections.Generic.Test.ListTest
3 //
4 // Authors:
5 //      David Waite (mass@akuma.org)
6 //      Andres G. Aragoneses (andres.aragoneses@7digital.com)
7 //
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
9 // Copyright (C) 2005 David Waite (mass@akuma.org)
10 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
11 // Copyright 2012 7digital Ltd (http://www.7digital.com).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Collections;
35 using System.Collections.Generic;
36 using System.Collections.ObjectModel;
37 using System.IO;
38 using System.Runtime.Serialization.Formatters.Binary;
39 using System.Text;
40
41 using NUnit.Framework;
42
43 namespace MonoTests.System.Collections.Generic {
44
45         class GenericComparer<T> : IComparer<T> {
46
47                 private bool called = false;
48
49                 public bool Called {
50                         get {
51                                 bool result = called;
52                                 called = false;
53                                 return called;
54                         }
55                 }
56
57                 public int Compare (T x, T y)
58                 {
59                         called = true;
60                         return 0;
61                 }
62         }
63
64         [TestFixture]
65         public class ListTest
66         {
67                 static byte [] _serializedList = new byte [] {
68                         0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
69                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
70                         0x7e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x43, 0x6f, 0x6c,
71                         0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65,
72                         0x6e, 0x65, 0x72, 0x69, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x60,
73                         0x31, 0x5b, 0x5b, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x49,
74                         0x6e, 0x74, 0x33, 0x32, 0x2c, 0x20, 0x6d, 0x73, 0x63, 0x6f, 0x72,
75                         0x6c, 0x69, 0x62, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
76                         0x6e, 0x3d, 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2c, 0x20,
77                         0x43, 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65, 0x3d, 0x6e, 0x65, 0x75,
78                         0x74, 0x72, 0x61, 0x6c, 0x2c, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69,
79                         0x63, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3d, 0x62,
80                         0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34,
81                         0x65, 0x30, 0x38, 0x39, 0x5d, 0x5d, 0x03, 0x00, 0x00, 0x00, 0x06,
82                         0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x05, 0x5f, 0x73, 0x69, 0x7a,
83                         0x65, 0x08, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x07,
84                         0x00, 0x00, 0x08, 0x08, 0x08, 0x09, 0x02, 0x00, 0x00, 0x00, 0x03,
85                         0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0f, 0x02, 0x00, 0x00,
86                         0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00,
87                         0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88                         0x0b };
89                 int [] _list1_contents;
90                 List <int> _list1;
91
92                 [SetUp]
93                 public void SetUp ()
94                 {
95                         // FIXME arrays currently do not support generic collection
96                         // interfaces
97                         _list1_contents = new int [] { 55, 50, 22, 80, 56, 52, 40, 63 };
98                         // _list1 = new List <int> (_list1_contents);
99                         
100                         _list1 = new List <int> (8);
101                         foreach (int i in _list1_contents)
102                                 _list1.Add (i);
103                 }
104
105                 [Test]  // This was for bug #74980
106                 public void InsertTest ()
107                 {
108                         List <string> test = new List <string> ();
109                         test.Insert (0, "a");
110                         test.Insert (0, "b");
111                         test.Insert (1, "c");
112
113                         Assert.AreEqual (3, test.Count);
114                         Assert.AreEqual ("b", test [0]);
115                         Assert.AreEqual ("c", test [1]);
116                         Assert.AreEqual ("a", test [2]);
117                 }
118
119                 [Test]
120                 public void InsertRangeTest ()
121                 {
122                         int count = _list1.Count;
123                         // FIXME arrays currently do not support generic collection 
124                         // interfaces
125                         int [] items = {1, 2, 3};
126                         // List <int> newRange = new List <int> (items);
127                         List <int> newRange = new List <int> (3);
128                         foreach (int i in items)
129                                 newRange.Add (i);
130                         _list1.InsertRange (1, newRange);
131                         Assert.AreEqual (count + 3, _list1.Count);
132                         Assert.AreEqual (55, _list1 [0]);
133                         Assert.AreEqual (1, _list1 [1]);
134                         Assert.AreEqual (2, _list1 [2]);
135                         Assert.AreEqual (3, _list1 [3]);
136                         Assert.AreEqual (50, _list1 [4]);
137
138                         newRange = new List <int> ();
139                         List <int> li = new List <int> ();
140                         li.Add (1);
141                         newRange.InsertRange (0, li);
142                         newRange.InsertRange (newRange.Count, li);
143                         Assert.AreEqual (2, newRange.Count);
144                 }
145                 
146                 [Test]
147                 public void InsertSelfTest()
148                 {
149                         List <int> range = new List <int> (5);
150                         for (int i = 0; i < 5; ++ i)
151                                 range.Add (i);
152                         
153                         range.InsertRange(2, range);
154                         Assert.AreEqual (10, range.Count);
155                         Assert.AreEqual (0, range [0]);
156                         Assert.AreEqual (1, range [1]);
157                         Assert.AreEqual (0, range [2]);
158                         Assert.AreEqual (1, range [3]);
159                         Assert.AreEqual (2, range [4]);
160                         Assert.AreEqual (3, range [5]);
161                         Assert.AreEqual (4, range [6]);
162                         Assert.AreEqual (2, range [7]);
163                         Assert.AreEqual (3, range [8]);
164                         Assert.AreEqual (4, range [9]);
165                 }
166
167                 [Test, ExpectedException (typeof (ArgumentNullException))]
168                 public void InsertRangeNullTest ()
169                 {
170                         IEnumerable <int> n = null;
171                         _list1.InsertRange (0, n);
172                 }
173
174                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
175                 public void InsertRangeNegativeIndexTest ()
176                 {
177                         _list1.InsertRange (-1, _list1);
178                 }
179
180                 [Test]
181                 public void IndexOfTest ()
182                 {
183                         List <int> l = new List <int> ();
184
185                         l.Add (100);
186                         l.Add (200);
187
188                         Assert.AreEqual (1, l.IndexOf (200), "Could not find value");
189                 }
190                 
191                 [Test, ExpectedException(typeof (ArgumentException))]
192                 public void IList_InsertInvalidType1 ()
193                 {
194                         IList list = _list1 as IList;
195                         list.Insert(0, new object());
196                 }
197
198                 [Test, ExpectedException(typeof (ArgumentNullException))]
199                 public void IList_InsertInvalidType2 ()
200                 {
201                         IList list = _list1 as IList;
202                         list.Insert(0, null);
203                 }
204                 
205                 [Test, ExpectedException(typeof (ArgumentException))]
206                 public void IList_AddInvalidType1()
207                 {
208                         IList list = _list1 as IList;
209                         list.Add(new object());
210                 }
211
212                 [Test, ExpectedException(typeof (ArgumentNullException))]
213                 public void IList_AddInvalidType2()
214                 {
215                         IList list = _list1 as IList;
216                         list.Add(null);
217                 }
218                 
219                 [Test]
220                 public void IList_RemoveInvalidType()
221                 {
222                         IList list = _list1 as IList;
223                         int nCount = list.Count;
224                         list.Remove(new object());
225                         Assert.AreEqual(nCount, list.Count);
226
227                         list.Remove(null);
228                         Assert.AreEqual(nCount, list.Count);
229                 }
230
231                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
232                 public void IndexOfOutOfRangeTest ()
233                 {
234                         List <int> l = new List <int> (4);
235                         l.IndexOf (0, 0, 4);
236                 }
237
238                 [Test]
239                 public void GetRangeTest ()
240                 {
241                         List <int> r = _list1.GetRange (2, 4);
242                         Assert.AreEqual (4, r.Count);
243                         Assert.AreEqual (22, r [0]);
244                         Assert.AreEqual (80, r [1]);
245                         Assert.AreEqual (56, r [2]);
246                         Assert.AreEqual (52, r [3]);
247                 }
248
249                 [Test]
250                 public void EnumeratorTest ()
251                 {
252                         List <int>.Enumerator e = _list1.GetEnumerator ();
253                         for (int i = 0; i < _list1_contents.Length; i++)
254                         {
255                                 Assert.IsTrue (e.MoveNext ());
256                                 Assert.AreEqual (_list1_contents [i], e.Current);
257                         }
258                         Assert.IsFalse (e.MoveNext ());
259                 }
260
261                 [Test]
262                 public void ConstructWithSizeTest ()
263                 {
264                         List <object> l_1 = new List <object> (1);
265                         List <object> l_2 = new List <object> (50);
266                         List <object> l_3 = new List <object> (0);
267
268                         Assert.AreEqual (1, l_1.Capacity);
269                         Assert.AreEqual (50, l_2.Capacity);
270                         Assert.AreEqual (0, l_3.Capacity);
271                 }
272
273                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
274                 public void ConstructWithInvalidSizeTest ()
275                 {
276                         List <int> l = new List <int> (-1);
277                 }
278
279                 [Test]
280                 public void ConstructWithCollectionTest ()
281                 {
282                         List <int> l1 = new List <int> (_list1);
283                         Assert.AreEqual (_list1.Count, l1.Count);
284                         Assert.AreEqual (l1.Count, l1.Capacity);
285                         for (int i = 0; i < l1.Count; i++)
286                                 Assert.AreEqual (_list1 [i], l1 [i]);
287
288                         var input = new [] { "a", "b", "c" };
289                         var l2 = new List<string>(input);
290                         Assert.AreEqual (3, l2.Capacity);
291                 }
292
293                 [Test, ExpectedException (typeof (ArgumentNullException))]
294                 public void ConstructWithInvalidCollectionTest ()
295                 {
296                         List <int> n = null;
297                         List <int> l1 = new List <int> (n);
298                 }
299
300                 [Test]
301                 public void AddTest ()
302                 {
303                         int count = _list1.Count;
304                         _list1.Add (-1);
305                         Assert.AreEqual (count + 1, _list1.Count);
306                         Assert.AreEqual (-1, _list1 [_list1.Count - 1]);
307                 }
308
309                 [Test]
310                 public void AddRangeTest ()
311                 {
312                         int count = _list1.Count;
313                         // FIXME arrays currently do not support generic collection
314                         // interfaces
315                         int [] range = { -1, -2, -3 };
316                         List <int> tmp = new List <int> (3);
317                         foreach (int i in range)
318                                 tmp.Add (i);
319                         // _list1.AddRange (range);
320                         _list1.AddRange (tmp);
321                         
322                         Assert.AreEqual (count + 3, _list1.Count);
323                         Assert.AreEqual (-1, _list1 [_list1.Count - 3]);
324                         Assert.AreEqual (-2, _list1 [_list1.Count - 2]);
325                         Assert.AreEqual (-3, _list1 [_list1.Count - 1]);
326                 }
327
328                 [Test, ExpectedException (typeof (ArgumentNullException))]
329                 public void AddNullRangeTest ()
330                 {
331                         int [] n = null;
332                         _list1.AddRange (n);
333                 }
334
335                 [Test]
336                 public void BinarySearchTest ()
337                 {
338                         List <int> l = new List <int> (_list1);
339                         l.Sort ();
340                         Assert.AreEqual (0, l.BinarySearch (22));
341                         Assert.AreEqual (-2, l.BinarySearch (23));
342                         Assert.AreEqual (- (l.Count + 1), l.BinarySearch (int.MaxValue));
343                 }
344
345
346                 [Test]
347                 public void DeserializeTest ()
348                 {
349                         MemoryStream ms = new MemoryStream ();
350                         ms.Write (_serializedList, 0, _serializedList.Length);
351                         ms.Position = 0;
352
353                         BinaryFormatter bf = new BinaryFormatter ();
354                         List<int> list = (List<int>) bf.Deserialize (ms);
355                         Assert.AreEqual (3, list.Count, "#1");
356                         Assert.AreEqual (5, list [0], "#2");
357                         Assert.AreEqual (0, list [1], "#3");
358                         Assert.AreEqual (7, list [2], "#4");
359                 }
360
361                 [Test]
362                 public void SortTest ()
363                 {
364                         List <int> l = new List <int> (_list1);
365                         l.Sort ();
366                         Assert.AreEqual (_list1.Count, l.Count);
367                         Assert.AreEqual (22, l [0]);
368                         int minimum = 22;
369                         foreach (int i in l)
370                         {
371                                 Assert.IsTrue (minimum <= i);
372                                 minimum = i;
373                         }
374                 }
375
376                 [Test]
377                 public void ClearTest ()
378                 {
379                         int capacity = _list1.Capacity;
380                         _list1.Clear ();
381                         Assert.AreEqual (0, _list1.Count);
382                         Assert.AreEqual (capacity, _list1.Capacity);
383                 }
384
385                 [Test]
386                 public void ContainsTest ()
387                 {
388                         Assert.IsTrue (_list1.Contains (22));
389                         Assert.IsFalse (_list1.Contains (23));
390                 }
391
392                 private string StringConvert (int i)
393                 {
394                         return i.ToString ();
395                 }
396                 
397                 [Test]
398                 public void ConvertAllTest ()
399                 {
400                         List <string> s = _list1.ConvertAll ( (Converter <int, string>)StringConvert);
401                         Assert.AreEqual (_list1.Count, s.Count);
402                         Assert.AreEqual ("55", s [0]);
403                 }
404
405                 [Test]
406                 public void CopyToTest ()
407                 {
408                         int [] a = new int [2];
409                         _list1.CopyTo (1, a, 0, 2);
410                         Assert.AreEqual (50, a [0]);
411                         Assert.AreEqual (22, a [1]);
412
413                         int [] b = new int [_list1.Count + 1];
414                         b [_list1.Count] = 555;
415                         _list1.CopyTo (b);
416                         Assert.AreEqual (55, b [0]);
417                         Assert.AreEqual (555, b [_list1.Count]);
418
419                         b [0] = 888;
420                         _list1.CopyTo (b, 1);
421                         Assert.AreEqual (888, b [0]);
422                         Assert.AreEqual (55, b [1]);
423                 }
424
425                 [Test, ExpectedException (typeof (ArgumentNullException))]
426                 public void CopyToNullTest ()
427                 {
428                         int [] a = null;
429                         _list1.CopyTo (0, a, 0, 0);
430                 }
431
432                 static bool FindMultipleOfThree (int i)
433                 {
434                         return (i % 3) == 0;
435                 }
436
437                 static bool FindMultipleOfFour (int i)
438                 {
439                         return (i % 4) == 0;
440                 }
441
442                 static bool FindMultipleOfTwelve (int i)
443                 {
444                         return (i % 12) == 0;
445                 }
446
447                 [Test]
448                 public void FindTest ()
449                 {
450                         int i = _list1.Find (FindMultipleOfThree);
451                         Assert.AreEqual (63, i);
452
453                         i = _list1.Find (FindMultipleOfTwelve);
454                         Assert.AreEqual (default (int), i);
455                 }
456
457                 [Test, ExpectedException (typeof (ArgumentNullException))]
458                 public void FindNullTest ()
459                 {
460                         int i = _list1.Find (null);
461                 }
462
463                 [Test]
464                 public void FindAllSmallTest ()
465                 {
466                         List <int> findings = _list1.FindAll (FindMultipleOfFour);
467                         Assert.AreEqual (4, findings.Count);
468                         Assert.AreEqual (80, findings [0]);
469                         Assert.AreEqual (56, findings [1]);
470                         Assert.AreEqual (52, findings [2]);
471                         Assert.AreEqual (40, findings [3]);
472
473                         findings = _list1.FindAll (FindMultipleOfTwelve);
474                         Assert.IsNotNull (findings);
475                         Assert.AreEqual (0, findings.Count);
476                 }
477                 
478                 [Test]
479                 public void FindAllMediumTest ()
480                 {
481                         List <int> integers = new List <int> (10000);
482                         for (int i = 1; i <= 10000; i++)
483                                 integers.Add (i);
484                         
485                         List <int> results = integers.FindAll (FindMultipleOfFour);
486                         
487                         Assert.IsNotNull (results);
488                         Assert.AreEqual (2500, results.Count);
489                         
490                         results = integers.FindAll (FindMultipleOfTwelve);
491                         
492                         Assert.IsNotNull (results);
493                         Assert.AreEqual (833, results.Count);
494                 }
495                 
496                 [Test]
497                 public void FindAllLargeTest ()
498                 {
499                         List <int> integers = new List <int> (70000);
500                         for (int i = 1; i <= 80000; i++)
501                                 integers.Add (i);
502                         
503                         List <int> results = integers.FindAll (FindMultipleOfFour);
504                         
505                         Assert.IsNotNull (results);
506                         Assert.AreEqual (20000, results.Count);
507                         
508                         results = integers.FindAll (FindMultipleOfTwelve);
509                         
510                         Assert.IsNotNull (results);
511                         Assert.AreEqual (6666, results.Count);
512                 }
513
514                 [Test, ExpectedException (typeof (ArgumentNullException))]
515                 public void FindAllNullTest ()
516                 {
517                         List <int> findings = _list1.FindAll (null);
518                 }
519
520                 [Test]
521                 public void FindIndexTest ()
522                 {
523                         int i = _list1.FindIndex (FindMultipleOfThree);
524                         Assert.AreEqual (7, i);
525
526                         i = _list1.FindIndex (FindMultipleOfTwelve);
527                         Assert.AreEqual (-1, i);
528
529                         var a = new List<int> () { 2, 2, 2, 3, 2 };
530                         Assert.AreEqual (2, a.FindIndex (2, 2, l => true));
531                 }
532
533                 [Test]
534                 public void FindIndex_Invalid ()
535                 {
536                         try {
537                                 _list1.FindIndex (null);
538                                 Assert.Fail ("#1");
539                         } catch (ArgumentNullException) {
540                         }
541
542                         try {
543                                 _list1.FindIndex (-1, l => true);
544                                 Assert.Fail ("#2");
545                         } catch (ArgumentOutOfRangeException) {
546                         }
547
548                         try {
549                                 _list1.FindIndex (-1, 0, l => true);
550                                 Assert.Fail ("#2b");
551                         } catch (ArgumentOutOfRangeException) {
552                         }
553
554                         try {
555                                 _list1.FindIndex (0, -1, l => true);
556                                 Assert.Fail ("#3");
557                         } catch (ArgumentOutOfRangeException) {
558                         }
559
560                         try {
561                                 _list1.FindIndex (100, l => true);
562                                 Assert.Fail ("#4");
563                         } catch (ArgumentOutOfRangeException) {
564                         }
565
566                         try {
567                                 _list1.FindIndex (100, 0, l => true);
568                                 Assert.Fail ("#4b");
569                         } catch (ArgumentOutOfRangeException) {
570                         }
571
572                         try {
573                                 _list1.FindIndex (7, 2, l => true);
574                                 Assert.Fail ("#5");
575                         } catch (ArgumentOutOfRangeException) {
576                         }
577                 }
578
579                 [Test]
580                 public void FindLastTest ()
581                 {
582                         int i = _list1.FindLast (FindMultipleOfFour);
583                         Assert.AreEqual (40, i);
584
585                         i = _list1.FindLast (FindMultipleOfTwelve);
586                         Assert.AreEqual (default (int), i);
587                 }
588
589                 [Test, ExpectedException (typeof (ArgumentNullException))]
590                 public void FindLastNullTest ()
591                 {
592                         int i = _list1.FindLast (null);
593                 }
594
595                 [Test]
596                 public void ForEachTest ()
597                 {
598                         int i = 0;
599                         _list1.ForEach (delegate (int j) { i += j; });
600
601                         Assert.AreEqual (418, i);
602                 }
603
604                 [Test]
605                 public void ForEach_Modified ()
606                 {
607                         try {
608                                 _list1.ForEach (l => _list1.Add (0));
609                                 Assert.Fail ();
610                         } catch (InvalidOperationException) {
611                         }
612                 }
613
614                 [Test]
615                 public void FindLastIndexTest ()
616                 {
617                         int i = _list1.FindLastIndex (FindMultipleOfFour);
618                         Assert.AreEqual (6, i);
619
620                         i = _list1.FindLastIndex (5, FindMultipleOfFour);
621                         Assert.AreEqual (5, i);
622
623                         i = _list1.FindIndex (FindMultipleOfTwelve);
624                         Assert.AreEqual (-1, i);
625
626                         Assert.AreEqual (2, _list1.FindLastIndex (2, 3, l => true));
627                         Assert.AreEqual (2, _list1.FindLastIndex (2, 2, l => true));
628                         Assert.AreEqual (1, _list1.FindLastIndex (1, 2, l => true));
629                 }
630
631                 [Test]
632                 public void FindLastIndex_Invalid ()
633                 {
634                         try {
635                                 _list1.FindLastIndex (null);
636                                 Assert.Fail ("#1");
637                         } catch (ArgumentNullException) {
638                         }
639
640                         try {
641                                 _list1.FindLastIndex (-1, l => true);
642                                 Assert.Fail ("#2");
643                         } catch (ArgumentOutOfRangeException) {
644                         }
645
646                         try {
647                                 _list1.FindLastIndex (-1, 0, l => true);
648                                 Assert.Fail ("#2b");
649                         } catch (ArgumentOutOfRangeException) {
650                         }
651
652                         try {
653                                 _list1.FindLastIndex (0, -1, l => true);
654                                 Assert.Fail ("#3");
655                         } catch (ArgumentOutOfRangeException) {
656                         }
657
658                         try {
659                                 _list1.FindLastIndex (100, l => true);
660                                 Assert.Fail ("#4");
661                         } catch (ArgumentOutOfRangeException) {
662                         }
663
664                         try {
665                                 _list1.FindLastIndex (100, 0, l => true);
666                                 Assert.Fail ("#4b");
667                         } catch (ArgumentOutOfRangeException) {
668                         }
669
670                         try {
671                                 _list1.FindLastIndex (2, 4, l => true);
672                                 Assert.Fail ("#5");
673                         } catch (ArgumentOutOfRangeException) {
674                         }
675                 }
676
677                 [Test]
678                 public void RemoveTest ()
679                 {
680                         int count = _list1.Count;
681                         bool result = _list1.Remove (22);
682                         Assert.IsTrue (result);
683                         Assert.AreEqual (count - 1, _list1.Count);
684
685                         Assert.AreEqual (-1, _list1.IndexOf (22));
686
687                         result = _list1.Remove (0);
688                         Assert.IsFalse (result);
689                 }
690
691                 [Test]
692                 public void RemoveAllTest ()
693                 {
694                         int count = _list1.Count;
695                         int removedCount = _list1.RemoveAll (FindMultipleOfFour);
696                         Assert.AreEqual (4, removedCount);
697                         Assert.AreEqual (count - 4, _list1.Count);
698
699                         removedCount = _list1.RemoveAll (FindMultipleOfTwelve);
700                         Assert.AreEqual (0, removedCount);
701                         Assert.AreEqual (count - 4, _list1.Count);
702                 }
703
704                 [Test]
705                 public void RemoveAtTest ()
706                 {
707                         int count = _list1.Count;
708                         _list1.RemoveAt (0);
709                         Assert.AreEqual (count - 1, _list1.Count);
710                         Assert.AreEqual (50, _list1 [0]);
711                 }
712
713                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
714                 public void RemoveOutOfRangeTest ()
715                 {
716                         _list1.RemoveAt (_list1.Count);
717                 }
718
719                 [Test]
720                 public void RemoveRangeTest ()
721                 {
722                         int count = _list1.Count;
723                         _list1.RemoveRange (1, 2);
724                         Assert.AreEqual (count - 2, _list1.Count);
725                         Assert.AreEqual (55, _list1 [0]);
726                         Assert.AreEqual (80, _list1 [1]);
727
728                         _list1.RemoveRange (0, 0);
729                         Assert.AreEqual (count - 2, _list1.Count);
730                 }
731
732                 [Test]
733                 public void RemoveRangeFromEmptyListTest ()
734                 {
735                         List<int> l = new List<int> ();
736                         l.RemoveRange (0, 0);
737                 }
738
739                 [Test, ExpectedException (typeof (ArgumentException))]
740                 public void RemoveRangeOutOfRangeTest ()
741                 {
742                         _list1.RemoveRange (1, _list1.Count);
743                 }
744
745                 [Test]
746                 public void ReverseTest ()
747                 {
748                         int count = _list1.Count;
749                         _list1.Reverse ();
750                         Assert.AreEqual (count, _list1.Count);
751
752                         Assert.AreEqual (63, _list1 [0]);
753                         Assert.AreEqual (55, _list1 [count - 1]);
754
755                         _list1.Reverse (0, 2);
756
757                         Assert.AreEqual (40, _list1 [0]);
758                         Assert.AreEqual (63, _list1 [1]);
759                 }
760
761                 [Test, ExpectedException (typeof (ArgumentException))]
762                 public void ReverseOutOfRangeTest ()
763                 {
764                         _list1.Reverse (1, _list1.Count);
765                 }
766
767                 [Test]
768                 public void ToArrayTest ()
769                 {
770                         int [] copiedContents = _list1.ToArray ();
771                         Assert.IsFalse (ReferenceEquals (copiedContents, _list1_contents));
772
773                         Assert.AreEqual (_list1.Count, copiedContents.Length);
774                         Assert.AreEqual (_list1 [0], copiedContents [0]);
775                 }
776
777                 [Test]
778                 public void TrimExcessTest ()
779                 {
780                         List <string> l = new List <string> ();
781                         l.Add ("foo");
782
783                         Assert.IsTrue (l.Count < l.Capacity);
784                         l.TrimExcess ();
785                         Assert.AreEqual (l.Count, l.Capacity);
786                 }
787
788                 bool IsPositive (int i)
789                 {
790                         return i >= 0;
791                 }
792
793                 [Test]
794                 public void TrueForAllTest ()
795                 {
796                         Assert.IsFalse (_list1.TrueForAll (FindMultipleOfFour));
797                         Assert.IsTrue (_list1.TrueForAll (IsPositive));
798                 }
799
800                 [Test, ExpectedException (typeof (ArgumentNullException))]
801                 public void TrueForAllNullTest ()
802                 {
803                         _list1.TrueForAll (null);
804                 }
805
806                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
807                 public void CapacityOutOfRangeTest ()
808                 {
809                         _list1.Capacity = _list1.Count - 1;
810                 }
811
812                 [Test]
813                 public void BinarySearch_EmptyList ()
814                 {
815                         GenericComparer<int> comparer = new GenericComparer<int> ();
816                         List<int> l = new List<int> ();
817                         Assert.AreEqual (-1, l.BinarySearch (0, comparer), "BinarySearch");
818                         // bug 77030 - the comparer isn't called for an empty array/list
819                         Assert.IsFalse (comparer.Called, "Called");
820                 }
821
822                 [Test]
823                 public void BinarySearch2_EmptyList ()
824                 {
825                         GenericComparer<int> comparer = new GenericComparer<int> ();
826                         List<int> l = new List<int> ();
827                         Assert.AreEqual (-1, l.BinarySearch (0, 0, 0, comparer), "BinarySearch");
828                         // bug 77030 - the comparer isn't called for an empty array/list
829                         Assert.IsFalse (comparer.Called, "Called");
830                 }
831
832                 [Test]
833                 public void AddRange_Bug77019 ()
834                 {
835                         List<int> l = new List<int> ();
836                         Dictionary<string, int> d = new Dictionary<string, int> ();
837                         l.AddRange (d.Values);
838                         Assert.AreEqual (0, l.Count, "Count");
839                 }
840
841                 [Test]
842                 public void VersionCheck_Add ()
843                 {
844                         List<int> list = new List<int> ();
845                         IEnumerator enumerator = list.GetEnumerator ();
846                         list.Add (5);
847
848                         try {
849                                 enumerator.MoveNext ();
850                                 Assert.Fail ("#1");
851                         } catch (InvalidOperationException) {
852                         }
853
854                         try {
855                                 enumerator.Reset ();
856                                 Assert.Fail ("#2");
857                         } catch (InvalidOperationException) {
858                         }
859
860                         enumerator = list.GetEnumerator ();
861                         enumerator.MoveNext ();
862                 }
863
864                 [Test]
865                 public void VersionCheck_AddRange ()
866                 {
867                         List<int> list = new List<int> ();
868                         IEnumerator enumerator = list.GetEnumerator ();
869                         list.AddRange (new int [] { 5, 7 });
870
871                         try {
872                                 enumerator.MoveNext ();
873                                 Assert.Fail ("#1");
874                         } catch (InvalidOperationException) {
875                         }
876
877                         try {
878                                 enumerator.Reset ();
879                                 Assert.Fail ("#2");
880                         } catch (InvalidOperationException) {
881                         }
882
883                         enumerator = list.GetEnumerator ();
884                         enumerator.MoveNext ();
885                 }
886
887                 [Test]
888                 public void VersionCheck_Clear ()
889                 {
890                         List<int> list = new List<int> ();
891                         IEnumerator enumerator = list.GetEnumerator ();
892                         list.Clear ();
893
894                         try {
895                                 enumerator.MoveNext ();
896                                 Assert.Fail ("#1");
897                         } catch (InvalidOperationException) {
898                         }
899
900                         try {
901                                 enumerator.Reset ();
902                                 Assert.Fail ("#2");
903                         } catch (InvalidOperationException) {
904                         }
905
906                         enumerator = list.GetEnumerator ();
907                         enumerator.MoveNext ();
908                 }
909
910                 [Test]
911                 public void VersionCheck_Insert ()
912                 {
913                         List<int> list = new List<int> ();
914                         IEnumerator enumerator = list.GetEnumerator ();
915                         list.Insert (0, 7);
916
917                         try {
918                                 enumerator.MoveNext ();
919                                 Assert.Fail ("#1");
920                         } catch (InvalidOperationException) {
921                         }
922
923                         try {
924                                 enumerator.Reset ();
925                                 Assert.Fail ("#2");
926                         } catch (InvalidOperationException) {
927                         }
928
929                         enumerator = list.GetEnumerator ();
930                         enumerator.MoveNext ();
931                 }
932
933                 [Test]
934                 public void VersionCheck_InsertRange ()
935                 {
936                         List<int> list = new List<int> ();
937                         IEnumerator enumerator = list.GetEnumerator ();
938                         list.InsertRange (0, new int [] { 5, 7 });
939
940                         try {
941                                 enumerator.MoveNext ();
942                                 Assert.Fail ("#1");
943                         } catch (InvalidOperationException) {
944                         }
945
946                         try {
947                                 enumerator.Reset ();
948                                 Assert.Fail ("#2");
949                         } catch (InvalidOperationException) {
950                         }
951
952                         enumerator = list.GetEnumerator ();
953                         enumerator.MoveNext ();
954                 }
955
956                 [Test]
957                 public void VersionCheck_Remove ()
958                 {
959                         List<int> list = new List<int> ();
960                         list.Add (5);
961                         IEnumerator enumerator = list.GetEnumerator ();
962                         // version number is not incremented if item does not exist in list
963                         list.Remove (7);
964                         enumerator.MoveNext ();
965                         list.Remove (5);
966
967                         try {
968                                 enumerator.MoveNext ();
969                                 Assert.Fail ("#1");
970                         } catch (InvalidOperationException) {
971                         }
972
973                         try {
974                                 enumerator.Reset ();
975                                 Assert.Fail ("#2");
976                         } catch (InvalidOperationException) {
977                         }
978
979                         enumerator = list.GetEnumerator ();
980                         enumerator.MoveNext ();
981                 }
982
983                 [Test]
984                 public void VersionCheck_RemoveAll ()
985                 {
986                         List<int> list = new List<int> ();
987                         list.Add (5);
988                         IEnumerator enumerator = list.GetEnumerator ();
989                         // version is not incremented if there are no items to remove
990                         list.RemoveAll (FindMultipleOfFour);
991                         enumerator.MoveNext ();
992                         list.Add (4);
993
994                         enumerator = list.GetEnumerator ();
995                         list.RemoveAll (FindMultipleOfFour);
996
997                         try {
998                                 enumerator.MoveNext ();
999                                 Assert.Fail ("#1");
1000                         } catch (InvalidOperationException) {
1001                         }
1002
1003                         try {
1004                                 enumerator.Reset ();
1005                                 Assert.Fail ("#2");
1006                         } catch (InvalidOperationException) {
1007                         }
1008
1009                         enumerator = list.GetEnumerator ();
1010                         enumerator.MoveNext ();
1011                 }
1012
1013                 [Test]
1014                 public void VersionCheck_RemoveAt ()
1015                 {
1016                         List<int> list = new List<int> ();
1017                         list.Add (5);
1018                         IEnumerator enumerator = list.GetEnumerator ();
1019                         list.RemoveAt (0);
1020
1021                         try {
1022                                 enumerator.MoveNext ();
1023                                 Assert.Fail ("#1");
1024                         } catch (InvalidOperationException) {
1025                         }
1026
1027                         try {
1028                                 enumerator.Reset ();
1029                                 Assert.Fail ("#2");
1030                         } catch (InvalidOperationException) {
1031                         }
1032
1033                         enumerator = list.GetEnumerator ();
1034                         enumerator.MoveNext ();
1035                 }
1036
1037                 [Test]
1038                 public void VersionCheck_RemoveRange ()
1039                 {
1040                         List<int> list = new List<int> ();
1041                         list.Add (5);
1042                         IEnumerator enumerator = list.GetEnumerator ();
1043                         // version is not incremented if count is zero
1044                         list.RemoveRange (0, 0);
1045                         enumerator.MoveNext ();
1046                         enumerator.Reset ();
1047                         list.RemoveRange (0, 1);
1048
1049                         try {
1050                                 enumerator.MoveNext ();
1051                                 Assert.Fail ("#1");
1052                         } catch (InvalidOperationException) {
1053                         }
1054
1055                         try {
1056                                 enumerator.Reset ();
1057                                 Assert.Fail ("#2");
1058                         } catch (InvalidOperationException) {
1059                         }
1060
1061                         enumerator = list.GetEnumerator ();
1062                         enumerator.MoveNext ();
1063                 }
1064
1065                 [Test, ExpectedException (typeof (InvalidOperationException))] // #699182
1066                 public void VersionCheck_Indexer ()
1067                 {
1068                         var list = new List<int> () { 0, 2, 3 };
1069                         var enumerator = list.GetEnumerator ();
1070
1071                         list [0] = 1;
1072
1073                         enumerator.MoveNext ();
1074                 }
1075
1076                 [Test]
1077                 public void VersionCheck_Reverse ()
1078                 {
1079                         List<int> list = new List<int> ();
1080                         IEnumerator enumerator = list.GetEnumerator ();
1081                         list.Reverse ();
1082
1083                         try {
1084                                 enumerator.MoveNext ();
1085                                 Assert.Fail ("#A1");
1086                         } catch (InvalidOperationException) {
1087                         }
1088
1089                         try {
1090                                 enumerator.Reset ();
1091                                 Assert.Fail ("#A2");
1092                         } catch (InvalidOperationException) {
1093                         }
1094
1095                         enumerator = list.GetEnumerator ();
1096                         list.Reverse (0, 0);
1097
1098                         try {
1099                                 enumerator.MoveNext ();
1100                                 Assert.Fail ("#B1");
1101                         } catch (InvalidOperationException) {
1102                         }
1103
1104                         try {
1105                                 enumerator.Reset ();
1106                                 Assert.Fail ("#B2");
1107                         } catch (InvalidOperationException) {
1108                         }
1109
1110                         enumerator = list.GetEnumerator ();
1111                         enumerator.MoveNext ();
1112                 }
1113
1114                 class SortTestComparer: IComparer<string> {
1115
1116                         public int Compare (string s1, string s2)
1117                         {
1118                                 return String.Compare (s1, s2);
1119                         }
1120                 }
1121
1122                 [Test]
1123                 public void Sort_Bug76361 ()
1124                 {
1125                         SortTestComparer comparer = new SortTestComparer ();
1126                         List<string> l = new List<string> ();
1127                         l.Add ("foo");
1128                         l.Add ("bar");
1129                         l.Sort (comparer);
1130                         Assert.AreEqual ("bar", l[0], "0");
1131                         Assert.AreEqual ("foo", l[1], "1");
1132                         Assert.AreEqual (2, l.Count, "Count");
1133                 }
1134
1135                 // for bug #77039 test case
1136                 class GenericIComparable: IComparable<GenericIComparable> {
1137                         private int _NumberToSortOn;
1138
1139                         public int NumberToSortOn {
1140                                 get { return _NumberToSortOn; }
1141                                 set { _NumberToSortOn = value; }
1142                         }
1143
1144                         public GenericIComparable (int val)
1145                         {
1146                                 _NumberToSortOn = val;
1147                         }
1148
1149                         public int CompareTo (GenericIComparable other)
1150                         {
1151                                 return NumberToSortOn.CompareTo (other.NumberToSortOn);
1152                         }
1153                 }
1154
1155                 [Test]
1156                 public void Sort_GenericIComparable_Bug77039 ()
1157                 {
1158                         List<GenericIComparable> l = new List<GenericIComparable> ();
1159                         l.Add (new GenericIComparable (2));
1160                         l.Add (new GenericIComparable (1));
1161                         l.Add (new GenericIComparable (3));
1162                         l.Sort ();
1163                         Assert.AreEqual (1, l[0].NumberToSortOn, "0");
1164                         Assert.AreEqual (2, l[1].NumberToSortOn, "1");
1165                         Assert.AreEqual (3, l[2].NumberToSortOn, "2");
1166                 }
1167
1168                 class NonGenericIComparable: IComparable {
1169                         private int _NumberToSortOn;
1170
1171                         public int NumberToSortOn {
1172                                 get { return _NumberToSortOn; }
1173                                 set { _NumberToSortOn = value; }
1174                         }
1175
1176                         public NonGenericIComparable (int val)
1177                         {
1178                                 _NumberToSortOn = val;
1179                         }
1180
1181                         public int CompareTo (object obj)
1182                         {
1183                                 return NumberToSortOn.CompareTo ((obj as NonGenericIComparable).NumberToSortOn);
1184                         }
1185                 }
1186
1187                 [Test]
1188                 public void Sort_NonGenericIComparable ()
1189                 {
1190                         List<NonGenericIComparable> l = new List<NonGenericIComparable> ();
1191                         l.Add (new NonGenericIComparable (2));
1192                         l.Add (new NonGenericIComparable (1));
1193                         l.Add (new NonGenericIComparable (3));
1194                         l.Sort ();
1195                         Assert.AreEqual (1, l[0].NumberToSortOn, "0");
1196                         Assert.AreEqual (2, l[1].NumberToSortOn, "1");
1197                         Assert.AreEqual (3, l[2].NumberToSortOn, "2");
1198                 }
1199
1200                 class NonComparable {
1201                 }
1202
1203                 [Test]
1204                 public void Sort_GenericNonIComparable ()
1205                 {
1206                         List<NonComparable> l = new List<NonComparable> ();
1207                         l.Sort ();
1208                         // no element -> no sort -> no exception
1209                         l.Add (new NonComparable ());
1210                         l.Sort ();
1211                         // one element -> no sort -> no exception
1212                 }
1213
1214                 [Test]
1215                 [ExpectedException (typeof (InvalidOperationException))]
1216                 public void Sort_GenericNonIComparable_2 ()
1217                 {
1218                         List<NonComparable> l = new List<NonComparable> ();
1219                         l.Add (new NonComparable ());
1220                         l.Add (new NonComparable ());
1221                         l.Sort ();
1222                         // two element -> sort -> exception!
1223                 }
1224                 
1225                 [Test]
1226                 public void IList_Contains_InvalidType()
1227                 {
1228                         List<string> list = new List<string>();
1229                         list.Add("foo");
1230                         Assert.IsFalse (((IList)list).Contains(new object()));
1231
1232                         Assert.IsFalse (((IList)_list1).Contains(null));
1233                 }
1234                 
1235                 [Test]
1236                 public void IList_IndexOf_InvalidType()
1237                 {
1238                         List<string> list = new List<string>();
1239                         list.Add("foo");
1240                         Assert.AreEqual (-1, ((IList)list).IndexOf(new object()));
1241
1242                         Assert.AreEqual (-1, ((IList)_list1).IndexOf(null));
1243                 }
1244
1245                 // for bug #77277 test case
1246                 [Test]
1247                 public void Test_ContainsAndIndexOf_EquatableItem ()
1248                 {
1249                         List<EquatableClass> list = new List<EquatableClass> ();
1250                         EquatableClass item0 = new EquatableClass (0);
1251                         EquatableClass item1 = new EquatableClass (1);
1252
1253                         list.Add (item0);
1254                         list.Add (item1);
1255                         list.Add (item0);
1256
1257                         Assert.AreEqual (true, list.Contains (item0), "#0");
1258                         Assert.AreEqual (true, list.Contains (new EquatableClass (0)), "#1");
1259                         Assert.AreEqual (0, list.IndexOf (item0), "#2");
1260                         Assert.AreEqual (0, list.IndexOf (new EquatableClass (0)), "#3");
1261                         Assert.AreEqual (2, list.LastIndexOf (item0), "#4");
1262                         Assert.AreEqual (2, list.LastIndexOf (new EquatableClass (0)), "#5");
1263                 }
1264
1265                 // for bug #81387 test case
1266                 [Test]
1267                 public void Test_Contains_After_Remove ()
1268                 {
1269                         List<int> list = new List<int> ();
1270             list.Add (2);
1271
1272             list.Remove (2);
1273
1274                         Assert.AreEqual (false, list.Contains (2), "#0");
1275                 }
1276                 
1277                 [Test]
1278                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1279                 public void SetItem_OutOfRange()
1280                 {
1281                         List<string> list = new List<string>();
1282                         list[0] = "foo";
1283                 }
1284                 
1285                 [Test]
1286                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1287                 public void SetItem_IList_OutOfRange()
1288                 {
1289                         IList<string> list = new List<string>();
1290                         list[0] = "foo";
1291                 }
1292
1293                 public class EquatableClass : IEquatable<EquatableClass>
1294                 {
1295                         int _x;
1296                         public EquatableClass (int x)
1297                         {
1298                                 _x = x;
1299                         }
1300
1301                         public bool Equals (EquatableClass other)
1302                         {
1303                                 return this._x == other._x;
1304                         }
1305                 }
1306
1307                 delegate void D ();
1308                 bool Throws (D d)
1309                 {
1310                         try {
1311                                 d ();
1312                                 return false;
1313                         } catch {
1314                                 return true;
1315                         }
1316                 }
1317
1318                 [Test]
1319                 // based on #491858, #517415
1320                 public void Enumerator_Current ()
1321                 {
1322                         var e1 = new List<int>.Enumerator ();
1323                         Assert.IsFalse (Throws (delegate { var x = e1.Current; }));
1324
1325                         var d = new List<int> ();
1326                         var e2 = d.GetEnumerator ();
1327                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1328                         e2.MoveNext ();
1329                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1330                         e2.Dispose ();
1331                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1332
1333                         var e3 = ((IEnumerable<int>) d).GetEnumerator ();
1334                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1335                         e3.MoveNext ();
1336                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1337                         e3.Dispose ();
1338                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1339
1340                         var e4 = ((IEnumerable) d).GetEnumerator ();
1341                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1342                         e4.MoveNext ();
1343                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1344                         ((IDisposable) e4).Dispose ();
1345                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1346                 }
1347
1348                 [Test]
1349                 public void Enumerator_Reset ()
1350                 {
1351                         var l = new List<int> () {
1352                                 4
1353                         };
1354
1355                         IEnumerator<int> e = l.GetEnumerator ();
1356                         Assert.IsTrue (e.MoveNext (), "#1");
1357                         Assert.AreEqual (4, e.Current, "#2");
1358                         e.Reset ();
1359                         Assert.AreEqual (0, e.Current, "#3");
1360                 }
1361
1362                 [Test] //bug #672907
1363                 public void ICollectionCopyToExceptions ()
1364                 {
1365                         var l = new List <int> ();
1366                         ICollection x = l;
1367                         try {
1368                                 x.CopyTo (null, 0);
1369                                 Assert.Fail ("#1");
1370                         } catch (Exception e) {
1371                                 Assert.IsTrue (e is ArgumentNullException, "#2");
1372                         }
1373
1374                         try {
1375                                 x.CopyTo (new int [10], -1);
1376                                 Assert.Fail ("#3");
1377                         } catch (Exception e) {
1378                                 Assert.IsTrue (e is ArgumentOutOfRangeException, "#4");
1379                         }
1380
1381                         try {
1382                                 x.CopyTo (new int [10, 1], 0);
1383                                 Assert.Fail ("#5");
1384                         } catch (Exception e) {
1385                                 Assert.IsTrue (e is ArgumentException, "#6");
1386                         }
1387
1388                         try {
1389                                 x.CopyTo (Array.CreateInstance (typeof (int), new int [] { 10 }, new int[] { 1 }), 0);
1390                                 Assert.Fail ("#7");
1391                         } catch (Exception e) {
1392                                 Assert.IsTrue (e is ArgumentOutOfRangeException, "#8");
1393                         }
1394
1395                         l.Add (10); l.Add (20);
1396                         try {
1397                                 x.CopyTo (new int [1], 0);
1398                                 Assert.Fail ("#9");
1399                         } catch (Exception e) {
1400                                 Assert.IsTrue (e is ArgumentException, "#10");
1401                         }
1402                 }
1403
1404                 [Test]
1405                 public void LastIndexOfEmpty_2558 () {
1406                         var l = new List<int> ();
1407                         Assert.AreEqual (-1, l.IndexOf (-1));
1408                 }
1409
1410
1411 #region Enumerator mutability
1412
1413                 class Bar
1414                 {
1415                 }
1416
1417                 class Foo : IEnumerable<Bar>
1418                 {
1419                         Baz enumerator;
1420
1421                         public Foo ()
1422                         {
1423                                 enumerator = new Baz ();
1424                         }
1425
1426                         public IEnumerator<Bar> GetEnumerator ()
1427                         {
1428                                 return enumerator;
1429                         }
1430
1431                         IEnumerator IEnumerable.GetEnumerator ()
1432                         {
1433                                 return enumerator;
1434                         }
1435                 }
1436
1437                 class Baz : IEnumerator<Bar>
1438                 {
1439                         public bool DisposeWasCalled = false;
1440
1441                         public void Dispose ()
1442                         {
1443                                 DisposeWasCalled = true;
1444                         }
1445
1446                         public bool MoveNext ()
1447                         {
1448                                 return false; //assume empty collection
1449                         }
1450
1451                         public void Reset ()
1452                         {
1453                         }
1454
1455                         public Bar Current
1456                         {
1457                                 get { return null; }
1458                         }
1459
1460                         object IEnumerator.Current
1461                         {
1462                                 get { return Current; }
1463                         }
1464                 }
1465
1466                 [Test]
1467                 public void PremiseAboutDisposeBeingCalledWhenLooping ()
1468                 {
1469                         Foo enumerable = new Foo ();
1470                         Baz enumerator = enumerable.GetEnumerator () as Baz;
1471                         Assert.IsNotNull (enumerator);
1472                         Assert.AreEqual (false, enumerator.DisposeWasCalled);
1473                         foreach (var element in enumerable) ; //sic
1474                         Assert.AreEqual (true, enumerator.DisposeWasCalled);
1475                 }
1476
1477                 [Test]
1478                 public void TwoEnumeratorsOfTwoDifferentListsAreDifferent ()
1479                 {
1480                         var twoThree = new List<int> { 2, 3 };
1481                         var oneTwo = new List<int> { 2, 4 };
1482                         Assert.IsFalse (oneTwo.GetEnumerator ().Equals (twoThree.GetEnumerator ()));
1483                 }
1484
1485                 [Test]
1486                 public void TwoEnumeratorsOfTwoDifferentListsWithSameElementsAreDifferent ()
1487                 {
1488                         var twoThree = new List<int> { 2, 3 };
1489                         var anotherTwoThree = new List<int> { 2, 3 };
1490                         Assert.IsFalse(twoThree.GetEnumerator ().Equals (anotherTwoThree.GetEnumerator ()));
1491                 }
1492
1493                 [Test]
1494                 public void EnumeratorIsSameInSameListAfterSubsequentCalls ()
1495                 {
1496                         var enumerable = new List<Bar> ();
1497                         var enumerator = enumerable.GetEnumerator ();
1498                         var enumerator2 = enumerable.GetEnumerator ();
1499
1500                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1501
1502                         Assert.IsTrue (enumerator2.Equals (enumerator));
1503                 }
1504
1505
1506                 [Test] // was bug in Mono 2.10.9
1507                 public void EnumeratorIsStillSameInSubsequentCallsEvenHavingADisposalInBetween ()
1508                 {
1509                         var enumerable = new List<Bar> ();
1510                         var enumerator = enumerable.GetEnumerator ();
1511                         enumerator.Dispose ();
1512                         var enumerator2 = enumerable.GetEnumerator ();
1513
1514                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1515
1516                         Assert.IsTrue (enumerator2.Equals (enumerator));
1517                 }
1518
1519                 [Test]
1520                 public void EnumeratorIsObviouslyDifferentAfterListChanges ()
1521                 {
1522                         var enumerable = new List<Bar> ();
1523                         var enumerator = enumerable.GetEnumerator ();
1524                         enumerable.Add (new Bar ());
1525                         var enumerator2 = enumerable.GetEnumerator ();
1526
1527                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1528
1529                         Assert.IsFalse (enumerator2.Equals (enumerator));
1530                 }
1531
1532                 [Test] // was bug in Mono 2.10.9
1533                 public void DotNetDoesntThrowObjectDisposedExceptionAfterSubsequentDisposes()
1534                 {
1535                         var enumerable = new List<Bar> ();
1536                         var enumerator = enumerable.GetEnumerator ();
1537                         Assert.AreEqual (false, enumerator.MoveNext ());
1538                         enumerator.Dispose();
1539                         Assert.AreEqual (false, enumerator.MoveNext ());
1540                 }
1541 #endregion
1542
1543
1544         }
1545 }
1546