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