diff --git a/Source/Settings/ConfigurationFileStore.Test.cs b/Source/Settings/ConfigurationFileStore.Test.cs
index b1ae6a5..5b1cb23 100644
--- a/Source/Settings/ConfigurationFileStore.Test.cs
+++ b/Source/Settings/ConfigurationFileStore.Test.cs
@@ -305,7 +305,7 @@ namespace Nuclex.Support.Settings {
}
///
- /// Verifies that it's possible to assign an empty value to an option
+ /// Verifies that it's possible to remove options from the configuration file
///
[Test]
public void OptionsCanBeRemoved() {
@@ -313,6 +313,9 @@ namespace Nuclex.Support.Settings {
configurationFile.Set(null, "test", null);
Assert.That(configurationFile.Remove(null, "test"), Is.True);
+
+ string value;
+ Assert.That(configurationFile.TryGet(null, "test", out value), Is.False);
}
///
@@ -385,6 +388,19 @@ namespace Nuclex.Support.Settings {
Assert.That(info.OptionType, Is.EqualTo(expectedType));
}
+ ///
+ /// Verifies that configuration files containing duplicate option names can not
+ /// be used with the configuration file store
+ ///
+ [Test]
+ public void FilesWithDuplicateOptionNamesCannotBeProcessed() {
+ string fileContents =
+ "duplicate name = 1\r\n" +
+ "duplicate name = 2";
+
+ Assert.That(() => load(fileContents), Throws.Exception);
+ }
+
/// Loads a configuration file from a string
/// Contents of the configuration file
/// The configuration file loaded from the string
diff --git a/Source/Settings/MemoryStore.Test.cs b/Source/Settings/MemoryStore.Test.cs
index 4be3be9..cde79ab 100644
--- a/Source/Settings/MemoryStore.Test.cs
+++ b/Source/Settings/MemoryStore.Test.cs
@@ -21,6 +21,7 @@ License along with this library
#if UNITTEST
using System;
+using System.Collections.Generic;
using NUnit.Framework;
@@ -29,6 +30,134 @@ namespace Nuclex.Support.Settings {
/// Unit tests for the memory settings store
[TestFixture]
internal class MemoryStoreTest {
+
+ /// Verifies that constructed a memory store throws an exception
+ [Test]
+ public void CanBeCreated() {
+ Assert.That(() => new MemoryStore(), Throws.Nothing);
+ }
+
+ ///
+ /// Verifies that it's possible to enumerate the options in a non-existing category
+ ///
+ [Test]
+ public void NonExistingCategoriesCanBeEnumerated() {
+ var memoryStore = new MemoryStore();
+ Assert.That(memoryStore.EnumerateOptions("doesn't exist"), Is.Empty);
+ }
+
+ ///
+ /// Verifies that accessing an option that doesn't exist throws an exception
+ ///
+ [Test]
+ public void AccessingNonExistingOptionThrowsException() {
+ var memoryStore = new MemoryStore();
+
+ Assert.That(
+ () => memoryStore.Get(null, "doesn't exist"),
+ Throws.Exception.AssignableTo()
+ );
+ }
+
+ ///
+ /// Verifies that accessing a category that doesn't exist throws an exception
+ ///
+ [Test]
+ public void AccessingNonExistingCategoryThrowsException() {
+ var memoryStore = new MemoryStore();
+ memoryStore.Set(null, "test", "123");
+
+ Assert.That(
+ () => memoryStore.Get("doesn't exist", "test"),
+ Throws.Exception.AssignableTo()
+ );
+ }
+
+ ///
+ /// Verifies that settings can be stored in the memory store
+ ///
+ [Test]
+ public void SettingsCanBeAssignedAndRetrieved() {
+ var memoryStore = new MemoryStore();
+ memoryStore.Set("general", "sol", "42");
+
+ Assert.That(memoryStore.Get("general", "sol"), Is.EqualTo("42"));
+ }
+
+ ///
+ /// Verifies that it's possible to remove options from the memory store
+ ///
+ [Test]
+ public void OptionsCanBeRemoved() {
+ var memoryStore = new MemoryStore();
+ memoryStore.Set(null, "test", null);
+
+ Assert.That(memoryStore.Remove(null, "test"), Is.True);
+
+ string value;
+ Assert.That(memoryStore.TryGet(null, "test", out value), Is.False);
+ }
+
+ ///
+ /// Verifies that it's not an error to remove an option from a non-existing category
+ ///
+ [Test]
+ public void CanRemoveOptionFromNonExistingCategory() {
+ var memoryStore = new MemoryStore();
+ Assert.That(memoryStore.Remove("nothing", "first"), Is.False);
+ }
+
+ ///
+ /// Verifies that it's not an error to remove a non-existing option
+ ///
+ [Test]
+ public void CanRemoveNonExistingOption() {
+ var memoryStore = new MemoryStore();
+ Assert.That(memoryStore.Remove(null, "first"), Is.False);
+ }
+
+ ///
+ /// Verifies that the root category is not part of the enumerated categories
+ ///
+ [Test]
+ public void RootCategoryIsNotEnumerated() {
+ var memoryStore = new MemoryStore();
+ Assert.That(memoryStore.EnumerateCategories(), Is.Empty);
+ }
+
+ ///
+ /// Verifies that the root category is not part of the enumerated categories
+ ///
+ [Test]
+ public void OptionsInRootCategoryCanBeEnumerated() {
+ var memoryStore = new MemoryStore();
+
+ string[] optionNames = new string[] { "first", "second" };
+ memoryStore.Set(null, optionNames[0], 1);
+ memoryStore.Set(null, optionNames[1], 2);
+
+ var optionInfos = new List(memoryStore.EnumerateOptions());
+ Assert.That(optionInfos.Count, Is.EqualTo(2));
+
+ var enumeratedOptionNames = new List() {
+ optionInfos[0].Name, optionInfos[1].Name
+ };
+ Assert.That(enumeratedOptionNames, Is.EquivalentTo(optionNames));
+ }
+
+ ///
+ /// Verifies that the root category is not part of the enumerated categories
+ ///
+ [Test]
+ public void CategoriesCanBeCreated() {
+ var memoryStore = new MemoryStore();
+
+ memoryStore.Set(null, "not", "used");
+ memoryStore.Set("test", "message", "hello world");
+
+ Assert.That(memoryStore.EnumerateCategories(), Is.EquivalentTo(new string[] { "test" }));
+ }
+
}
} // namespace Nuclex.Support.Settings
diff --git a/Source/Settings/MemoryStore.cs b/Source/Settings/MemoryStore.cs
index a25518e..083373f 100644
--- a/Source/Settings/MemoryStore.cs
+++ b/Source/Settings/MemoryStore.cs
@@ -91,7 +91,17 @@ namespace Nuclex.Support.Settings {
/// parameter, false otherwise
///
public bool TryGet(string category, string optionName, out TValue value) {
- throw new NotImplementedException();
+ IDictionary categoryOptions = getCategoryByName(category);
+ if(categoryOptions != null) {
+ object valueAsObject;
+ if(categoryOptions.TryGetValue(optionName, out valueAsObject)) {
+ value = (TValue)Convert.ChangeType(valueAsObject, typeof(TValue));
+ return true;
+ }
+ }
+
+ value = default(TValue);
+ return false;
}
/// Saves an option in the settings store
@@ -100,7 +110,18 @@ namespace Nuclex.Support.Settings {
/// Name of the option that will be saved
/// The value under which the option will be saved
public void Set(string category, string optionName, TValue value) {
- throw new NotImplementedException();
+ IDictionary targetCategory;
+
+ if(string.IsNullOrEmpty(category)) {
+ targetCategory = this.rootOptions;
+ } else if(!this.options.TryGetValue(category, out targetCategory)) {
+ targetCategory = new Dictionary();
+ this.options.Add(category, targetCategory);
+ targetCategory.Add(optionName, value);
+ return;
+ }
+
+ targetCategory[optionName] = value;
}
/// Removes the option with the specified name
@@ -108,7 +129,27 @@ namespace Nuclex.Support.Settings {
/// Name of the option that will be removed
/// True if the option was found and removed
public bool Remove(string category, string optionName) {
- throw new NotImplementedException();
+ IDictionary targetCategory = getCategoryByName(category);
+ if(targetCategory == null) {
+ return false;
+ }
+
+ return targetCategory.Remove(optionName);
+ }
+
+ /// Looks up a category by its name
+ /// Name of the category that will be looked up
+ /// The category with the specified name if found, null otherwise
+ private IDictionary getCategoryByName(string name) {
+ IDictionary category;
+
+ if(string.IsNullOrEmpty(name)) {
+ category = this.rootOptions;
+ } else if(!this.options.TryGetValue(name, out category)) {
+ return null;
+ }
+
+ return category;
}
/// Categories and the options stored in them