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
					
				
					 3 changed files with 190 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue