ResultEventArgsTests.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. namespace ApplicationTests;
  2. public class ResultEventArgsTests
  3. {
  4. [Fact]
  5. public void DefaultConstructor_InitializesProperties ()
  6. {
  7. ResultEventArgs<string> args = new ();
  8. Assert.Null (args.Result);
  9. Assert.False (args.Handled);
  10. }
  11. [Fact]
  12. public void Constructor_WithResult_SetsResult ()
  13. {
  14. ResultEventArgs<int> args = new (42);
  15. Assert.Equal (42, args.Result);
  16. Assert.False (args.Handled);
  17. }
  18. [Fact]
  19. public void Constructor_WithNullResult_AllowsNull ()
  20. {
  21. ResultEventArgs<string?> args = new (null);
  22. Assert.Null (args.Result);
  23. Assert.False (args.Handled);
  24. }
  25. [Fact]
  26. public void Result_CanBeSetAndRetrieved ()
  27. {
  28. ResultEventArgs<string> args = new ();
  29. args.Result = "foo";
  30. Assert.Equal ("foo", args.Result);
  31. args.Result = null;
  32. Assert.Null (args.Result);
  33. }
  34. [Fact]
  35. public void Handled_CanBeSetAndRetrieved ()
  36. {
  37. ResultEventArgs<object> args = new ();
  38. Assert.False (args.Handled);
  39. args.Handled = true;
  40. Assert.True (args.Handled);
  41. args.Handled = false;
  42. Assert.False (args.Handled);
  43. }
  44. [Fact]
  45. public void WorksWithValueTypes ()
  46. {
  47. ResultEventArgs<int> args = new ();
  48. Assert.Equal (0, args.Result); // default(int) is 0
  49. args.Result = 123;
  50. Assert.Equal (123, args.Result);
  51. }
  52. [Fact]
  53. public void WorksWithReferenceTypes ()
  54. {
  55. var obj = new object ();
  56. ResultEventArgs<object> args = new (obj);
  57. Assert.Same (obj, args.Result);
  58. args.Result = null;
  59. Assert.Null (args.Result);
  60. }
  61. // Simulate an event pattern
  62. public event EventHandler<ResultEventArgs<string>>? StringResultEvent;
  63. [Fact]
  64. public void EventHandler_CanChangeResult_AndCallerSeesChange ()
  65. {
  66. // Arrange
  67. ResultEventArgs<string> args = new ("initial");
  68. StringResultEvent += (sender, e) =>
  69. {
  70. // Handler changes the result
  71. e.Result = "changed by handler";
  72. };
  73. // Act
  74. StringResultEvent?.Invoke (this, args);
  75. // Assert
  76. Assert.Equal ("changed by handler", args.Result);
  77. }
  78. [Fact]
  79. public void EventHandler_CanSetResultToNull ()
  80. {
  81. // Arrange
  82. ResultEventArgs<string> args = new ("not null");
  83. StringResultEvent += (sender, e) => { e.Result = null; };
  84. // Act
  85. StringResultEvent?.Invoke (this, args);
  86. // Assert
  87. Assert.Null (args.Result);
  88. }
  89. [Fact]
  90. public void MultipleHandlers_LastHandlerWins ()
  91. {
  92. // Arrange
  93. ResultEventArgs<int> args = new (1);
  94. EventHandler<ResultEventArgs<int>>? intEvent = null;
  95. intEvent += (s, e) => e.Result = 2;
  96. intEvent += (s, e) => e.Result = 3;
  97. // Act
  98. intEvent?.Invoke (this, args);
  99. // Assert
  100. Assert.Equal (3, args.Result);
  101. }
  102. // Value type: int
  103. [Fact]
  104. public void EventHandler_CanChangeResult_Int ()
  105. {
  106. EventHandler<ResultEventArgs<int>> handler = (s, e) => e.Result = 99;
  107. ResultEventArgs<int> args = new (1);
  108. handler.Invoke (this, args);
  109. Assert.Equal (99, args.Result);
  110. }
  111. // Value type: double
  112. [Fact]
  113. public void EventHandler_CanChangeResult_Double ()
  114. {
  115. EventHandler<ResultEventArgs<double>> handler = (s, e) => e.Result = 2.718;
  116. ResultEventArgs<double> args = new (3.14);
  117. handler.Invoke (this, args);
  118. Assert.Equal (2.718, args.Result);
  119. }
  120. // Value type: bool
  121. [Fact]
  122. public void EventHandler_CanChangeResult_Bool ()
  123. {
  124. EventHandler<ResultEventArgs<bool>> handler = (s, e) => e.Result = false;
  125. ResultEventArgs<bool> args = new (true);
  126. handler.Invoke (this, args);
  127. Assert.False (args.Result);
  128. }
  129. // Enum
  130. private enum MyEnum
  131. {
  132. A,
  133. B,
  134. C
  135. }
  136. [Fact]
  137. public void EventHandler_CanChangeResult_Enum ()
  138. {
  139. EventHandler<ResultEventArgs<MyEnum>> handler = (s, e) => e.Result = MyEnum.C;
  140. ResultEventArgs<MyEnum> args = new (MyEnum.A);
  141. handler.Invoke (this, args);
  142. Assert.Equal (MyEnum.C, args.Result);
  143. }
  144. // Struct
  145. private struct MyStruct
  146. {
  147. public int X;
  148. }
  149. [Fact]
  150. public void EventHandler_CanChangeResult_Struct ()
  151. {
  152. EventHandler<ResultEventArgs<MyStruct>> handler = (s, e) => e.Result = new() { X = 42 };
  153. ResultEventArgs<MyStruct> args = new (new() { X = 1 });
  154. handler.Invoke (this, args);
  155. Assert.Equal (42, args.Result.X);
  156. }
  157. // Reference type: string
  158. [Fact]
  159. public void EventHandler_CanChangeResult_String ()
  160. {
  161. EventHandler<ResultEventArgs<string>> handler = (s, e) => e.Result = "changed";
  162. ResultEventArgs<string> args = new ("original");
  163. handler.Invoke (this, args);
  164. Assert.Equal ("changed", args.Result);
  165. }
  166. // Reference type: object
  167. [Fact]
  168. public void EventHandler_CanChangeResult_Object ()
  169. {
  170. var newObj = new object ();
  171. EventHandler<ResultEventArgs<object>> handler = (s, e) => e.Result = newObj;
  172. ResultEventArgs<object> args = new (new ());
  173. handler.Invoke (this, args);
  174. Assert.Same (newObj, args.Result);
  175. }
  176. // Nullable value type
  177. [Fact]
  178. public void EventHandler_CanChangeResult_NullableInt ()
  179. {
  180. EventHandler<ResultEventArgs<int?>> handler = (s, e) => e.Result = null;
  181. ResultEventArgs<int?> args = new (42);
  182. handler.Invoke (this, args);
  183. Assert.Null (args.Result);
  184. }
  185. // Array
  186. [Fact]
  187. public void EventHandler_CanChangeResult_Array ()
  188. {
  189. var newArr = new [] { "x", "y" };
  190. EventHandler<ResultEventArgs<string []>> handler = (s, e) => e.Result = newArr;
  191. ResultEventArgs<string []> args = new (new [] { "a", "b" });
  192. handler.Invoke (this, args);
  193. Assert.Equal (newArr, args.Result);
  194. }
  195. // List<T>
  196. [Fact]
  197. public void EventHandler_CanChangeResult_List ()
  198. {
  199. List<int> newList = new() { 1, 2, 3 };
  200. EventHandler<ResultEventArgs<List<int>>> handler = (s, e) => e.Result = newList;
  201. ResultEventArgs<List<int>> args = new (new() { 9 });
  202. handler.Invoke (this, args);
  203. Assert.Equal (newList, args.Result);
  204. }
  205. // Dictionary<K,V>
  206. [Fact]
  207. public void EventHandler_CanChangeResult_Dictionary ()
  208. {
  209. Dictionary<string, int> newDict = new() { ["a"] = 1 };
  210. EventHandler<ResultEventArgs<Dictionary<string, int>>> handler = (s, e) => e.Result = newDict;
  211. ResultEventArgs<Dictionary<string, int>> args = new (new ());
  212. handler.Invoke (this, args);
  213. Assert.Equal (newDict, args.Result);
  214. }
  215. // Record
  216. public record MyRecord (int Id, string Name);
  217. [Fact]
  218. public void EventHandler_CanChangeResult_Record ()
  219. {
  220. var rec = new MyRecord (1, "foo");
  221. EventHandler<ResultEventArgs<MyRecord>> handler = (s, e) => e.Result = rec;
  222. ResultEventArgs<MyRecord> args = new (null);
  223. handler.Invoke (this, args);
  224. Assert.Equal (rec, args.Result);
  225. }
  226. // Nullable int
  227. [Fact]
  228. public void EventHandler_CanChangeResult_NullableInt_ToValue_AndNull ()
  229. {
  230. EventHandler<ResultEventArgs<int?>> handler = (s, e) => e.Result = 123;
  231. ResultEventArgs<int?> args = new (null);
  232. handler.Invoke (this, args);
  233. Assert.Equal (123, args.Result);
  234. handler = (s, e) => e.Result = null;
  235. args = new (456);
  236. handler.Invoke (this, args);
  237. Assert.Null (args.Result);
  238. }
  239. // Nullable double
  240. [Fact]
  241. public void EventHandler_CanChangeResult_NullableDouble_ToValue_AndNull ()
  242. {
  243. EventHandler<ResultEventArgs<double?>> handler = (s, e) => e.Result = 3.14;
  244. ResultEventArgs<double?> args = new (null);
  245. handler.Invoke (this, args);
  246. Assert.Equal (3.14, args.Result);
  247. handler = (s, e) => e.Result = null;
  248. args = new (2.71);
  249. handler.Invoke (this, args);
  250. Assert.Null (args.Result);
  251. }
  252. // Nullable custom struct
  253. [Fact]
  254. public void EventHandler_CanChangeResult_NullableStruct_ToValue_AndNull ()
  255. {
  256. EventHandler<ResultEventArgs<MyStruct?>> handler = (s, e) => e.Result = new MyStruct { X = 7 };
  257. ResultEventArgs<MyStruct?> args = new (null);
  258. handler.Invoke (this, args);
  259. Assert.Equal (7, args.Result?.X);
  260. handler = (s, e) => e.Result = null;
  261. args = new (new MyStruct { X = 8 });
  262. handler.Invoke (this, args);
  263. Assert.Null (args.Result);
  264. }
  265. // Nullable string (reference type)
  266. [Fact]
  267. public void EventHandler_CanChangeResult_NullableString_ToValue_AndNull ()
  268. {
  269. EventHandler<ResultEventArgs<string?>> handler = (s, e) => e.Result = "hello";
  270. ResultEventArgs<string?> args = new (null);
  271. handler.Invoke (this, args);
  272. Assert.Equal ("hello", args.Result);
  273. handler = (s, e) => e.Result = null;
  274. args = new ("world");
  275. handler.Invoke (this, args);
  276. Assert.Null (args.Result);
  277. }
  278. // Nullable custom class
  279. private class MyClass
  280. {
  281. public int Y { get; set; }
  282. }
  283. [Fact]
  284. public void EventHandler_CanChangeResult_NullableClass_ToValue_AndNull ()
  285. {
  286. EventHandler<ResultEventArgs<MyClass?>> handler = (s, e) => e.Result = new() { Y = 42 };
  287. ResultEventArgs<MyClass?> args = new (null);
  288. handler.Invoke (this, args);
  289. Assert.NotNull (args.Result);
  290. Assert.Equal (42, args.Result?.Y);
  291. handler = (s, e) => e.Result = null;
  292. args = new (new() { Y = 99 });
  293. handler.Invoke (this, args);
  294. Assert.Null (args.Result);
  295. }
  296. }