PageRenderTime 62ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/Utilities/Collections/KeyedList.cs

#
C# | 1110 lines | 741 code | 98 blank | 271 comment | 64 complexity | b372e33041993ff02d89a5549075129d MD5 | raw file
Possible License(s): Apache-2.0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using NUnit.Framework;
  5. namespace Delta.Utilities.Collections
  6. {
  7. /// <summary>
  8. /// Keyed list, the generic version.
  9. /// </summary>
  10. /// <typeparam name="K">Key type</typeparam>
  11. /// <typeparam name="V">Value type</typeparam>
  12. public class KeyedList<K, V>
  13. : IDictionary<K, V>, IList<KeyValuePair<K, V>>
  14. {
  15. #region IsReadOnly (Public)
  16. /// <summary>
  17. /// Returns false.
  18. /// </summary>
  19. /// <typeparam name="K">K</typeparam>
  20. /// <typeparam name="V">V</typeparam>
  21. public bool IsReadOnly
  22. {
  23. get
  24. {
  25. return false;
  26. } // get
  27. }
  28. #endregion
  29. #region Count (Public)
  30. /// <summary>
  31. /// Returns the number of entries in the KeyedList.
  32. /// </summary>
  33. /// <typeparam name="K">K</typeparam>
  34. /// <typeparam name="V">V</typeparam>
  35. public int Count
  36. {
  37. get
  38. {
  39. return objectList.Count;
  40. } // get
  41. }
  42. #endregion
  43. #region Keys (Public)
  44. /// <summary>
  45. /// Get an unordered list of keys.
  46. /// This collection refers back to the keys in the original Dictionary.
  47. /// </summary>
  48. /// <typeparam name="K">K</typeparam>
  49. /// <typeparam name="V">V</typeparam>
  50. public ICollection<K> Keys
  51. {
  52. get
  53. {
  54. return objectTable.Keys;
  55. } // get
  56. }
  57. #endregion
  58. #region Values (Public)
  59. /// <summary>
  60. /// Get an unordered list of values.
  61. /// This collection refers back to the values in the original Dictionary.
  62. /// </summary>
  63. /// <typeparam name="K">K</typeparam>
  64. /// <typeparam name="V">V</typeparam>
  65. public ICollection<V> Values
  66. {
  67. get
  68. {
  69. return objectTable.Values;
  70. } // get
  71. }
  72. #endregion
  73. #region OrderedKeys (Public)
  74. /// <summary>
  75. /// Get the ordered list of keys.
  76. /// This is a copy of the keys in the original Dictionary.
  77. /// </summary>
  78. /// <typeparam name="K">K</typeparam>
  79. /// <typeparam name="V">V</typeparam>
  80. public List<K> OrderedKeys
  81. {
  82. get
  83. {
  84. List<K> retList = new List<K>();
  85. foreach (KeyValuePair<K, V> kvp in objectList)
  86. {
  87. retList.Add(kvp.Key);
  88. }
  89. return retList;
  90. }
  91. }
  92. #endregion
  93. #region OrderedValues (Public)
  94. /// <summary>
  95. /// Get the ordered list of values.
  96. /// This is a copy of the values in the original Dictionary.
  97. /// </summary>
  98. /// <typeparam name="K">K</typeparam>
  99. /// <typeparam name="V">V</typeparam>
  100. public List<V> OrderedValues
  101. {
  102. get
  103. {
  104. List<V> retList = new List<V>();
  105. foreach (KeyValuePair<K, V> kvp in objectList)
  106. {
  107. retList.Add(kvp.Value);
  108. }
  109. return retList;
  110. }
  111. }
  112. #endregion
  113. #region Item (Public)
  114. /// <summary>
  115. /// Get/Set the value at the specified index.
  116. /// </summary>
  117. /// <param name="idx">The index.</param>
  118. /// <returns>The value.</returns>
  119. public KeyValuePair<K, V> this[int idx]
  120. {
  121. get
  122. {
  123. if (idx < 0 ||
  124. idx >= Count)
  125. {
  126. throw new ArgumentOutOfRangeException("index");
  127. }
  128. return objectList[idx];
  129. }
  130. set
  131. {
  132. if (idx < 0 ||
  133. idx >= Count)
  134. {
  135. throw new ArgumentOutOfRangeException("index");
  136. }
  137. objectList[idx] = value;
  138. objectTable[value.Key] = value.Value;
  139. }
  140. }
  141. /// <summary>
  142. /// Get/Set the value associated with the specified key.
  143. /// </summary>
  144. /// <param name="key">The key.</param>
  145. /// <returns>The associated value.</returns>
  146. public virtual V this[K key]
  147. {
  148. get
  149. {
  150. return objectTable[key];
  151. } // get
  152. set
  153. {
  154. if (objectTable.ContainsKey(key))
  155. {
  156. objectTable[key] = value;
  157. objectList[IndexOf(key)] = new KeyValuePair<K, V>(key, value);
  158. }
  159. else
  160. {
  161. Add(key, value);
  162. }
  163. }
  164. }
  165. #endregion
  166. #region ObjectTable (Public)
  167. /// <summary>
  168. /// Gets the Dictionary class backing the KeyedList.
  169. /// </summary>
  170. public Dictionary<K, V> ObjectTable
  171. {
  172. get
  173. {
  174. return objectTable;
  175. } // get
  176. }
  177. #endregion
  178. #region Private
  179. #region objectTable (Private)
  180. /// <summary>
  181. /// Object table
  182. /// </summary>
  183. /// <typeparam name="K">K</typeparam>
  184. /// <typeparam name="V">V</typeparam>
  185. private readonly Dictionary<K, V> objectTable =
  186. new Dictionary<K, V>();
  187. #endregion
  188. #region objectList (Private)
  189. /// <summary>
  190. /// Object list
  191. /// </summary>
  192. /// <typeparam name="K">K</typeparam>
  193. /// <typeparam name="V">V</typeparam>
  194. private readonly List<KeyValuePair<K, V>> objectList =
  195. new List<KeyValuePair<K, V>>();
  196. #endregion
  197. #endregion
  198. #region ICollection<KeyValuePair<K,V>> Members
  199. /// <summary>
  200. /// Adds a key-value pair to the KeyedList.
  201. /// </summary>
  202. /// <param name="kvp">The KeyValuePair instance.</param>
  203. public void Add(KeyValuePair<K, V> kvp)
  204. {
  205. Add(kvp.Key, kvp.Value);
  206. }
  207. /// <summary>
  208. /// Clears all entries in the KeyedList.
  209. /// </summary>
  210. public void Clear()
  211. {
  212. objectTable.Clear();
  213. objectList.Clear();
  214. }
  215. /// <summary>
  216. /// Test if the KeyedList contains the key in the key-value pair.
  217. /// </summary>
  218. /// <param name="kvp">The key-value pair.</param>
  219. /// <returns>True if the key is found.</returns>
  220. public bool Contains(KeyValuePair<K, V> kvp)
  221. {
  222. return objectTable.ContainsKey(kvp.Key);
  223. }
  224. /// <summary>
  225. /// Copy the entire key-value pairs to the KeyValuePair array, starting
  226. /// at the specified index of the target array. The array is populated
  227. /// as an ordered list.
  228. /// </summary>
  229. /// <param name="kvpa">The KeyValuePair array.</param>
  230. /// <param name="idx">The position to start the copy.</param>
  231. public void CopyTo(KeyValuePair<K, V>[] kvpa, int idx)
  232. {
  233. objectList.CopyTo(kvpa, idx);
  234. }
  235. /// <summary>
  236. /// Remove the key in the specified KeyValuePair instance. The Value
  237. /// property is ignored.
  238. /// </summary>
  239. /// <param name="kvp">The key-value identifying the entry.</param>
  240. /// <returns>True if removed.</returns>
  241. public bool Remove(KeyValuePair<K, V> kvp)
  242. {
  243. return Remove(kvp.Key);
  244. }
  245. #endregion
  246. #region IDictionary<K,V> Members
  247. /// <summary>
  248. /// Adds a key-value pair to the KeyedList.
  249. /// </summary>
  250. /// <param name="key">The key.</param>
  251. /// <param name="value">The associated value.</param>
  252. public void Add(K key, V value)
  253. {
  254. objectTable.Add(key, value);
  255. objectList.Add(new KeyValuePair<K, V>(key, value));
  256. }
  257. /// <summary>
  258. /// Test if the KeyedList contains the key.
  259. /// </summary>
  260. /// <param name="key">The key.</param>
  261. /// <returns>True if the key is found.</returns>
  262. public bool ContainsKey(K key)
  263. {
  264. return objectTable.ContainsKey(key);
  265. }
  266. /// <summary>
  267. /// Remove the entry.
  268. /// </summary>
  269. /// <param name="key">The key identifying the key-value pair.</param>
  270. /// <returns>True if removed.</returns>
  271. public bool Remove(K key)
  272. {
  273. bool found = objectTable.Remove(key);
  274. if (found)
  275. {
  276. objectList.RemoveAt(IndexOf(key));
  277. }
  278. return found;
  279. }
  280. /// <summary>
  281. /// Attempt to get the value, given the key, without throwing an exception
  282. /// if not found.
  283. /// </summary>
  284. /// <param name="key">The key indentifying the entry.</param>
  285. /// <param name="val">The value, if found.</param>
  286. /// <returns>True if found.</returns>
  287. public bool TryGetValue(K key, out V val)
  288. {
  289. return objectTable.TryGetValue(key, out val);
  290. }
  291. #endregion
  292. #region IEnumerable Members
  293. /// <summary>
  294. /// Returns an ordered System.Collections KeyValuePair objects.
  295. /// </summary>
  296. IEnumerator IEnumerable.GetEnumerator()
  297. {
  298. return objectList.GetEnumerator();
  299. }
  300. #endregion
  301. #region IEnumerable<KeyValuePair<K,V>> Members
  302. /// <summary>
  303. /// Returns an ordered KeyValuePair enumerator.
  304. /// </summary>
  305. IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.
  306. GetEnumerator()
  307. {
  308. return objectList.GetEnumerator();
  309. }
  310. #endregion
  311. #region IList<KeyValuePair<K,V>> Members
  312. /// <summary>
  313. /// Given the key-value pair, find the index.
  314. /// </summary>
  315. /// <param name="kvp">The key-value pair.</param>
  316. /// <returns>The index, or -1 if not found.</returns>
  317. public int IndexOf(KeyValuePair<K, V> kvp)
  318. {
  319. return IndexOf(kvp.Key);
  320. }
  321. /// <summary>
  322. /// Insert the key-value pair at the specified index location.
  323. /// </summary>
  324. /// <param name="idx">The key.</param>
  325. /// <param name="kvp">The value.</param>
  326. public void Insert(int idx, KeyValuePair<K, V> kvp)
  327. {
  328. if ((idx < 0) ||
  329. (idx > Count))
  330. {
  331. throw new ArgumentOutOfRangeException("index");
  332. }
  333. objectTable.Add(kvp.Key, kvp.Value);
  334. objectList.Insert(idx, kvp);
  335. }
  336. /// <summary>
  337. /// Remove the entry at the specified index.
  338. /// </summary>
  339. /// <param name="idx">The index to the entry to be removed.</param>
  340. public void RemoveAt(int idx)
  341. {
  342. if ((idx < 0) ||
  343. (idx >= Count))
  344. {
  345. throw new ArgumentOutOfRangeException("index");
  346. }
  347. objectTable.Remove(objectList[idx].Key);
  348. objectList.RemoveAt(idx);
  349. }
  350. #endregion
  351. #region GetKey (Public)
  352. /// <summary>
  353. /// Returns the key at the specified index.
  354. /// </summary>
  355. /// <param name="idx">The index.</param>
  356. /// <returns>The key at the index.</returns>
  357. public K GetKey(int idx)
  358. {
  359. if (idx < 0 ||
  360. idx >= Count)
  361. {
  362. throw new ArgumentOutOfRangeException("index");
  363. }
  364. return objectList[idx].Key;
  365. }
  366. #endregion
  367. #region GetValue (Public)
  368. /// <summary>
  369. /// Returns the value at the specified index.
  370. /// </summary>
  371. /// <param name="idx">The index.</param>
  372. /// <returns>The value at the index.</returns>
  373. public V GetValue(int idx)
  374. {
  375. if (idx < 0 ||
  376. idx >= Count)
  377. {
  378. throw new ArgumentOutOfRangeException("index");
  379. }
  380. return objectList[idx].Value;
  381. }
  382. #endregion
  383. #region IndexOf (Public)
  384. /// <summary>
  385. /// Get the index of a particular key.
  386. /// </summary>
  387. /// <param name="key">The key to find the index of.</param>
  388. /// <returns>The index of the key, or -1 if not found.</returns>
  389. public int IndexOf(K key)
  390. {
  391. int ret = -1;
  392. for (int i = 0; i < objectList.Count; i++)
  393. {
  394. if (objectList[i].Key.Equals(key))
  395. {
  396. ret = i;
  397. break;
  398. }
  399. }
  400. return ret;
  401. }
  402. #endregion
  403. #region Insert (Public)
  404. /// <summary>
  405. /// Insert the key-value at the specified index.
  406. /// </summary>
  407. /// <param name="idx">The zero-based insert point.</param>
  408. /// <param name="key">The key.</param>
  409. /// <param name="value">The value.</param>
  410. public void Insert(int idx, K key, V value)
  411. {
  412. if ((idx < 0) ||
  413. (idx > Count))
  414. {
  415. throw new ArgumentOutOfRangeException("index");
  416. }
  417. objectTable.Add(key, value);
  418. objectList.Insert(idx, new KeyValuePair<K, V>(key, value));
  419. }
  420. #endregion
  421. }
  422. /// <summary>
  423. /// Keyed list tests, must be declared outside of a generic class.
  424. /// </summary>
  425. internal class KeyedListTests
  426. {
  427. #region Helpers
  428. #region k
  429. /// <summary>
  430. /// KeyedList for testing ..
  431. /// </summary>
  432. protected static KeyedList<string, int> k;
  433. #endregion
  434. #region .ctor
  435. /// <summary>
  436. /// KeyedListTests
  437. /// </summary>
  438. public KeyedListTests()
  439. {
  440. k = new KeyedList<string, int>();
  441. k.Add("Zero", 0);
  442. k.Add("One", 1);
  443. k.Add("Two", 2);
  444. k.Add("Three", 3);
  445. k.Add("Four", 4);
  446. k.Add("Five", 5);
  447. k.Add("Six", 6);
  448. k.Add("Seven", 7);
  449. k.Add("Eight", 8);
  450. k.Add("Nine", 9);
  451. k.Add("Ten", 10);
  452. }
  453. #endregion
  454. #endregion
  455. #region NegativeIndexTest (Static)
  456. /// <summary>
  457. /// Negative index test. Note: Too slow for a dynamic unit test.
  458. /// </summary>
  459. [Test]
  460. public static void NegativeIndexTest()
  461. {
  462. Assert.Throws(typeof(ArgumentOutOfRangeException),
  463. delegate
  464. {
  465. int foo = k[-1].Value;
  466. });
  467. }
  468. #endregion
  469. #region ValueIteratorTest
  470. /// <summary>
  471. /// Value iterator test
  472. /// </summary>
  473. [Test]
  474. public void ValueIteratorTest()
  475. {
  476. int idx = 0;
  477. foreach (int val in k.Values)
  478. {
  479. Assert.True(val == idx, "Itereator: Expected " + idx.ToString());
  480. ++idx;
  481. }
  482. }
  483. #endregion
  484. #region ValueByIndexTests
  485. /// <summary>
  486. /// Value by index tests
  487. /// </summary>
  488. [Test]
  489. public void ValueByIndexTests()
  490. {
  491. Assert.True(k[0].Value == 0, "Indexer: Expected 0");
  492. Assert.True(k[1].Value == 1, "Indexer: Expected 1");
  493. Assert.True(k[2].Value == 2, "Indexer: Expected 2");
  494. Assert.True(k[3].Value == 3, "Indexer: Expected 3");
  495. Assert.True(k[4].Value == 4, "Indexer: Expected 4");
  496. Assert.True(k[5].Value == 5, "Indexer: Expected 5");
  497. Assert.True(k[6].Value == 6, "Indexer: Expected 6");
  498. Assert.True(k[7].Value == 7, "Indexer: Expected 7");
  499. Assert.True(k[8].Value == 8, "Indexer: Expected 8");
  500. Assert.True(k[9].Value == 9, "Indexer: Expected 9");
  501. Assert.True(k[10].Value == 10, "Indexer: Expected 10");
  502. }
  503. #endregion
  504. #region ValueByKeyTests
  505. /// <summary>
  506. /// Value by key tests
  507. /// </summary>
  508. [Test]
  509. public void ValueByKeyTests()
  510. {
  511. Assert.True(k["Zero"] == 0, "Lookup: Expected 0");
  512. Assert.True(k["One"] == 1, "Lookup: Expected 1");
  513. Assert.True(k["Two"] == 2, "Lookup: Expected 2");
  514. Assert.True(k["Three"] == 3, "Lookup: Expected 3");
  515. Assert.True(k["Four"] == 4, "Lookup: Expected 4");
  516. Assert.True(k["Five"] == 5, "Lookup: Expected 5");
  517. Assert.True(k["Six"] == 6, "Lookup: Expected 6");
  518. Assert.True(k["Seven"] == 7, "Lookup: Expected 7");
  519. Assert.True(k["Eight"] == 8, "Lookup: Expected 8");
  520. Assert.True(k["Nine"] == 9, "Lookup: Expected 9");
  521. Assert.True(k["Ten"] == 10, "Lookup: Expected 10");
  522. }
  523. #endregion
  524. #region IndexOfTests
  525. /// <summary>
  526. /// Index of tests
  527. /// </summary>
  528. [Test]
  529. public void IndexOfTests()
  530. {
  531. Assert.True(k.IndexOf("Zero") == 0, "IndexOf: Expected 0");
  532. Assert.True(k.IndexOf("One") == 1, "IndexOf: Expected 1");
  533. Assert.True(k.IndexOf("Two") == 2, "IndexOf: Expected 2");
  534. Assert.True(k.IndexOf("Three") == 3, "IndexOf: Expected 3");
  535. Assert.True(k.IndexOf("Four") == 4, "IndexOf: Expected 4");
  536. Assert.True(k.IndexOf("Five") == 5, "IndexOf: Expected 5");
  537. Assert.True(k.IndexOf("Six") == 6, "IndexOf: Expected 6");
  538. Assert.True(k.IndexOf("Seven") == 7, "IndexOf: Expected 7");
  539. Assert.True(k.IndexOf("Eight") == 8, "IndexOf: Expected 8");
  540. Assert.True(k.IndexOf("Nine") == 9, "IndexOf: Expected 9");
  541. Assert.True(k.IndexOf("Ten") == 10, "IndexOf: Expected 10");
  542. }
  543. #endregion
  544. #region ContainsKeyTests
  545. /// <summary>
  546. /// Contains key tests
  547. /// </summary>
  548. [Test]
  549. public void ContainsKeyTests()
  550. {
  551. Assert.True(k.ContainsKey("Zero"), "Expected true");
  552. Assert.True(k.ContainsKey("One"), "Expected true");
  553. Assert.True(k.ContainsKey("Two"), "Expected true");
  554. Assert.True(k.ContainsKey("Three"), "Expected true");
  555. Assert.True(k.ContainsKey("Four"), "Expected true");
  556. Assert.True(k.ContainsKey("Five"), "Expected true");
  557. Assert.True(k.ContainsKey("Six"), "Expected true");
  558. Assert.True(k.ContainsKey("Seven"), "Expected true");
  559. Assert.True(k.ContainsKey("Eight"), "Expected true");
  560. Assert.True(k.ContainsKey("Nine"), "Expected true");
  561. Assert.True(k.ContainsKey("Ten"), "Expected true");
  562. }
  563. #endregion
  564. #region ContainsTests
  565. /// <summary>
  566. /// Contains tests
  567. /// </summary>
  568. [Test]
  569. public void ContainsTests()
  570. {
  571. Assert.True(k.Contains(
  572. new KeyValuePair<string, int>("Zero", 0)), "Expected true");
  573. Assert.True(k.Contains(
  574. new KeyValuePair<string, int>("One", 1)), "Expected true");
  575. Assert.True(k.Contains(
  576. new KeyValuePair<string, int>("Two", 2)), "Expected true");
  577. Assert.True(k.Contains(
  578. new KeyValuePair<string, int>("Three", 3)), "Expected true");
  579. Assert.True(k.Contains(
  580. new KeyValuePair<string, int>("Four", 4)), "Expected true");
  581. Assert.True(k.Contains(
  582. new KeyValuePair<string, int>("Five", 5)), "Expected true");
  583. Assert.True(k.Contains(
  584. new KeyValuePair<string, int>("Six", 6)), "Expected true");
  585. Assert.True(k.Contains(
  586. new KeyValuePair<string, int>("Seven", 7)), "Expected true");
  587. Assert.True(k.Contains(
  588. new KeyValuePair<string, int>("Eight", 8)), "Expected true");
  589. Assert.True(k.Contains(
  590. new KeyValuePair<string, int>("Nine", 9)), "Expected true");
  591. Assert.True(k.Contains(
  592. new KeyValuePair<string, int>("Ten", 10)), "Expected true");
  593. }
  594. #endregion
  595. #region NotContainsKeyTest
  596. /// <summary>
  597. /// Does not contains key test
  598. /// </summary>
  599. [Test]
  600. public void NotContainsKeyTest()
  601. {
  602. Assert.False(k.ContainsKey("Eleven"), "Expected false");
  603. }
  604. #endregion
  605. #region NotContainsTests
  606. /// <summary>
  607. /// Does not contains tests
  608. /// </summary>
  609. [Test]
  610. public void NotContainsTests()
  611. {
  612. Assert.True(k.Contains(
  613. new KeyValuePair<string, int>("Zero", 5)),
  614. "List does not contain kvp Zero-5, but Contains returned true!");
  615. Assert.False(k.Contains(
  616. new KeyValuePair<string, int>("Eleven", 11)),
  617. "List does contain kvp Eleven-11, but it was not found!");
  618. }
  619. #endregion
  620. #region OrderedKeyTest
  621. /// <summary>
  622. /// Ordered key test
  623. /// </summary>
  624. [Test]
  625. public void OrderedKeyTest()
  626. {
  627. int idx = 0;
  628. foreach (string key in k.OrderedKeys)
  629. {
  630. Assert.True(key == k.GetKey(idx++),
  631. "Expected key to match indexed key.");
  632. }
  633. }
  634. #endregion
  635. #region OrderedValueTest
  636. /// <summary>
  637. /// Ordered value test
  638. /// </summary>
  639. [Test]
  640. public void OrderedValueTest()
  641. {
  642. int idx = 0;
  643. foreach (int val in k.OrderedValues)
  644. {
  645. Assert.True(val == k[idx++].Value,
  646. "Expected value to match indexed value.");
  647. }
  648. }
  649. #endregion
  650. #region IndexToLargeTest
  651. /// <summary>
  652. /// Index to large test
  653. /// </summary>
  654. [Test]
  655. public void IndexToLargeTest()
  656. {
  657. Assert.Throws(typeof(ArgumentOutOfRangeException),
  658. delegate
  659. {
  660. int foo = k[k.Count].Value;
  661. });
  662. }
  663. #endregion
  664. #region BadKeyTest
  665. /// <summary>
  666. /// Bad key test
  667. /// </summary>
  668. [Test]
  669. public void BadKeyTest()
  670. {
  671. Assert.Throws(typeof(KeyNotFoundException),
  672. delegate
  673. {
  674. int foo = k["Eleven"];
  675. });
  676. }
  677. #endregion
  678. #region IndexOfNotFound
  679. /// <summary>
  680. /// Index of not found
  681. /// </summary>
  682. [Test]
  683. public void IndexOfNotFound()
  684. {
  685. Assert.True(k.IndexOf("Foo") == -1,
  686. "Expected the returned index to be -1.");
  687. }
  688. #endregion
  689. }
  690. /// <summary>
  691. /// Sequenced keyed list tests
  692. /// </summary>
  693. internal class SequencedKeyedListTests
  694. {
  695. #region Helpers
  696. #region k
  697. /// <summary>
  698. /// K
  699. /// </summary>
  700. protected KeyedList<string, double> k;
  701. #endregion
  702. #region .ctor
  703. /// <summary>
  704. /// Fixture setup
  705. /// </summary>
  706. public SequencedKeyedListTests()
  707. {
  708. FillList();
  709. }
  710. #endregion
  711. #region FillList
  712. private void FillList()
  713. {
  714. k = new KeyedList<string, double>();
  715. k.Add("Zero", 0);
  716. k.Add("One", 1);
  717. k.Add("Two", 2);
  718. k.Add("Three", 3);
  719. k.Add("Four", 4);
  720. k.Add("Five", 5);
  721. k.Add("Six", 6);
  722. k.Add("Seven", 7);
  723. k.Add("Eight", 8);
  724. k.Add("Nine", 9);
  725. k.Add("Ten", 10);
  726. }
  727. #endregion
  728. #endregion
  729. #region CopyToTest
  730. /// <summary>
  731. /// Copy to test
  732. /// </summary>
  733. [Test]
  734. public void CopyToTest()
  735. {
  736. FillList();
  737. KeyValuePair<string, double>[] kvpa =
  738. new KeyValuePair<string, double>[k.Count];
  739. k.CopyTo(kvpa, 0);
  740. int idx = 0;
  741. foreach (KeyValuePair<string, double> kvp in kvpa)
  742. {
  743. Assert.True(kvp.Key == k.GetKey(idx),
  744. "KeyValuePair not ordered.");
  745. Assert.True(kvp.Value == k[idx].Value,
  746. "KeyValuePair not ordered.");
  747. ++idx;
  748. }
  749. }
  750. #endregion
  751. #region CopyToArraySizeExceptionTest
  752. /// <summary>
  753. /// Copy to array size exception test
  754. /// </summary>
  755. [Test]
  756. public void CopyToArraySizeExceptionTest()
  757. {
  758. Assert.Throws(typeof(ArgumentException),
  759. delegate
  760. {
  761. KeyValuePair<string, double>[] kvpa =
  762. new KeyValuePair<string, double>[k.Count];
  763. k.CopyTo(kvpa, 5);
  764. });
  765. }
  766. #endregion
  767. #region AddTest
  768. /// <summary>
  769. /// Add test
  770. /// </summary>
  771. [Test]
  772. public void AddTest()
  773. {
  774. FillList();
  775. k.Add("Eleven", 11);
  776. Assert.True(k[k.Count - 1].Value == 11,
  777. "Expected the last entry to be 11.");
  778. }
  779. #endregion
  780. #region AddTestByKeyValuePair
  781. /// <summary>
  782. /// Add test by key value pair
  783. /// </summary>
  784. [Test]
  785. public void AddTestByKeyValuePair()
  786. {
  787. FillList();
  788. k.Add(new KeyValuePair<string, double>("Twelve", 12));
  789. Assert.True(k[k.Count - 1].Value == 12,
  790. "Expected the last entry to be 12.");
  791. }
  792. #endregion
  793. #region InsertTest
  794. /// <summary>
  795. /// Insert test
  796. /// </summary>
  797. [Test]
  798. public void InsertTest()
  799. {
  800. FillList();
  801. k.Insert(2, "One Point Five", 1.5);
  802. Assert.True(k[1].Value == 1, "Expected [1] entry to = 1");
  803. Assert.True(k[2].Value == 1.5, "Expected [2] entry to = 1.5");
  804. Assert.True(k[3].Value == 2, "Expected [3] entry to = 2");
  805. }
  806. #endregion
  807. #region RemoveNotFoundTest
  808. /// <summary>
  809. /// Remove not found test
  810. /// </summary>
  811. [Test]
  812. public void RemoveNotFoundTest()
  813. {
  814. FillList();
  815. bool ret = k.Remove("One Point Five");
  816. Assert.True(!ret, "Expected false");
  817. }
  818. #endregion
  819. #region RemoveByKeyValuePair
  820. /// <summary>
  821. /// Remove by key value pair
  822. /// </summary>
  823. [Test]
  824. public void RemoveByKeyValuePair()
  825. {
  826. FillList();
  827. k.Add("Eleven", 11);
  828. k.Add("Twelve", 12);
  829. KeyValuePair<string, double> kvp =
  830. new KeyValuePair<string, double>("Eleven", 11);
  831. bool ret = k.Remove(kvp);
  832. Assert.True(ret, "Expected true");
  833. Assert.True(k[11].Value == 12,
  834. "Expected entry 11 to be removed");
  835. }
  836. #endregion
  837. #region RemoveNotFoundByKeyValuePair
  838. /// <summary>
  839. /// Remove not found by key value pair
  840. /// </summary>
  841. [Test]
  842. public void RemoveNotFoundByKeyValuePair()
  843. {
  844. FillList();
  845. // value is ignored.
  846. KeyValuePair<string, double> kvp =
  847. new KeyValuePair<string, double>("Eleven", 0);
  848. bool ret = k.Remove(kvp);
  849. Assert.True(!ret, "Expected false");
  850. }
  851. #endregion
  852. #region RemoveAtTest
  853. /// <summary>
  854. /// Remove at test
  855. /// </summary>
  856. [Test]
  857. public void RemoveAtTest()
  858. {
  859. FillList();
  860. k.RemoveAt(1);
  861. Assert.True(k[0].Value == 0, "Expected [0] entry to = 0");
  862. Assert.True(k[1].Value == 2, "Expected [1] entry to = 2");
  863. }
  864. #endregion
  865. #region TryGetValueTest
  866. /// <summary>
  867. /// Try get value test
  868. /// </summary>
  869. [Test]
  870. public void TryGetValueTest()
  871. {
  872. FillList();
  873. double v;
  874. bool ret = k.TryGetValue("Ten", out v);
  875. Assert.True(ret, "Expected true");
  876. Assert.True(v == 10, "Expected return value = 10");
  877. }
  878. #endregion
  879. #region TryGetValueNotFoundTest
  880. /// <summary>
  881. /// Try get value not found test
  882. /// </summary>
  883. [Test]
  884. public void TryGetValueNotFoundTest()
  885. {
  886. FillList();
  887. double v;
  888. bool ret = k.TryGetValue("Elevent", out v);
  889. Assert.True(!ret, "Expected false");
  890. Assert.True(v == 0, "Expected return value = default value");
  891. }
  892. #endregion
  893. #region EmptyListInsertAtZero
  894. /// <summary>
  895. /// Empty list insert at zero
  896. /// </summary>
  897. [Test]
  898. public void EmptyListInsertAtZero()
  899. {
  900. k.Clear();
  901. k.Insert(0, "Z", 0);
  902. Assert.True(k[0].Value == 0, "Expected a value of 0");
  903. }
  904. #endregion
  905. #region RemoveTest
  906. /// <summary>
  907. /// Remove test
  908. /// </summary>
  909. [Test]
  910. public void RemoveTest()
  911. {
  912. FillList();
  913. bool ret = k.Remove("One");// Point Five");
  914. Assert.True(ret, "Expected true");
  915. Assert.Equal(0, k[0].Value);
  916. Assert.Equal(2, k[1].Value);
  917. Assert.Equal(3, k[2].Value);
  918. }
  919. #endregion
  920. }
  921. /// <summary>
  922. /// Enumerator tests
  923. /// </summary>
  924. internal class EnumeratorTests
  925. {
  926. #region Helpers
  927. #region k
  928. /// <summary>
  929. /// K
  930. /// </summary>
  931. protected KeyedList<string, int> k;
  932. #endregion
  933. #region .ctor
  934. /// <summary>
  935. /// Fixture setup
  936. /// </summary>
  937. public EnumeratorTests()
  938. {
  939. k = new KeyedList<string, int>();
  940. k.Add("Zero", 0);
  941. k.Add("One", 1);
  942. k.Add("Two", 2);
  943. k.Add("Three", 3);
  944. k.Add("Four", 4);
  945. k.Add("Five", 5);
  946. k.Add("Six", 6);
  947. k.Add("Seven", 7);
  948. k.Add("Eight", 8);
  949. k.Add("Nine", 9);
  950. k.Add("Ten", 10);
  951. }
  952. #endregion
  953. #endregion
  954. #region DefaultEnumerator
  955. /// <summary>
  956. /// Default enumerator
  957. /// </summary>
  958. [Test]
  959. public void DefaultEnumerator()
  960. {
  961. foreach (object obj in k)
  962. {
  963. }
  964. }
  965. #endregion
  966. #region EnumerationTest
  967. /// <summary>
  968. /// Enumeration test
  969. /// </summary>
  970. [Test]
  971. public void EnumerationTest()
  972. {
  973. int n = 0;
  974. foreach (KeyValuePair<string, int> kvp in k)
  975. {
  976. Assert.True(kvp.Value == n, "Expected ordered list of values.");
  977. ++n;
  978. }
  979. }
  980. #endregion
  981. #region ValueEnumeratorTest
  982. /// <summary>
  983. /// Value enumerator test
  984. /// </summary>
  985. [Test]
  986. public void ValueEnumeratorTest()
  987. {
  988. int n = 0;
  989. foreach (int i in k.OrderedValues)
  990. {
  991. Assert.True(n == i, "Expected ordered list of values.");
  992. ++n;
  993. }
  994. }
  995. #endregion
  996. #region KeyEnumeratorTest
  997. /// <summary>
  998. /// Key enumerator test
  999. /// </summary>
  1000. [Test]
  1001. public void KeyEnumeratorTest()
  1002. {
  1003. int n = 0;
  1004. foreach (string s in k.OrderedKeys)
  1005. {
  1006. Assert.True(k.GetKey(n) == s, "Expected ordered list of keys.");
  1007. ++n;
  1008. }
  1009. }
  1010. #endregion
  1011. }
  1012. }