HashtableTest.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. // HashtableTest.cs - NUnit Test Cases for the System.Collections.Hashtable class
  2. //
  3. //
  4. // (C) Ximian, Inc. http://www.ximian.com
  5. //
  6. using System;
  7. using System.Collections;
  8. using NUnit.Framework;
  9. namespace MonoTests.System.Collections {
  10. /// <summary>Hashtable test.</summary>
  11. [TestFixture]
  12. public class HashtableTest : TestCase {
  13. public void TestCtor1() {
  14. Hashtable h = new Hashtable();
  15. AssertNotNull("No hash table", h);
  16. }
  17. public void TestCtor2() {
  18. {
  19. bool errorThrown = false;
  20. try {
  21. Hashtable h = new Hashtable(null);
  22. } catch (ArgumentNullException) {
  23. errorThrown = true;
  24. }
  25. Assert("null hashtable error not thrown",
  26. errorThrown);
  27. }
  28. {
  29. string[] keys = {"this", "is", "a", "test"};
  30. char[] values = {'a', 'b', 'c', 'd'};
  31. Hashtable h1 = new Hashtable();
  32. for (int i = 0; i < keys.Length; i++) {
  33. h1[keys[i]] = values[i];
  34. }
  35. Hashtable h2 = new Hashtable(h1);
  36. for (int i = 0; i < keys.Length; i++) {
  37. AssertEquals("No match for key " + keys[i],
  38. values[i], h2[keys[i]]);
  39. }
  40. }
  41. }
  42. // TODO - Ctors for capacity and load (how to test? any access?)
  43. // TODO - Ctors with IComparer, IHashCodeProvider, Serialization
  44. public void TestCount() {
  45. Hashtable h = new Hashtable();
  46. AssertEquals("new table - count zero", 0, h.Count);
  47. int max = 100;
  48. for (int i = 1; i <= max; i++) {
  49. h[i] = i;
  50. AssertEquals("Count wrong for " + i,
  51. i, h.Count);
  52. }
  53. for (int i = 1; i <= max; i++) {
  54. h[i] = i * 2;
  55. AssertEquals("Count shouldn't change at " + i,
  56. max, h.Count);
  57. }
  58. }
  59. public void TestIsFixedSize() {
  60. Hashtable h = new Hashtable();
  61. AssertEquals("hashtable not fixed by default",
  62. false, h.IsFixedSize);
  63. // TODO - any way to get a fixed-size hashtable?
  64. }
  65. public void TestIsReadOnly() {
  66. Hashtable h = new Hashtable();
  67. AssertEquals("hashtable not read-only by default",
  68. false, h.IsReadOnly);
  69. // TODO - any way to get a read-only hashtable?
  70. }
  71. public void TestIsSynchronized() {
  72. Hashtable h = new Hashtable();
  73. Assert("hashtable not synced by default", !h.IsSynchronized);
  74. Hashtable h2 = Hashtable.Synchronized(h);
  75. Assert("hashtable should by synced", h2.IsSynchronized);
  76. }
  77. public void TestItem() {
  78. {
  79. bool errorThrown = false;
  80. try {
  81. Hashtable h = new Hashtable();
  82. Object o = h[null];
  83. } catch (ArgumentNullException) {
  84. errorThrown = true;
  85. }
  86. Assert("null hashtable error not thrown",
  87. errorThrown);
  88. }
  89. // TODO - if read-only and/or fixed-size is possible,
  90. // test 'NotSupportedException' here
  91. {
  92. Hashtable h = new Hashtable();
  93. int max = 100;
  94. for (int i = 1; i <= max; i++) {
  95. h[i] = i;
  96. AssertEquals("value wrong for " + i,
  97. i, h[i]);
  98. }
  99. }
  100. }
  101. public void TestKeys() {
  102. string[] keys = {"this", "is", "a", "test"};
  103. char[] values1 = {'a', 'b', 'c', 'd'};
  104. char[] values2 = {'e', 'f', 'g', 'h'};
  105. Hashtable h1 = new Hashtable();
  106. for (int i = 0; i < keys.Length; i++) {
  107. h1[keys[i]] = values1[i];
  108. }
  109. AssertEquals("keys wrong size",
  110. keys.Length, h1.Keys.Count);
  111. for (int i = 0; i < keys.Length; i++) {
  112. h1[keys[i]] = values2[i];
  113. }
  114. AssertEquals("keys wrong size 2",
  115. keys.Length, h1.Keys.Count);
  116. }
  117. // TODO - SyncRoot
  118. public void TestValues() {
  119. string[] keys = {"this", "is", "a", "test"};
  120. char[] values1 = {'a', 'b', 'c', 'd'};
  121. char[] values2 = {'e', 'f', 'g', 'h'};
  122. Hashtable h1 = new Hashtable();
  123. for (int i = 0; i < keys.Length; i++) {
  124. h1[keys[i]] = values1[i];
  125. }
  126. AssertEquals("values wrong size",
  127. keys.Length, h1.Values.Count);
  128. for (int i = 0; i < keys.Length; i++) {
  129. h1[keys[i]] = values2[i];
  130. }
  131. AssertEquals("values wrong size 2",
  132. keys.Length, h1.Values.Count);
  133. }
  134. public void TestAdd() {
  135. {
  136. bool errorThrown = false;
  137. try {
  138. Hashtable h = new Hashtable();
  139. h.Add(null, "huh?");
  140. } catch (ArgumentNullException) {
  141. errorThrown = true;
  142. }
  143. Assert("null add error not thrown",
  144. errorThrown);
  145. }
  146. {
  147. bool errorThrown = false;
  148. try {
  149. Hashtable h = new Hashtable();
  150. h.Add('a', 1);
  151. h.Add('a', 2);
  152. } catch (ArgumentException) {
  153. errorThrown = true;
  154. }
  155. Assert("re-add error not thrown",
  156. errorThrown);
  157. }
  158. // TODO - hit NotSupportedException
  159. {
  160. Hashtable h = new Hashtable();
  161. int max = 100;
  162. for (int i = 1; i <= max; i++) {
  163. h.Add(i, i);
  164. AssertEquals("value wrong for " + i,
  165. i, h[i]);
  166. }
  167. }
  168. }
  169. public void TestClear() {
  170. // TODO - hit NotSupportedException
  171. Hashtable h = new Hashtable();
  172. AssertEquals("new table - count zero", 0, h.Count);
  173. int max = 100;
  174. for (int i = 1; i <= max; i++) {
  175. h[i] = i;
  176. }
  177. Assert("table don't gots stuff", h.Count > 0);
  178. h.Clear();
  179. AssertEquals("Table should be cleared",
  180. 0, h.Count);
  181. }
  182. public void TestClone() {
  183. {
  184. char[] c1 = {'a', 'b', 'c'};
  185. char[] c2 = {'d', 'e', 'f'};
  186. Hashtable h1 = new Hashtable();
  187. for (int i = 0; i < c1.Length; i++) {
  188. h1[c1[i]] = c2[i];
  189. }
  190. Hashtable h2 = (Hashtable)h1.Clone();
  191. AssertNotNull("got no clone!", h2);
  192. AssertNotNull("clone's got nothing!", h2[c1[0]]);
  193. for (int i = 0; i < c1.Length; i++) {
  194. AssertEquals("Hashtable match",
  195. h1[c1[i]], h2[c1[i]]);
  196. }
  197. }
  198. {
  199. char[] c1 = {'a', 'b', 'c'};
  200. char[] c20 = {'1', '2'};
  201. char[] c21 = {'3', '4'};
  202. char[] c22 = {'5', '6'};
  203. char[][] c2 = {c20, c21, c22};
  204. Hashtable h1 = new Hashtable();
  205. for (int i = 0; i < c1.Length; i++) {
  206. h1[c1[i]] = c2[i];
  207. }
  208. Hashtable h2 = (Hashtable)h1.Clone();
  209. AssertNotNull("got no clone!", h2);
  210. AssertNotNull("clone's got nothing!", h2[c1[0]]);
  211. for (int i = 0; i < c1.Length; i++) {
  212. AssertEquals("Hashtable match",
  213. h1[c1[i]], h2[c1[i]]);
  214. }
  215. ((char[])h1[c1[0]])[0] = 'z';
  216. AssertEquals("shallow copy", h1[c1[0]], h2[c1[0]]);
  217. }
  218. }
  219. public void TestContains() {
  220. {
  221. bool errorThrown = false;
  222. try {
  223. Hashtable h = new Hashtable();
  224. bool result = h.Contains(null);
  225. } catch (ArgumentNullException) {
  226. errorThrown = true;
  227. }
  228. Assert("null add error not thrown",
  229. errorThrown);
  230. }
  231. {
  232. Hashtable h = new Hashtable();
  233. h['a'] = "blue";
  234. Assert("'a'? it's in there!", h.Contains('a'));
  235. Assert("'b'? no way!", !h.Contains('b'));
  236. }
  237. }
  238. public void TestContainsKey() {
  239. {
  240. bool errorThrown = false;
  241. try {
  242. Hashtable h = new Hashtable();
  243. bool result = h.ContainsKey(null);
  244. } catch (ArgumentNullException) {
  245. errorThrown = true;
  246. }
  247. Assert("null add error not thrown",
  248. errorThrown);
  249. }
  250. {
  251. Hashtable h = new Hashtable();
  252. h['a'] = "blue";
  253. Assert("'a'? it's in there!", h.ContainsKey('a'));
  254. Assert("'b'? no way!", !h.ContainsKey('b'));
  255. }
  256. }
  257. public void TestContainsValue() {
  258. {
  259. Hashtable h = new Hashtable();
  260. h['a'] = "blue";
  261. Assert("blue? it's in there!",
  262. h.ContainsValue("blue"));
  263. Assert("green? no way!",
  264. !h.ContainsValue("green"));
  265. }
  266. }
  267. public void TestCopyTo() {
  268. {
  269. bool errorThrown = false;
  270. try {
  271. Hashtable h = new Hashtable();
  272. h.CopyTo(null, 0);
  273. } catch (ArgumentNullException) {
  274. errorThrown = true;
  275. }
  276. Assert("null hashtable error not thrown",
  277. errorThrown);
  278. }
  279. {
  280. bool errorThrown = false;
  281. try {
  282. Hashtable h = new Hashtable();
  283. Object[] o = new Object[1];
  284. h.CopyTo(o, -1);
  285. } catch (ArgumentOutOfRangeException) {
  286. errorThrown = true;
  287. }
  288. Assert("out of range error not thrown",
  289. errorThrown);
  290. }
  291. {
  292. bool errorThrown = false;
  293. try {
  294. Hashtable h = new Hashtable();
  295. Object[,] o = new Object[1,1];
  296. h.CopyTo(o, 1);
  297. } catch (ArgumentException) {
  298. errorThrown = true;
  299. }
  300. Assert("multi-dim array error not thrown",
  301. errorThrown);
  302. }
  303. {
  304. bool errorThrown = false;
  305. try {
  306. Hashtable h = new Hashtable();
  307. h['a'] = 1; // no error if table is empty
  308. Object[] o = new Object[5];
  309. h.CopyTo(o, 5);
  310. } catch (ArgumentException) {
  311. errorThrown = true;
  312. }
  313. Assert("no room in array error not thrown",
  314. errorThrown);
  315. }
  316. {
  317. bool errorThrown = false;
  318. try {
  319. Hashtable h = new Hashtable();
  320. h['a'] = 1;
  321. h['b'] = 2;
  322. h['c'] = 2;
  323. Object[] o = new Object[2];
  324. h.CopyTo(o, 0);
  325. } catch (ArgumentException) {
  326. errorThrown = true;
  327. }
  328. Assert("table too big error not thrown",
  329. errorThrown);
  330. }
  331. {
  332. bool errorThrown = false;
  333. try {
  334. Hashtable h = new Hashtable();
  335. h["blue"] = 1;
  336. h["green"] = 2;
  337. h["red"] = 3;
  338. Char[] o = new Char[3];
  339. h.CopyTo(o, 0);
  340. } catch (InvalidCastException) {
  341. errorThrown = true;
  342. }
  343. Assert("invalid cast error not thrown",
  344. errorThrown);
  345. }
  346. {
  347. Hashtable h = new Hashtable();
  348. h['a'] = 1;
  349. h['b'] = 2;
  350. DictionaryEntry[] o = new DictionaryEntry[2];
  351. h.CopyTo(o,0);
  352. AssertEquals("first copy fine.", 'a', o[0].Key);
  353. AssertEquals("first copy fine.", 1, o[0].Value);
  354. AssertEquals("second copy fine.", 'b', o[1].Key);
  355. AssertEquals("second copy fine.", 2, o[1].Value);
  356. }
  357. }
  358. public void TestGetEnumerator() {
  359. String[] s1 = {"this", "is", "a", "test"};
  360. Char[] c1 = {'a', 'b', 'c', 'd'};
  361. Hashtable h1 = new Hashtable();
  362. for (int i = 0; i < s1.Length; i++) {
  363. h1[s1[i]] = c1[i];
  364. }
  365. IDictionaryEnumerator en = h1.GetEnumerator();
  366. AssertNotNull("No enumerator", en);
  367. for (int i = 0; i < s1.Length; i++) {
  368. en.MoveNext();
  369. Assert("Not enumerating for " + en.Key,
  370. Array.IndexOf(s1, en.Key) >= 0);
  371. Assert("Not enumerating for " + en.Value,
  372. Array.IndexOf(c1, en.Value) >= 0);
  373. }
  374. }
  375. // TODO - GetObjectData
  376. // TODO - OnDeserialization
  377. public void TestRemove() {
  378. {
  379. bool errorThrown = false;
  380. try {
  381. Hashtable h = new Hashtable();
  382. h.Remove(null);
  383. } catch (ArgumentNullException) {
  384. errorThrown = true;
  385. }
  386. Assert("null hashtable error not thrown",
  387. errorThrown);
  388. }
  389. {
  390. string[] keys = {"this", "is", "a", "test"};
  391. char[] values = {'a', 'b', 'c', 'd'};
  392. Hashtable h = new Hashtable();
  393. for (int i = 0; i < keys.Length; i++) {
  394. h[keys[i]] = values[i];
  395. }
  396. AssertEquals("not enough in table",
  397. 4, h.Count);
  398. h.Remove("huh?");
  399. AssertEquals("not enough in table",
  400. 4, h.Count);
  401. h.Remove("this");
  402. AssertEquals("Wrong count in table",
  403. 3, h.Count);
  404. h.Remove("this");
  405. AssertEquals("Wrong count in table",
  406. 3, h.Count);
  407. }
  408. }
  409. public void TestSynchronized() {
  410. {
  411. bool errorThrown = false;
  412. try {
  413. Hashtable h = Hashtable.Synchronized(null);
  414. } catch (ArgumentNullException) {
  415. errorThrown = true;
  416. }
  417. Assert("null hashtable error not thrown",
  418. errorThrown);
  419. }
  420. {
  421. Hashtable h = new Hashtable();
  422. Assert("hashtable not synced by default",
  423. !h.IsSynchronized);
  424. Hashtable h2 = Hashtable.Synchronized(h);
  425. Assert("hashtable should by synced",
  426. h2.IsSynchronized);
  427. }
  428. }
  429. protected Hashtable ht;
  430. private static Random rnd;
  431. [SetUp]
  432. protected override void SetUp() {
  433. ht=new Hashtable();
  434. rnd=new Random();
  435. }
  436. private void SetDefaultData() {
  437. ht.Clear();
  438. ht.Add("k1","another");
  439. ht.Add("k2","yet");
  440. ht.Add("k3","hashtable");
  441. }
  442. public void TestAddRemoveClear() {
  443. ht.Clear();
  444. Assert(ht.Count==0);
  445. SetDefaultData();
  446. Assert(ht.Count==3);
  447. bool thrown=false;
  448. try {
  449. ht.Add("k2","cool");
  450. } catch (ArgumentException) {thrown=true;}
  451. Assert("Must throw ArgumentException!",thrown);
  452. ht["k2"]="cool";
  453. Assert(ht.Count==3);
  454. Assert(ht["k2"].Equals("cool"));
  455. }
  456. public void TestCopyTo2() {
  457. SetDefaultData();
  458. Object[] entries=new Object[ht.Count];
  459. ht.CopyTo(entries,0);
  460. Assert("Not an entry.",entries[0] is DictionaryEntry);
  461. }
  462. public void TestUnderHeavyLoad() {
  463. ht.Clear();
  464. int max=100000;
  465. String[] cache=new String[max*2];
  466. int n=0;
  467. for (int i=0;i<max;i++) {
  468. int id=rnd.Next()&0xFFFF;
  469. String key=""+id+"-key-"+id;
  470. String val="value-"+id;
  471. if (ht[key]==null) {
  472. ht[key]=val;
  473. cache[n]=key;
  474. cache[n+max]=val;
  475. n++;
  476. }
  477. }
  478. Assert(ht.Count==n);
  479. for (int i=0;i<n;i++) {
  480. String key=cache[i];
  481. String val=ht[key] as String;
  482. String err="ht[\""+key+"\"]=\""+val+
  483. "\", expected \""+cache[i+max]+"\"";
  484. Assert(err,val!=null && val.Equals(cache[i+max]));
  485. }
  486. int r1=(n/3);
  487. int r2=r1+(n/5);
  488. for (int i=r1;i<r2;i++) {
  489. ht.Remove(cache[i]);
  490. }
  491. for (int i=0;i<n;i++) {
  492. if (i>=r1 && i<r2) {
  493. Assert(ht[cache[i]]==null);
  494. } else {
  495. String key=cache[i];
  496. String val=ht[key] as String;
  497. String err="ht[\""+key+"\"]=\""+val+
  498. "\", expected \""+cache[i+max]+"\"";
  499. Assert(err,val!=null && val.Equals(cache[i+max]));
  500. }
  501. }
  502. ICollection keys=ht.Keys;
  503. int nKeys=0;
  504. foreach (Object key in keys) {
  505. Assert((key as String) != null);
  506. nKeys++;
  507. }
  508. Assert(nKeys==ht.Count);
  509. ICollection vals=ht.Values;
  510. int nVals=0;
  511. foreach (Object val in vals) {
  512. Assert((val as String) != null);
  513. nVals++;
  514. }
  515. Assert(nVals==ht.Count);
  516. }
  517. [TestFixture]
  518. public class HashtableTest2 : TestCase {
  519. protected Hashtable ht;
  520. private static Random rnd;
  521. [SetUp]
  522. protected override void SetUp ()
  523. {
  524. ht=new Hashtable ();
  525. rnd=new Random ();
  526. }
  527. private void SetDefaultData ()
  528. {
  529. ht.Clear ();
  530. ht.Add ("k1","another");
  531. ht.Add ("k2","yet");
  532. ht.Add ("k3","hashtable");
  533. }
  534. public void TestAddRemoveClear ()
  535. {
  536. ht.Clear ();
  537. Assert (ht.Count == 0);
  538. SetDefaultData ();
  539. Assert (ht.Count == 3);
  540. bool thrown=false;
  541. try {
  542. ht.Add ("k2","cool");
  543. } catch (ArgumentException) {thrown=true;}
  544. Assert("Must throw ArgumentException!",thrown);
  545. ht["k2"]="cool";
  546. Assert(ht.Count == 3);
  547. Assert(ht["k2"].Equals("cool"));
  548. }
  549. public void TestCopyTo ()
  550. {
  551. SetDefaultData ();
  552. Object[] entries=new Object[ht.Count];
  553. ht.CopyTo (entries,0);
  554. Assert("Not an entry.",entries[0] is DictionaryEntry);
  555. }
  556. public void TestUnderHeavyLoad ()
  557. {
  558. ht.Clear ();
  559. int max=100000;
  560. String[] cache=new String[max*2];
  561. int n=0;
  562. for (int i=0;i<max;i++) {
  563. int id=rnd.Next()&0xFFFF;
  564. String key=""+id+"-key-"+id;
  565. String val="value-"+id;
  566. if (ht[key]==null) {
  567. ht[key]=val;
  568. cache[n]=key;
  569. cache[n+max]=val;
  570. n++;
  571. }
  572. }
  573. Assert(ht.Count==n);
  574. for (int i=0;i<n;i++) {
  575. String key=cache[i];
  576. String val=ht[key] as String;
  577. String err="ht[\""+key+"\"]=\""+val+
  578. "\", expected \""+cache[i+max]+"\"";
  579. Assert(err,val!=null && val.Equals(cache[i+max]));
  580. }
  581. int r1=(n/3);
  582. int r2=r1+(n/5);
  583. for (int i=r1;i<r2;i++) {
  584. ht.Remove(cache[i]);
  585. }
  586. for (int i=0;i<n;i++) {
  587. if (i>=r1 && i<r2) {
  588. Assert(ht[cache[i]]==null);
  589. } else {
  590. String key=cache[i];
  591. String val=ht[key] as String;
  592. String err="ht[\""+key+"\"]=\""+val+
  593. "\", expected \""+cache[i+max]+"\"";
  594. Assert(err,val!=null && val.Equals(cache[i+max]));
  595. }
  596. }
  597. ICollection keys=ht.Keys;
  598. int nKeys=0;
  599. foreach (Object key in keys) {
  600. Assert((key as String) != null);
  601. nKeys++;
  602. }
  603. Assert(nKeys==ht.Count);
  604. ICollection vals=ht.Values;
  605. int nVals=0;
  606. foreach (Object val in vals) {
  607. Assert((val as String) != null);
  608. nVals++;
  609. }
  610. Assert(nVals==ht.Count);
  611. }
  612. /// <summary>
  613. /// Test hashtable with CaseInsensitiveHashCodeProvider
  614. /// and CaseInsensitive comparer.
  615. /// </summary>
  616. public void TestCaseInsensitive ()
  617. {
  618. // Not very meaningfull test, just to make
  619. // sure that hcp is set properly set.
  620. Hashtable ciHashtable = new Hashtable(11,1.0f,CaseInsensitiveHashCodeProvider.Default,CaseInsensitiveComparer.Default);
  621. ciHashtable ["key1"] = "value";
  622. ciHashtable ["key2"] = "VALUE";
  623. Assert(ciHashtable ["key1"].Equals ("value"));
  624. Assert(ciHashtable ["key2"].Equals ("VALUE"));
  625. ciHashtable ["KEY1"] = "new_value";
  626. Assert(ciHashtable ["key1"].Equals ("new_value"));
  627. }
  628. public void TestCopyConstructor ()
  629. {
  630. SetDefaultData ();
  631. Hashtable htCopy = new Hashtable (ht);
  632. Assert(ht.Count == htCopy.Count);
  633. }
  634. public void TestEnumerator ()
  635. {
  636. SetDefaultData ();
  637. IEnumerator e = ht.GetEnumerator ();
  638. while (e.MoveNext ()) {}
  639. Assert (!e.MoveNext ());
  640. }
  641. }
  642. }
  643. }