| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- namespace Apq.Cfg.Tests;
- /// <summary>
- /// ICfgSection 配置节测试
- /// </summary>
- public class CfgSectionTests : IDisposable
- {
- private readonly string _testDir;
- public CfgSectionTests()
- {
- _testDir = Path.Combine(Path.GetTempPath(), $"ApqCfgTests_{Guid.NewGuid():N}");
- Directory.CreateDirectory(_testDir);
- }
- public void Dispose()
- {
- if (Directory.Exists(_testDir))
- {
- Directory.Delete(_testDir, true);
- }
- }
- #region GetSection 基本功能
- [Fact]
- public void GetSection_SimpleSection_ReturnsCorrectValues()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "Database": {
- "Host": "localhost",
- "Port": 5432,
- "Name": "testdb"
- }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var dbSection = cfg.GetSection("Database");
- // Assert
- Assert.Equal("Database", dbSection.Path);
- Assert.Equal("localhost", dbSection.Get("Host"));
- Assert.Equal("5432", dbSection.Get("Port"));
- Assert.Equal("testdb", dbSection.Get("Name"));
- }
- [Fact]
- public void GetSection_TypedGet_ReturnsCorrectType()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "Settings": {
- "MaxRetries": 3,
- "Enabled": true,
- "Timeout": 30.5
- }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("Settings");
- // Assert
- Assert.Equal(3, section.Get<int>("MaxRetries"));
- Assert.True(section.Get<bool>("Enabled"));
- Assert.Equal(30.5, section.Get<double>("Timeout"));
- }
- [Fact]
- public void GetSection_NestedSection_ReturnsCorrectValues()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "Database": {
- "Connection": {
- "Host": "localhost",
- "Port": 5432
- },
- "Pool": {
- "MinSize": 5,
- "MaxSize": 100
- }
- }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var dbSection = cfg.GetSection("Database");
- var connSection = dbSection.GetSection("Connection");
- var poolSection = dbSection.GetSection("Pool");
- // Assert
- Assert.Equal("Database:Connection", connSection.Path);
- Assert.Equal("localhost", connSection.Get("Host"));
- Assert.Equal(5432, connSection.Get<int>("Port"));
- Assert.Equal("Database:Pool", poolSection.Path);
- Assert.Equal(5, poolSection.Get<int>("MinSize"));
- Assert.Equal(100, poolSection.Get<int>("MaxSize"));
- }
- [Fact]
- public void GetSection_Exists_ReturnsCorrectResult()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "App": {
- "Name": "TestApp",
- "Version": "1.0.0"
- }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("App");
- // Assert
- Assert.True(section.Exists("Name"));
- Assert.True(section.Exists("Version"));
- Assert.False(section.Exists("NonExistent"));
- }
- #endregion
- #region GetSection 写入功能
- [Fact]
- public async Task GetSection_Set_UpdatesValue()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "App": {
- "Name": "OldName"
- }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: true, isPrimaryWriter: true)
- .Build();
- // Act
- var section = cfg.GetSection("App");
- section.Set("Name", "NewName");
- await cfg.SaveAsync();
- // Assert
- Assert.Equal("NewName", section.Get("Name"));
- Assert.Equal("NewName", cfg.Get("App:Name"));
- }
- [Fact]
- public async Task GetSection_Remove_RemovesKey()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "App": {
- "Name": "TestApp",
- "ToRemove": "RemoveMe"
- }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: true, isPrimaryWriter: true)
- .Build();
- // Act
- var section = cfg.GetSection("App");
- section.Remove("ToRemove");
- await cfg.SaveAsync();
- // Assert
- Assert.True(section.Exists("Name"));
- Assert.False(section.Exists("ToRemove"));
- }
- #endregion
- #region GetChildKeys 功能
- [Fact]
- public void GetChildKeys_ReturnsAllTopLevelKeys()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "App": { "Name": "Test" },
- "Database": { "Host": "localhost" },
- "Logging": { "Level": "Info" }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var keys = cfg.GetChildKeys().ToList();
- // Assert
- Assert.Contains("App", keys);
- Assert.Contains("Database", keys);
- Assert.Contains("Logging", keys);
- Assert.Equal(3, keys.Count);
- }
- [Fact]
- public void GetSection_GetChildKeys_ReturnsSectionKeys()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "Database": {
- "Host": "localhost",
- "Port": 5432,
- "Name": "testdb"
- }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("Database");
- var keys = section.GetChildKeys().ToList();
- // Assert
- Assert.Contains("Host", keys);
- Assert.Contains("Port", keys);
- Assert.Contains("Name", keys);
- Assert.Equal(3, keys.Count);
- }
- #endregion
- #region GetSection 边界情况
- [Fact]
- public void GetSection_NonExistentSection_ReturnsEmptySection()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """{"Key": "Value"}""");
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("NonExistent");
- // Assert
- Assert.Equal("NonExistent", section.Path);
- Assert.Null(section.Get("AnyKey"));
- Assert.False(section.Exists("AnyKey"));
- }
- [Fact]
- public void GetSection_EmptyPath_WorksCorrectly()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """{"TopLevel": "Value"}""");
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act - 获取空路径的 section,然后访问顶级键
- var section = cfg.GetSection("");
- // Assert
- Assert.Equal("", section.Path);
- Assert.Equal("Value", section.Get("TopLevel"));
- }
- [Fact]
- public void GetSection_DeepNesting_WorksCorrectly()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "Level1": {
- "Level2": {
- "Level3": {
- "Level4": {
- "DeepValue": "Found"
- }
- }
- }
- }
- }
- """);
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("Level1")
- .GetSection("Level2")
- .GetSection("Level3")
- .GetSection("Level4");
- // Assert
- Assert.Equal("Level1:Level2:Level3:Level4", section.Path);
- Assert.Equal("Found", section.Get("DeepValue"));
- }
- #endregion
- #region GetOrDefault 扩展方法
- [Fact]
- public void GetOrDefault_ExistingKey_ReturnsValue()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """{"IntValue": 42}""");
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act & Assert
- Assert.Equal(42, cfg.GetOrDefault("IntValue", 0));
- }
- [Fact]
- public void GetOrDefault_NonExistingKey_ReturnsDefault()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """{"Key": "Value"}""");
- using var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act & Assert
- Assert.Equal(100, cfg.GetOrDefault("NonExistent", 100));
- Assert.Equal("DefaultString", cfg.GetOrDefault("NonExistent", "DefaultString"));
- }
- #endregion
- }
|