2 // System.Collections.SortedListTest.cs
5 // Zoltan Varga (vargaz@gmail.com)
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
10 // Copyright 2012 Xamarin Inc.
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.Collections.Generic;
38 using System.Runtime.Serialization;
39 using System.Runtime.Serialization.Formatters.Binary;
40 using NUnit.Framework;
42 using NUnit.Framework.SyntaxHelpers;
45 namespace MonoTests.System.Collections.Generic
48 public class SortedListTest
50 SortedList<int, string> list;
51 SortedList<string, int> list2;
54 public void SetUp () {
55 list = new SortedList <int, string> ();
61 list2 = new SortedList<string, int> ();
66 Assert.AreEqual ("A", list [0]);
67 Assert.AreEqual ("B", list [2]);
68 Assert.AreEqual ("C", list [5]);
72 Assert.AreEqual ("D", list [2]);
76 [ExpectedException (typeof (ArgumentNullException))]
77 public void ItemNullKey () {
82 [ExpectedException (typeof (KeyNotFoundException))]
83 public void ItemMissingKey () {
89 IList<int> keys = list.Keys;
91 Assert.AreEqual (3, keys.Count);
92 Assert.AreEqual (0, keys [0]);
93 Assert.AreEqual (2, keys [1]);
94 Assert.AreEqual (5, keys [2]);
96 int[] arr = new int [4];
98 Assert.AreEqual (0, arr [1]);
99 Assert.AreEqual (2, arr [2]);
100 Assert.AreEqual (5, arr [3]);
102 Assert.AreEqual (true, keys.Contains (2));
103 Assert.AreEqual (false, keys.Contains (100));
105 Assert.AreEqual (2, keys.IndexOf (5));
106 Assert.AreEqual (-1, keys.IndexOf (100));
112 foreach (int i in keys)
114 Assert.AreEqual (0, arr [0]);
115 Assert.AreEqual (2, arr [1]);
116 Assert.AreEqual (5, arr [2]);
120 public void KeysNonGeneric () {
121 ICollection keys = ((IDictionary)list).Keys;
123 Assert.AreEqual (3, keys.Count);
125 int[] arr = new int [4];
126 keys.CopyTo (arr, 1);
127 Assert.AreEqual (0, arr [1]);
128 Assert.AreEqual (2, arr [2]);
129 Assert.AreEqual (5, arr [3]);
135 foreach (int i in keys)
137 Assert.AreEqual (0, arr [0]);
138 Assert.AreEqual (2, arr [1]);
139 Assert.AreEqual (5, arr [2]);
143 public void Values () {
144 IList<string> values = list.Values;
146 Assert.AreEqual (3, values.Count);
147 Assert.AreEqual ("A", values [0]);
148 Assert.AreEqual ("B", values [1]);
149 Assert.AreEqual ("C", values [2]);
151 string[] arr = new string [4];
152 values.CopyTo (arr, 1);
153 Assert.AreEqual ("A", arr [1]);
154 Assert.AreEqual ("B", arr [2]);
155 Assert.AreEqual ("C", arr [3]);
157 Assert.AreEqual (true, values.Contains ("B"));
158 Assert.AreEqual (false, values.Contains ("X"));
160 Assert.AreEqual (2, values.IndexOf ("C"));
161 Assert.AreEqual (-1, values.IndexOf ("X"));
167 foreach (string s in values)
169 Assert.AreEqual ("A", arr [0]);
170 Assert.AreEqual ("B", arr [1]);
171 Assert.AreEqual ("C", arr [2]);
175 public void ValuesNonGeneric () {
176 ICollection values = ((IDictionary)list).Values;
178 Assert.AreEqual (3, values.Count);
180 string[] arr = new string [4];
181 values.CopyTo (arr, 1);
182 Assert.AreEqual ("A", arr [1]);
183 Assert.AreEqual ("B", arr [2]);
184 Assert.AreEqual ("C", arr [3]);
190 foreach (string s in values)
192 Assert.AreEqual ("A", arr [0]);
193 Assert.AreEqual ("B", arr [1]);
194 Assert.AreEqual ("C", arr [2]);
198 public void KeysIDictionaryGeneric () {
199 ICollection<int> keys = ((IDictionary<int,string>)list).Keys;
201 Assert.AreEqual (3, keys.Count);
205 public void EmptyKeysCopyToZeroSizedArray ()
207 string [] ary = new string [0];
208 list2.Keys.CopyTo (ary, 0);
212 public void EmptyValuesCopyToZeroSizedArray ()
214 int [] ary = new int [0];
215 list2.Values.CopyTo (ary, 0);
219 public void ValuesIDictionaryGeneric () {
220 ICollection<string> values = ((IDictionary<int,string>)list).Values;
222 Assert.AreEqual (3, values.Count);
228 Assert.AreEqual ("D", list [10]);
232 [ExpectedException (typeof (ArgumentNullException))]
233 public void AddNullKey () {
234 list2.Add (null, 10);
238 [ExpectedException (typeof (ArgumentException))]
239 public void AddKeyAlreadyExists () {
245 public void ContainsKey () {
246 Assert.AreEqual (true, list.ContainsKey (5));
247 Assert.AreEqual (false, list.ContainsKey (10));
251 public void Remove () {
252 Assert.AreEqual (true, list.Remove (5));
253 Assert.AreEqual (false, list.Remove (5));
254 Assert.AreEqual (false, list.Remove (10));
258 [ExpectedException (typeof (ArgumentNullException))]
259 public void RemoveNullKey () {
264 public void GetEnumerator () {
265 int[] keys = new int [3];
266 string[] values = new string [3];
268 foreach (KeyValuePair <int, string> kvp in list) {
270 values [i] = kvp.Value;
274 Assert.AreEqual (0, keys [0]);
275 Assert.AreEqual (2, keys [1]);
276 Assert.AreEqual (5, keys [2]);
277 Assert.AreEqual ("A", values [0]);
278 Assert.AreEqual ("B", values [1]);
279 Assert.AreEqual ("C", values [2]);
283 public void CopyTo ()
285 ICollection<KeyValuePair<int, string>> col1 =
286 list as ICollection<KeyValuePair<int, string>>;
287 KeyValuePair <int, string> [] array1 =
288 new KeyValuePair <int, string> [col1.Count];
289 col1.CopyTo (array1, 0);
290 Assert.AreEqual (3, array1.Length);
292 ICollection col = list as ICollection;
293 array1 = new KeyValuePair <int, string> [col.Count];
294 col.CopyTo (array1, 0);
295 Assert.AreEqual (3, array1.Length);
297 ICollection<KeyValuePair<string, int>> col2 =
298 list2 as ICollection<KeyValuePair<string, int>>;
299 KeyValuePair <string, int> [] array2 =
300 new KeyValuePair <string, int> [col2.Count];
301 col2.CopyTo (array2, 0);
302 Assert.AreEqual (0, array2.Length);
304 col = list2 as ICollection;
305 array2 = new KeyValuePair <string, int> [col.Count];
306 col.CopyTo (array2, 0);
307 Assert.AreEqual (0, array2.Length);
311 [ExpectedException (typeof (InvalidOperationException))]
312 public void KeyEnumeratorVersionChecking () {
313 var en = list.Keys.GetEnumerator();
317 list.Remove (en.Current);
322 [ExpectedException (typeof (InvalidOperationException))]
323 public void ValueEnumeratorVersionChecking () {
324 var en = list.Values.GetEnumerator();
332 sealed class StartsWithComparator : IComparer<string> {
333 private readonly static Comparer<string> _stringComparer = Comparer<string>.Default;
334 public static readonly StartsWithComparator Instance = new StartsWithComparator();
336 public int Compare(string part, string whole)
338 // let the default string comparer deal with null or when part is not smaller then whole
339 if (part == null || whole == null || part.Length >= whole.Length)
340 return _stringComparer.Compare(part, whole);
342 // loop through all characters that part and whole have in common
346 match = (part[pos] == whole[pos]);
347 } while (match && ++pos < part.Length);
349 // return result of last comparison
350 return match ? 0 : (part[pos] < whole[pos] ? -1 : 1);
354 sealed class StartsWithComparatorPartWholeCheck : IComparer<string>
356 private readonly static Comparer<string> _stringComparer = Comparer<string>.Default;
358 public static readonly StartsWithComparator Instance = new StartsWithComparator();
360 public int Compare(string part, string whole)
362 Assert.IsTrue(part == "Part", "#PWC0");
363 Assert.IsTrue(whole == "Whole", "#PWC1");
365 // let the default string comparer deal with null or when part is not smaller then whole
366 if (part == null || whole == null || part.Length >= whole.Length)
367 return _stringComparer.Compare(part, whole);
369 // loop through all characters that part and whole have in common
373 match = (part[pos] == whole[pos]);
374 } while (match && ++pos < part.Length);
376 // return result of last comparison
377 return match ? 0 : (part[pos] < whole[pos] ? -1 : 1);
382 public void ComparatorUsageTest()
384 SortedList<string, string> sl = new SortedList<string, string>(StartsWithComparator.Instance);
386 sl.Add("Apples", "Value-Apples");
387 sl.Add("Bananas", "Value-Bananas");
388 sl.Add("Oranges", "Value-Oranges");
390 // Ensure 3 objects exist in the collection
391 Assert.IsTrue(sl.Count == 3, "Count");
393 // Complete Match Test Set
394 Assert.IsTrue(sl.ContainsKey("Apples"), "#A0");
395 Assert.IsTrue(sl.ContainsKey("Bananas"), "#A1");
396 Assert.IsTrue(sl.ContainsKey("Oranges"), "#A2");
398 // Partial Match Test Set
399 Assert.IsTrue(sl.ContainsKey("Apples are great fruit!"), "#B0");
400 Assert.IsTrue(sl.ContainsKey("Bananas are better fruit."), "#B1");
401 Assert.IsTrue(sl.ContainsKey("Oranges are fun to peel."), "#B2");
403 // Reversed Match Test Set
404 Assert.IsFalse(sl.ContainsKey("Value"), "#C0");
407 Assert.IsFalse(sl.ContainsKey("I forgot to bring my bananas."), "#D0");
408 Assert.IsFalse(sl.ContainsKey("My apples are on vacation."), "#D0");
409 Assert.IsFalse(sl.ContainsKey("The oranges are not ripe yet."), "#D0");
414 public void ComparatorPartWholeCheck()
416 SortedList<string, string> sl = new SortedList<string, string>(StartsWithComparatorPartWholeCheck.Instance);
417 sl.Add("Part", "Value-Part");
418 Assert.IsFalse(sl.ContainsKey("Whole"), "#PWC2");
422 public void NonComparatorStringCheck()
424 SortedList<string, string> sl = new SortedList<string, string>();
426 sl.Add("Oranges", "Value-Oranges");
427 sl.Add("Apples", "Value-Apples");
428 sl.Add("Bananas", "Value-Bananas");
431 Assert.IsTrue(sl.Count == 3, "NCSC #A0");
433 Assert.IsTrue(sl.ContainsKey("Apples"), "NCSC #B1");
434 Assert.IsTrue(sl.ContainsKey("Bananas"), "NCSC #B2");
435 Assert.IsTrue(sl.ContainsKey("Oranges"), "NCSC #B3");
437 Assert.IsFalse(sl.ContainsKey("XApples"), "NCSC #C1");
438 Assert.IsFalse(sl.ContainsKey("XBananas"), "NCSC #C2");
439 Assert.IsFalse(sl.ContainsKey("XOranges"), "NCSC #C3");
441 Assert.IsTrue(sl.Keys[0] == "Apples", "NCSC #D1");
442 Assert.IsTrue(sl.Keys[1] == "Bananas", "NCSC #D2");
443 Assert.IsTrue(sl.Keys[2] == "Oranges", "NCSC #D3");
447 public void NonComparatorIntCheck()
449 SortedList<int, string> sl = new SortedList<int, string>();
451 sl.Add(3, "Value-Oranges");
452 sl.Add(2, "Value-Bananas");
453 sl.Add(1, "Value-Apples");
455 Assert.IsTrue(sl.Count == 3, "NCIC #A0");
457 Assert.IsTrue(sl.ContainsKey(1), "NCIC #B1");
458 Assert.IsTrue(sl.ContainsKey(2), "NCIC #B2");
459 Assert.IsTrue(sl.ContainsKey(3), "NCIC #B3");
461 Assert.IsFalse(sl.ContainsKey(11), "NCIC #C1");
462 Assert.IsFalse(sl.ContainsKey(22), "NCIC #C2");
463 Assert.IsFalse(sl.ContainsKey(33), "NCIC #C3");
465 Assert.IsTrue(sl.Keys[0] == 1, "NCIC #D1");
466 Assert.IsTrue(sl.Keys[1] == 2, "NCIC #D2");
467 Assert.IsTrue(sl.Keys[2] == 3, "NCIC #D3");
471 public void ClearDoesNotTouchCapacity ()
473 SortedList<int, int> sl = new SortedList<int, int> ();
474 for (int i = 0; i < 18; i++) {
477 int capacityBeforeClear = sl.Capacity;
479 int capacityAfterClear = sl.Capacity;
480 Assert.AreEqual (capacityBeforeClear, capacityAfterClear);
483 class Uncomparable : IComparer<double>
485 public int Compare (double x, double y)
487 throw new DivideByZeroException ();
493 public void UncomparableList ()
495 var list = new SortedList<double, int> (new Uncomparable ());
497 list.Add (Math.PI, 1);
500 list.Add (Math.E, 2);
501 Assert.Fail ("UC #1");
502 } catch (Exception ex) {
503 Assert.That (ex, Is.TypeOf (typeof (InvalidOperationException)), "UC #2");
504 Assert.IsNotNull (ex.InnerException, "UC #3");
505 Assert.That (ex.InnerException, Is.TypeOf (typeof (DivideByZeroException)), "UC #4");
510 list.TryGetValue (Math.E, out a);
511 Assert.Fail ("UC #5");
512 } catch (Exception ex) {
513 Assert.That (ex, Is.TypeOf (typeof (InvalidOperationException)), "UC #6");
514 Assert.IsNotNull (ex.InnerException, "UC #7");
515 Assert.That (ex.InnerException, Is.TypeOf (typeof (DivideByZeroException)), "UC #8");
520 public void IDictionaryNullOnNonExistingKey ()
522 IDictionary list = new SortedList<long, string> ();
523 object val = list [1234L];