Fix for the bug #4328.
[mono.git] / mcs / class / System / Test / System.Collections.Generic / SortedListTest.cs
1 // 
2 // System.Collections.SortedListTest.cs
3 // 
4 // Author:
5 //   Zoltan Varga (vargaz@gmail.com)
6 // 
7
8 //
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 #if NET_2_0
32
33 using System;
34 using System.Collections;
35 using System.Collections.Generic;
36 using System.IO;
37 using System.Text;
38 using System.Runtime.Serialization;
39 using System.Runtime.Serialization.Formatters.Binary;
40 using NUnit.Framework;
41
42 namespace MonoTests.System.Collections.Generic
43 {
44         [TestFixture]
45         public class SortedListTest
46         {
47                 SortedList<int, string> list;
48                 SortedList<string, int> list2;
49
50                 [SetUp]
51                 public void SetUp () {
52                         list = new SortedList <int, string> ();
53
54                         list [0] = "A";
55                         list [5] = "C";
56                         list [2] = "B";
57
58                         list2 = new SortedList<string, int> ();
59                 }
60
61                 [Test]
62                 public void Item () {
63                         Assert.AreEqual ("A", list [0]);
64                         Assert.AreEqual ("B", list [2]);
65                         Assert.AreEqual ("C", list [5]);
66
67                         list [2] = "D";
68
69                         Assert.AreEqual ("D", list [2]);
70                 }
71
72                 [Test]
73                 [ExpectedException (typeof (ArgumentNullException))]
74                 public void ItemNullKey () {
75                         int i = list2 [null];
76                 }
77
78                 [Test]
79                 [ExpectedException (typeof (KeyNotFoundException))]
80                 public void ItemMissingKey () {
81                         string s = list [99];
82                 }
83
84                 [Test]
85                 public void Keys () {
86                         IList<int> keys = list.Keys;
87
88                         Assert.AreEqual (3, keys.Count);
89                         Assert.AreEqual (0, keys [0]);
90                         Assert.AreEqual (2, keys [1]);
91                         Assert.AreEqual (5, keys [2]);
92
93                         int[] arr = new int [4];
94                         keys.CopyTo (arr, 1);
95                         Assert.AreEqual (0, arr [1]);
96                         Assert.AreEqual (2, arr [2]);
97                         Assert.AreEqual (5, arr [3]);
98
99                         Assert.AreEqual (true, keys.Contains (2));
100                         Assert.AreEqual (false, keys.Contains (100));
101
102                         Assert.AreEqual (2, keys.IndexOf (5));
103                         Assert.AreEqual (-1, keys.IndexOf (100));
104
105                         int index = 0;
106                         arr [0] = 0;
107                         arr [1] = 0;
108                         arr [2] = 0;
109                         foreach (int i in keys)
110                                 arr [index ++] = i;
111                         Assert.AreEqual (0, arr [0]);
112                         Assert.AreEqual (2, arr [1]);
113                         Assert.AreEqual (5, arr [2]);
114                 }
115
116                 [Test]
117                 public void KeysNonGeneric () {
118                         ICollection keys = ((IDictionary)list).Keys;
119
120                         Assert.AreEqual (3, keys.Count);
121
122                         int[] arr = new int [4];
123                         keys.CopyTo (arr, 1);
124                         Assert.AreEqual (0, arr [1]);
125                         Assert.AreEqual (2, arr [2]);
126                         Assert.AreEqual (5, arr [3]);
127
128                         int index = 0;
129                         arr [0] = 0;
130                         arr [1] = 0;
131                         arr [2] = 0;
132                         foreach (int i in keys)
133                                 arr [index ++] = i;
134                         Assert.AreEqual (0, arr [0]);
135                         Assert.AreEqual (2, arr [1]);
136                         Assert.AreEqual (5, arr [2]);
137                 }
138
139                 [Test]
140                 public void Values () {
141                         IList<string> values = list.Values;
142
143                         Assert.AreEqual (3, values.Count);
144                         Assert.AreEqual ("A", values [0]);
145                         Assert.AreEqual ("B", values [1]);
146                         Assert.AreEqual ("C", values [2]);
147
148                         string[] arr = new string [4];
149                         values.CopyTo (arr, 1);
150                         Assert.AreEqual ("A", arr [1]);
151                         Assert.AreEqual ("B", arr [2]);
152                         Assert.AreEqual ("C", arr [3]);
153
154                         Assert.AreEqual (true, values.Contains ("B"));
155                         Assert.AreEqual (false, values.Contains ("X"));
156
157                         Assert.AreEqual (2, values.IndexOf ("C"));
158                         Assert.AreEqual (-1, values.IndexOf ("X"));
159
160                         int index = 0;
161                         arr [0] = null;
162                         arr [1] = null;
163                         arr [2] = null;
164                         foreach (string s in values)
165                                 arr [index ++] = s;
166                         Assert.AreEqual ("A", arr [0]);
167                         Assert.AreEqual ("B", arr [1]);
168                         Assert.AreEqual ("C", arr [2]);
169                 }
170
171                 [Test]
172                 public void ValuesNonGeneric () {
173                         ICollection values = ((IDictionary)list).Values;
174
175                         Assert.AreEqual (3, values.Count);
176
177                         string[] arr = new string [4];
178                         values.CopyTo (arr, 1);
179                         Assert.AreEqual ("A", arr [1]);
180                         Assert.AreEqual ("B", arr [2]);
181                         Assert.AreEqual ("C", arr [3]);
182
183                         int index = 0;
184                         arr [0] = null;
185                         arr [1] = null;
186                         arr [2] = null;
187                         foreach (string s in values)
188                                 arr [index ++] = s;
189                         Assert.AreEqual ("A", arr [0]);
190                         Assert.AreEqual ("B", arr [1]);
191                         Assert.AreEqual ("C", arr [2]);
192                 }
193
194                 [Test]
195                 public void KeysIDictionaryGeneric () {
196                         ICollection<int> keys = ((IDictionary<int,string>)list).Keys;
197
198                         Assert.AreEqual (3, keys.Count);
199                 }
200
201                 [Test]
202                 public void EmptyKeysCopyToZeroSizedArray ()
203                 {
204                         string [] ary = new string [0];
205                         list2.Keys.CopyTo (ary, 0);
206                 }
207
208                 [Test]
209                 public void EmptyValuesCopyToZeroSizedArray ()
210                 {
211                         int [] ary = new int [0];
212                         list2.Values.CopyTo (ary, 0);
213                 }
214
215                 [Test]
216                 public void ValuesIDictionaryGeneric () {
217                         ICollection<string> values = ((IDictionary<int,string>)list).Values;
218
219                         Assert.AreEqual (3, values.Count);
220                 }
221
222                 public void Add () {
223                         list.Add (10, "D");
224
225                         Assert.AreEqual ("D", list [10]);
226                 }
227
228                 [Test]
229                 [ExpectedException (typeof (ArgumentNullException))]
230                 public void AddNullKey () {
231                         list2.Add (null, 10);
232                 }
233
234                 [Test]
235                 [ExpectedException (typeof (ArgumentException))]
236                 public void AddKeyAlreadyExists () {
237                         list.Add (10, "B");
238                         list.Add (10, "C");
239                 }
240
241                 [Test]
242                 public void ContainsKey () {
243                         Assert.AreEqual (true, list.ContainsKey (5));
244                         Assert.AreEqual (false, list.ContainsKey (10));
245                 }
246
247                 [Test]
248                 public void Remove () {
249                         Assert.AreEqual (true, list.Remove (5));
250                         Assert.AreEqual (false, list.Remove (5));
251                         Assert.AreEqual (false, list.Remove (10));
252                 }
253
254                 [Test]
255                 [ExpectedException (typeof (ArgumentNullException))]
256                 public void RemoveNullKey () {
257                         list2.Remove (null);
258                 }
259
260                 [Test]
261                 public void GetEnumerator () {
262                         int[] keys = new int [3];
263                         string[] values = new string [3];
264                         int i = 0;
265                         foreach (KeyValuePair <int, string> kvp in list) {
266                                 keys [i] = kvp.Key;
267                                 values [i] = kvp.Value;
268                                 i ++;
269                         }
270
271                         Assert.AreEqual (0, keys [0]);
272                         Assert.AreEqual (2, keys [1]);
273                         Assert.AreEqual (5, keys [2]);
274                         Assert.AreEqual ("A", values [0]);
275                         Assert.AreEqual ("B", values [1]);
276                         Assert.AreEqual ("C", values [2]);
277                 }
278
279                 [Test]
280                 public void CopyTo ()
281                 {       
282                         ICollection<KeyValuePair<int, string>> col1 =
283                                 list as ICollection<KeyValuePair<int, string>>;
284                         KeyValuePair <int, string> [] array1 =
285                                 new KeyValuePair <int, string> [col1.Count];
286                         col1.CopyTo (array1, 0);
287                         Assert.AreEqual (3, array1.Length);
288                         
289                         ICollection col = list as ICollection;
290                         array1 = new KeyValuePair <int, string> [col.Count];
291                         col.CopyTo (array1, 0);                 
292                         Assert.AreEqual (3, array1.Length);
293                         
294                         ICollection<KeyValuePair<string, int>> col2 =
295                                 list2 as ICollection<KeyValuePair<string, int>>;
296                         KeyValuePair <string, int> [] array2 =
297                                 new KeyValuePair <string, int> [col2.Count];
298                         col2.CopyTo (array2, 0);
299                         Assert.AreEqual (0, array2.Length);
300                         
301                         col = list2 as ICollection;
302                         array2 = new KeyValuePair <string, int> [col.Count];
303                         col.CopyTo (array2, 0);
304                         Assert.AreEqual (0, array2.Length);                     
305                 }
306
307                 [Test]
308                 [ExpectedException (typeof (InvalidOperationException))]
309                 public void KeyEnumeratorVersionChecking () {
310                         var en = list.Keys.GetEnumerator();
311
312                         int i = 0;
313                         en.MoveNext ();
314                         list.Remove (en.Current);
315                         en.MoveNext ();
316                 }
317
318                 [Test]
319                 [ExpectedException (typeof (InvalidOperationException))]
320                 public void ValueEnumeratorVersionChecking () {
321             var en = list.Values.GetEnumerator();
322
323             int i = 0;
324                         en.MoveNext ();
325                         list.RemoveAt (0);
326                         en.MoveNext ();
327                 }
328
329                 sealed class StartsWithComparator : IComparer<string> {
330                         private readonly static Comparer<string> _stringComparer = Comparer<string>.Default;
331                         public static readonly StartsWithComparator Instance = new StartsWithComparator();
332
333                         public int Compare(string part, string whole)
334                         {
335                                 // let the default string comparer deal with null or when part is not smaller then whole
336                                 if (part == null || whole == null || part.Length >= whole.Length)
337                                         return _stringComparer.Compare(part, whole);
338
339                                 // loop through all characters that part and whole have in common
340                                 int pos = 0;
341                                 bool match;
342                                 do {
343                                         match = (part[pos] == whole[pos]);
344                                 } while (match && ++pos < part.Length);
345
346                                 // return result of last comparison
347                                 return match ? 0 : (part[pos] < whole[pos] ? -1 : 1);
348                         }
349                 }
350
351                 sealed class StartsWithComparatorPartWholeCheck : IComparer<string>
352                 {
353                         private readonly static Comparer<string> _stringComparer = Comparer<string>.Default;
354
355                         public static readonly StartsWithComparator Instance = new StartsWithComparator();
356
357                         public int Compare(string part, string whole)
358                         {
359                                 Assert.IsTrue(part == "Part", "#PWC0");
360                                 Assert.IsTrue(whole == "Whole", "#PWC1");
361
362                                 // let the default string comparer deal with null or when part is not smaller then whole
363                                 if (part == null || whole == null || part.Length >= whole.Length)
364                                         return _stringComparer.Compare(part, whole);
365
366                                 // loop through all characters that part and whole have in common
367                                 int pos = 0;
368                                 bool match;
369                                 do {
370                                         match = (part[pos] == whole[pos]);
371                                 } while (match && ++pos < part.Length);
372
373                                 // return result of last comparison
374                                 return match ? 0 : (part[pos] < whole[pos] ? -1 : 1);
375                         }
376                 }
377
378                 [Test]
379                 public void ComparatorUsageTest()
380                 {
381                         SortedList<string, string> sl = new SortedList<string, string>(StartsWithComparator.Instance);
382
383                         sl.Add("Apples", "Value-Apples");
384                         sl.Add("Bananas", "Value-Bananas");
385                         sl.Add("Oranges", "Value-Oranges");
386
387                         // Ensure 3 objects exist in the collection
388                         Assert.IsTrue(sl.Count == 3, "Count");
389
390                         // Complete Match Test Set
391                         Assert.IsTrue(sl.ContainsKey("Apples"), "#A0");
392                         Assert.IsTrue(sl.ContainsKey("Bananas"), "#A1");
393                         Assert.IsTrue(sl.ContainsKey("Oranges"), "#A2");
394
395                         // Partial Match Test Set
396                         Assert.IsTrue(sl.ContainsKey("Apples are great fruit!"), "#B0");
397                         Assert.IsTrue(sl.ContainsKey("Bananas are better fruit."), "#B1");
398                         Assert.IsTrue(sl.ContainsKey("Oranges are fun to peel."), "#B2");
399
400                         // Reversed Match Test Set
401                         Assert.IsFalse(sl.ContainsKey("Value"), "#C0");
402
403                         // No match tests
404                         Assert.IsFalse(sl.ContainsKey("I forgot to bring my bananas."), "#D0");
405                         Assert.IsFalse(sl.ContainsKey("My apples are on vacation."), "#D0");
406                         Assert.IsFalse(sl.ContainsKey("The oranges are not ripe yet."), "#D0");
407
408                 }
409
410                 [Test]
411                 public void ComparatorPartWholeCheck()
412                 {
413                         SortedList<string, string> sl = new SortedList<string, string>(StartsWithComparatorPartWholeCheck.Instance);
414                         sl.Add("Part", "Value-Part");
415                         Assert.IsFalse(sl.ContainsKey("Whole"), "#PWC2");
416                 }
417
418                 [Test]
419                 public void NonComparatorStringCheck()
420                 {
421                         SortedList<string, string> sl = new SortedList<string, string>();
422
423                         sl.Add("Oranges", "Value-Oranges");
424                         sl.Add("Apples", "Value-Apples");
425                         sl.Add("Bananas", "Value-Bananas");
426
427                         int i = 0;
428                         Assert.IsTrue(sl.Count == 3, "NCSC #A0");
429
430                         Assert.IsTrue(sl.ContainsKey("Apples"), "NCSC #B1");
431                         Assert.IsTrue(sl.ContainsKey("Bananas"), "NCSC #B2");
432                         Assert.IsTrue(sl.ContainsKey("Oranges"), "NCSC #B3");
433
434                         Assert.IsFalse(sl.ContainsKey("XApples"), "NCSC #C1");
435                         Assert.IsFalse(sl.ContainsKey("XBananas"), "NCSC #C2");
436                         Assert.IsFalse(sl.ContainsKey("XOranges"), "NCSC #C3");
437
438                         Assert.IsTrue(sl.Keys[0] == "Apples", "NCSC #D1");
439                         Assert.IsTrue(sl.Keys[1] == "Bananas", "NCSC #D2");
440                         Assert.IsTrue(sl.Keys[2] == "Oranges", "NCSC #D3");
441                 }
442
443                 [Test]
444                 public void NonComparatorIntCheck()
445                 {
446                         SortedList<int, string> sl = new SortedList<int, string>();
447
448                         sl.Add(3, "Value-Oranges");
449                         sl.Add(2, "Value-Bananas");
450                         sl.Add(1, "Value-Apples");
451
452                         Assert.IsTrue(sl.Count == 3, "NCIC #A0");
453
454                         Assert.IsTrue(sl.ContainsKey(1), "NCIC #B1");
455                         Assert.IsTrue(sl.ContainsKey(2), "NCIC #B2");
456                         Assert.IsTrue(sl.ContainsKey(3), "NCIC #B3");
457
458                         Assert.IsFalse(sl.ContainsKey(11), "NCIC #C1");
459                         Assert.IsFalse(sl.ContainsKey(22), "NCIC #C2");
460                         Assert.IsFalse(sl.ContainsKey(33), "NCIC #C3");
461
462                         Assert.IsTrue(sl.Keys[0] == 1, "NCIC #D1");
463                         Assert.IsTrue(sl.Keys[1] == 2, "NCIC #D2");
464                         Assert.IsTrue(sl.Keys[2] == 3, "NCIC #D3");
465                 }
466
467                 [Test]
468                 public void ClearDoesNotTouchCapacity ()
469                 {
470                         SortedList<int, int> sl = new SortedList<int, int> ();
471                         for (int i = 0; i < 18; i++) {
472                                 sl.Add (i, i);
473                         }
474                         int capacityBeforeClear = sl.Capacity;
475                         sl.Clear ();
476                         int capacityAfterClear = sl.Capacity;
477                         Assert.AreEqual (capacityBeforeClear, capacityAfterClear);
478                 }
479         }
480 }
481
482 #endif