(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / corlib / Test / System.Collections / HashtableTest.cs
blob6dba1fcdb993ba08dfd0f0824dbaf32a731aac22
1 // HashtableTest.cs - NUnit Test Cases for the System.Collections.Hashtable class
2 //
3 //
4 // (C) Ximian, Inc. http://www.ximian.com
5 //
8 using System;
9 using System.Collections;
11 using System.IO;
12 using System.Runtime.Serialization;
13 using System.Runtime.Serialization.Formatters;
14 using System.Runtime.Serialization.Formatters.Binary;
16 using NUnit.Framework;
20 namespace MonoTests.System.Collections {
23 /// <summary>Hashtable test.</summary>
24 [TestFixture]
25 public class HashtableTest : Assertion {
27 [Test]
28 public void TestCtor1() {
29 Hashtable h = new Hashtable();
30 AssertNotNull("No hash table", h);
33 [Test]
34 public void TestCtor2() {
36 bool errorThrown = false;
37 try {
38 Hashtable h = new Hashtable((IDictionary) null);
39 } catch (ArgumentNullException) {
40 errorThrown = true;
42 Assert("null hashtable error not thrown",
43 errorThrown);
46 string[] keys = {"this", "is", "a", "test"};
47 char[] values = {'a', 'b', 'c', 'd'};
48 Hashtable h1 = new Hashtable();
49 for (int i = 0; i < keys.Length; i++) {
50 h1[keys[i]] = values[i];
52 Hashtable h2 = new Hashtable(h1);
53 for (int i = 0; i < keys.Length; i++) {
54 AssertEquals("No match for key " + keys[i],
55 values[i], h2[keys[i]]);
60 [Test]
61 [ExpectedException (typeof (ArgumentOutOfRangeException))]
62 public void TestCtor3 ()
64 Hashtable h = new Hashtable ();
65 Hashtable hh = new Hashtable (h, Single.NaN);
68 [Test]
69 [ExpectedException (typeof (ArgumentException))]
70 public void TestCtor4 ()
72 Hashtable ht = new Hashtable (Int32.MaxValue, 0.1f, null, null);
75 [Test]
76 public void TestCtor5 ()
78 // tests if negative capacity throws exception
79 try {
80 Hashtable ht = new Hashtable (-10, 0.1f, null, null);
81 Assert("must throw ArgumentOutOfRange exception, param: capacity", false);
82 } catch (ArgumentOutOfRangeException e) {
83 Assert("ParamName is not capacity", e.ParamName == "capacity");
86 // tests if loadFactor out of range throws exception (low)
87 try {
88 Hashtable ht = new Hashtable (100, 0.01f, null, null);
89 Assert("must throw ArgumentOutOfRange exception, param: loadFactor, too low value", false);
90 } catch (ArgumentOutOfRangeException e)
92 Assert("ParamName is not loadFactor",e.ParamName == "loadFactor");
95 // tests if loadFactor out of range throws exception (high)
96 try
98 Hashtable ht = new Hashtable (100, 2f, null, null);
99 Assert("must throw ArgumentOutOfRange exception, param: loadFactor, too high value", false);
101 catch (ArgumentOutOfRangeException e)
103 Assert("ParamName is not loadFactor", e.ParamName == "loadFactor");
108 // TODO - Ctors for capacity and load (how to test? any access?)
109 // TODO - Ctors with IComparer, IHashCodeProvider, Serialization
111 [Test]
112 public void TestCount() {
113 Hashtable h = new Hashtable();
114 AssertEquals("new table - count zero", 0, h.Count);
115 int max = 100;
116 for (int i = 1; i <= max; i++) {
117 h[i] = i;
118 AssertEquals("Count wrong for " + i,
119 i, h.Count);
121 for (int i = 1; i <= max; i++) {
122 h[i] = i * 2;
123 AssertEquals("Count shouldn't change at " + i,
124 max, h.Count);
128 [Test]
129 public void TestIsFixedSize() {
130 Hashtable h = new Hashtable();
131 AssertEquals("hashtable not fixed by default",
132 false, h.IsFixedSize);
133 // TODO - any way to get a fixed-size hashtable?
136 public void TestIsReadOnly() {
137 Hashtable h = new Hashtable();
138 AssertEquals("hashtable not read-only by default",
139 false, h.IsReadOnly);
140 // TODO - any way to get a read-only hashtable?
143 [Test]
144 public void TestIsSynchronized ()
146 Hashtable h = new Hashtable ();
147 Assert ("hashtable not synched by default", !h.IsSynchronized);
149 Hashtable h2 = Hashtable.Synchronized (h);
150 Assert ("hashtable should by synched", h2.IsSynchronized);
152 Hashtable h3 = (Hashtable) h2.Clone ();
153 Assert ("Cloned Hashtable should by synched", h3.IsSynchronized);
156 [Test]
157 public void TestItem() {
159 bool errorThrown = false;
160 try {
161 Hashtable h = new Hashtable();
162 Object o = h[null];
163 } catch (ArgumentNullException e) {
164 errorThrown = true;
165 AssertEquals("ParamName is not \"key\"", "key", e.ParamName);
167 Assert("null hashtable error not thrown",
168 errorThrown);
170 // TODO - if read-only and/or fixed-size is possible,
171 // test 'NotSupportedException' here
174 Hashtable h = new Hashtable();
175 int max = 100;
176 for (int i = 1; i <= max; i++) {
177 h[i] = i;
178 AssertEquals("value wrong for " + i,
179 i, h[i]);
184 [Test]
185 public void TestKeys() {
186 string[] keys = {"this", "is", "a", "test"};
187 string[] keys2 = {"new", "keys"};
188 char[] values1 = {'a', 'b', 'c', 'd'};
189 char[] values2 = {'e', 'f', 'g', 'h'};
190 ICollection keysReference, keysReference2;
191 Hashtable h1 = new Hashtable();
192 for (int i = 0; i < keys.Length; i++) {
193 h1[keys[i]] = values1[i];
195 AssertEquals("keys wrong size",
196 keys.Length, h1.Keys.Count);
197 for (int i = 0; i < keys.Length; i++) {
198 h1[keys[i]] = values2[i];
200 AssertEquals("keys wrong size 2",
201 keys.Length, h1.Keys.Count);
203 // MS .NET Always returns the same reference when calling Keys property
204 keysReference = h1.Keys;
205 keysReference2 = h1.Keys;
206 AssertEquals("keys references differ", keysReference, keysReference2);
208 for (int i = 0; i < keys2.Length; i++)
210 h1[keys2[i]] = values2[i];
212 AssertEquals("keys wrong size 3",
213 keys.Length+keys2.Length, h1.Keys.Count);
214 AssertEquals("keys wrong size 4",
215 keys.Length+keys2.Length, keysReference.Count);
218 // TODO - SyncRoot
219 [Test]
220 public void TestValues() {
221 string[] keys = {"this", "is", "a", "test"};
222 char[] values1 = {'a', 'b', 'c', 'd'};
223 char[] values2 = {'e', 'f', 'g', 'h'};
224 Hashtable h1 = new Hashtable();
225 for (int i = 0; i < keys.Length; i++) {
226 h1[keys[i]] = values1[i];
228 AssertEquals("values wrong size",
229 keys.Length, h1.Values.Count);
230 for (int i = 0; i < keys.Length; i++) {
231 h1[keys[i]] = values2[i];
233 AssertEquals("values wrong size 2",
234 keys.Length, h1.Values.Count);
236 // MS .NET Always returns the same reference when calling Values property
237 ICollection valuesReference1 = h1.Values;
238 ICollection valuesReference2 = h1.Values;
239 AssertEquals("values references differ", valuesReference1, valuesReference2);
242 [Test]
243 public void TestAdd() {
245 bool errorThrown = false;
246 try {
247 Hashtable h = new Hashtable();
248 h.Add(null, "huh?");
249 } catch (ArgumentNullException e) {
250 errorThrown = true;
251 AssertEquals("ParamName is not 'key'", "key", e.ParamName);
253 Assert("null add error not thrown",
254 errorThrown);
257 bool errorThrown = false;
258 try {
259 Hashtable h = new Hashtable();
260 h.Add('a', 1);
261 h.Add('a', 2);
262 } catch (ArgumentException) {
263 errorThrown = true;
265 Assert("re-add error not thrown",
266 errorThrown);
268 // TODO - hit NotSupportedException
270 Hashtable h = new Hashtable();
271 int max = 100;
272 for (int i = 1; i <= max; i++) {
273 h.Add(i, i);
274 AssertEquals("value wrong for " + i,
275 i, h[i]);
280 [Test]
281 public void TestClear() {
282 // TODO - hit NotSupportedException
283 Hashtable h = new Hashtable();
284 AssertEquals("new table - count zero", 0, h.Count);
285 int max = 100;
286 for (int i = 1; i <= max; i++) {
287 h[i] = i;
289 Assert("table don't gots stuff", h.Count > 0);
290 h.Clear();
291 AssertEquals("Table should be cleared",
292 0, h.Count);
295 [Test]
296 public void TestClone() {
298 char[] c1 = {'a', 'b', 'c'};
299 char[] c2 = {'d', 'e', 'f'};
300 Hashtable h1 = new Hashtable();
301 for (int i = 0; i < c1.Length; i++) {
302 h1[c1[i]] = c2[i];
304 Hashtable h2 = (Hashtable)h1.Clone();
305 AssertNotNull("got no clone!", h2);
306 AssertNotNull("clone's got nothing!", h2[c1[0]]);
307 for (int i = 0; i < c1.Length; i++) {
308 AssertEquals("Hashtable match",
309 h1[c1[i]], h2[c1[i]]);
313 char[] c1 = {'a', 'b', 'c'};
314 char[] c20 = {'1', '2'};
315 char[] c21 = {'3', '4'};
316 char[] c22 = {'5', '6'};
317 char[][] c2 = {c20, c21, c22};
318 Hashtable h1 = new Hashtable();
319 for (int i = 0; i < c1.Length; i++) {
320 h1[c1[i]] = c2[i];
322 Hashtable h2 = (Hashtable)h1.Clone();
323 AssertNotNull("got no clone!", h2);
324 AssertNotNull("clone's got nothing!", h2[c1[0]]);
325 for (int i = 0; i < c1.Length; i++) {
326 AssertEquals("Hashtable match",
327 h1[c1[i]], h2[c1[i]]);
330 ((char[])h1[c1[0]])[0] = 'z';
331 AssertEquals("shallow copy", h1[c1[0]], h2[c1[0]]);
335 [Test]
336 public void TestContains() {
338 bool errorThrown = false;
339 try {
340 Hashtable h = new Hashtable();
341 bool result = h.Contains(null);
342 } catch (ArgumentNullException e) {
343 errorThrown = true;
344 AssertEquals("ParamName is not 'key'", "key", e.ParamName);
346 Assert("null add error not thrown",
347 errorThrown);
350 Hashtable h = new Hashtable();
351 for (int i = 0; i < 10000; i += 2)
353 h[i] = i;
355 for (int i = 0; i < 10000; i += 2)
357 Assert("hashtable must contain"+i.ToString(), h.Contains(i));
358 Assert("hashtable does not contain "+((int)(i+1)).ToString(), !h.Contains(i+1));
363 [Test]
364 public void TestContainsKey() {
366 bool errorThrown = false;
367 try
369 Hashtable h = new Hashtable();
370 bool result = h.Contains(null);
372 catch (ArgumentNullException e)
374 errorThrown = true;
375 AssertEquals("ParamName is not 'key'", "key", e.ParamName);
377 Assert("null add error not thrown",
378 errorThrown);
381 Hashtable h = new Hashtable();
382 for (int i = 0; i < 1000; i += 2)
384 h[i] = i;
386 for (int i = 0; i < 1000; i += 2)
388 Assert("hashtable must contain"+i.ToString(), h.Contains(i));
389 Assert("hashtable does not contain "+((int)(i+1)).ToString(), !h.Contains(i+1));
395 [Test]
396 public void TestContainsValue() {
398 Hashtable h = new Hashtable();
399 h['a'] = "blue";
400 Assert("blue? it's in there!",
401 h.ContainsValue("blue"));
402 Assert("green? no way!",
403 !h.ContainsValue("green"));
404 Assert("null? no way!",
405 !h.ContainsValue(null));
406 h['b'] = null;
407 Assert("null? it's in there!",
408 h.ContainsValue(null));
413 [Test]
414 public void TestCopyTo() {
416 bool errorThrown = false;
417 try {
418 Hashtable h = new Hashtable();
419 h.CopyTo(null, 0);
420 } catch (ArgumentNullException e) {
421 errorThrown = true;
422 AssertEquals("ParamName is not \"array\"", "array", e.ParamName);
424 Assert("null hashtable error not thrown",
425 errorThrown);
428 bool errorThrown = false;
429 try {
430 Hashtable h = new Hashtable();
431 Object[] o = new Object[1];
432 h.CopyTo(o, -1);
433 } catch (ArgumentOutOfRangeException e) {
434 errorThrown = true;
435 AssertEquals("ParamName is not \"arrayIndex\"", "arrayIndex", e.ParamName);
437 Assert("out of range error not thrown",
438 errorThrown);
441 bool errorThrown = false;
442 try {
443 Hashtable h = new Hashtable();
444 Object[,] o = new Object[1,1];
445 h.CopyTo(o, 1);
446 } catch (ArgumentException) {
447 errorThrown = true;
449 Assert("multi-dim array error not thrown",
450 errorThrown);
453 bool errorThrown = false;
454 try {
455 Hashtable h = new Hashtable();
456 h['a'] = 1; // no error if table is empty
457 Object[] o = new Object[5];
458 h.CopyTo(o, 5);
459 } catch (ArgumentException) {
460 errorThrown = true;
462 Assert("no room in array error not thrown",
463 errorThrown);
466 bool errorThrown = false;
467 try {
468 Hashtable h = new Hashtable();
469 h['a'] = 1;
470 h['b'] = 2;
471 h['c'] = 2;
472 Object[] o = new Object[2];
473 h.CopyTo(o, 0);
474 } catch (ArgumentException) {
475 errorThrown = true;
477 Assert("table too big error not thrown",
478 errorThrown);
481 bool errorThrown = false;
482 try {
483 Hashtable h = new Hashtable();
484 h["blue"] = 1;
485 h["green"] = 2;
486 h["red"] = 3;
487 Char[] o = new Char[3];
488 h.CopyTo(o, 0);
489 } catch (InvalidCastException) {
490 errorThrown = true;
492 Assert("invalid cast error not thrown",
493 errorThrown);
497 Hashtable h = new Hashtable();
498 h['a'] = 1;
499 h['b'] = 2;
500 DictionaryEntry[] o = new DictionaryEntry[2];
501 h.CopyTo(o,0);
502 AssertEquals("first copy fine.", 'a', o[0].Key);
503 AssertEquals("first copy fine.", 1, o[0].Value);
504 AssertEquals("second copy fine.", 'b', o[1].Key);
505 AssertEquals("second copy fine.", 2, o[1].Value);
509 [Test]
510 public void TestGetEnumerator() {
511 String[] s1 = {"this", "is", "a", "test"};
512 Char[] c1 = {'a', 'b', 'c', 'd'};
513 Hashtable h1 = new Hashtable();
514 for (int i = 0; i < s1.Length; i++) {
515 h1[s1[i]] = c1[i];
517 IDictionaryEnumerator en = h1.GetEnumerator();
518 AssertNotNull("No enumerator", en);
520 for (int i = 0; i < s1.Length; i++) {
521 en.MoveNext();
522 Assert("Not enumerating for " + en.Key,
523 Array.IndexOf(s1, en.Key) >= 0);
524 Assert("Not enumerating for " + en.Value,
525 Array.IndexOf(c1, en.Value) >= 0);
529 // TODO - GetObjectData
530 // TODO - OnDeserialization
531 [Test]
532 public void TestSerialization () {
533 Random r = new Random();
534 string filename = "hashtable_" + r.Next(99999).ToString() + ".dat";
535 Hashtable table1 = new Hashtable();
536 Hashtable table2;
537 Stream str;
538 BinaryFormatter formatter = new BinaryFormatter();
540 for (int i = 0; i < 100; i++) {
541 table1[i] = "TestString Key: " + i.ToString();
543 str = File.OpenWrite(filename);
544 formatter.Serialize(str, table1);
545 str.Close();
547 str = File.OpenRead(filename);
548 table2 = (Hashtable) formatter.Deserialize(str);
549 str.Close();
551 File.Delete(filename);
553 bool result;
554 foreach (DictionaryEntry de in table1) {
555 int key1 = (int) de.Key;
556 string val1 = (string) de.Value;
557 string val2 = (string) table2[key1];
558 if (val2 != val1) {
559 result = false;
562 result = true;
564 Assert("Binary Serialization Error", result);
567 [Test]
568 public void TestRemove() {
570 bool errorThrown = false;
571 try {
572 Hashtable h = new Hashtable();
573 h.Remove(null);
574 } catch (ArgumentNullException e) {
575 errorThrown = true;
576 AssertEquals("ParamName is not \"key\"", "key", e.ParamName);
578 Assert("null hashtable error not thrown",
579 errorThrown);
582 string[] keys = {"this", "is", "a", "test"};
583 char[] values = {'a', 'b', 'c', 'd'};
584 Hashtable h = new Hashtable();
585 for (int i = 0; i < keys.Length; i++) {
586 h[keys[i]] = values[i];
588 AssertEquals("not enough in table",
589 4, h.Count);
590 h.Remove("huh?");
591 AssertEquals("not enough in table",
592 4, h.Count);
593 h.Remove("this");
594 AssertEquals("Wrong count in table",
595 3, h.Count);
596 h.Remove("this");
597 AssertEquals("Wrong count in table",
598 3, h.Count);
602 [Test]
603 public void TestSynchronized() {
605 bool errorThrown = false;
606 try {
607 Hashtable h = Hashtable.Synchronized(null);
608 } catch (ArgumentNullException e) {
609 errorThrown = true;
610 AssertEquals("ParamName is not \"table\"", "table", e.ParamName);
612 Assert("null hashtable error not thrown",
613 errorThrown);
616 Hashtable h = new Hashtable();
617 Assert("hashtable not synced by default",
618 !h.IsSynchronized);
619 Hashtable h2 = Hashtable.Synchronized(h);
620 Assert("hashtable should by synced",
621 h2.IsSynchronized);
626 protected Hashtable ht;
627 private static Random rnd;
629 [SetUp]
630 public void SetUp() {
631 ht=new Hashtable();
632 rnd=new Random();
635 private void SetDefaultData() {
636 ht.Clear();
637 ht.Add("k1","another");
638 ht.Add("k2","yet");
639 ht.Add("k3","hashtable");
642 [Test]
643 public void TestAddRemoveClear() {
644 ht.Clear();
645 Assert(ht.Count==0);
647 SetDefaultData();
648 Assert(ht.Count==3);
650 bool thrown=false;
651 try {
652 ht.Add("k2","cool");
653 } catch (ArgumentException) {thrown=true;}
654 Assert("Must throw ArgumentException!",thrown);
656 ht["k2"]="cool";
657 Assert(ht.Count==3);
658 Assert(ht["k2"].Equals("cool"));
662 [Test]
663 public void TestCopyTo2() {
664 SetDefaultData();
665 Object[] entries=new Object[ht.Count];
666 ht.CopyTo(entries,0);
667 Assert("Not an entry.",entries[0] is DictionaryEntry);
670 [Test]
671 public void CopyTo_Empty ()
673 Hashtable ht = new Hashtable ();
674 AssertEquals ("Count", 0, ht.Count);
675 object[] array = new object [ht.Count];
676 ht.CopyTo (array, 0);
679 [Test]
680 public void TestUnderHeavyLoad() {
681 ht.Clear();
682 int max=100000;
683 String[] cache=new String[max*2];
684 int n=0;
686 for (int i=0;i<max;i++) {
687 int id=rnd.Next()&0xFFFF;
688 String key=""+id+"-key-"+id;
689 String val="value-"+id;
690 if (ht[key]==null) {
691 ht[key]=val;
692 cache[n]=key;
693 cache[n+max]=val;
694 n++;
698 Assert(ht.Count==n);
700 for (int i=0;i<n;i++) {
701 String key=cache[i];
702 String val=ht[key] as String;
703 String err="ht[\""+key+"\"]=\""+val+
704 "\", expected \""+cache[i+max]+"\"";
705 Assert(err,val!=null && val.Equals(cache[i+max]));
708 int r1=(n/3);
709 int r2=r1+(n/5);
711 for (int i=r1;i<r2;i++) {
712 ht.Remove(cache[i]);
716 for (int i=0;i<n;i++) {
717 if (i>=r1 && i<r2) {
718 Assert(ht[cache[i]]==null);
719 } else {
720 String key=cache[i];
721 String val=ht[key] as String;
722 String err="ht[\""+key+"\"]=\""+val+
723 "\", expected \""+cache[i+max]+"\"";
724 Assert(err,val!=null && val.Equals(cache[i+max]));
728 ICollection keys=ht.Keys;
729 int nKeys=0;
730 foreach (Object key in keys) {
731 Assert((key as String) != null);
732 nKeys++;
734 Assert(nKeys==ht.Count);
737 ICollection vals=ht.Values;
738 int nVals=0;
739 foreach (Object val in vals) {
740 Assert((val as String) != null);
741 nVals++;
743 Assert(nVals==ht.Count);
748 /// <summary>
749 /// Test hashtable with CaseInsensitiveHashCodeProvider
750 /// and CaseInsensitive comparer.
751 /// </summary>
752 [Test]
753 public void TestCaseInsensitive ()
755 // Not very meaningfull test, just to make
756 // sure that hcp is set properly set.
757 Hashtable ciHashtable = new Hashtable(11,1.0f,CaseInsensitiveHashCodeProvider.Default,CaseInsensitiveComparer.Default);
758 ciHashtable ["key1"] = "value";
759 ciHashtable ["key2"] = "VALUE";
760 Assert(ciHashtable ["key1"].Equals ("value"));
761 Assert(ciHashtable ["key2"].Equals ("VALUE"));
763 ciHashtable ["KEY1"] = "new_value";
764 Assert(ciHashtable ["key1"].Equals ("new_value"));
768 [Test]
769 public void TestCopyConstructor ()
771 SetDefaultData ();
773 Hashtable htCopy = new Hashtable (ht);
775 Assert(ht.Count == htCopy.Count);
778 [Test]
779 public void TestEnumerator ()
781 SetDefaultData ();
783 IEnumerator e = ht.GetEnumerator ();
785 while (e.MoveNext ()) {}
787 Assert (!e.MoveNext ());
791 [Test]
792 [ExpectedException (typeof (ArgumentNullException))]
793 public void GetObjectData_NullSerializationInfo ()
795 SetDefaultData ();
796 ht.GetObjectData (null, new StreamingContext ());