PageRenderTime 77ms CodeModel.GetById 53ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Utilities/Collections/KeyedList.cs

#
C# | 1110 lines | 741 code | 98 blank | 271 comment | 64 complexity | b372e33041993ff02d89a5549075129d MD5 | raw file
   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}