Fully implemented the memory store and added unit tests for it
git-svn-id: file:///srv/devel/repo-conversion/nusu@308 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
03ada146e5
commit
d55ba52369
|
@ -305,7 +305,7 @@ namespace Nuclex.Support.Settings {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 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
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void OptionsCanBeRemoved() {
|
public void OptionsCanBeRemoved() {
|
||||||
|
@ -313,6 +313,9 @@ namespace Nuclex.Support.Settings {
|
||||||
configurationFile.Set<string>(null, "test", null);
|
configurationFile.Set<string>(null, "test", null);
|
||||||
|
|
||||||
Assert.That(configurationFile.Remove(null, "test"), Is.True);
|
Assert.That(configurationFile.Remove(null, "test"), Is.True);
|
||||||
|
|
||||||
|
string value;
|
||||||
|
Assert.That(configurationFile.TryGet<string>(null, "test", out value), Is.False);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -385,6 +388,19 @@ namespace Nuclex.Support.Settings {
|
||||||
Assert.That(info.OptionType, Is.EqualTo(expectedType));
|
Assert.That(info.OptionType, Is.EqualTo(expectedType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that configuration files containing duplicate option names can not
|
||||||
|
/// be used with the configuration file store
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void FilesWithDuplicateOptionNamesCannotBeProcessed() {
|
||||||
|
string fileContents =
|
||||||
|
"duplicate name = 1\r\n" +
|
||||||
|
"duplicate name = 2";
|
||||||
|
|
||||||
|
Assert.That(() => load(fileContents), Throws.Exception);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Loads a configuration file from a string</summary>
|
/// <summary>Loads a configuration file from a string</summary>
|
||||||
/// <param name="fileContents">Contents of the configuration file</param>
|
/// <param name="fileContents">Contents of the configuration file</param>
|
||||||
/// <returns>The configuration file loaded from the string</returns>
|
/// <returns>The configuration file loaded from the string</returns>
|
||||||
|
|
|
@ -21,6 +21,7 @@ License along with this library
|
||||||
#if UNITTEST
|
#if UNITTEST
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
@ -29,6 +30,134 @@ namespace Nuclex.Support.Settings {
|
||||||
/// <summary>Unit tests for the memory settings store</summary>
|
/// <summary>Unit tests for the memory settings store</summary>
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
internal class MemoryStoreTest {
|
internal class MemoryStoreTest {
|
||||||
|
|
||||||
|
/// <summary>Verifies that constructed a memory store throws an exception</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanBeCreated() {
|
||||||
|
Assert.That(() => new MemoryStore(), Throws.Nothing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that it's possible to enumerate the options in a non-existing category
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void NonExistingCategoriesCanBeEnumerated() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
Assert.That(memoryStore.EnumerateOptions("doesn't exist"), Is.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that accessing an option that doesn't exist throws an exception
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void AccessingNonExistingOptionThrowsException() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
() => memoryStore.Get<string>(null, "doesn't exist"),
|
||||||
|
Throws.Exception.AssignableTo<KeyNotFoundException>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that accessing a category that doesn't exist throws an exception
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void AccessingNonExistingCategoryThrowsException() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
memoryStore.Set<string>(null, "test", "123");
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
() => memoryStore.Get<string>("doesn't exist", "test"),
|
||||||
|
Throws.Exception.AssignableTo<KeyNotFoundException>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that settings can be stored in the memory store
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void SettingsCanBeAssignedAndRetrieved() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
memoryStore.Set<string>("general", "sol", "42");
|
||||||
|
|
||||||
|
Assert.That(memoryStore.Get<string>("general", "sol"), Is.EqualTo("42"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that it's possible to remove options from the memory store
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void OptionsCanBeRemoved() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
memoryStore.Set<string>(null, "test", null);
|
||||||
|
|
||||||
|
Assert.That(memoryStore.Remove(null, "test"), Is.True);
|
||||||
|
|
||||||
|
string value;
|
||||||
|
Assert.That(memoryStore.TryGet<string>(null, "test", out value), Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that it's not an error to remove an option from a non-existing category
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void CanRemoveOptionFromNonExistingCategory() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
Assert.That(memoryStore.Remove("nothing", "first"), Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that it's not an error to remove a non-existing option
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void CanRemoveNonExistingOption() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
Assert.That(memoryStore.Remove(null, "first"), Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that the root category is not part of the enumerated categories
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void RootCategoryIsNotEnumerated() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
Assert.That(memoryStore.EnumerateCategories(), Is.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that the root category is not part of the enumerated categories
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void OptionsInRootCategoryCanBeEnumerated() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
|
||||||
|
string[] optionNames = new string[] { "first", "second" };
|
||||||
|
memoryStore.Set<int>(null, optionNames[0], 1);
|
||||||
|
memoryStore.Set<int>(null, optionNames[1], 2);
|
||||||
|
|
||||||
|
var optionInfos = new List<OptionInfo>(memoryStore.EnumerateOptions());
|
||||||
|
Assert.That(optionInfos.Count, Is.EqualTo(2));
|
||||||
|
|
||||||
|
var enumeratedOptionNames = new List<string>() {
|
||||||
|
optionInfos[0].Name, optionInfos[1].Name
|
||||||
|
};
|
||||||
|
Assert.That(enumeratedOptionNames, Is.EquivalentTo(optionNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that the root category is not part of the enumerated categories
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void CategoriesCanBeCreated() {
|
||||||
|
var memoryStore = new MemoryStore();
|
||||||
|
|
||||||
|
memoryStore.Set<string>(null, "not", "used");
|
||||||
|
memoryStore.Set<string>("test", "message", "hello world");
|
||||||
|
|
||||||
|
Assert.That(memoryStore.EnumerateCategories(), Is.EquivalentTo(new string[] { "test" }));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Nuclex.Support.Settings
|
} // namespace Nuclex.Support.Settings
|
||||||
|
|
|
@ -91,7 +91,17 @@ namespace Nuclex.Support.Settings {
|
||||||
/// parameter, false otherwise
|
/// parameter, false otherwise
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public bool TryGet<TValue>(string category, string optionName, out TValue value) {
|
public bool TryGet<TValue>(string category, string optionName, out TValue value) {
|
||||||
throw new NotImplementedException();
|
IDictionary<string, object> 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Saves an option in the settings store</summary>
|
/// <summary>Saves an option in the settings store</summary>
|
||||||
|
@ -100,7 +110,18 @@ namespace Nuclex.Support.Settings {
|
||||||
/// <param name="optionName">Name of the option that will be saved</param>
|
/// <param name="optionName">Name of the option that will be saved</param>
|
||||||
/// <param name="value">The value under which the option will be saved</param>
|
/// <param name="value">The value under which the option will be saved</param>
|
||||||
public void Set<TValue>(string category, string optionName, TValue value) {
|
public void Set<TValue>(string category, string optionName, TValue value) {
|
||||||
throw new NotImplementedException();
|
IDictionary<string, object> targetCategory;
|
||||||
|
|
||||||
|
if(string.IsNullOrEmpty(category)) {
|
||||||
|
targetCategory = this.rootOptions;
|
||||||
|
} else if(!this.options.TryGetValue(category, out targetCategory)) {
|
||||||
|
targetCategory = new Dictionary<string, object>();
|
||||||
|
this.options.Add(category, targetCategory);
|
||||||
|
targetCategory.Add(optionName, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
targetCategory[optionName] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Removes the option with the specified name</summary>
|
/// <summary>Removes the option with the specified name</summary>
|
||||||
|
@ -108,7 +129,27 @@ namespace Nuclex.Support.Settings {
|
||||||
/// <param name="optionName">Name of the option that will be removed</param>
|
/// <param name="optionName">Name of the option that will be removed</param>
|
||||||
/// <returns>True if the option was found and removed</returns>
|
/// <returns>True if the option was found and removed</returns>
|
||||||
public bool Remove(string category, string optionName) {
|
public bool Remove(string category, string optionName) {
|
||||||
throw new NotImplementedException();
|
IDictionary<string, object> targetCategory = getCategoryByName(category);
|
||||||
|
if(targetCategory == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetCategory.Remove(optionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Looks up a category by its name</summary>
|
||||||
|
/// <param name="name">Name of the category that will be looked up</param>
|
||||||
|
/// <returns>The category with the specified name if found, null otherwise</returns>
|
||||||
|
private IDictionary<string, object> getCategoryByName(string name) {
|
||||||
|
IDictionary<string, object> category;
|
||||||
|
|
||||||
|
if(string.IsNullOrEmpty(name)) {
|
||||||
|
category = this.rootOptions;
|
||||||
|
} else if(!this.options.TryGetValue(name, out category)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return category;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Categories and the options stored in them</summary>
|
/// <summary>Categories and the options stored in them</summary>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user