#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 && WINDOWS using System; using System.Collections.Generic; using System.Globalization; using Microsoft.Win32; using NUnit.Framework; namespace Nuclex.Support.Settings { /// Unit tests for the windows registry settings store [TestFixture] internal class WindowsRegistryStoreTest { #region class TestContext /// Sets up a temporary registry key for the unit test private class TestContext : IDisposable { /// Initializes a new test context public TestContext() { this.keyName = Guid.NewGuid().ToString(); this.registryKey = Registry.CurrentUser.CreateSubKey(this.keyName); this.store = new WindowsRegistryStore(this.registryKey, writable: true); } /// Immediately frees all resources owned by the test context public void Dispose() { if(this.store != null) { this.store.Dispose(); this.store = null; this.registryKey = null; } else if(this.registryKey != null) { this.registryKey.Dispose(); this.registryKey = null; } if(this.keyName != null) { Registry.CurrentUser.DeleteSubKeyTree(this.keyName); this.keyName = null; } } /// Store created on a temporary registry key public WindowsRegistryStore Store { get { return this.store; } } /// Name of the temporary registry key private string keyName; /// Registry key (ownership transfered to the store) private RegistryKey registryKey; /// Store that is accessing the registry key private WindowsRegistryStore store; } #endregion // class TestContext /// Verifies that new instances of the registry store can be created [Test] public void CanBeCreated() { Assert.That( () => { using(var context = new TestContext()) { } }, Throws.Nothing ); } /// Verifies that new instances of the registry store can be created [Test] public void RegistryHivesCanBeOpened() { Assert.That( () => { using( var store = new WindowsRegistryStore( RegistryHive.CurrentUser, "", writable: false ) ) { } }, Throws.Nothing ); } /// Verifies that booleans can be stored in the registry [Test] public void BooleansCanBeStored() { using(var context = new TestContext()) { context.Store.Set(null, "test", true); Assert.That(context.Store.Get(null, "test"), Is.True); context.Store.Set(null, "test", false); Assert.That(context.Store.Get(null, "test"), Is.False); } } /// Verifies that integers can be stored in the registry [Test] public void IntegersCanBeStored() { using(var context = new TestContext()) { context.Store.Set(null, "test", 123); Assert.That(context.Store.Get(null, "test"), Is.EqualTo(123)); context.Store.Set(null, "test", 456); Assert.That(context.Store.Get(null, "test"), Is.EqualTo(456)); } } /// Verifies that floats can be stored in the registry [Test] public void FloatsCanBeStored() { float testValue = float.Parse("123.456", CultureInfo.InvariantCulture); using(var context = new TestContext()) { context.Store.Set(null, "test", testValue); Assert.That(context.Store.Get(null, "test"), Is.EqualTo(testValue)); testValue = float.Parse("654.321", CultureInfo.InvariantCulture); context.Store.Set(null, "test", testValue); Assert.That(context.Store.Get(null, "test"), Is.EqualTo(testValue)); } } /// Verifies that strings can be stored in the registry [Test] public void StringsCanBeStored() { using(var context = new TestContext()) { context.Store.Set(null, "test", "hello world"); Assert.That(context.Store.Get(null, "test"), Is.EqualTo("hello world")); context.Store.Set(null, "test", "world hello"); Assert.That(context.Store.Get(null, "test"), Is.EqualTo("world hello")); } } /// Verifies that long integers can be stored in the registry [Test] public void LongIntegersCanBeStored() { using(var context = new TestContext()) { context.Store.Set(null, "test", long.MaxValue); Assert.That(context.Store.Get(null, "test"), Is.EqualTo(long.MaxValue)); context.Store.Set(null, "test", long.MinValue); Assert.That(context.Store.Get(null, "test"), Is.EqualTo(long.MinValue)); } } /// Verifies that string arrays can be stored in the registry [Test] public void StringArraysCanBeStored() { string[] english = new string[] { "one", "two", "three" }; string[] german = new string[] { "eins", "zwei", "drei" }; using(var context = new TestContext()) { context.Store.Set(null, "test", english); Assert.That(context.Store.Get(null, "test"), Is.EquivalentTo(english)); context.Store.Set(null, "test", german); Assert.That(context.Store.Get(null, "test"), Is.EquivalentTo(german)); } } /// Verifies that byte arrays can be stored in the registry [Test] public void ByteArraysCanBeStored() { byte[] ascending = new byte[] { 1, 2, 3 }; byte[] descending = new byte[] { 9, 8, 7 }; using(var context = new TestContext()) { context.Store.Set(null, "test", ascending); Assert.That(context.Store.Get(null, "test"), Is.EquivalentTo(ascending)); context.Store.Set(null, "test", descending); Assert.That(context.Store.Get(null, "test"), Is.EquivalentTo(descending)); } } /// Verifies that strings can be stored in the registry [Test] public void ValuesCanBeStoredInCategories() { using(var context = new TestContext()) { context.Store.Set("main", "test", "hello world"); string value; Assert.That(context.Store.TryGet(null, "test", out value), Is.False); Assert.That(context.Store.Get("main", "test"), Is.EqualTo("hello world")); } } /// Verifies that the subkeys of a registry key can be enumerated [Test] public void CategoriesCanBeEnumerated() { string[] names = new string[] { "one", "two", "three" }; using(var context = new TestContext()) { context.Store.Set(names[0], "sol", 21); context.Store.Set(names[1], "sol", 42); context.Store.Set(names[2], "sol", 84); Assert.That(context.Store.EnumerateCategories(), Is.EquivalentTo(names)); } } /// Verifies that the values under a registry subkey can be enumerated [Test] public void OptionsInCategoryCanBeEnumerated() { string[] names = new string[] { "one", "two", "three" }; using(var context = new TestContext()) { context.Store.Set("test", names[0], 1); context.Store.Set("test", names[1], 2); context.Store.Set("test", names[2], 3); var optionInfos = new List(context.Store.EnumerateOptions("test")); Assert.That(optionInfos.Count, Is.EqualTo(3)); } } /// Verifies that the values under a registry key can be enumerated [Test] public void RootOptionsCanBeEnumerated() { string[] names = new string[] { "one", "two", "three" }; using(var context = new TestContext()) { context.Store.Set(null, names[0], 1); context.Store.Set(null, names[1], 2); context.Store.Set(null, names[2], 3); var optionInfos = new List(context.Store.EnumerateOptions(null)); Assert.That(optionInfos.Count, Is.EqualTo(3)); string[] actualNames = new string[] { optionInfos[0].Name, optionInfos[1].Name, optionInfos[2].Name }; Assert.That(actualNames, Is.EquivalentTo(names)); } } /// /// Verifies that accessing an option that doesn't exist throws an exception /// [Test] public void AccessingNonExistingOptionThrowsException() { using(var context = new TestContext()) { Assert.That( () => context.Store.Get(null, "doesn't exist"), Throws.Exception.AssignableTo() ); } } /// /// Verifies that accessing a category that doesn't exist throws an exception /// [Test] public void AccessingNonExistingCategoryThrowsException() { using(var context = new TestContext()) { Assert.That( () => context.Store.Get("doesn't exist", "test"), Throws.Exception.AssignableTo() ); } } /// /// Verifies that values can be removed from a registry key /// [Test] public void ValuesCanBeRemovedFromRoot() { using(var context = new TestContext()) { context.Store.Set(null, "nothing", "short-lived"); Assert.That(context.Store.Remove(null, "nothing"), Is.True); Assert.That(context.Store.Remove(null, "nothing"), Is.False); Assert.That(context.Store.EnumerateOptions(), Is.Empty); } } /// /// Verifies that values can be removed from the subkey of a registry key /// [Test] public void ValuesCanBeRemovedFromCategory() { using(var context = new TestContext()) { context.Store.Set("limbo", "nothing", "short-lived"); Assert.That(context.Store.Remove("limbo", "nothing"), Is.True); Assert.That(context.Store.Remove("limbo", "nothing"), Is.False); Assert.That(context.Store.EnumerateOptions("limbo"), Is.Empty); } } /// /// Verifies that values can be removed from a non-existing subkey without /// causing an error /// [Test] public void RemovingValueFromNonExistingCategoryCanBeHandled() { using(var context = new TestContext()) { Assert.That(context.Store.Remove("empty", "nothing"), Is.False); } } /// /// Verifies that the store identifies the types of values stored in /// a registry when they are enumerated /// [Test] public void ValueTypesAreIdentifiedWhenEnumerating() { Type[] types = new Type[] { typeof(int), typeof(long), typeof(byte[]), typeof(string), typeof(string[]) }; using(var context = new TestContext()) { context.Store.Set(null, "0", 123); context.Store.Set(null, "1", 456L); context.Store.Set(null, "2", new byte[] { 7, 8, 9 }); context.Store.Set(null, "3", "text"); context.Store.Set(null, "4", new string[] { "many", "words" }); var optionInfos = new List(context.Store.EnumerateOptions()); for(int index = 0; index < optionInfos.Count; ++index) { int typeIndex = int.Parse(optionInfos[index].Name); Assert.That(optionInfos[index].OptionType, Is.EqualTo(types[typeIndex])); } } } } } // namespace Nuclex.Support.Settings #endif // UNITTEST