#region CPL License /* Nuclex Framework Copyright (C) 2002-2014 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion #if UNITTEST using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using NUnit.Framework; namespace Nuclex.Support.Collections { /// Unit Test for the read only dictionary wrapper [TestFixture] internal class ReadOnlyDictionaryTest { /// /// Verifies that the copy constructor of the read only dictionary works /// [Test] public void TestCopyConstructor() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); CollectionAssert.AreEqual(numbers, testDictionary); } /// Verifies that the IsReadOnly property returns true [Test] public void TestIsReadOnly() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.IsTrue(testDictionary.IsReadOnly); } /// /// Checks whether the Contains() method of the read only dictionary is able to /// determine if the dictionary contains an item /// [Test] public void TestContains() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.IsTrue( testDictionary.Contains(new KeyValuePair(42, "forty-two")) ); Assert.IsFalse( testDictionary.Contains(new KeyValuePair(24, "twenty-four")) ); } /// /// Checks whether the Contains() method of the read only dictionary is able to /// determine if the dictionary contains a key /// [Test] public void TestContainsKey() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.IsTrue(testDictionary.ContainsKey(42)); Assert.IsFalse(testDictionary.ContainsKey(24)); } /// /// Verifies that the CopyTo() of the read only dictionary works /// [Test] public void TestCopyToArray() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); KeyValuePair[] items = new KeyValuePair[numbers.Count]; testDictionary.CopyTo(items, 0); CollectionAssert.AreEqual(numbers, items); } /// /// Tests whether the typesafe enumerator of the read only dictionary is working /// [Test] public void TestTypesafeEnumerator() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); List> outputItems = new List>(); foreach(KeyValuePair item in testDictionary) { outputItems.Add(item); } CollectionAssert.AreEqual(numbers, outputItems); } /// /// Tests whether the keys collection of the read only dictionary can be queried /// [Test] public void TestGetKeysCollection() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); ICollection inputKeys = numbers.Keys; ICollection keys = testDictionary.Keys; CollectionAssert.AreEqual(inputKeys, keys); } /// /// Tests whether the values collection of the read only dictionary can be queried /// [Test] public void TestGetValuesCollection() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); ICollection inputValues = numbers.Values; ICollection values = testDictionary.Values; CollectionAssert.AreEqual(inputValues, values); } /// /// Tests whether the TryGetValue() method of the read only dictionary is working /// [Test] public void TestTryGetValue() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); string value; Assert.IsTrue(testDictionary.TryGetValue(42, out value)); Assert.AreEqual("forty-two", value); Assert.IsFalse(testDictionary.TryGetValue(24, out value)); Assert.AreEqual(null, value); } /// /// Tests whether the retrieval of values using the indexer of the read only /// dictionary is working /// [Test] public void TestRetrieveValueByIndexer() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.AreEqual("forty-two", testDictionary[42]); } /// /// Tests whether an exception is thrown if the indexer of the read only dictionary /// is used to attempt to retrieve a non-existing value /// [Test] public void TestThrowOnRetrieveNonExistingValueByIndexer() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { Console.WriteLine(testDictionary[24]); } ); } /// /// Checks whether the read only dictionary will throw an exception if its /// Add() method is called via the generic IDictionary<> interface /// [Test] public void TestThrowOnAddViaGenericIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as IDictionary).Add(10, "ten"); } ); } /// /// Checks whether the read only dictionary will throw an exception if its /// Remove() method is called via the generic IDictionary<> interface /// [Test] public void TestThrowOnRemoveViaGenericIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as IDictionary).Remove(3); } ); } /// /// Tests whether the TryGetValue() method of the read only dictionary is working /// [Test] public void TestRetrieveValueByIndexerViaGenericIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.AreEqual("forty-two", (testDictionary as IDictionary)[42]); } /// /// Checks whether the read only dictionary will throw an exception if its /// indexer is used to insert an item via the generic IDictionar<> interface /// [Test] public void TestThrowOnReplaceByIndexerViaGenericIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as IDictionary)[24] = "twenty-four"; } ); } /// /// Checks whether the read only dictionary will throw an exception if its /// Clear() method is called via the IDictionary interface /// [Test] public void TestThrowOnClearViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as IDictionary).Clear(); } ); } /// /// Checks whether the read only dictionary will throw an exception if its /// Add() method is called via the IDictionary interface /// [Test] public void TestThrowOnAddViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as IDictionary).Add(24, "twenty-four"); } ); } /// /// Checks whether the Contains() method of the read only dictionary is able to /// determine if the dictionary contains an item via the IDictionary interface /// [Test] public void TestContainsViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.IsTrue((testDictionary as IDictionary).Contains(42)); Assert.IsFalse((testDictionary as IDictionary).Contains(24)); } /// /// Checks whether the GetEnumerator() method of the read only dictionary returns /// a working enumerator if accessed via the IDictionary interface /// [Test] public void TestEnumeratorViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Dictionary outputNumbers = new Dictionary(); foreach(DictionaryEntry entry in (testDictionary as IDictionary)) { (outputNumbers as IDictionary).Add(entry.Key, entry.Value); } CollectionAssert.AreEquivalent(numbers, outputNumbers); } /// /// Checks whether the IsFixedSize property of the read only dictionary returns /// the expected result for a read only dictionary based on a dynamic dictionary /// [Test] public void TestIsFixedSizeViaIList() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.IsFalse((testDictionary as IDictionary).IsFixedSize); } /// /// Tests whether the keys collection of the read only dictionary can be queried /// via the IDictionary interface /// [Test] public void TestGetKeysCollectionViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); ICollection inputKeys = (numbers as IDictionary).Keys; ICollection keys = (testDictionary as IDictionary).Keys; CollectionAssert.AreEqual(inputKeys, keys); } /// /// Tests whether the values collection of the read only dictionary can be queried /// via the IDictionary interface /// [Test] public void TestGetValuesCollectionViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); ICollection inputValues = (numbers as IDictionary).Values; ICollection values = (testDictionary as IDictionary).Values; CollectionAssert.AreEqual(inputValues, values); } /// /// Checks whether the read only dictionary will throw an exception if its /// Remove() method is called via the IDictionary interface /// [Test] public void TestThrowOnRemoveViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as IDictionary).Remove(3); } ); } /// /// Tests whether the retrieval of values using the indexer of the read only /// dictionary is working via the IDictionary interface /// [Test] public void TestRetrieveValueByIndexerViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.AreEqual("forty-two", (testDictionary as IDictionary)[42]); } /// /// Checks whether the read only dictionary will throw an exception if its /// indexer is used to insert an item via the IDictionary interface /// [Test] public void TestThrowOnReplaceByIndexerViaIDictionary() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as IDictionary)[24] = "twenty-four"; } ); } /// /// Checks whether the read only dictionary will throw an exception if its /// Add() method is used via the generic ICollection<> interface /// [Test] public void TestThrowOnAddViaGenericICollection() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as ICollection>).Add( new KeyValuePair(24, "twenty-four") ); } ); } /// /// Checks whether the read only dictionary will throw an exception if its /// Clear() method is used via the generic ICollection<> interface /// [Test] public void TestThrowOnClearViaGenericICollection() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as ICollection>).Clear(); } ); } /// /// Checks whether the read only dictionary will throw an exception if its /// Remove() method is used via the generic ICollection<> interface /// [Test] public void TestThrowOnRemoveViaGenericICollection() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); Assert.Throws( delegate() { (testDictionary as ICollection>).Remove( new KeyValuePair(42, "fourty-two") ); } ); } /// /// Verifies that the CopyTo() of the read only dictionary works when called /// via the the ICollection interface /// [Test] public void TestCopyToArrayViaICollection() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); DictionaryEntry[] entries = new DictionaryEntry[numbers.Count]; (testDictionary as ICollection).CopyTo(entries, 0); KeyValuePair[] items = new KeyValuePair[numbers.Count]; for(int index = 0; index < entries.Length; ++index) { items[index] = new KeyValuePair( (int)entries[index].Key, (string)entries[index].Value ); } CollectionAssert.AreEquivalent(numbers, items); } /// /// Verifies that the IsSynchronized property and the SyncRoot property are working /// [Test] public void TestSynchronization() { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary = makeReadOnly(numbers); if(!(testDictionary as ICollection).IsSynchronized) { lock((testDictionary as ICollection).SyncRoot) { Assert.AreEqual(numbers.Count, testDictionary.Count); } } } /// /// Test whether the read only dictionary can be serialized /// [Test] public void TestSerialization() { BinaryFormatter formatter = new BinaryFormatter(); using(MemoryStream memory = new MemoryStream()) { Dictionary numbers = createTestDictionary(); ReadOnlyDictionary testDictionary1 = makeReadOnly(numbers); formatter.Serialize(memory, testDictionary1); memory.Position = 0; object testDictionary2 = formatter.Deserialize(memory); CollectionAssert.AreEquivalent(testDictionary1, (IEnumerable)testDictionary2); } } /// /// Creates a new read-only dictionary filled with some values for testing /// /// The newly created read-only dictionary private static Dictionary createTestDictionary() { Dictionary numbers = new Dictionary(); numbers.Add(1, "one"); numbers.Add(2, "two"); numbers.Add(3, "three"); numbers.Add(42, "forty-two"); return new Dictionary(numbers); } /// /// Creates a new read-only dictionary filled with some values for testing /// /// The newly created read-only dictionary private static ReadOnlyDictionary makeReadOnly( IDictionary dictionary ) { return new ReadOnlyDictionary(dictionary); } } } // namespace Nuclex.Support.Collections #endif // UNITTEST