| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- using Apq.Cfg;
- namespace Apq.Cfg.Tests;
- /// <summary>
- /// Source Generator 生成的配置类测试
- /// </summary>
- public class SourceGeneratorTests : IDisposable
- {
- private readonly string _testDir;
- public SourceGeneratorTests()
- {
- _testDir = Path.Combine(Path.GetTempPath(), $"ApqCfgSgTests_{Guid.NewGuid():N}");
- Directory.CreateDirectory(_testDir);
- }
- [Fact]
- public void BindFrom_SimpleProperties_ShouldBindCorrectly()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "simple.json");
- File.WriteAllText(jsonPath, @"{
- ""Database"": {
- ""ConnectionString"": ""Server=localhost;Database=test"",
- ""Timeout"": 30,
- ""MaxRetries"": 3,
- ""EnableLogging"": true
- }
- }");
- var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("Database");
- var config = TestDatabaseConfig.BindFrom(section);
- // Assert
- Assert.Equal("Server=localhost;Database=test", config.ConnectionString);
- Assert.Equal(30, config.Timeout);
- Assert.Equal(3, config.MaxRetries);
- Assert.True(config.EnableLogging);
- }
- [Fact]
- public void BindFrom_NestedObject_ShouldBindCorrectly()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "nested.json");
- File.WriteAllText(jsonPath, @"{
- ""App"": {
- ""Name"": ""TestApp"",
- ""Version"": ""1.0.0"",
- ""Database"": {
- ""ConnectionString"": ""Server=db"",
- ""Timeout"": 60,
- ""MaxRetries"": 5,
- ""EnableLogging"": false
- }
- }
- }");
- var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("App");
- var config = TestAppConfig.BindFrom(section);
- // Assert
- Assert.Equal("TestApp", config.Name);
- Assert.Equal("1.0.0", config.Version);
- Assert.NotNull(config.Database);
- Assert.Equal("Server=db", config.Database.ConnectionString);
- Assert.Equal(60, config.Database.Timeout);
- }
- [Fact]
- public void BindFrom_ArrayProperty_ShouldBindCorrectly()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "array.json");
- File.WriteAllText(jsonPath, @"{
- ""Server"": {
- ""Name"": ""WebServer"",
- ""Ports"": [80, 443, 8080],
- ""AllowedHosts"": [""localhost"", ""127.0.0.1"", ""example.com""]
- }
- }");
- var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("Server");
- var config = TestServerConfig.BindFrom(section);
- // Assert
- Assert.Equal("WebServer", config.Name);
- Assert.NotNull(config.Ports);
- Assert.Equal(3, config.Ports.Length);
- Assert.Equal(80, config.Ports[0]);
- Assert.Equal(443, config.Ports[1]);
- Assert.Equal(8080, config.Ports[2]);
- Assert.NotNull(config.AllowedHosts);
- Assert.Equal(3, config.AllowedHosts.Count);
- Assert.Contains("localhost", config.AllowedHosts);
- }
- [Fact]
- public void BindFrom_DictionaryProperty_ShouldBindCorrectly()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "dict.json");
- File.WriteAllText(jsonPath, @"{
- ""Features"": {
- ""Name"": ""FeatureFlags"",
- ""Flags"": {
- ""DarkMode"": true,
- ""BetaFeatures"": false,
- ""Analytics"": true
- }
- }
- }");
- var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("Features");
- var config = TestFeaturesConfig.BindFrom(section);
- // Assert
- Assert.Equal("FeatureFlags", config.Name);
- Assert.NotNull(config.Flags);
- Assert.Equal(3, config.Flags.Count);
- Assert.True(config.Flags["DarkMode"]);
- Assert.False(config.Flags["BetaFeatures"]);
- Assert.True(config.Flags["Analytics"]);
- }
- [Fact]
- public void BindFrom_NullableProperties_ShouldHandleNulls()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "nullable.json");
- File.WriteAllText(jsonPath, @"{
- ""Optional"": {
- ""RequiredValue"": ""test"",
- ""OptionalInt"": 42
- }
- }");
- var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("Optional");
- var config = TestOptionalConfig.BindFrom(section);
- // Assert
- Assert.Equal("test", config.RequiredValue);
- Assert.Equal(42, config.OptionalInt);
- Assert.Null(config.OptionalString);
- }
- [Fact]
- public void BindTo_ExistingObject_ShouldUpdateProperties()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "update.json");
- File.WriteAllText(jsonPath, @"{
- ""Database"": {
- ""ConnectionString"": ""NewConnection"",
- ""Timeout"": 120
- }
- }");
- var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- var existingConfig = new TestDatabaseConfig
- {
- ConnectionString = "OldConnection",
- Timeout = 30,
- MaxRetries = 5,
- EnableLogging = true
- };
- // Act
- var section = cfg.GetSection("Database");
- TestDatabaseConfig.BindTo(section, existingConfig);
- // Assert
- Assert.Equal("NewConnection", existingConfig.ConnectionString);
- Assert.Equal(120, existingConfig.Timeout);
- // 未在配置中指定的属性保持原值
- Assert.Equal(5, existingConfig.MaxRetries);
- Assert.True(existingConfig.EnableLogging);
- }
- [Fact]
- public void BindFrom_EmptySection_ShouldReturnDefaultValues()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "empty.json");
- File.WriteAllText(jsonPath, @"{}");
- var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act
- var section = cfg.GetSection("NonExistent");
- var config = TestDatabaseConfig.BindFrom(section);
- // Assert
- Assert.Null(config.ConnectionString);
- Assert.Equal(0, config.Timeout);
- Assert.Equal(0, config.MaxRetries);
- Assert.False(config.EnableLogging);
- }
- [Fact]
- public void GeneratedExtension_ShouldWork()
- {
- // Arrange
- var jsonPath = Path.Combine(_testDir, "ext.json");
- File.WriteAllText(jsonPath, @"{
- ""TestDatabase"": {
- ""ConnectionString"": ""ExtTest"",
- ""Timeout"": 99
- }
- }");
- var cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // Act - 使用生成的扩展方法
- var config = cfg.GetTestDatabaseConfig();
- // Assert
- Assert.Equal("ExtTest", config.ConnectionString);
- Assert.Equal(99, config.Timeout);
- }
- public void Dispose()
- {
- try
- {
- if (Directory.Exists(_testDir))
- {
- Directory.Delete(_testDir, true);
- }
- }
- catch { }
- }
- }
- // 测试用配置类 - 使用 [CfgSection] 特性标记
- [CfgSection("TestDatabase")]
- public partial class TestDatabaseConfig
- {
- public string? ConnectionString { get; set; }
- public int Timeout { get; set; }
- public int MaxRetries { get; set; }
- public bool EnableLogging { get; set; }
- }
- [CfgSection("App")]
- public partial class TestAppConfig
- {
- public string? Name { get; set; }
- public string? Version { get; set; }
- public TestDatabaseConfig? Database { get; set; }
- }
- [CfgSection("Server")]
- public partial class TestServerConfig
- {
- public string? Name { get; set; }
- public int[]? Ports { get; set; }
- public List<string>? AllowedHosts { get; set; }
- }
- [CfgSection("Features")]
- public partial class TestFeaturesConfig
- {
- public string? Name { get; set; }
- public Dictionary<string, bool>? Flags { get; set; }
- }
- [CfgSection("Optional")]
- public partial class TestOptionalConfig
- {
- public string? RequiredValue { get; set; }
- public int? OptionalInt { get; set; }
- public string? OptionalString { get; set; }
- }
|