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