Skip to content

Commit 33402bd

Browse files
committed
feat(本地化): 添加本地化测试模块及相关测试用例
添加本地化服务测试模块,包括资源提供者测试、资源管理器测试和本地化服务测试 新增测试用例覆盖核心功能如字符串获取、资源加载、异常处理等 添加项目引用至GameFrameX.Foundation.Localization 修复部分测试代码中的条件判断逻辑
1 parent 5b6c453 commit 33402bd

7 files changed

Lines changed: 990 additions & 1 deletion

File tree

GameFrameX.Foundation.Tests/Encryption/Sm4HelperTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,9 @@ public void EncryptEcb_WithInvalidNonHexKeyLength_ShouldThrowException()
311311
private static bool IsValidHexString(string hex)
312312
{
313313
if (string.IsNullOrEmpty(hex))
314+
{
314315
return false;
316+
}
315317

316318
return hex.All(c => char.IsDigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));
317319
}

GameFrameX.Foundation.Tests/Extensions/ListExtensionsTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,13 @@ public async Task ForEachAsync_List_ExceptionInFunc_ShouldPropagateException()
8787
list.ForEachAsync(async item =>
8888
{
8989
await Task.Delay(1);
90-
if (item == 2)
90+
if (item != 2)
91+
{
92+
}
93+
else
94+
{
9195
throw expectedException;
96+
}
9297
}));
9398
Assert.Equal(expectedException.Message, actualException.Message);
9499
}
@@ -171,7 +176,9 @@ public async Task ForEachAsync_IEnumerable_ExceptionInAction_ShouldPropagateExce
171176
{
172177
await Task.Delay(1);
173178
if (item == 2)
179+
{
174180
throw expectedException;
181+
}
175182
}));
176183
Assert.Equal(expectedException.Message, actualException.Message);
177184
}

GameFrameX.Foundation.Tests/GameFrameX.Foundation.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<ProjectReference Include="..\GameFrameX.Foundation.Logger\GameFrameX.Foundation.Logger.csproj" />
3434
<ProjectReference Include="..\GameFrameX.Foundation.Options\GameFrameX.Foundation.Options.csproj"/>
3535
<ProjectReference Include="..\GameFrameX.Foundation.Utility\GameFrameX.Foundation.Utility.csproj"/>
36+
<ProjectReference Include="..\GameFrameX.Foundation.Localization\GameFrameX.Foundation.Localization.csproj"/>
3637
</ItemGroup>
3738

