2 // MonoTests.System.Collections.Generic.Test.DictionaryTest
5 // Sureshkumar T (tsureshkumar@novell.com)
6 // Ankit Jain (radical@corewars.org)
7 // David Waite (mass@akuma.org)
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
10 // Copyright (C) 2005 David Waite (mass@akuma.org)
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.
35 using System.Collections;
36 using System.Collections.Generic;
38 using System.Runtime.Serialization.Formatters.Binary;
40 using NUnit.Framework;
42 namespace MonoTests.System.Collections.Generic {
44 public class DictionaryTest {
48 public MyClass (int a, int b)
53 public override int GetHashCode ()
58 public override bool Equals (object obj)
60 if (!(obj is MyClass))
62 return ((MyClass)obj).Value == a;
72 Dictionary <string, object> _dictionary = null;
73 Dictionary <MyClass, MyClass> _dictionary2 = null;
74 Dictionary <int, int> _dictionary3 = null;
79 _dictionary = new Dictionary <string, object> ();
80 _dictionary2 = new Dictionary <MyClass, MyClass> ();
81 _dictionary3 = new Dictionary <int, int>();
85 public void AddTest ()
87 _dictionary.Add ("key1", "value");
88 Assert.AreEqual ("value", _dictionary ["key1"].ToString (), "Add failed!");
92 public void AddTest2 ()
94 MyClass m1 = new MyClass (10,5);
95 MyClass m2 = new MyClass (20,5);
96 MyClass m3 = new MyClass (12,3);
97 _dictionary2.Add (m1,m1);
98 _dictionary2.Add (m2, m2);
99 _dictionary2.Add (m3, m3);
100 Assert.AreEqual (20, _dictionary2 [m2].Value, "#1");
101 Assert.AreEqual (10, _dictionary2 [m1].Value, "#2");
102 Assert.AreEqual (12, _dictionary2 [m3].Value, "#3");
106 public void AddTest3 ()
108 _dictionary3.Add (1, 2);
109 _dictionary3.Add (2, 3);
110 _dictionary3.Add (3, 4);
111 Assert.AreEqual (2, _dictionary3[1], "#1");
112 Assert.AreEqual (3, _dictionary3[2], "#2");
113 Assert.AreEqual (4, _dictionary3[3], "#3");
116 [Test, ExpectedException(typeof(ArgumentNullException))]
117 public void AddNullTest ()
119 _dictionary.Add (null, "");
122 [Test, ExpectedException(typeof(ArgumentException))]
123 public void AddDuplicateTest ()
125 _dictionary.Add("foo", "bar");
126 _dictionary.Add("foo", "bar");
129 //Tests Add when resize takes place
131 public void AddLargeTest ()
133 int i, numElems = 50;
135 for (i = 0; i < numElems; i++)
137 _dictionary3.Add (i, i);
141 foreach (KeyValuePair <int, int> entry in _dictionary3)
146 Assert.AreEqual (i, numElems, "Add with resize failed!");
150 public void IndexerGetExistingTest ()
152 _dictionary.Add ("key1", "value");
153 Assert.AreEqual ("value", _dictionary ["key1"].ToString (), "Add failed!");
156 [Test, ExpectedException(typeof(KeyNotFoundException))]
157 public void IndexerGetNonExistingTest ()
159 object foo = _dictionary ["foo"];
162 [Test, ExpectedException(typeof(ArgumentNullException))]
163 public void IndexerGetNullTest()
165 object s = _dictionary[null];
169 public void IndexerSetExistingTest ()
171 _dictionary.Add ("key1", "value1");
172 _dictionary ["key1"] = "value2";
173 Assert.AreEqual (1, _dictionary.Count);
174 Assert.AreEqual ("value2", _dictionary ["key1"]);
178 public void IndexerSetNonExistingTest ()
180 _dictionary ["key1"] = "value1";
181 Assert.AreEqual (1, _dictionary.Count);
182 Assert.AreEqual ("value1", _dictionary ["key1"]);
186 public void RemoveTest ()
188 _dictionary.Add ("key1", "value1");
189 _dictionary.Add ("key2", "value2");
190 _dictionary.Add ("key3", "value3");
191 _dictionary.Add ("key4", "value4");
192 Assert.IsTrue (_dictionary.Remove ("key3"));
193 Assert.IsFalse (_dictionary.Remove ("foo"));
194 Assert.AreEqual (3, _dictionary.Count);
195 Assert.IsFalse (_dictionary.ContainsKey ("key3"));
199 public void RemoveTest2 ()
201 MyClass m1 = new MyClass (10, 5);
202 MyClass m2 = new MyClass (20, 5);
203 MyClass m3 = new MyClass (12, 3);
204 _dictionary2.Add (m1, m1);
205 _dictionary2.Add (m2, m2);
206 _dictionary2.Add (m3, m3);
207 _dictionary2.Remove (m1); // m2 is in rehash path
208 Assert.AreEqual (20, _dictionary2 [m2].Value, "#4");
212 [Test, ExpectedException(typeof(ArgumentNullException))]
213 public void IndexerSetNullTest()
215 _dictionary[null] = "bar";
219 public void ClearTest ()
221 _dictionary.Add ("key1", "value1");
222 _dictionary.Add ("key2", "value2");
223 _dictionary.Add ("key3", "value3");
224 _dictionary.Add ("key4", "value4");
225 _dictionary.Clear ();
226 Assert.AreEqual (0, _dictionary.Count, "Clear method failed!");
227 Assert.IsFalse (_dictionary.ContainsKey ("key2"));
231 public void ContainsKeyTest ()
233 _dictionary.Add ("key1", "value1");
234 _dictionary.Add ("key2", "value2");
235 _dictionary.Add ("key3", "value3");
236 _dictionary.Add ("key4", "value4");
237 bool contains = _dictionary.ContainsKey ("key4");
238 Assert.IsTrue (contains, "ContainsKey does not return correct value!");
239 contains = _dictionary.ContainsKey ("key5");
240 Assert.IsFalse (contains, "ContainsKey for non existant does not return correct value!");
244 public void ContainsValueTest ()
246 _dictionary.Add ("key1", "value1");
247 _dictionary.Add ("key2", "value2");
248 _dictionary.Add ("key3", "value3");
249 _dictionary.Add ("key4", "value4");
250 bool contains = _dictionary.ContainsValue ("value2");
251 Assert.IsTrue(contains, "ContainsValue does not return correct value!");
252 contains = _dictionary.ContainsValue ("@@daisofja@@");
253 Assert.IsFalse (contains, "ContainsValue for non existant does not return correct value!");
257 public void TryGetValueTest()
259 _dictionary.Add ("key1", "value1");
260 _dictionary.Add ("key2", "value2");
261 _dictionary.Add ("key3", "value3");
262 _dictionary.Add ("key4", "value4");
264 bool retrieved = _dictionary.TryGetValue ("key4", out value);
265 Assert.IsTrue (retrieved);
266 Assert.AreEqual ("value4", (string)value, "TryGetValue does not return value!");
268 retrieved = _dictionary.TryGetValue ("key7", out value);
269 Assert.IsFalse (retrieved);
270 Assert.IsNull (value, "value for non existant value should be null!");
274 public void ValueTypeTest ()
276 Dictionary <int, float> dict = new Dictionary <int, float> ();
277 dict.Add (10, 10.3f);
278 dict.Add (11, 10.4f);
279 dict.Add (12, 10.5f);
280 Assert.AreEqual (10.4f, dict [11], "#5");
288 public MyTest (string name, int number)
294 public override int GetHashCode ()
296 return Name.GetHashCode () ^ RollNo;
299 public override bool Equals (object obj)
301 MyTest myt = obj as MyTest;
302 return myt.Name.Equals (this.Name) &&
303 myt.RollNo.Equals (this.RollNo);
309 public void ObjectAsKeyTest ()
311 Dictionary <object, object> dict = new Dictionary <object, object> ();
312 MyTest key1, key2, key3;
313 dict.Add ( (key1 = new MyTest ("key1", 234)), "value1");
314 dict.Add ( (key2 = new MyTest ("key2", 444)), "value2");
315 dict.Add ( (key3 = new MyTest ("key3", 5655)), "value3");
317 Assert.AreEqual ("value2", dict [key2], "value is not returned!");
318 Assert.AreEqual ("value3", dict [key3], "neg: exception should not be thrown!");
321 [Test, ExpectedException (typeof (ArgumentException))]
322 public void IDictionaryAddTest ()
324 IDictionary iDict = _dictionary as IDictionary;
325 iDict.Add ("key1", "value1");
326 iDict.Add ("key2", "value3");
327 Assert.AreEqual (2, iDict.Count, "IDictioanry interface add is not working!");
330 iDict.Add (12, "value");
331 iDict.Add ("key", 34);
335 public void IEnumeratorTest ()
337 _dictionary.Add ("key1", "value1");
338 _dictionary.Add ("key2", "value2");
339 _dictionary.Add ("key3", "value3");
340 _dictionary.Add ("key4", "value4");
341 IEnumerator itr = ((IEnumerable)_dictionary).GetEnumerator ();
342 while (itr.MoveNext ()) {
343 object o = itr.Current;
344 Assert.AreEqual (typeof (KeyValuePair<string,object>), o.GetType (), "Current should return a type of KeyValuePair");
345 KeyValuePair<string,object> entry = (KeyValuePair<string,object>) itr.Current;
347 Assert.AreEqual ("value4", _dictionary ["key4"].ToString (), "");
352 public void IEnumeratorGenericTest ()
354 _dictionary.Add ("key1", "value1");
355 _dictionary.Add ("key2", "value2");
356 _dictionary.Add ("key3", "value3");
357 _dictionary.Add ("key4", "value4");
358 IEnumerator <KeyValuePair <string, object>> itr = ((IEnumerable <KeyValuePair <string, object>>)_dictionary).GetEnumerator ();
359 while (itr.MoveNext ()) {
360 object o = itr.Current;
361 Assert.AreEqual (typeof (KeyValuePair <string, object>), o.GetType (), "Current should return a type of KeyValuePair<object,string>");
362 KeyValuePair <string, object> entry = (KeyValuePair <string, object>)itr.Current;
364 Assert.AreEqual ("value4", _dictionary ["key4"].ToString (), "");
369 public void IDictionaryEnumeratorTest ()
371 _dictionary.Add ("key1", "value1");
372 _dictionary.Add ("key2", "value2");
373 _dictionary.Add ("key3", "value3");
374 _dictionary.Add ("key4", "value4");
375 IDictionaryEnumerator itr = ((IDictionary)_dictionary).GetEnumerator ();
376 while (itr.MoveNext ()) {
377 object o = itr.Current;
378 Assert.AreEqual (typeof (DictionaryEntry), o.GetType (), "Current should return a type of DictionaryEntry");
379 DictionaryEntry entry = (DictionaryEntry) itr.Current;
381 Assert.AreEqual ("value4", _dictionary ["key4"].ToString (), "");
386 public void ForEachTest ()
388 _dictionary.Add ("key1", "value1");
389 _dictionary.Add ("key2", "value2");
390 _dictionary.Add ("key3", "value3");
391 _dictionary.Add ("key4", "value4");
394 foreach (KeyValuePair <string, object> entry in _dictionary)
396 Assert.AreEqual(4, i, "fail1: foreach entry failed!");
399 foreach (KeyValuePair <string, object> entry in ((IEnumerable)_dictionary))
401 Assert.AreEqual(4, i, "fail2: foreach entry failed!");
404 foreach (DictionaryEntry entry in ((IDictionary)_dictionary))
406 Assert.AreEqual (4, i, "fail3: foreach entry failed!");
410 public void ResizeTest ()
412 Dictionary <string, object> dictionary = new Dictionary <string, object> (3);
413 dictionary.Add ("key1", "value1");
414 dictionary.Add ("key2", "value2");
415 dictionary.Add ("key3", "value3");
417 Assert.AreEqual (3, dictionary.Count);
419 dictionary.Add ("key4", "value4");
420 Assert.AreEqual (4, dictionary.Count);
421 Assert.AreEqual ("value1", dictionary ["key1"].ToString (), "");
422 Assert.AreEqual ("value2", dictionary ["key2"].ToString (), "");
423 Assert.AreEqual ("value4", dictionary ["key4"].ToString (), "");
424 Assert.AreEqual ("value3", dictionary ["key3"].ToString (), "");
428 public void KeyCollectionTest ()
430 _dictionary.Add ("key1", "value1");
431 _dictionary.Add ("key2", "value2");
432 _dictionary.Add ("key3", "value3");
433 _dictionary.Add ("key4", "value4");
435 ICollection <string> keys = ((IDictionary <string, object>)_dictionary).Keys;
436 Assert.AreEqual (4, keys.Count);
438 foreach (string key in keys)
442 Assert.AreEqual(4, i);
446 public void KeyValueEnumeratorTest ()
448 IDictionary<int, int> d = new Dictionary<int, int>();
450 // Values are chosen such that two keys map to the same bucket.
451 // Default dictionary table size == 10
456 Assert.AreEqual (d.Count, d.Keys.Count, "d and d.Keys don't appear to match");
457 Assert.AreEqual (d.Values.Count, d.Keys.Count, "d.Keys and d.Values don't appear to match");
460 foreach (int i in d.Values)
462 Assert.AreEqual (count, d.Values.Count, "d.Values doesn't have the correct number of elements");
465 foreach (int i in d.Keys)
467 Assert.AreEqual (count, d.Keys.Count, "d.Keys doesn't have the correct number of elements");
471 foreach (int i in d.Keys) {
473 if (count++ >= nkeys)
474 Assert.Fail ("Reading a value appears to trash enumerator state");
479 public void SliceCollectionsEnumeratorTest ()
481 Dictionary<string, int> values = new Dictionary<string, int> ();
483 IEnumerator <string> ke = values.Keys.GetEnumerator ();
484 IEnumerator <int> ve = values.Values.GetEnumerator ();
486 Assert.IsTrue (ke is Dictionary<string, int>.KeyCollection.Enumerator);
487 Assert.IsTrue (ve is Dictionary<string, int>.ValueCollection.Enumerator);
491 public void PlainEnumeratorReturnTest ()
493 // Test that we return a KeyValuePair even for non-generic dictionary iteration
494 _dictionary["foo"] = "bar";
495 IEnumerator<KeyValuePair<string, object>> enumerator = _dictionary.GetEnumerator();
496 Assert.IsTrue(enumerator.MoveNext(), "#1");
497 Assert.AreEqual (typeof (KeyValuePair<string,object>), ((IEnumerator)enumerator).Current.GetType (), "#2");
498 Assert.AreEqual (typeof (DictionaryEntry), ((IDictionaryEnumerator)enumerator).Entry.GetType (), "#3");
499 Assert.AreEqual (typeof (KeyValuePair<string,object>), ((IDictionaryEnumerator)enumerator).Current.GetType (), "#4");
500 Assert.AreEqual (typeof (KeyValuePair<string,object>), ((object) enumerator.Current).GetType (), "#5");
503 [Test, ExpectedException (typeof (InvalidOperationException))]
504 public void FailFastTest1 ()
506 Dictionary<int, int> d = new Dictionary<int, int> ();
509 foreach (KeyValuePair<int, int> kv in d) {
510 d [kv.Key + 1] = kv.Value + 1;
512 Assert.Fail ("Should not be reached");
514 Assert.Fail ("Should not be reached");
517 [Test, ExpectedException (typeof (InvalidOperationException))]
518 public void FailFastTest2 ()
520 Dictionary<int, int> d = new Dictionary<int, int> ();
523 foreach (int i in d.Keys) {
526 Assert.Fail ("Should not be reached");
528 Assert.Fail ("Should not be reached");
531 [Test, ExpectedException (typeof (InvalidOperationException))]
532 public void FailFastTest3 ()
534 Dictionary<int, int> d = new Dictionary<int, int> ();
537 foreach (int i in d.Keys) {
540 Assert.Fail ("Should not be reached");
542 Assert.Fail ("Should not be reached");
546 public void SerializationTest()
548 for (int i = 0; i < 50; i++)
550 _dictionary3.Add(i, i);
553 BinaryFormatter formatter = new BinaryFormatter();
554 MemoryStream stream = new MemoryStream();
555 formatter.Serialize(stream, _dictionary3);
558 object deserialized = formatter.Deserialize(stream);
560 Assert.IsNotNull(deserialized);
561 Assert.IsFalse(deserialized == _dictionary3);
563 Assert.IsTrue(deserialized is Dictionary<int, int>);
564 Dictionary<int, int> d3 = deserialized as Dictionary<int, int>;
566 Assert.AreEqual(50, d3.Count);
567 for (int i = 0; i < 50; i++)
569 Assert.AreEqual(i, d3[i]);
574 public void ZeroCapacity ()
576 Dictionary<int, int> x = new Dictionary <int, int> (0);
579 x = new Dictionary <int, int> (0);
582 x = new Dictionary <int, int> (0);
585 x = new Dictionary <int, int> (0);
588 } catch (KeyNotFoundException){
592 b = x.ContainsKey (10);
593 b = x.ContainsValue (10);
595 x = new Dictionary <int, int> (0);
598 x = new Dictionary <int, int> (0);
600 x.TryGetValue (1, out intv);
603 object ob = x.Values;
604 foreach (KeyValuePair<int,int> a in x){
609 public void Empty_KeysValues_CopyTo ()
611 Dictionary<int, int> d = new Dictionary<int, int> ();
612 int[] array = new int[1];
613 d.Keys.CopyTo (array, array.Length);
614 d.Values.CopyTo (array, array.Length);
618 public void Empty_CopyTo ()
620 Dictionary<int, int> d = new Dictionary<int, int> ();
621 ICollection c = (ICollection) d;
622 DictionaryEntry [] array = new DictionaryEntry [1];
623 c.CopyTo (array, array.Length);
625 ICollection<KeyValuePair<int,int>> c2 = d;
626 KeyValuePair<int,int> [] array2 = new KeyValuePair<int,int> [1];
627 c2.CopyTo (array2, array2.Length);
631 public void IDictionary_Contains ()
633 IDictionary d = new Dictionary<int, int> ();
635 Assert.IsTrue (d.Contains (1));
636 Assert.IsFalse (d.Contains (2));
637 Assert.IsFalse (d.Contains ("x"));
640 [Test, ExpectedException (typeof (ArgumentNullException))]
641 public void IDictionary_Contains2 ()
643 IDictionary d = new Dictionary<int, int> ();
647 [Test, ExpectedException (typeof (ArgumentNullException))]
648 public void IDictionary_Add1 ()
650 IDictionary d = new Dictionary<int, int> ();
654 [Test, ExpectedException (typeof (ArgumentException))]
655 public void IDictionary_Add2 ()
657 IDictionary d = new Dictionary<int, int> ();
661 [Test, ExpectedException (typeof (ArgumentException))]
662 public void IDictionary_Add3 ()
664 IDictionary d = new Dictionary<int, int> ();
669 public void IDictionary_Remove1 ()
671 IDictionary d = new Dictionary<int, int> ();
678 [Test, ExpectedException (typeof (ArgumentNullException))]
679 public void IDictionary_Remove2 ()
681 IDictionary d = new Dictionary<int, int> ();