From dda2d8f8640481ec6e914ca20929aa2e2bb2f905 Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Thu, 15 Jan 2026 13:53:08 +0800 Subject: [PATCH] =?UTF-8?q?test(core):=20=E6=B7=BB=E5=8A=A0=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E7=BB=84=E4=BB=B6=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E7=9B=AE=E6=A0=87=E6=A1=86=E6=9E=B6?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在AsyncTestModel和TestModel中添加override关键字修复方法重写 - 调整GFramework.Core.Tests和GFramework.SourceGenerators.Tests的目标框架顺序为net10.0;net8.0 - 优化SyncArchitectureTests中的注释格式,统一添加前导空格 - 移除TestQuery相关代码文件 - 新增BindablePropertyTests测试绑定属性功能 - 新增CommandBusTests测试命令总线功能 - 新增EasyEventsTests和EventTests测试事件系统功能 - 新增IocContainerTests测试依赖注入容器功能 - 新增ObjectExtensionsTests测试对象扩展方法功能 - 新增ObjectPoolTests测试对象池功能 - 新增OrEventTests测试或事件功能 - 新增QueryBusTests测试查询总线功能 - [skip ci] --- .../GFramework.Core.Tests.csproj | 2 +- .../command/CommandBusTests.cs | 88 ++++++ .../events/EasyEventsTests.cs | 50 ++++ GFramework.Core.Tests/events/EventTests.cs | 134 +++++++++ GFramework.Core.Tests/events/OrEventTests.cs | 81 ++++++ .../extensions/ObjectExtensionsTests.cs | 180 ++++++++++++ .../ioc/IocContainerTests.cs | 262 ++++++++++++++++++ GFramework.Core.Tests/model/AsyncTestModel.cs | 4 +- GFramework.Core.Tests/model/TestModel.cs | 4 +- GFramework.Core.Tests/pool/ObjectPoolTests.cs | 131 +++++++++ .../property/BindablePropertyTests.cs | 133 +++++++++ GFramework.Core.Tests/query/QueryBusTests.cs | 74 +++++ GFramework.Core.Tests/query/TestQuery.cs | 28 -- .../tests/SyncArchitectureTests.cs | 8 +- .../GFramework.SourceGenerators.Tests.csproj | 2 +- 15 files changed, 1143 insertions(+), 38 deletions(-) create mode 100644 GFramework.Core.Tests/command/CommandBusTests.cs create mode 100644 GFramework.Core.Tests/events/EasyEventsTests.cs create mode 100644 GFramework.Core.Tests/events/EventTests.cs create mode 100644 GFramework.Core.Tests/events/OrEventTests.cs create mode 100644 GFramework.Core.Tests/extensions/ObjectExtensionsTests.cs create mode 100644 GFramework.Core.Tests/ioc/IocContainerTests.cs create mode 100644 GFramework.Core.Tests/pool/ObjectPoolTests.cs create mode 100644 GFramework.Core.Tests/property/BindablePropertyTests.cs create mode 100644 GFramework.Core.Tests/query/QueryBusTests.cs delete mode 100644 GFramework.Core.Tests/query/TestQuery.cs diff --git a/GFramework.Core.Tests/GFramework.Core.Tests.csproj b/GFramework.Core.Tests/GFramework.Core.Tests.csproj index 672904d..2392396 100644 --- a/GFramework.Core.Tests/GFramework.Core.Tests.csproj +++ b/GFramework.Core.Tests/GFramework.Core.Tests.csproj @@ -3,7 +3,7 @@ enable enable - net8.0;net9.0;net10.0 + net10.0;net8.0 diff --git a/GFramework.Core.Tests/command/CommandBusTests.cs b/GFramework.Core.Tests/command/CommandBusTests.cs new file mode 100644 index 0000000..5b1be15 --- /dev/null +++ b/GFramework.Core.Tests/command/CommandBusTests.cs @@ -0,0 +1,88 @@ +using GFramework.Core.Abstractions.command; +using GFramework.Core.command; +using NUnit.Framework; + +namespace GFramework.Core.Tests.command; + +[TestFixture] +public class CommandBusTests +{ + [SetUp] + public void SetUp() + { + _commandBus = new CommandBus(); + } + + private CommandBus _commandBus = null!; + + [Test] + public void Send_Should_Execute_Command() + { + var input = new TestCommandInput { Value = 42 }; + var command = new TestCommand(input); + + Assert.DoesNotThrow(() => _commandBus.Send(command)); + Assert.That(command.Executed, Is.True); + Assert.That(command.ExecutedValue, Is.EqualTo(42)); + } + + [Test] + public void Send_WithNullCommand_Should_ThrowArgumentNullException() + { + Assert.Throws(() => _commandBus.Send(null!)); + } + + [Test] + public void Send_WithResult_Should_Return_Value() + { + var input = new TestCommandInput { Value = 100 }; + var command = new TestCommandWithResult(input); + + var result = _commandBus.Send(command); + + Assert.That(command.Executed, Is.True); + Assert.That(result, Is.EqualTo(200)); + } + + [Test] + public void Send_WithResult_AndNullCommand_Should_ThrowArgumentNullException() + { + Assert.Throws(() => _commandBus.Send(null!)); + } +} + +public sealed class TestCommandInput : ICommandInput +{ + public int Value { get; init; } +} + +public sealed class TestCommand : AbstractCommand +{ + public TestCommand(TestCommandInput input) : base(input) + { + } + + public bool Executed { get; private set; } + public int ExecutedValue { get; private set; } + + protected override void OnExecute(TestCommandInput input) + { + Executed = true; + ExecutedValue = 42; + } +} + +public sealed class TestCommandWithResult : AbstractCommand +{ + public TestCommandWithResult(TestCommandInput input) : base(input) + { + } + + public bool Executed { get; private set; } + + protected override int OnExecute(TestCommandInput input) + { + Executed = true; + return input.Value * 2; + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/events/EasyEventsTests.cs b/GFramework.Core.Tests/events/EasyEventsTests.cs new file mode 100644 index 0000000..4364c98 --- /dev/null +++ b/GFramework.Core.Tests/events/EasyEventsTests.cs @@ -0,0 +1,50 @@ +using GFramework.Core.events; +using NUnit.Framework; + +namespace GFramework.Core.Tests.events; + +[TestFixture] +public class EasyEventsTests +{ + [SetUp] + public void SetUp() + { + _easyEvents = new EasyEvents(); + } + + private EasyEvents _easyEvents = null!; + + [Test] + public void Get_EventT_Should_Trigger_With_Parameter() + { + _easyEvents.GetOrAddEvent>(); + + var receivedValue = 0; + var @event = EasyEvents.Get>(); + + @event.Register(value => { receivedValue = value; }); + @event.Trigger(42); + + Assert.That(receivedValue, Is.EqualTo(42)); + } + + [Test] + public void Get_EventTTK_Should_Trigger_With_Two_Parameters() + { + _easyEvents.GetOrAddEvent>(); + + var receivedInt = 0; + var receivedString = string.Empty; + var @event = EasyEvents.Get>(); + + @event.Register((i, s) => + { + receivedInt = i; + receivedString = s; + }); + @event.Trigger(100, "hello"); + + Assert.That(receivedInt, Is.EqualTo(100)); + Assert.That(receivedString, Is.EqualTo("hello")); + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/events/EventTests.cs b/GFramework.Core.Tests/events/EventTests.cs new file mode 100644 index 0000000..8a5bd6b --- /dev/null +++ b/GFramework.Core.Tests/events/EventTests.cs @@ -0,0 +1,134 @@ +using GFramework.Core.events; +using NUnit.Framework; + +namespace GFramework.Core.Tests.events; + +[TestFixture] +public class EventTests +{ + [SetUp] + public void SetUp() + { + _easyEvent = new EasyEvent(); + _eventInt = new Event(); + _eventIntString = new Event(); + } + + private EasyEvent _easyEvent = null!; + private Event _eventInt = null!; + private Event _eventIntString = null!; + + [Test] + public void EasyEvent_Register_Should_Add_Handler() + { + var called = false; + _easyEvent.Register(() => { called = true; }); + + _easyEvent.Trigger(); + + Assert.That(called, Is.True); + } + + [Test] + public void EasyEvent_UnRegister_Should_Remove_Handler() + { + var count = 0; + var handler = () => { count++; }; + + _easyEvent.Register(handler); + _easyEvent.Trigger(); + Assert.That(count, Is.EqualTo(1)); + + _easyEvent.UnRegister(handler); + _easyEvent.Trigger(); + Assert.That(count, Is.EqualTo(1)); + } + + [Test] + public void EasyEvent_Multiple_Handlers_Should_All_Be_Called() + { + var count1 = 0; + var count2 = 0; + + _easyEvent.Register(() => { count1++; }); + _easyEvent.Register(() => { count2++; }); + + _easyEvent.Trigger(); + + Assert.That(count1, Is.EqualTo(1)); + Assert.That(count2, Is.EqualTo(1)); + } + + [Test] + public void EventT_Register_Should_Add_Handler() + { + var receivedValue = 0; + _eventInt.Register(value => { receivedValue = value; }); + + _eventInt.Trigger(42); + + Assert.That(receivedValue, Is.EqualTo(42)); + } + + [Test] + public void EventT_UnRegister_Should_Remove_Handler() + { + var count = 0; + Action handler = value => { count++; }; + + _eventInt.Register(handler); + _eventInt.Trigger(1); + Assert.That(count, Is.EqualTo(1)); + + _eventInt.UnRegister(handler); + _eventInt.Trigger(2); + Assert.That(count, Is.EqualTo(1)); + } + + [Test] + public void EventT_Multiple_Handlers_Should_All_Be_Called() + { + var values = new List(); + + _eventInt.Register(value => { values.Add(value); }); + _eventInt.Register(value => { values.Add(value * 2); }); + + _eventInt.Trigger(5); + + Assert.That(values.Count, Is.EqualTo(2)); + Assert.That(values, Does.Contain(5)); + Assert.That(values, Does.Contain(10)); + } + + [Test] + public void EventTTK_Register_Should_Add_Handler() + { + var receivedInt = 0; + var receivedString = string.Empty; + _eventIntString.Register((i, s) => + { + receivedInt = i; + receivedString = s; + }); + + _eventIntString.Trigger(42, "test"); + + Assert.That(receivedInt, Is.EqualTo(42)); + Assert.That(receivedString, Is.EqualTo("test")); + } + + [Test] + public void EventTTK_UnRegister_Should_Remove_Handler() + { + var count = 0; + Action handler = (i, s) => { count++; }; + + _eventIntString.Register(handler); + _eventIntString.Trigger(1, "a"); + Assert.That(count, Is.EqualTo(1)); + + _eventIntString.UnRegister(handler); + _eventIntString.Trigger(2, "b"); + Assert.That(count, Is.EqualTo(1)); + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/events/OrEventTests.cs b/GFramework.Core.Tests/events/OrEventTests.cs new file mode 100644 index 0000000..51fa4ab --- /dev/null +++ b/GFramework.Core.Tests/events/OrEventTests.cs @@ -0,0 +1,81 @@ +using GFramework.Core.events; +using NUnit.Framework; + +namespace GFramework.Core.Tests.events; + +[TestFixture] +public class OrEventTests +{ + [Test] + public void OrEvent_Should_Trigger_When_Any_Event_Fires() + { + var event1 = new Event(); + var event2 = new Event(); + var orEvent = new OrEvent(); + + var triggered = false; + orEvent.Register(() => { triggered = true; }); + + orEvent.Or(event1).Or(event2); + + event1.Trigger(0); + + Assert.That(triggered, Is.True); + } + + [Test] + public void OrEvent_Should_Trigger_When_Second_Event_Fires() + { + var event1 = new Event(); + var event2 = new Event(); + var orEvent = new OrEvent(); + + var triggered = false; + orEvent.Register(() => { triggered = true; }); + + orEvent.Or(event1).Or(event2); + + event2.Trigger(0); + + Assert.That(triggered, Is.True); + } + + [Test] + public void OrEvent_Should_Support_Multiple_Handlers() + { + var @event = new Event(); + var orEvent = new OrEvent(); + + var count1 = 0; + var count2 = 0; + + orEvent.Register(() => { count1++; }); + orEvent.Register(() => { count2++; }); + + orEvent.Or(@event); + @event.Trigger(0); + + Assert.That(count1, Is.EqualTo(1)); + Assert.That(count2, Is.EqualTo(1)); + } + + [Test] + public void OrEvent_UnRegister_Should_Remove_Handler() + { + var @event = new Event(); + var orEvent = new OrEvent(); + + var count = 0; + var handler = () => { count++; }; + + orEvent.Register(handler); + orEvent.Or(@event); + + @event.Trigger(0); + Assert.That(count, Is.EqualTo(1)); + + orEvent.UnRegister(handler); + @event.Trigger(0); + Assert.That(count, Is.EqualTo(1)); + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/extensions/ObjectExtensionsTests.cs b/GFramework.Core.Tests/extensions/ObjectExtensionsTests.cs new file mode 100644 index 0000000..b2d5433 --- /dev/null +++ b/GFramework.Core.Tests/extensions/ObjectExtensionsTests.cs @@ -0,0 +1,180 @@ +using GFramework.Core.extensions; +using NUnit.Framework; + +namespace GFramework.Core.Tests.extensions; + +[TestFixture] +public class ObjectExtensionsTests +{ + [Test] + public void IfType_Should_Execute_Action_When_Type_Matches() + { + var obj = new TestClass(); + var executed = false; + + obj.IfType(_ => { executed = true; }); + + Assert.That(executed, Is.True); + } + + [Test] + public void IfType_Should_Not_Execute_Action_When_Type_Does_Not_Match() + { + var obj = new TestClass(); + var executed = false; + + obj.IfType(_ => { executed = true; }); + + Assert.That(executed, Is.False); + } + + [Test] + public void IfType_WithPredicate_Should_Execute_When_Type_Matches_And_Predicate_True() + { + var obj = new TestClass { Value = 10 }; + var executed = false; + + obj.IfType(x => x.Value > 5, _ => { executed = true; }); + + Assert.That(executed, Is.True); + } + + [Test] + public void IfType_WithPredicate_Should_Not_Execute_When_Predicate_False() + { + var obj = new TestClass { Value = 3 }; + var executed = false; + + obj.IfType(x => x.Value > 5, _ => { executed = true; }); + + Assert.That(executed, Is.False); + } + + [Test] + public void IfType_WithBoth_Actions_Should_Execute_Correct_Action() + { + var matchCount = 0; + var noMatchCount = 0; + + var obj = new TestClass(); + obj.IfType( + _ => { matchCount++; }, + _ => { noMatchCount++; } + ); + + Assert.That(matchCount, Is.EqualTo(1)); + Assert.That(noMatchCount, Is.EqualTo(0)); + } + + [Test] + public void IfType_WithResult_Should_Return_Value_When_Type_Matches() + { + var obj = new TestClass { Name = "Test" }; + + var result = obj.IfType(x => x.Name); + + Assert.That(result, Is.EqualTo("Test")); + } + + [Test] + public void IfType_WithResult_Should_Return_Default_When_Type_Does_Not_Match() + { + var obj = new TestClass(); + + var result = obj.IfType(x => x); + + Assert.That(result, Is.Null); + } + + [Test] + public void As_Should_Return_Instance_When_Type_Matches() + { + var obj = new TestClass(); + + var result = obj.As(); + + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.SameAs(obj)); + } + + [Test] + public void As_Should_Return_Null_When_Type_Does_Not_Match() + { + var obj = new TestClass(); + + var result = obj.As(); + + Assert.That(result, Is.Null); + } + + [Test] + public void Do_Should_Execute_Action_And_Return_Object() + { + var obj = new TestClass { Value = 5 }; + + var result = obj.Do(x => x.Value = 10); + + Assert.That(result, Is.SameAs(obj)); + Assert.That(obj.Value, Is.EqualTo(10)); + } + + [Test] + public void Do_Should_Support_Chaining() + { + var obj = new TestClass { Value = 1, Name = "A" }; + + obj.Do(x => x.Value = 2) + .Do(x => x.Name = "B"); + + Assert.That(obj.Value, Is.EqualTo(2)); + Assert.That(obj.Name, Is.EqualTo("B")); + } + + [Test] + public void SwitchType_Should_Execute_Matching_Handler() + { + var obj = new TestClass(); + var executed = false; + + obj.SwitchType( + (typeof(TestClass), _ => { executed = true; }), + (typeof(string), _ => { Assert.Fail("Should not execute"); }) + ); + + Assert.That(executed, Is.True); + } + + [Test] + public void SwitchType_Should_Execute_First_Matching_Handler() + { + var obj = new TestClass(); + var count = 0; + + obj.SwitchType( + (typeof(TestClass), _ => { count++; }), + (typeof(TestClass), _ => { count++; }) + ); + + Assert.That(count, Is.EqualTo(1)); + } + + [Test] + public void SwitchType_Should_Not_Execute_When_No_Match() + { + var obj = new TestClass(); + var executed = false; + + obj.SwitchType( + (typeof(string), _ => { executed = true; }), + (typeof(int), _ => { executed = true; }) + ); + + Assert.That(executed, Is.False); + } +} + +public class TestClass +{ + public int Value { get; set; } + public string Name { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/GFramework.Core.Tests/ioc/IocContainerTests.cs b/GFramework.Core.Tests/ioc/IocContainerTests.cs new file mode 100644 index 0000000..207a456 --- /dev/null +++ b/GFramework.Core.Tests/ioc/IocContainerTests.cs @@ -0,0 +1,262 @@ +using System.Reflection; +using GFramework.Core.ioc; +using GFramework.Core.logging; +using GFramework.Core.Tests.system; +using NUnit.Framework; + +namespace GFramework.Core.Tests.ioc; + +[TestFixture] +public class IocContainerTests +{ + [SetUp] + public void SetUp() + { + // 初始化 LoggerFactoryResolver 以支持 IocContainer + LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider(); + _container = new IocContainer(); + + // 直接初始化 logger 字段 + var loggerField = typeof(IocContainer).GetField("_logger", + BindingFlags.NonPublic | BindingFlags.Instance); + loggerField?.SetValue(_container, + LoggerFactoryResolver.Provider.CreateLogger(nameof(IocContainer))); + } + + private IocContainer _container = null!; + private readonly Dictionary _mockContextServices = new(); + + [Test] + public void RegisterSingleton_Should_Register_Instance() + { + var instance = new TestService(); + + Assert.DoesNotThrow(() => _container.RegisterSingleton(instance)); + } + + [Test] + public void RegisterSingleton_WithDuplicate_Should_ThrowInvalidOperationException() + { + var instance1 = new TestService(); + var instance2 = new TestService(); + + _container.RegisterSingleton(instance1); + + Assert.Throws(() => _container.RegisterSingleton(instance2)); + } + + [Test] + public void RegisterSingleton_AfterFreeze_Should_ThrowInvalidOperationException() + { + var instance = new TestService(); + _container.Freeze(); + + Assert.Throws(() => _container.RegisterSingleton(instance)); + } + + [Test] + public void RegisterPlurality_Should_Register_Instance_To_All_Types() + { + var instance = new TestService(); + + _container.RegisterPlurality(instance); + + Assert.That(_container.Contains(), Is.True); + Assert.That(_container.Contains(), Is.True); + } + + [Test] + public void RegisterPlurality_AfterFreeze_Should_ThrowInvalidOperationException() + { + var instance = new TestService(); + _container.Freeze(); + + Assert.Throws(() => _container.RegisterPlurality(instance)); + } + + [Test] + public void Register_Generic_Should_Register_Instance() + { + var instance = new TestService(); + + _container.Register(instance); + + Assert.That(_container.Contains(), Is.True); + } + + [Test] + public void Register_Generic_AfterFreeze_Should_ThrowInvalidOperationException() + { + var instance = new TestService(); + _container.Freeze(); + + Assert.Throws(() => _container.Register(instance)); + } + + [Test] + public void Register_Type_Should_Register_Instance() + { + var instance = new TestService(); + + _container.Register(typeof(TestService), instance); + + Assert.That(_container.Contains(), Is.True); + } + + [Test] + public void Get_Should_Return_First_Instance() + { + var instance = new TestService(); + _container.Register(instance); + + var result = _container.Get(); + + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.SameAs(instance)); + } + + [Test] + public void Get_WithNoInstances_Should_ReturnNull() + { + var result = _container.Get(); + + Assert.That(result, Is.Null); + } + + [Test] + public void GetRequired_Should_Return_Single_Instance() + { + var instance = new TestService(); + _container.Register(instance); + + var result = _container.GetRequired(); + + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.SameAs(instance)); + } + + [Test] + public void GetRequired_WithNoInstances_Should_ThrowInvalidOperationException() + { + Assert.Throws(() => _container.GetRequired()); + } + + [Test] + public void GetRequired_WithMultipleInstances_Should_ThrowInvalidOperationException() + { + _container.Register(new TestService()); + _container.Register(new TestService()); + + Assert.Throws(() => _container.GetRequired()); + } + + [Test] + public void GetAll_Should_Return_All_Instances() + { + var instance1 = new TestService(); + var instance2 = new TestService(); + + _container.Register(instance1); + _container.Register(instance2); + + var results = _container.GetAll(); + + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(results, Does.Contain(instance1)); + Assert.That(results, Does.Contain(instance2)); + } + + [Test] + public void GetAll_WithNoInstances_Should_Return_Empty_Array() + { + var results = _container.GetAll(); + + Assert.That(results.Count, Is.EqualTo(0)); + } + + [Test] + public void GetAllSorted_Should_Return_Sorted_Instances() + { + _container.Register(new TestService { Priority = 3 }); + _container.Register(new TestService { Priority = 1 }); + _container.Register(new TestService { Priority = 2 }); + + var results = _container.GetAllSorted((a, b) => a.Priority.CompareTo(b.Priority)); + + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(results[0].Priority, Is.EqualTo(1)); + Assert.That(results[1].Priority, Is.EqualTo(2)); + Assert.That(results[2].Priority, Is.EqualTo(3)); + } + + [Test] + public void Contains_WithExistingInstance_Should_ReturnTrue() + { + var instance = new TestService(); + _container.Register(instance); + + Assert.That(_container.Contains(), Is.True); + } + + [Test] + public void Contains_WithNoInstances_Should_ReturnFalse() + { + Assert.That(_container.Contains(), Is.False); + } + + [Test] + public void ContainsInstance_WithExistingInstance_Should_ReturnTrue() + { + var instance = new TestService(); + _container.Register(instance); + + Assert.That(_container.ContainsInstance(instance), Is.True); + } + + [Test] + public void ContainsInstance_WithNonExistingInstance_Should_ReturnFalse() + { + var instance = new TestService(); + + Assert.That(_container.ContainsInstance(instance), Is.False); + } + + [Test] + public void Clear_Should_Remove_All_Instances() + { + var instance = new TestService(); + _container.Register(instance); + + _container.Clear(); + + Assert.That(_container.Contains(), Is.False); + } + + [Test] + public void Freeze_Should_Prevent_Further_Registrations() + { + var instance1 = new TestService(); + _container.Register(instance1); + _container.Freeze(); + + var instance2 = new TestService(); + Assert.Throws(() => _container.Register(instance2)); + } + + [Test] + public void RegisterSystem_Should_Register_Instance() + { + var system = new TestSystem(); + + _container.RegisterSystem(system); + + Assert.That(_container.Contains(), Is.True); + } +} + +public interface IService; + +public sealed class TestService : IService +{ + public int Priority { get; set; } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/model/AsyncTestModel.cs b/GFramework.Core.Tests/model/AsyncTestModel.cs index 2d0e80d..700229f 100644 --- a/GFramework.Core.Tests/model/AsyncTestModel.cs +++ b/GFramework.Core.Tests/model/AsyncTestModel.cs @@ -1,4 +1,4 @@ -using GFramework.Core.Abstractions.architecture; +using GFramework.Core.Abstractions.architecture; using GFramework.Core.Abstractions.enums; using GFramework.Core.model; @@ -38,7 +38,7 @@ public sealed class AsyncTestModel : AbstractModel, IAsyncInitializable /// 处理架构阶段事件 /// /// 架构阶段枚举值 - public void OnArchitecturePhase(ArchitecturePhase phase) + public override void OnArchitecturePhase(ArchitecturePhase phase) { } diff --git a/GFramework.Core.Tests/model/TestModel.cs b/GFramework.Core.Tests/model/TestModel.cs index 26da6fa..59fc9ad 100644 --- a/GFramework.Core.Tests/model/TestModel.cs +++ b/GFramework.Core.Tests/model/TestModel.cs @@ -1,4 +1,4 @@ -using GFramework.Core.Abstractions.enums; +using GFramework.Core.Abstractions.enums; using GFramework.Core.model; namespace GFramework.Core.Tests.model; @@ -24,7 +24,7 @@ public sealed class TestModel : AbstractModel, ITestModel } - public void OnArchitecturePhase(ArchitecturePhase phase) + public override void OnArchitecturePhase(ArchitecturePhase phase) { } diff --git a/GFramework.Core.Tests/pool/ObjectPoolTests.cs b/GFramework.Core.Tests/pool/ObjectPoolTests.cs new file mode 100644 index 0000000..27c9449 --- /dev/null +++ b/GFramework.Core.Tests/pool/ObjectPoolTests.cs @@ -0,0 +1,131 @@ +using GFramework.Core.Abstractions.pool; +using GFramework.Core.pool; +using NUnit.Framework; + +namespace GFramework.Core.Tests.pool; + +[TestFixture] +public class ObjectPoolTests +{ + [SetUp] + public void SetUp() + { + _pool = new TestObjectPool(); + } + + private TestObjectPool _pool = null!; + + [Test] + public void Acquire_Should_Create_New_Object_When_Pool_Empty() + { + var obj = _pool.Acquire("test"); + + Assert.That(obj, Is.Not.Null); + Assert.That(obj.PoolKey, Is.EqualTo("test")); + Assert.That(obj.OnAcquireCalled, Is.True); + } + + [Test] + public void Acquire_Should_Return_Pooled_Object() + { + var obj1 = _pool.Acquire("test"); + obj1.TestValue = 100; + + _pool.Release("test", obj1); + + var obj2 = _pool.Acquire("test"); + + Assert.That(obj2, Is.SameAs(obj1)); + Assert.That(obj2.TestValue, Is.EqualTo(100)); + Assert.That(obj2.OnAcquireCalled, Is.True); + } + + [Test] + public void Release_Should_Call_OnRelease() + { + var obj = _pool.Acquire("test"); + + _pool.Release("test", obj); + + Assert.That(obj.OnReleaseCalled, Is.True); + } + + [Test] + public void Clear_Should_Destroy_All_Objects() + { + var obj1 = _pool.Acquire("key1"); + var obj2 = _pool.Acquire("key2"); + + _pool.Release("key1", obj1); + _pool.Release("key2", obj2); + + _pool.Clear(); + + Assert.That(obj1.OnPoolDestroyCalled, Is.True); + Assert.That(obj2.OnPoolDestroyCalled, Is.True); + } + + [Test] + public void Multiple_Pools_Should_Be_Independent() + { + var obj1 = _pool.Acquire("key1"); + var obj2 = _pool.Acquire("key2"); + + _pool.Release("key1", obj1); + + var obj3 = _pool.Acquire("key1"); + var obj4 = _pool.Acquire("key2"); + + Assert.That(obj3, Is.SameAs(obj1)); + Assert.That(obj4, Is.Not.SameAs(obj2)); + } + + [Test] + public void OnAcquire_Should_Be_Called_On_New_And_Pooled_Objects() + { + var obj1 = _pool.Acquire("test"); + Assert.That(obj1.OnAcquireCalled, Is.True); + + _pool.Release("test", obj1); + obj1.OnAcquireCalled = false; + + var obj2 = _pool.Acquire("test"); + Assert.That(obj2.OnAcquireCalled, Is.True); + } +} + +public class TestObjectPool : AbstractObjectPoolSystem +{ + protected override TestPoolableObject Create(string key) + { + return new TestPoolableObject { PoolKey = key }; + } + + protected override void OnInit() + { + } +} + +public class TestPoolableObject : IPoolableObject +{ + public string PoolKey { get; set; } = string.Empty; + public int TestValue { get; set; } + public bool OnAcquireCalled { get; set; } + public bool OnReleaseCalled { get; set; } + public bool OnPoolDestroyCalled { get; set; } + + public void OnAcquire() + { + OnAcquireCalled = true; + } + + public void OnRelease() + { + OnReleaseCalled = true; + } + + public void OnPoolDestroy() + { + OnPoolDestroyCalled = true; + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/property/BindablePropertyTests.cs b/GFramework.Core.Tests/property/BindablePropertyTests.cs new file mode 100644 index 0000000..c87b277 --- /dev/null +++ b/GFramework.Core.Tests/property/BindablePropertyTests.cs @@ -0,0 +1,133 @@ +using GFramework.Core.property; +using NUnit.Framework; + +namespace GFramework.Core.Tests.property; + +[TestFixture] +public class BindablePropertyTests +{ + [Test] + public void Value_Get_Should_Return_Default_Value() + { + var property = new BindableProperty(5); + + Assert.That(property.Value, Is.EqualTo(5)); + } + + [Test] + public void Value_Set_Should_Trigger_Event() + { + var property = new BindableProperty(); + var receivedValue = 0; + + property.Register(value => { receivedValue = value; }); + + property.Value = 42; + + Assert.That(receivedValue, Is.EqualTo(42)); + } + + [Test] + public void Value_Set_To_Same_Value_Should_Not_Trigger_Event() + { + var property = new BindableProperty(5); + var count = 0; + + property.Register(_ => { count++; }); + + property.Value = 5; + + Assert.That(count, Is.EqualTo(0)); + } + + [Test] + public void UnRegister_Should_Remove_Handler() + { + var property = new BindableProperty(); + var count = 0; + + Action handler = _ => { count++; }; + property.Register(handler); + + property.Value = 1; + Assert.That(count, Is.EqualTo(1)); + + property.UnRegister(handler); + property.Value = 2; + Assert.That(count, Is.EqualTo(1)); + } + + [Test] + public void RegisterWithInitValue_Should_Call_Handler_Immediately() + { + var property = new BindableProperty(5); + var receivedValue = 0; + + property.RegisterWithInitValue(value => { receivedValue = value; }); + + Assert.That(receivedValue, Is.EqualTo(5)); + } + + [Test] + public void SetValueWithoutEvent_Should_Not_Trigger_Event() + { + var property = new BindableProperty(); + var count = 0; + + property.Register(_ => { count++; }); + + property.SetValueWithoutEvent(42); + + Assert.That(count, Is.EqualTo(0)); + Assert.That(property.Value, Is.EqualTo(42)); + } + + [Test] + public void WithComparer_Should_Use_Custom_Comparer() + { + var property = new BindableProperty("test").WithComparer((a, b) => a.Length == b.Length); + var count = 0; + + property.Register(_ => { count++; }); + + property.Value = "hello"; + + // "test" 和 "hello" 长度都是 4,所以不应该触发事件 + Assert.That(count, Is.EqualTo(0)); + } + + [Test] + public void Multiple_Handlers_Should_All_Be_Called() + { + var property = new BindableProperty(); + var count1 = 0; + var count2 = 0; + + property.Register(_ => { count1++; }); + property.Register(_ => { count2++; }); + + property.Value = 42; + + Assert.That(count1, Is.EqualTo(1)); + Assert.That(count2, Is.EqualTo(1)); + } + + [Test] + public void Register_Should_Return_IUnRegister() + { + var property = new BindableProperty(); + var unRegister = property.Register(_ => { }); + + Assert.That(unRegister, Is.Not.Null); + } + + [Test] + public void ToString_Should_Return_Value_As_String() + { + var property = new BindableProperty(42); + + var result = property.ToString(); + + Assert.That(result, Is.EqualTo("42")); + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/query/QueryBusTests.cs b/GFramework.Core.Tests/query/QueryBusTests.cs new file mode 100644 index 0000000..2efa95a --- /dev/null +++ b/GFramework.Core.Tests/query/QueryBusTests.cs @@ -0,0 +1,74 @@ +using GFramework.Core.Abstractions.query; +using GFramework.Core.query; +using NUnit.Framework; + +namespace GFramework.Core.Tests.query; + +[TestFixture] +public class QueryBusTests +{ + [SetUp] + public void SetUp() + { + _queryBus = new QueryBus(); + } + + private QueryBus _queryBus = null!; + + [Test] + public void Send_Should_Return_Query_Result() + { + var input = new TestQueryInput { Value = 10 }; + var query = new TestQuery(input); + + var result = _queryBus.Send(query); + + Assert.That(result, Is.EqualTo(20)); + } + + [Test] + public void Send_WithNullQuery_Should_ThrowArgumentNullException() + { + Assert.Throws(() => _queryBus.Send(null!)); + } + + [Test] + public void Send_WithStringResult_Should_Return_String() + { + var input = new TestQueryInput { Value = 5 }; + var query = new TestStringQuery(input); + + var result = _queryBus.Send(query); + + Assert.That(result, Is.EqualTo("Result: 10")); + } +} + +public sealed class TestQueryInput : IQueryInput +{ + public int Value { get; init; } +} + +public sealed class TestQuery : AbstractQuery +{ + public TestQuery(TestQueryInput input) : base(input) + { + } + + protected override int OnDo(TestQueryInput input) + { + return input.Value * 2; + } +} + +public sealed class TestStringQuery : AbstractQuery +{ + public TestStringQuery(TestQueryInput input) : base(input) + { + } + + protected override string OnDo(TestQueryInput input) + { + return $"Result: {input.Value * 2}"; + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/query/TestQuery.cs b/GFramework.Core.Tests/query/TestQuery.cs deleted file mode 100644 index 9dd62fc..0000000 --- a/GFramework.Core.Tests/query/TestQuery.cs +++ /dev/null @@ -1,28 +0,0 @@ -using GFramework.Core.Abstractions.query; -using GFramework.Core.extensions; -using GFramework.Core.query; -using GFramework.Core.Tests.model; - -namespace GFramework.Core.Tests.query; - -/// -/// 测试查询类,用于执行测试查询操作 -/// -/// 测试查询输入参数 -public class TestQuery(TestQueryInput input) : AbstractQuery(input) -{ - /// - /// 执行查询操作的重写方法 - /// - /// 测试查询输入参数 - /// 返回固定的整数值42 - protected override int OnDo(TestQueryInput input) - { - return this.GetModel()!.GetCurrentXp; - } -} - -/// -/// 测试查询输入类,实现查询输入接口 -/// -public sealed class TestQueryInput : IQueryInput; \ No newline at end of file diff --git a/GFramework.Core.Tests/tests/SyncArchitectureTests.cs b/GFramework.Core.Tests/tests/SyncArchitectureTests.cs index 0695be3..5fe0ed1 100644 --- a/GFramework.Core.Tests/tests/SyncArchitectureTests.cs +++ b/GFramework.Core.Tests/tests/SyncArchitectureTests.cs @@ -142,10 +142,10 @@ public class SyncArchitectureTests : ArchitectureTestsBase } /// - /// 测试事件是否能够被正确接收和处理 + /// 测试事件是否能够被正确接收和处理 /// /// - /// 该测试验证了事件系统的注册和发送功能,确保事件能够被正确传递给注册的处理器 + /// 该测试验证了事件系统的注册和发送功能,确保事件能够被正确传递给注册的处理器 /// [Test] public void Event_Should_Be_Received() @@ -168,10 +168,10 @@ public class SyncArchitectureTests : ArchitectureTestsBase } /// - /// 测试事件取消注册功能是否正常工作 + /// 测试事件取消注册功能是否正常工作 /// /// - /// 该测试验证了事件处理器的取消注册功能,确保取消注册后事件处理器不再被调用 + /// 该测试验证了事件处理器的取消注册功能,确保取消注册后事件处理器不再被调用 /// [Test] public void Event_UnRegister_Should_Work() diff --git a/GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj b/GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj index 073a052..3679072 100644 --- a/GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj +++ b/GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj @@ -3,7 +3,7 @@ enable enable - net8.0;net9.0;net10.0 + net10.0;net8.0