3839
<ItemGroup>
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
using GameFrameX.Foundation.Localization.Core;
2+
using GameFrameX.Foundation.Localization.Providers;
3+
using System.Reflection;
4+
using GameFrameX.Foundation.Utility.Localization;
5+
using Xunit;
6+
7+
namespace GameFrameX.Foundation.Tests.Localization;
8+
9+
/// <summary>
10+
/// AssemblyResourceProvider 单元测试
11+
/// </summary>
12+
public class AssemblyResourceProviderTests : IDisposable
13+
{
14+
private readonly AssemblyResourceProvider _provider;
15+
16+
public AssemblyResourceProviderTests()
17+
{
18+
_provider = new AssemblyResourceProvider(typeof(Foundation.Utility.ConsoleHelper).Assembly);
19+
}
20+
21+
public void Dispose()
22+
{
23+
_provider?.Dispose();
24+
}
25+
26+
[Fact]
27+
public void Constructor_WithValidAssembly_ShouldCreateInstance()
28+
{
29+
// Arrange & Act
30+
var assembly = Assembly.GetExecutingAssembly();
31+
var provider = new AssemblyResourceProvider(assembly);
32+
33+
// Assert
34+
Assert.NotNull(provider);
35+
Assert.False(provider.IsInitialized);
36+
}
37+
38+
[Fact]
39+
public void Constructor_WithNullAssembly_ShouldThrowArgumentNullException()
40+
{
41+
// Arrange
42+
Assembly assembly = null;
43+
44+
// Act & Assert
45+
Assert.Throws<ArgumentNullException>(() => new AssemblyResourceProvider(assembly));
46+
}
47+
48+
[Fact]
49+
public void IsInitialized_Initially_ShouldBeFalse()
50+
{
51+
// Act
52+
var result = _provider.IsInitialized;
53+
54+
// Assert
55+
Assert.False(result);
56+
}
57+
58+
[Fact]
59+
public void EnsureLoaded_ShouldInitializeProvider()
60+
{
61+
// Act
62+
_provider.EnsureLoaded();
63+
var x = _provider.GetString(LocalizationKeys.Exceptions.TimestampOutOfRange);
64+
// Assert
65+
Assert.True(_provider.IsInitialized);
66+
}
67+
68+
[Fact]
69+
public void GetString_BeforeInitialization_ShouldLoadAndReturn()
70+
{
71+
// Arrange
72+
const string key = "Test.Message";
73+
74+
// Act
75+
var result = _provider.GetString(key);
76+
77+
// Assert
78+
Assert.True(_provider.IsInitialized); // Should have been loaded automatically
79+
Assert.Equal(key, result); // Since test assembly doesn't have resources
80+
}
81+
82+
[Fact]
83+
public void GetString_WithNullKey_ShouldReturnNull()
84+
{
85+
// Arrange
86+
const string key = null;
87+
88+
// Act
89+
var result = _provider.GetString(key);
90+
91+
// Assert
92+
Assert.Null(result);
93+
}
94+
95+
[Fact]
96+
public void GetString_WithEmptyKey_ShouldReturnEmpty()
97+
{
98+
// Arrange
99+
const string key = "";
100+
101+
// Act
102+
var result = _provider.GetString(key);
103+
104+
// Assert
105+
Assert.Equal("", result);
106+
}
107+
108+
[Fact]
109+
public void GetString_WithUnknownKey_ShouldReturnKey()
110+
{
111+
// Arrange
112+
const string key = "Unknown.Test.Key";
113+
114+
// Act
115+
var result = _provider.GetString(key);
116+
117+
// Assert
118+
Assert.Equal(key, result);
119+
}
120+
121+
[Fact]
122+
public void GetLoadedCategories_BeforeInitialization_ShouldReturnEmpty()
123+
{
124+
// Act
125+
var categories = _provider.GetLoadedCategories();
126+
127+
// Assert
128+
Assert.NotNull(categories);
129+
Assert.Empty(categories);
130+
}
131+
132+
[Fact]
133+
public void GetLoadedCategories_AfterInitialization_ShouldReturnCategories()
134+
{
135+
// Arrange
136+
_provider.EnsureLoaded();
137+
138+
// Act
139+
var categories = _provider.GetLoadedCategories();
140+
141+
// Assert
142+
Assert.NotNull(categories);
143+
// Since test assembly doesn't have localization resources, should be empty
144+
}
145+
146+
[Fact]
147+
public void GetStatistics_ShouldReturnValidStatistics()
148+
{
149+
// Act
150+
var stats = _provider.GetStatistics();
151+
152+
// Assert
153+
Assert.NotNull(stats);
154+
Assert.Equal(typeof(Foundation.Utility.ConsoleHelper).Assembly.GetName().Name, stats.AssemblyName);
155+
}
156+
157+
[Fact]
158+
public void EnsureLoaded_MultipleCalls_ShouldNotThrow()
159+
{
160+
// Act & Assert (should not throw)
161+
_provider.EnsureLoaded();
162+
_provider.EnsureLoaded();
163+
_provider.EnsureLoaded();
164+
165+
Assert.True(_provider.IsInitialized);
166+
}
167+
168+
[Theory]
169+
[InlineData("Module.Category.Key", "Category")]
170+
[InlineData("A.B.C.D", "B")]
171+
[InlineData("Test.Message", "Message")]
172+
public void TryGetResourceManager_WithValidKey_ShouldExtractCategory(string key, string expectedCategory)
173+
{
174+
// Act
175+
// This is testing internal behavior through public interface
176+
// The actual implementation might not find ResourceManager, but should not throw
177+
var result = _provider.GetString(key);
178+
179+
// Assert
180+
Assert.NotNull(result); // Should not throw or return null
181+
}
182+
183+
[Fact]
184+
public void Dispose_ShouldNotThrow()
185+
{
186+
// Arrange
187+
var provider = new AssemblyResourceProvider(Assembly.GetExecutingAssembly());
188+
189+
// Act & Assert (should not throw)
190+
provider.Dispose();
191+
}
192+
}

0 commit comments

Comments
 (0)