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