using System.IO;
using GFramework.Core.Configuration;
using NUnit.Framework;
namespace GFramework.Core.Tests.Configuration;
///
/// ConfigurationManager 功能测试类
///
[TestFixture]
public class ConfigurationManagerTests
{
[SetUp]
public void SetUp()
{
_configManager = new ConfigurationManager();
}
[TearDown]
public void TearDown()
{
_configManager.Clear();
}
private ConfigurationManager _configManager = null!;
[Test]
public void SetConfig_And_GetConfig_Should_Work()
{
_configManager.SetConfig("test.key", 42);
var value = _configManager.GetConfig("test.key");
Assert.That(value, Is.EqualTo(42));
}
[Test]
public void GetConfig_With_DefaultValue_Should_Return_DefaultValue_When_Key_Not_Exists()
{
var value = _configManager.GetConfig("nonexistent.key", 100);
Assert.That(value, Is.EqualTo(100));
}
[Test]
public void GetConfig_Should_Return_Default_When_Key_Not_Exists()
{
var value = _configManager.GetConfig("nonexistent.key");
Assert.That(value, Is.EqualTo(0));
}
[Test]
public void HasConfig_Should_Return_True_When_Key_Exists()
{
_configManager.SetConfig("test.key", "value");
Assert.That(_configManager.HasConfig("test.key"), Is.True);
}
[Test]
public void HasConfig_Should_Return_False_When_Key_Not_Exists()
{
Assert.That(_configManager.HasConfig("nonexistent.key"), Is.False);
}
[Test]
public void RemoveConfig_Should_Remove_Existing_Key()
{
_configManager.SetConfig("test.key", "value");
var removed = _configManager.RemoveConfig("test.key");
Assert.That(removed, Is.True);
Assert.That(_configManager.HasConfig("test.key"), Is.False);
}
[Test]
public void RemoveConfig_Should_Return_False_When_Key_Not_Exists()
{
var removed = _configManager.RemoveConfig("nonexistent.key");
Assert.That(removed, Is.False);
}
[Test]
public void Clear_Should_Remove_All_Configs()
{
_configManager.SetConfig("key1", "value1");
_configManager.SetConfig("key2", "value2");
_configManager.Clear();
Assert.That(_configManager.Count, Is.EqualTo(0));
}
[Test]
public void Count_Should_Return_Correct_Number()
{
_configManager.SetConfig("key1", "value1");
_configManager.SetConfig("key2", "value2");
_configManager.SetConfig("key3", "value3");
Assert.That(_configManager.Count, Is.EqualTo(3));
}
[Test]
public void GetAllKeys_Should_Return_All_Keys()
{
_configManager.SetConfig("key1", "value1");
_configManager.SetConfig("key2", "value2");
var keys = _configManager.GetAllKeys().ToList();
Assert.That(keys, Has.Count.EqualTo(2));
Assert.That(keys, Contains.Item("key1"));
Assert.That(keys, Contains.Item("key2"));
}
[Test]
public void GetConfig_Should_Support_Different_Types()
{
_configManager.SetConfig("int.key", 42);
_configManager.SetConfig("string.key", "hello");
_configManager.SetConfig("bool.key", true);
_configManager.SetConfig("double.key", 3.14);
Assert.That(_configManager.GetConfig("int.key"), Is.EqualTo(42));
Assert.That(_configManager.GetConfig("string.key"), Is.EqualTo("hello"));
Assert.That(_configManager.GetConfig("bool.key"), Is.True);
Assert.That(_configManager.GetConfig("double.key"), Is.EqualTo(3.14).Within(0.001));
}
[Test]
public void WatchConfig_Should_Trigger_When_Config_Changes()
{
var callCount = 0;
var receivedValue = 0;
_configManager.WatchConfig("test.key", value =>
{
callCount++;
receivedValue = value;
});
_configManager.SetConfig("test.key", 42);
Assert.That(callCount, Is.EqualTo(1));
Assert.That(receivedValue, Is.EqualTo(42));
}
[Test]
public void WatchConfig_Should_Not_Trigger_When_Value_Not_Changed()
{
_configManager.SetConfig("test.key", 42);
var callCount = 0;
_configManager.WatchConfig("test.key", _ => callCount++);
_configManager.SetConfig("test.key", 42);
Assert.That(callCount, Is.EqualTo(0));
}
[Test]
public void UnRegister_Should_Stop_Watching()
{
var callCount = 0;
var unRegister = _configManager.WatchConfig("test.key", _ => callCount++);
_configManager.SetConfig("test.key", 42);
Assert.That(callCount, Is.EqualTo(1));
unRegister.UnRegister();
_configManager.SetConfig("test.key", 100);
Assert.That(callCount, Is.EqualTo(1));
}
[Test]
public void Multiple_Watchers_Should_All_Be_Triggered()
{
var count1 = 0;
var count2 = 0;
_configManager.WatchConfig("test.key", _ => count1++);
_configManager.WatchConfig("test.key", _ => count2++);
_configManager.SetConfig("test.key", 42);
Assert.That(count1, Is.EqualTo(1));
Assert.That(count2, Is.EqualTo(1));
}
[Test]
public void SaveToJson_And_LoadFromJson_Should_Work()
{
_configManager.SetConfig("key1", "value1");
_configManager.SetConfig("key2", 42);
var json = _configManager.SaveToJson();
var newManager = new ConfigurationManager();
newManager.LoadFromJson(json);
Assert.That(newManager.GetConfig("key1"), Is.EqualTo("value1"));
Assert.That(newManager.GetConfig("key2"), Is.EqualTo(42));
}
[Test]
public void SaveToFile_And_LoadFromFile_Should_Work()
{
var tempFile = Path.GetTempFileName();
try
{
_configManager.SetConfig("key1", "value1");
_configManager.SetConfig("key2", 42);
_configManager.SaveToFile(tempFile);
var newManager = new ConfigurationManager();
newManager.LoadFromFile(tempFile);
Assert.That(newManager.GetConfig("key1"), Is.EqualTo("value1"));
Assert.That(newManager.GetConfig("key2"), Is.EqualTo(42));
}
finally
{
if (File.Exists(tempFile))
{
File.Delete(tempFile);
}
}
}
[Test]
public void LoadFromFile_Should_Throw_When_File_Not_Exists()
{
Assert.Throws(() => { _configManager.LoadFromFile("nonexistent.json"); });
}
[Test]
public void SetConfig_Should_Throw_When_Key_Is_Null_Or_Empty()
{
Assert.Throws(() => _configManager.SetConfig(null!, "value"));
Assert.Throws(() => _configManager.SetConfig("", "value"));
Assert.Throws(() => _configManager.SetConfig(" ", "value"));
}
[Test]
public void GetConfig_Should_Throw_When_Key_Is_Null_Or_Empty()
{
Assert.Throws(() => _configManager.GetConfig(null!));
Assert.Throws(() => _configManager.GetConfig(""));
Assert.Throws(() => _configManager.GetConfig(" "));
}
[Test]
public void WatchConfig_Should_Throw_When_Parameters_Invalid()
{
Assert.Throws(() => _configManager.WatchConfig(null!, _ => { }));
Assert.Throws(() => _configManager.WatchConfig("key", null!));
}
[Test]
public void Concurrent_SetConfig_Should_Be_Thread_Safe()
{
const int threadCount = 10;
const int iterationsPerThread = 100;
var tasks = new Task[threadCount];
var exceptions = new List();
for (var i = 0; i < threadCount; i++)
{
var threadId = i;
tasks[i] = Task.Run(() =>
{
try
{
for (var j = 0; j < iterationsPerThread; j++)
{
_configManager.SetConfig($"key.{threadId}", j);
}
}
catch (Exception ex)
{
lock (exceptions)
{
exceptions.Add(ex);
}
}
});
}
Task.WaitAll(tasks);
Assert.That(exceptions, Is.Empty);
}
[Test]
public void Concurrent_GetConfig_And_SetConfig_Should_Be_Thread_Safe()
{
const int threadCount = 5;
var tasks = new Task[threadCount];
var exceptions = new List();
for (var i = 0; i < threadCount; i++)
{
tasks[i] = Task.Run(() =>
{
try
{
for (var j = 0; j < 100; j++)
{
if (j % 2 == 0)
{
_configManager.SetConfig("shared.key", j);
}
else
{
_configManager.GetConfig("shared.key");
}
}
}
catch (Exception ex)
{
lock (exceptions)
{
exceptions.Add(ex);
}
}
});
}
Task.WaitAll(tasks);
Assert.That(exceptions, Is.Empty);
}
[Test]
public void Concurrent_WatchConfig_Should_Be_Thread_Safe()
{
const int threadCount = 10;
var tasks = new Task[threadCount];
var exceptions = new List();
var callCounts = new int[threadCount];
for (var i = 0; i < threadCount; i++)
{
var threadId = i;
tasks[i] = Task.Run(() =>
{
try
{
_configManager.WatchConfig("test.key",
_ => { Interlocked.Increment(ref callCounts[threadId]); });
}
catch (Exception ex)
{
lock (exceptions)
{
exceptions.Add(ex);
}
}
});
}
Task.WaitAll(tasks);
_configManager.SetConfig("test.key", 42);
Assert.That(exceptions, Is.Empty);
Assert.That(callCounts.Sum(), Is.EqualTo(threadCount));
}
}