2008-05-23 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / class / corlib / Test / System.Collections / HashtableTest.cs
1 // HashtableTest.cs - NUnit Test Cases for the System.Collections.Hashtable class\r
2 //\r
3 //\r
4 // (C) Ximian, Inc.  http://www.ximian.com\r
5 // \r
6 \r
7 \r
8 using System;\r
9 using System.Collections;\r
10 \r
11 using System.IO;\r
12 using System.Runtime.Serialization;\r
13 using System.Runtime.Serialization.Formatters;\r
14 using System.Runtime.Serialization.Formatters.Binary;\r
15 \r
16 using NUnit.Framework;\r
17 \r
18 \r
19 \r
20 namespace MonoTests.System.Collections {\r
21 \r
22 \r
23 /// <summary>Hashtable test.</summary>\r
24 [TestFixture]\r
25 public class HashtableTest : Assertion {\r
26 \r
27         [Test]\r
28         public void TestCtor1() {\r
29                 Hashtable h = new Hashtable();\r
30                 AssertNotNull("No hash table", h);\r
31         }\r
32 \r
33         [Test]\r
34         public void TestCtor2() {\r
35                 {\r
36                         bool errorThrown = false;\r
37                         try {\r
38                                 Hashtable h = new Hashtable((IDictionary) null);\r
39                         } catch (ArgumentNullException) {\r
40                                 errorThrown = true;\r
41                         }\r
42                         Assert("null hashtable error not thrown", \r
43                                errorThrown);\r
44                 }\r
45                 {\r
46                         string[] keys = {"this", "is", "a", "test"};\r
47                         char[] values = {'a', 'b', 'c', 'd'};\r
48                         Hashtable h1 = new Hashtable();\r
49                         for (int i = 0; i < keys.Length; i++) {\r
50                                 h1[keys[i]] = values[i];\r
51                         }\r
52                         Hashtable h2 = new Hashtable(h1);\r
53                         for (int i = 0; i < keys.Length; i++) {\r
54                                 AssertEquals("No match for key " + keys[i],\r
55                                              values[i], h2[keys[i]]);\r
56                         }\r
57                 }\r
58         }\r
59 \r
60         [Test]\r
61         [ExpectedException (typeof (ArgumentOutOfRangeException))]\r
62         public void TestCtor3 ()\r
63         {\r
64                 Hashtable h = new Hashtable ();\r
65                 Hashtable hh = new Hashtable (h, Single.NaN);\r
66         }\r
67 \r
68         [Test]\r
69         [ExpectedException (typeof (ArgumentException))]\r
70         public void TestCtor4 ()\r
71         {\r
72                 Hashtable ht = new Hashtable (Int32.MaxValue, 0.1f, null, null);\r
73         }\r
74 \r
75         [Test]\r
76         public void TestCtor5 ()\r
77         {\r
78                 // tests if negative capacity throws exception\r
79                 try {\r
80                         Hashtable ht = new Hashtable (-10, 0.1f, null, null);\r
81                         Assert("must throw ArgumentOutOfRange exception, param: capacity", false);\r
82                 } catch (ArgumentOutOfRangeException e) {\r
83                         Assert("ParamName is not capacity", e.ParamName == "capacity");\r
84                 }\r
85 \r
86                 // tests if loadFactor out of range throws exception (low)\r
87                 try {\r
88                         Hashtable ht = new Hashtable (100, 0.01f, null, null);\r
89                         Assert("must throw ArgumentOutOfRange exception, param: loadFactor, too low value", false);\r
90                 }       catch (ArgumentOutOfRangeException e) \r
91                 {\r
92                         Assert("ParamName is not loadFactor",e.ParamName == "loadFactor");\r
93                 }\r
94 \r
95                 // tests if loadFactor out of range throws exception (high)\r
96                 try \r
97                 {\r
98                         Hashtable ht = new Hashtable (100, 2f, null, null);\r
99                         Assert("must throw ArgumentOutOfRange exception, param: loadFactor, too high value", false);\r
100                 }       \r
101                 catch (ArgumentOutOfRangeException e) \r
102                 {\r
103                         Assert("ParamName is not loadFactor", e.ParamName == "loadFactor");\r
104                 }\r
105 \r
106         }\r
107 \r
108         // TODO - Ctors for capacity and load (how to test? any access?)\r
109         // TODO - Ctors with IComparer, IHashCodeProvider, Serialization\r
110 \r
111         [Test]  \r
112         public void TestCount() {\r
113                 Hashtable h = new Hashtable();\r
114                 AssertEquals("new table - count zero", 0, h.Count);\r
115                 int max = 100;\r
116                 for (int i = 1; i <= max; i++) {\r
117                         h[i] = i;\r
118                         AssertEquals("Count wrong for " + i,\r
119                                      i, h.Count);\r
120                 }\r
121                 for (int i = 1; i <= max; i++) {\r
122                         h[i] = i * 2;\r
123                         AssertEquals("Count shouldn't change at " + i,\r
124                                      max, h.Count);\r
125                 }\r
126         }\r
127 \r
128         [Test]        \r
129         public void TestIsFixedSize() {\r
130                 Hashtable h = new Hashtable();\r
131                 AssertEquals("hashtable not fixed by default",\r
132                              false, h.IsFixedSize);\r
133                 // TODO - any way to get a fixed-size hashtable?\r
134         }\r
135 \r
136         public void TestIsReadOnly() {\r
137                 Hashtable h = new Hashtable();\r
138                 AssertEquals("hashtable not read-only by default",\r
139                              false, h.IsReadOnly);\r
140                 // TODO - any way to get a read-only hashtable?\r
141         }\r
142 \r
143         [Test]        \r
144         public void TestIsSynchronized ()\r
145         {\r
146                 Hashtable h = new Hashtable ();\r
147                 Assert ("hashtable not synched by default", !h.IsSynchronized);\r
148 \r
149                 Hashtable h2 = Hashtable.Synchronized (h);\r
150                 Assert ("hashtable should by synched", h2.IsSynchronized);\r
151 \r
152                 Hashtable h3 = (Hashtable) h2.Clone ();\r
153                 Assert ("Cloned Hashtable should by synched", h3.IsSynchronized);\r
154         }\r
155 \r
156         [Test]\r
157         public void TestItem() {\r
158                 {\r
159                         bool errorThrown = false;\r
160                         try {\r
161                                 Hashtable h = new Hashtable();\r
162                                 Object o = h[null];\r
163                         } catch (ArgumentNullException e) {\r
164                                 errorThrown = true;\r
165                                 AssertEquals("ParamName is not \"key\"", "key", e.ParamName);\r
166                         }\r
167                         Assert("null hashtable error not thrown", \r
168                                errorThrown);\r
169                 }\r
170                 // TODO - if read-only and/or fixed-size is possible,\r
171                 //        test 'NotSupportedException' here\r
172 \r
173                 {\r
174                         Hashtable h = new Hashtable();\r
175                         int max = 100;\r
176                         for (int i = 1; i <= max; i++) {\r
177                                 h[i] = i;\r
178                                 AssertEquals("value wrong for " + i,\r
179                                              i, h[i]);\r
180                         }\r
181                 }\r
182         }\r
183 \r
184         [Test]\r
185         public void TestKeys() {\r
186                 string[] keys = {"this", "is", "a", "test"};\r
187                 string[] keys2 = {"new", "keys"};\r
188                 char[] values1 = {'a', 'b', 'c', 'd'};\r
189                 char[] values2 = {'e', 'f', 'g', 'h'};\r
190                 ICollection keysReference, keysReference2;\r
191                 Hashtable h1 = new Hashtable();\r
192                 for (int i = 0; i < keys.Length; i++) {\r
193                         h1[keys[i]] = values1[i];\r
194                 }\r
195                 AssertEquals("keys wrong size",\r
196                              keys.Length, h1.Keys.Count);\r
197                 for (int i = 0; i < keys.Length; i++) {\r
198                         h1[keys[i]] = values2[i];\r
199                 }\r
200                 AssertEquals("keys wrong size 2",\r
201                              keys.Length, h1.Keys.Count);\r
202 \r
203                 // MS .NET Always returns the same reference when calling Keys property\r
204                 keysReference = h1.Keys;\r
205             keysReference2 = h1.Keys;\r
206                 AssertEquals("keys references differ", keysReference, keysReference2);\r
207 \r
208                 for (int i = 0; i < keys2.Length; i++) \r
209                 {\r
210                         h1[keys2[i]] = values2[i];\r
211                 }\r
212                 AssertEquals("keys wrong size 3",\r
213                         keys.Length+keys2.Length, h1.Keys.Count);\r
214                 AssertEquals("keys wrong size 4",\r
215                         keys.Length+keys2.Length, keysReference.Count);\r
216         }\r
217 \r
218         // TODO - SyncRoot\r
219         [Test]        \r
220         public void TestValues() {\r
221                 string[] keys = {"this", "is", "a", "test"};\r
222                 char[] values1 = {'a', 'b', 'c', 'd'};\r
223                 char[] values2 = {'e', 'f', 'g', 'h'};\r
224                 Hashtable h1 = new Hashtable();\r
225                 for (int i = 0; i < keys.Length; i++) {\r
226                         h1[keys[i]] = values1[i];\r
227                 }\r
228                 AssertEquals("values wrong size",\r
229                              keys.Length, h1.Values.Count);\r
230                 for (int i = 0; i < keys.Length; i++) {\r
231                         h1[keys[i]] = values2[i];\r
232                 }\r
233                 AssertEquals("values wrong size 2",\r
234                              keys.Length, h1.Values.Count);\r
235 \r
236                 // MS .NET Always returns the same reference when calling Values property\r
237                 ICollection valuesReference1 = h1.Values;\r
238                 ICollection valuesReference2 = h1.Values;\r
239                 AssertEquals("values references differ", valuesReference1, valuesReference2);\r
240         }\r
241 \r
242         [Test]\r
243         public void TestAdd() {\r
244                 {\r
245                         bool errorThrown = false;\r
246                         try {\r
247                                 Hashtable h = new Hashtable();\r
248                                 h.Add(null, "huh?");\r
249                         } catch (ArgumentNullException e) {\r
250                                 errorThrown = true;\r
251                                 AssertEquals("ParamName is not 'key'", "key", e.ParamName);\r
252                         }\r
253                         Assert("null add error not thrown", \r
254                                errorThrown);\r
255                 }\r
256                 {\r
257                         bool errorThrown = false;\r
258                         try {\r
259                                 Hashtable h = new Hashtable();\r
260                                 h.Add('a', 1);\r
261                                 h.Add('a', 2);\r
262                         } catch (ArgumentException) {\r
263                                 errorThrown = true;\r
264                         }\r
265                         Assert("re-add error not thrown", \r
266                                errorThrown);\r
267                 }\r
268                 // TODO - hit NotSupportedException\r
269                 {\r
270                         Hashtable h = new Hashtable();\r
271                         int max = 100;\r
272                         for (int i = 1; i <= max; i++) {\r
273                                 h.Add(i, i);\r
274                                 AssertEquals("value wrong for " + i,\r
275                                              i, h[i]);\r
276                         }\r
277                 }\r
278         }\r
279 \r
280         [Test]\r
281         public void TestClear() {\r
282                 // TODO - hit NotSupportedException\r
283                 Hashtable h = new Hashtable();\r
284                 AssertEquals("new table - count zero", 0, h.Count);\r
285                 int max = 100;\r
286                 for (int i = 1; i <= max; i++) {\r
287                         h[i] = i;\r
288                 }\r
289                 Assert("table don't gots stuff", h.Count > 0);\r
290                 h.Clear();\r
291                 AssertEquals("Table should be cleared",\r
292                              0, h.Count);\r
293         }\r
294 \r
295 #if NET_2_0\r
296         public class MyEqualityComparer : IEqualityComparer {\r
297                 public bool Equals (object x, object y) { return x == y; }\r
298                 public int GetHashCode (object obj) { return 1; }\r
299         }\r
300 \r
301         public class MyHashtable : Hashtable {\r
302                 public MyHashtable (IEqualityComparer c): base (c){}\r
303 \r
304                 public IEqualityComparer GetComparer ()\r
305                 {\r
306                         return EqualityComparer;\r
307                 }\r
308         }\r
309         \r
310 #endif\r
311         \r
312         [Test]\r
313         public void TestClone() {\r
314                 {\r
315                         char[] c1 = {'a', 'b', 'c'};\r
316                         char[] c2 = {'d', 'e', 'f'};\r
317                         Hashtable h1 = new Hashtable();\r
318                         for (int i = 0; i < c1.Length; i++) {\r
319                                 h1[c1[i]] = c2[i];\r
320                         }\r
321                         Hashtable h2 = (Hashtable)h1.Clone();\r
322                         AssertNotNull("got no clone!", h2);\r
323                         AssertNotNull("clone's got nothing!", h2[c1[0]]);\r
324                         for (int i = 0; i < c1.Length; i++) {\r
325                                 AssertEquals("Hashtable match", \r
326                                              h1[c1[i]], h2[c1[i]]);\r
327                         }\r
328                 }\r
329                 {\r
330                         char[] c1 = {'a', 'b', 'c'};\r
331                         char[] c20 = {'1', '2'};\r
332                         char[] c21 = {'3', '4'};\r
333                         char[] c22 = {'5', '6'};\r
334                         char[][] c2 = {c20, c21, c22};\r
335                         Hashtable h1 = new Hashtable();\r
336                         for (int i = 0; i < c1.Length; i++) {\r
337                                 h1[c1[i]] = c2[i];\r
338                         }\r
339                         Hashtable h2 = (Hashtable)h1.Clone();\r
340                         AssertNotNull("got no clone!", h2);\r
341                         AssertNotNull("clone's got nothing!", h2[c1[0]]);\r
342                         for (int i = 0; i < c1.Length; i++) {\r
343                                 AssertEquals("Hashtable match", \r
344                                              h1[c1[i]], h2[c1[i]]);\r
345                         }\r
346 \r
347                         ((char[])h1[c1[0]])[0] = 'z';\r
348                         AssertEquals("shallow copy", h1[c1[0]], h2[c1[0]]);\r
349 \r
350 #if NET_2_0\r
351                         // NET 2.0 stuff\r
352                         MyEqualityComparer a = new MyEqualityComparer ();\r
353                         MyHashtable mh1 = new MyHashtable (a);\r
354                         MyHashtable mh2 = (MyHashtable) h1.Clone ();\r
355                         \r
356                         AssertEquals ("EqualityComparer", mh1.GetComparer (), mh2.GetComparer ());\r
357 #endif\r
358                 }\r
359         }\r
360 \r
361         [Test]\r
362         public void TestContains() {\r
363                 {\r
364                         bool errorThrown = false;\r
365                         try {\r
366                                 Hashtable h = new Hashtable();\r
367                                 bool result = h.Contains(null);\r
368                         } catch (ArgumentNullException e) {\r
369                                 errorThrown = true;\r
370                                 AssertEquals("ParamName is not 'key'", "key", e.ParamName);\r
371                         }\r
372                         Assert("null add error not thrown", \r
373                                errorThrown);\r
374                 }\r
375                 {\r
376                         Hashtable h = new Hashtable();\r
377                         for (int i = 0; i < 10000; i += 2) \r
378                         {\r
379                                 h[i] = i;\r
380                         }\r
381                         for (int i = 0; i < 10000; i += 2) \r
382                         {\r
383                                 Assert("hashtable must contain"+i.ToString(), h.Contains(i));\r
384                                 Assert("hashtable does not contain "+((int)(i+1)).ToString(), !h.Contains(i+1));\r
385                         }\r
386                 }\r
387         }\r
388 \r
389         [Test]\r
390         public void TestContainsKey() {\r
391         {\r
392                         bool errorThrown = false;\r
393                         try \r
394                         {\r
395                                 Hashtable h = new Hashtable();\r
396                                 bool result = h.Contains(null);\r
397                         } \r
398                         catch (ArgumentNullException e) \r
399                         {\r
400                                 errorThrown = true;\r
401                                 AssertEquals("ParamName is not 'key'", "key", e.ParamName);\r
402                         }\r
403                         Assert("null add error not thrown", \r
404                                 errorThrown);\r
405                 }\r
406                 {\r
407                         Hashtable h = new Hashtable();\r
408                         for (int i = 0; i < 1000; i += 2) \r
409                         {\r
410                                 h[i] = i;\r
411                         }\r
412                         for (int i = 0; i < 1000; i += 2) \r
413                         {\r
414                                 Assert("hashtable must contain"+i.ToString(), h.Contains(i));\r
415                                 Assert("hashtable does not contain "+((int)(i+1)).ToString(), !h.Contains(i+1));\r
416                         }\r
417                 }\r
418 \r
419         }\r
420 \r
421         [Test]        \r
422         public void TestContainsValue() {\r
423                 {\r
424                         Hashtable h = new Hashtable();\r
425                         h['a'] = "blue";\r
426                         Assert("blue? it's in there!", \r
427                                h.ContainsValue("blue"));\r
428                         Assert("green? no way!", \r
429                                !h.ContainsValue("green"));\r
430                         Assert("null? no way!", \r
431                                 !h.ContainsValue(null));\r
432                         h['b'] = null;\r
433                         Assert("null? it's in there!", \r
434                                 h.ContainsValue(null));\r
435 \r
436                 }\r
437         }\r
438 \r
439         [Test]\r
440         public void TestCopyTo() {\r
441                 {\r
442                         bool errorThrown = false;\r
443                         try {\r
444                                 Hashtable h = new Hashtable();\r
445                                 h.CopyTo(null, 0);\r
446                         } catch (ArgumentNullException e) {\r
447                                 errorThrown = true;\r
448                                 AssertEquals("ParamName is not \"array\"", "array", e.ParamName); \r
449                         }\r
450                         Assert("null hashtable error not thrown", \r
451                                errorThrown);\r
452                 }\r
453                 {\r
454                         bool errorThrown = false;\r
455                         try {\r
456                                 Hashtable h = new Hashtable();\r
457                                 Object[] o = new Object[1];\r
458                                 h.CopyTo(o, -1);\r
459                         } catch (ArgumentOutOfRangeException e) {\r
460                                 errorThrown = true;\r
461                                 AssertEquals("ParamName is not \"arrayIndex\"", "arrayIndex", e.ParamName);\r
462                         }\r
463                         Assert("out of range error not thrown", \r
464                                errorThrown);\r
465                 }\r
466                 {\r
467                         bool errorThrown = false;\r
468                         try {\r
469                                 Hashtable h = new Hashtable();\r
470                                 Object[,] o = new Object[1,1];\r
471                                 h.CopyTo(o, 1);\r
472                         } catch (ArgumentException) {\r
473                                 errorThrown = true;\r
474                         }\r
475                         Assert("multi-dim array error not thrown", \r
476                                errorThrown);\r
477                 }\r
478                 {\r
479                         bool errorThrown = false;\r
480                         try {\r
481                                 Hashtable h = new Hashtable();\r
482                                 h['a'] = 1; // no error if table is empty\r
483                                 Object[] o = new Object[5];\r
484                                 h.CopyTo(o, 5);\r
485                         } catch (ArgumentException) {\r
486                                 errorThrown = true;\r
487                         }\r
488                         Assert("no room in array error not thrown", \r
489                                errorThrown);\r
490                 }\r
491                 {\r
492                         bool errorThrown = false;\r
493                         try {\r
494                                 Hashtable h = new Hashtable();\r
495                                 h['a'] = 1;\r
496                                 h['b'] = 2;\r
497                                 h['c'] = 2;\r
498                                 Object[] o = new Object[2];\r
499                                 h.CopyTo(o, 0);\r
500                         } catch (ArgumentException) {\r
501                                 errorThrown = true;\r
502                         }\r
503                         Assert("table too big error not thrown", \r
504                                errorThrown);\r
505                 }\r
506                 {\r
507                         bool errorThrown = false;\r
508                         try {\r
509                                 Hashtable h = new Hashtable();\r
510                                 h["blue"] = 1;\r
511                                 h["green"] = 2;\r
512                                 h["red"] = 3;\r
513                                 Char[] o = new Char[3];\r
514                                 h.CopyTo(o, 0);\r
515                         } catch (InvalidCastException) {\r
516                                 errorThrown = true;\r
517                         }\r
518                         Assert("invalid cast error not thrown", \r
519                                errorThrown);\r
520                 }\r
521 \r
522                 {\r
523                         Hashtable h = new Hashtable();\r
524                         h['a'] = 1;\r
525                         h['b'] = 2;\r
526                         DictionaryEntry[] o = new DictionaryEntry[2];\r
527                         h.CopyTo(o,0);\r
528 #if TARGET_JVM // Hashtable is not an ordered collection!\r
529                         if (o[0].Key.Equals('b')) {\r
530                                 DictionaryEntry v = o[0];\r
531                                 o[0] = o[1];\r
532                                 o[1] = v;\r
533                         }\r
534 #endif // TARGET_JVM\r
535                         AssertEquals("first copy fine.", 'a', o[0].Key);\r
536                         AssertEquals("first copy fine.", 1, o[0].Value);\r
537                         AssertEquals("second copy fine.", 'b', o[1].Key);\r
538                         AssertEquals("second copy fine.", 2, o[1].Value);\r
539                 }\r
540         }\r
541 \r
542         [Test]        \r
543         public void TestGetEnumerator() {\r
544                 String[] s1 = {"this", "is", "a", "test"};\r
545                 Char[] c1 = {'a', 'b', 'c', 'd'};\r
546                 Hashtable h1 = new Hashtable();\r
547                 for (int i = 0; i < s1.Length; i++) {\r
548                         h1[s1[i]] = c1[i];\r
549                 }\r
550                 IDictionaryEnumerator en = h1.GetEnumerator();\r
551                 AssertNotNull("No enumerator", en);\r
552                 \r
553                 for (int i = 0; i < s1.Length; i++) {\r
554                         en.MoveNext();\r
555                         Assert("Not enumerating for " + en.Key, \r
556                                Array.IndexOf(s1, en.Key) >= 0);\r
557                         Assert("Not enumerating for " + en.Value, \r
558                                Array.IndexOf(c1, en.Value) >= 0);\r
559                 }\r
560         }\r
561 \r
562         [Test]\r
563         public void TestSerialization () {\r
564                 Hashtable table1 = new Hashtable();\r
565                 Hashtable table2;\r
566                 Stream str = new MemoryStream ();\r
567                 BinaryFormatter formatter = new BinaryFormatter();\r
568 \r
569                 for (int i = 0; i < 100; i++)\r
570                         table1[i] = "TestString Key: " + i.ToString();\r
571                 \r
572                 formatter.Serialize (str, table1);\r
573                 str.Position = 0;\r
574                 table2 = (Hashtable) formatter.Deserialize (str);\r
575                 \r
576                 bool result;\r
577                 foreach (DictionaryEntry de in table1)\r
578                         AssertEquals (de.Value, table2 [de.Key]);\r
579         }\r
580         \r
581         [Test]\r
582         [Category ("TargetJvmNotWorking")]\r
583         public void TestSerialization2 () {\r
584                 // Test from bug #70570\r
585                 MemoryStream stream = new MemoryStream();\r
586                 BinaryFormatter formatter = new BinaryFormatter();\r
587         \r
588                 Hashtable table = new Hashtable();\r
589                 table.Add (new Bug(), "Hello");\r
590 \r
591                 formatter.Serialize(stream, table);\r
592                 stream.Position = 0;\r
593                 table = (Hashtable) formatter.Deserialize(stream);\r
594                 AssertEquals ("#1", 1, table.Count);\r
595         }\r
596 \r
597         [Test]        \r
598         public void TestRemove() {\r
599                 {\r
600                         bool errorThrown = false;\r
601                         try {\r
602                                 Hashtable h = new Hashtable();\r
603                                 h.Remove(null);\r
604                         } catch (ArgumentNullException e) {\r
605                                 errorThrown = true;\r
606                                 AssertEquals("ParamName is not \"key\"", "key", e.ParamName);\r
607                         }\r
608                         Assert("null hashtable error not thrown", \r
609                                errorThrown);\r
610                 }\r
611                 {\r
612                         string[] keys = {"this", "is", "a", "test"};\r
613                         char[] values = {'a', 'b', 'c', 'd'};\r
614                         Hashtable h = new Hashtable();\r
615                         for (int i = 0; i < keys.Length; i++) {\r
616                                 h[keys[i]] = values[i];\r
617                         }\r
618                         AssertEquals("not enough in table",\r
619                                      4, h.Count);\r
620                         h.Remove("huh?");\r
621                         AssertEquals("not enough in table",\r
622                                      4, h.Count);\r
623                         h.Remove("this");\r
624                         AssertEquals("Wrong count in table",\r
625                                      3, h.Count);\r
626                         h.Remove("this");\r
627                         AssertEquals("Wrong count in table",\r
628                                      3, h.Count);\r
629                 }\r
630         }\r
631 \r
632         [Test]        \r
633         public void TestSynchronized() {\r
634                 {\r
635                         bool errorThrown = false;\r
636                         try {\r
637                                 Hashtable h = Hashtable.Synchronized(null);\r
638                         } catch (ArgumentNullException e) {\r
639                                 errorThrown = true;\r
640                                 AssertEquals("ParamName is not \"table\"", "table", e.ParamName);\r
641                         }\r
642                         Assert("null hashtable error not thrown", \r
643                                errorThrown);\r
644                 }\r
645                 {\r
646                         Hashtable h = new Hashtable();\r
647                         Assert("hashtable not synced by default", \r
648                                !h.IsSynchronized);\r
649                         Hashtable h2 = Hashtable.Synchronized(h);\r
650                         Assert("hashtable should by synced", \r
651                                h2.IsSynchronized);\r
652                 }\r
653         }\r
654         \r
655         \r
656         protected Hashtable ht;\r
657         private static Random rnd;\r
658         \r
659         [SetUp]\r
660         public void SetUp() {\r
661                 ht=new Hashtable();\r
662                 rnd=new Random();\r
663         }\r
664         \r
665         private void SetDefaultData() {\r
666                 ht.Clear();\r
667                 ht.Add("k1","another");\r
668                 ht.Add("k2","yet");\r
669                 ht.Add("k3","hashtable");\r
670         }\r
671         \r
672         [Test]\r
673         public void TestAddRemoveClear() {\r
674                 ht.Clear();\r
675                 Assert(ht.Count==0);\r
676                 \r
677                 SetDefaultData();\r
678                 Assert(ht.Count==3);\r
679                 \r
680                 bool thrown=false;\r
681                 try {\r
682                         ht.Add("k2","cool");\r
683                 } catch (ArgumentException) {thrown=true;}\r
684                 Assert("Must throw ArgumentException!",thrown);\r
685                 \r
686                 ht["k2"]="cool";\r
687                 Assert(ht.Count==3);\r
688                 Assert(ht["k2"].Equals("cool"));\r
689                 \r
690         }\r
691 \r
692         [Test]  \r
693         public void TestCopyTo2() {\r
694                 SetDefaultData();\r
695                 Object[] entries=new Object[ht.Count];\r
696                 ht.CopyTo(entries,0);\r
697                 Assert("Not an entry.",entries[0] is DictionaryEntry);\r
698         }\r
699 \r
700         [Test]\r
701         public void CopyTo_Empty ()\r
702         {\r
703                 Hashtable ht = new Hashtable ();\r
704                 AssertEquals ("Count", 0, ht.Count);\r
705                 object[] array = new object [ht.Count];\r
706                 ht.CopyTo (array, 0);\r
707         }\r
708         \r
709         [Test]  \r
710         public void TestUnderHeavyLoad() {\r
711                 ht.Clear();\r
712                 int max=100000;\r
713                 String[] cache=new String[max*2];\r
714                 int n=0;\r
715                 \r
716                 for (int i=0;i<max;i++) {\r
717                         int id=rnd.Next()&0xFFFF;\r
718                         String key=""+id+"-key-"+id;\r
719                         String val="value-"+id;\r
720                         if (ht[key]==null) {\r
721                                 ht[key]=val;\r
722                                 cache[n]=key;\r
723                                 cache[n+max]=val;\r
724                                 n++;\r
725                         }\r
726                 }\r
727                 \r
728                 Assert(ht.Count==n);\r
729                 \r
730                 for (int i=0;i<n;i++) {\r
731                         String key=cache[i];\r
732                         String val=ht[key] as String;\r
733                         String err="ht[\""+key+"\"]=\""+val+\r
734                                 "\", expected \""+cache[i+max]+"\"";\r
735                         Assert(err,val!=null && val.Equals(cache[i+max]));\r
736                 }\r
737                 \r
738                 int r1=(n/3);\r
739                 int r2=r1+(n/5);\r
740                 \r
741                 for (int i=r1;i<r2;i++) {\r
742                         ht.Remove(cache[i]);\r
743                 }\r
744                 \r
745                 \r
746                 for (int i=0;i<n;i++) {\r
747                         if (i>=r1 && i<r2) {\r
748                                 Assert(ht[cache[i]]==null);\r
749                         } else {\r
750                                 String key=cache[i];\r
751                                 String val=ht[key] as String;\r
752                                 String err="ht[\""+key+"\"]=\""+val+\r
753                                         "\", expected \""+cache[i+max]+"\"";\r
754                                 Assert(err,val!=null && val.Equals(cache[i+max]));\r
755                         }\r
756                 }\r
757                 \r
758                 ICollection keys=ht.Keys;\r
759                 int nKeys=0;\r
760                 foreach (Object key in keys) {\r
761                         Assert((key as String) != null);\r
762                         nKeys++;\r
763                 }\r
764                 Assert(nKeys==ht.Count);\r
765 \r
766                 \r
767                 ICollection vals=ht.Values;\r
768                 int nVals=0;\r
769                 foreach (Object val in vals) {\r
770                         Assert((val as String) != null);\r
771                         nVals++;\r
772                 }\r
773                 Assert(nVals==ht.Count);\r
774                 \r
775         }\r
776 \r
777         \r
778         /// <summary>\r
779         ///  Test hashtable with CaseInsensitiveHashCodeProvider\r
780         ///  and CaseInsensitive comparer.\r
781         /// </summary>\r
782         [Test]        \r
783         public void TestCaseInsensitive ()\r
784         {\r
785                 // Not very meaningfull test, just to make\r
786                 // sure that hcp is set properly set.\r
787                 Hashtable ciHashtable = new Hashtable(11,1.0f,CaseInsensitiveHashCodeProvider.Default,CaseInsensitiveComparer.Default);\r
788                 ciHashtable ["key1"] = "value";\r
789                 ciHashtable ["key2"] = "VALUE";\r
790                 Assert(ciHashtable ["key1"].Equals ("value"));\r
791                 Assert(ciHashtable ["key2"].Equals ("VALUE"));\r
792 \r
793                 ciHashtable ["KEY1"] = "new_value";\r
794                 Assert(ciHashtable ["key1"].Equals ("new_value"));\r
795 \r
796         }\r
797 \r
798         [Test]\r
799         public void TestCopyConstructor ()\r
800         {\r
801                 SetDefaultData ();\r
802 \r
803                 Hashtable htCopy = new Hashtable (ht);\r
804 \r
805                 Assert(ht.Count == htCopy.Count);\r
806         }\r
807 \r
808         [Test]\r
809         public void TestEnumerator ()\r
810         {\r
811                 SetDefaultData ();\r
812 \r
813                 IEnumerator e = ht.GetEnumerator ();\r
814 \r
815                 while (e.MoveNext ()) {}\r
816 \r
817                 Assert (!e.MoveNext ());\r
818 \r
819         }\r
820 \r
821         [Test]\r
822         [ExpectedException (typeof (ArgumentNullException))]\r
823         public void GetObjectData_NullSerializationInfo () \r
824         {\r
825                 SetDefaultData ();\r
826                 ht.GetObjectData (null, new StreamingContext ());\r
827         }\r
828 \r
829         // bug #75790\r
830         [Test]\r
831         [Category ("NotDotNet")] // .NET raises InvalidOperationException.\r
832         public void SyncHashtable_ICollectionsGetEnumerator ()\r
833         {\r
834                 Hashtable hashtable = Hashtable.Synchronized (new Hashtable ());\r
835                 hashtable["a"] = 1;\r
836                 //IEnumerator e = (hashtable.Clone() as\r
837                 IEnumerator e = (hashtable as ICollection).GetEnumerator ();\r
838                 //e.Reset();\r
839                 e.MoveNext ();\r
840                 DictionaryEntry de = (DictionaryEntry) e.Current;\r
841         }\r
842 \r
843         [Test]\r
844         public void SerializableSubClasses ()\r
845         {\r
846                 Hashtable ht = new Hashtable ();\r
847                 // see bug #76300\r
848                 Assert ("Keys.IsSerializable", ht.Keys.GetType ().IsSerializable);\r
849                 Assert ("Values.IsSerializable", ht.Values.GetType ().IsSerializable);\r
850                 Assert ("GetEnumerator.IsSerializable", ht.GetEnumerator ().GetType ().IsSerializable);\r
851                 Assert ("Synchronized.IsSerializable", Hashtable.Synchronized (ht).GetType ().IsSerializable);\r
852         }\r
853 \r
854         [Test]\r
855         public void TestHashtableWithCustomComparer ()\r
856         {\r
857                 // see bug #324761\r
858                 IDHashtable dd = new IDHashtable ();\r
859                 Random r = new Random (1000);\r
860                 for (int n = 0; n < 10000; n++) {\r
861                         int v = r.Next (0, 1000);\r
862                         dd [v] = v;\r
863                         v = r.Next (0, 1000);\r
864                         dd.Remove (v);\r
865                 }\r
866         }\r
867 }\r
868 \r
869 class IDHashtable : Hashtable {\r
870 \r
871         class IDComparer : IComparer {\r
872                 public int Compare (object x, object y)\r
873                 {\r
874                         if ((int) x == (int) y)\r
875                                 return 0;\r
876                         else\r
877                                 return 1;\r
878                 }\r
879         }\r
880 \r
881         class IDHashCodeProvider : IHashCodeProvider {\r
882                 public int GetHashCode (object o)\r
883                 {\r
884                         return (int) o;\r
885                 }\r
886         }\r
887 \r
888         public IDHashtable ()\r
889                 : base (new IDHashCodeProvider (),\r
890                                 new IDComparer ())\r
891         {\r
892         }\r
893 }\r
894 \r
895 [Serializable]\r
896 public class Bug :ISerializable {\r
897 \r
898         [Serializable]\r
899         private sealed class InnerClassSerializationHelper : IObjectReference {\r
900                 public object GetRealObject( StreamingContext context )\r
901                 {\r
902                         return new Bug();\r
903                 }\r
904         };\r
905 \r
906         void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context )\r
907         {\r
908                 info.SetType( typeof(InnerClassSerializationHelper) );\r
909         }\r
910 };\r
911 \r
912 \r
913 }\r