Fully implemented the windows registry-based settings store; added more unit tests for the registry settings store
git-svn-id: file:///srv/devel/repo-conversion/nusu@319 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
0d1051dd84
commit
58504f4a8a
|
@ -18,15 +18,15 @@ License along with this library
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#if UNITTEST
|
#if UNITTEST && WINDOWS
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System.IO;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Nuclex.Support.Settings {
|
namespace Nuclex.Support.Settings {
|
||||||
|
|
||||||
|
@ -179,6 +179,76 @@ namespace Nuclex.Support.Settings {
|
||||||
|
|
||||||
var optionInfos = new List<OptionInfo>(context.Store.EnumerateOptions(null));
|
var optionInfos = new List<OptionInfo>(context.Store.EnumerateOptions(null));
|
||||||
Assert.That(optionInfos.Count, Is.EqualTo(3));
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that accessing an option that doesn't exist throws an exception
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void AccessingNonExistingOptionThrowsException() {
|
||||||
|
using(var context = new TestContext()) {
|
||||||
|
Assert.That(
|
||||||
|
() => context.Store.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() {
|
||||||
|
using(var context = new TestContext()) {
|
||||||
|
Assert.That(
|
||||||
|
() => context.Store.Get<string>("doesn't exist", "test"),
|
||||||
|
Throws.Exception.AssignableTo<KeyNotFoundException>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that values can be removed from a registry key
|
||||||
|
/// </summary>
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that values can be removed from the subkey of a registry key
|
||||||
|
/// </summary>
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that values can be removed from a non-existing subkey without
|
||||||
|
/// causing an error
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void RemovingValueFromNonExistingCategoryCanBeHandled() {
|
||||||
|
using(var context = new TestContext()) {
|
||||||
|
Assert.That(context.Store.Remove("empty", "nothing"), Is.False);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,11 +131,11 @@ namespace Nuclex.Support.Settings {
|
||||||
if(string.IsNullOrEmpty(category)) {
|
if(string.IsNullOrEmpty(category)) {
|
||||||
return tryGetValueFromKey(this.rootKey, optionName, out value);
|
return tryGetValueFromKey(this.rootKey, optionName, out value);
|
||||||
} else {
|
} else {
|
||||||
RegistryKey categoryKey = this.rootKey.OpenSubKey(category, this.writable);
|
RegistryKey categoryKey = this.rootKey.OpenSubKey(category, this.writable);
|
||||||
if(categoryKey == null) {
|
if(categoryKey == null) {
|
||||||
value = default(TValue);
|
value = default(TValue);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
using(categoryKey) {
|
using(categoryKey) {
|
||||||
return tryGetValueFromKey(categoryKey, optionName, out value);
|
return tryGetValueFromKey(categoryKey, optionName, out value);
|
||||||
}
|
}
|
||||||
|
@ -151,16 +151,38 @@ namespace Nuclex.Support.Settings {
|
||||||
if(string.IsNullOrEmpty(category)) {
|
if(string.IsNullOrEmpty(category)) {
|
||||||
setValue(this.rootKey, optionName, value);
|
setValue(this.rootKey, optionName, value);
|
||||||
} else {
|
} else {
|
||||||
RegistryKey categoryKey = this.rootKey.OpenSubKey(category, this.writable);
|
RegistryKey categoryKey = this.rootKey.OpenSubKey(category, this.writable);
|
||||||
if(categoryKey == null) {
|
if(categoryKey == null) {
|
||||||
categoryKey = this.rootKey.CreateSubKey(category);
|
categoryKey = this.rootKey.CreateSubKey(category);
|
||||||
}
|
}
|
||||||
using(categoryKey) {
|
using(categoryKey) {
|
||||||
setValue(categoryKey, optionName, value);
|
setValue(categoryKey, optionName, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Removes the option with the specified name</summary>
|
||||||
|
/// <param name="category">Category the option is found in. Can be null.</param>
|
||||||
|
/// <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) {
|
||||||
|
if(string.IsNullOrEmpty(category)) {
|
||||||
|
object value = this.rootKey.GetValue(optionName);
|
||||||
|
this.rootKey.DeleteValue(optionName, throwOnMissingValue: false);
|
||||||
|
return (value != null);
|
||||||
|
} else {
|
||||||
|
RegistryKey categoryKey = this.rootKey.OpenSubKey(category, this.writable);
|
||||||
|
if(categoryKey == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
using(categoryKey) {
|
||||||
|
object value = categoryKey.GetValue(optionName);
|
||||||
|
categoryKey.DeleteValue(optionName, throwOnMissingValue: false);
|
||||||
|
return (value != null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Writes a setting to the registry</summary>
|
/// <summary>Writes a setting to the registry</summary>
|
||||||
/// <typeparam name="TValue"></typeparam>
|
/// <typeparam name="TValue"></typeparam>
|
||||||
/// <param name="registryKey"></param>
|
/// <param name="registryKey"></param>
|
||||||
|
@ -187,14 +209,6 @@ namespace Nuclex.Support.Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Removes the option with the specified name</summary>
|
|
||||||
/// <param name="category">Category the option is found in. Can be null.</param>
|
|
||||||
/// <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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Tries to retrieve the value of a registry key if it exists</summary>
|
/// <summary>Tries to retrieve the value of a registry key if it exists</summary>
|
||||||
/// <typeparam name="TValue">Type of value the registry key is expected to have</typeparam>
|
/// <typeparam name="TValue">Type of value the registry key is expected to have</typeparam>
|
||||||
/// <param name="categoryKey">Registry key the value is stored under</param>
|
/// <param name="categoryKey">Registry key the value is stored under</param>
|
||||||
|
@ -228,33 +242,7 @@ namespace Nuclex.Support.Settings {
|
||||||
case RegistryValueKind.QWord: { return typeof(long); }
|
case RegistryValueKind.QWord: { return typeof(long); }
|
||||||
case RegistryValueKind.MultiString: { return typeof(string[]); }
|
case RegistryValueKind.MultiString: { return typeof(string[]); }
|
||||||
case RegistryValueKind.ExpandString:
|
case RegistryValueKind.ExpandString:
|
||||||
case RegistryValueKind.String: {
|
case RegistryValueKind.String: { return typeof(string); }
|
||||||
string value = (string)categoryKey.GetValue(optionName);
|
|
||||||
if(value.Length == 0) {
|
|
||||||
return typeof(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are at least two characters, it may be an integer with
|
|
||||||
// a sign in front of it
|
|
||||||
if(value.Length >= 2) {
|
|
||||||
int index = 0;
|
|
||||||
if(ParserHelper.SkipInteger(value, ref index)) {
|
|
||||||
if(index >= value.Length) {
|
|
||||||
return typeof(int);
|
|
||||||
}
|
|
||||||
if(value[index] == '.') {
|
|
||||||
return typeof(float);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // If it's just a single character, it may be a number
|
|
||||||
if(char.IsNumber(value, 0)) {
|
|
||||||
return typeof(int);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeof(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
case RegistryValueKind.Unknown:
|
case RegistryValueKind.Unknown:
|
||||||
case RegistryValueKind.None:
|
case RegistryValueKind.None:
|
||||||
default: { return typeof(string); }
|
default: { return typeof(string); }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user