namespace ApplicationTests; public class ResultEventArgsTests { [Fact] public void DefaultConstructor_InitializesProperties () { ResultEventArgs args = new (); Assert.Null (args.Result); Assert.False (args.Handled); } [Fact] public void Constructor_WithResult_SetsResult () { ResultEventArgs args = new (42); Assert.Equal (42, args.Result); Assert.False (args.Handled); } [Fact] public void Constructor_WithNullResult_AllowsNull () { ResultEventArgs args = new (null); Assert.Null (args.Result); Assert.False (args.Handled); } [Fact] public void Result_CanBeSetAndRetrieved () { ResultEventArgs args = new (); args.Result = "foo"; Assert.Equal ("foo", args.Result); args.Result = null; Assert.Null (args.Result); } [Fact] public void Handled_CanBeSetAndRetrieved () { ResultEventArgs args = new (); Assert.False (args.Handled); args.Handled = true; Assert.True (args.Handled); args.Handled = false; Assert.False (args.Handled); } [Fact] public void WorksWithValueTypes () { ResultEventArgs args = new (); Assert.Equal (0, args.Result); // default(int) is 0 args.Result = 123; Assert.Equal (123, args.Result); } [Fact] public void WorksWithReferenceTypes () { var obj = new object (); ResultEventArgs args = new (obj); Assert.Same (obj, args.Result); args.Result = null; Assert.Null (args.Result); } // Simulate an event pattern public event EventHandler>? StringResultEvent; [Fact] public void EventHandler_CanChangeResult_AndCallerSeesChange () { // Arrange ResultEventArgs args = new ("initial"); StringResultEvent += (sender, e) => { // Handler changes the result e.Result = "changed by handler"; }; // Act StringResultEvent?.Invoke (this, args); // Assert Assert.Equal ("changed by handler", args.Result); } [Fact] public void EventHandler_CanSetResultToNull () { // Arrange ResultEventArgs args = new ("not null"); StringResultEvent += (sender, e) => { e.Result = null; }; // Act StringResultEvent?.Invoke (this, args); // Assert Assert.Null (args.Result); } [Fact] public void MultipleHandlers_LastHandlerWins () { // Arrange ResultEventArgs args = new (1); EventHandler>? intEvent = null; intEvent += (s, e) => e.Result = 2; intEvent += (s, e) => e.Result = 3; // Act intEvent?.Invoke (this, args); // Assert Assert.Equal (3, args.Result); } // Value type: int [Fact] public void EventHandler_CanChangeResult_Int () { EventHandler> handler = (s, e) => e.Result = 99; ResultEventArgs args = new (1); handler.Invoke (this, args); Assert.Equal (99, args.Result); } // Value type: double [Fact] public void EventHandler_CanChangeResult_Double () { EventHandler> handler = (s, e) => e.Result = 2.718; ResultEventArgs args = new (3.14); handler.Invoke (this, args); Assert.Equal (2.718, args.Result); } // Value type: bool [Fact] public void EventHandler_CanChangeResult_Bool () { EventHandler> handler = (s, e) => e.Result = false; ResultEventArgs args = new (true); handler.Invoke (this, args); Assert.False (args.Result); } // Enum private enum MyEnum { A, B, C } [Fact] public void EventHandler_CanChangeResult_Enum () { EventHandler> handler = (s, e) => e.Result = MyEnum.C; ResultEventArgs args = new (MyEnum.A); handler.Invoke (this, args); Assert.Equal (MyEnum.C, args.Result); } // Struct private struct MyStruct { public int X; } [Fact] public void EventHandler_CanChangeResult_Struct () { EventHandler> handler = (s, e) => e.Result = new() { X = 42 }; ResultEventArgs args = new (new() { X = 1 }); handler.Invoke (this, args); Assert.Equal (42, args.Result.X); } // Reference type: string [Fact] public void EventHandler_CanChangeResult_String () { EventHandler> handler = (s, e) => e.Result = "changed"; ResultEventArgs args = new ("original"); handler.Invoke (this, args); Assert.Equal ("changed", args.Result); } // Reference type: object [Fact] public void EventHandler_CanChangeResult_Object () { var newObj = new object (); EventHandler> handler = (s, e) => e.Result = newObj; ResultEventArgs args = new (new ()); handler.Invoke (this, args); Assert.Same (newObj, args.Result); } // Nullable value type [Fact] public void EventHandler_CanChangeResult_NullableInt () { EventHandler> handler = (s, e) => e.Result = null; ResultEventArgs args = new (42); handler.Invoke (this, args); Assert.Null (args.Result); } // Array [Fact] public void EventHandler_CanChangeResult_Array () { var newArr = new [] { "x", "y" }; EventHandler> handler = (s, e) => e.Result = newArr; ResultEventArgs args = new (new [] { "a", "b" }); handler.Invoke (this, args); Assert.Equal (newArr, args.Result); } // List [Fact] public void EventHandler_CanChangeResult_List () { List newList = new() { 1, 2, 3 }; EventHandler>> handler = (s, e) => e.Result = newList; ResultEventArgs> args = new (new() { 9 }); handler.Invoke (this, args); Assert.Equal (newList, args.Result); } // Dictionary [Fact] public void EventHandler_CanChangeResult_Dictionary () { Dictionary newDict = new() { ["a"] = 1 }; EventHandler>> handler = (s, e) => e.Result = newDict; ResultEventArgs> args = new (new ()); handler.Invoke (this, args); Assert.Equal (newDict, args.Result); } // Record public record MyRecord (int Id, string Name); [Fact] public void EventHandler_CanChangeResult_Record () { var rec = new MyRecord (1, "foo"); EventHandler> handler = (s, e) => e.Result = rec; ResultEventArgs args = new (null); handler.Invoke (this, args); Assert.Equal (rec, args.Result); } // Nullable int [Fact] public void EventHandler_CanChangeResult_NullableInt_ToValue_AndNull () { EventHandler> handler = (s, e) => e.Result = 123; ResultEventArgs args = new (null); handler.Invoke (this, args); Assert.Equal (123, args.Result); handler = (s, e) => e.Result = null; args = new (456); handler.Invoke (this, args); Assert.Null (args.Result); } // Nullable double [Fact] public void EventHandler_CanChangeResult_NullableDouble_ToValue_AndNull () { EventHandler> handler = (s, e) => e.Result = 3.14; ResultEventArgs args = new (null); handler.Invoke (this, args); Assert.Equal (3.14, args.Result); handler = (s, e) => e.Result = null; args = new (2.71); handler.Invoke (this, args); Assert.Null (args.Result); } // Nullable custom struct [Fact] public void EventHandler_CanChangeResult_NullableStruct_ToValue_AndNull () { EventHandler> handler = (s, e) => e.Result = new MyStruct { X = 7 }; ResultEventArgs args = new (null); handler.Invoke (this, args); Assert.Equal (7, args.Result?.X); handler = (s, e) => e.Result = null; args = new (new MyStruct { X = 8 }); handler.Invoke (this, args); Assert.Null (args.Result); } // Nullable string (reference type) [Fact] public void EventHandler_CanChangeResult_NullableString_ToValue_AndNull () { EventHandler> handler = (s, e) => e.Result = "hello"; ResultEventArgs args = new (null); handler.Invoke (this, args); Assert.Equal ("hello", args.Result); handler = (s, e) => e.Result = null; args = new ("world"); handler.Invoke (this, args); Assert.Null (args.Result); } // Nullable custom class private class MyClass { public int Y { get; set; } } [Fact] public void EventHandler_CanChangeResult_NullableClass_ToValue_AndNull () { EventHandler> handler = (s, e) => e.Result = new() { Y = 42 }; ResultEventArgs args = new (null); handler.Invoke (this, args); Assert.NotNull (args.Result); Assert.Equal (42, args.Result?.Y); handler = (s, e) => e.Result = null; args = new (new() { Y = 99 }); handler.Invoke (this, args); Assert.Null (args.Result); } }