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>
|
||||
/// 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>
|
||||
[Test]
|
||||
public void OptionsCanBeRemoved() {
|
||||
|
@ -313,6 +313,9 @@ namespace Nuclex.Support.Settings {
|
|||
configurationFile.Set<string>(null, "test", null);
|
||||
|
||||
Assert.That(configurationFile.Remove(null, "test"), Is.True);
|
||||
|
||||
string value;
|
||||
Assert.That(configurationFile.TryGet<string>(null, "test", out value), Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -385,6 +388,19 @@ namespace Nuclex.Support.Settings {
|
|||
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>
|
||||
/// <param name="fileContents">Contents of the configuration file</param>
|
||||
/// <returns>The configuration file loaded from the string</returns>
|
||||
|
|
|
@ -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 {
|
|||
/// <summary>Unit tests for the memory settings store</summary>
|
||||
[TestFixture]
|
||||
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
|
||||
|
|
|
@ -91,7 +91,17 @@ namespace Nuclex.Support.Settings {
|
|||
/// parameter, false otherwise
|
||||
/// </returns>
|
||||
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>
|
||||
|
@ -100,7 +110,18 @@ namespace Nuclex.Support.Settings {
|
|||
/// <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>
|
||||
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>
|
||||
|
@ -108,7 +129,27 @@ namespace Nuclex.Support.Settings {
|
|||
/// <param name="optionName">Name of the option that will be removed</param>
|
||||
/// <returns>True if the option was found and removed</returns>
|
||||
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>
|
||||
|
|
Loading…
Reference in New Issue
Block a user