MessageBoxTests.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. using System.Text;
  2. using UICatalog;
  3. using UnitTests;
  4. using Xunit.Abstractions;
  5. namespace UnitTests.DialogTests;
  6. public class MessageBoxTests (ITestOutputHelper output)
  7. {
  8. [Fact]
  9. [AutoInitShutdown]
  10. public void KeyBindings_Enter_Causes_Focused_Button_Click_No_Accept ()
  11. {
  12. int result = -1;
  13. var iteration = 0;
  14. var btnAcceptCount = 0;
  15. Application.Iteration += OnApplicationOnIteration;
  16. Application.Run ().Dispose ();
  17. Application.Iteration -= OnApplicationOnIteration;
  18. Assert.Equal (1, result);
  19. Assert.Equal (1, btnAcceptCount);
  20. return;
  21. void OnApplicationOnIteration (object s, IterationEventArgs a)
  22. {
  23. iteration++;
  24. switch (iteration)
  25. {
  26. case 1:
  27. result = MessageBox.Query (string.Empty, string.Empty, 0, false, "btn0", "btn1");
  28. Application.RequestStop ();
  29. break;
  30. case 2:
  31. // Tab to btn2
  32. Application.RaiseKeyDownEvent (Key.Tab);
  33. var btn = Application.Navigation!.GetFocused () as Button;
  34. btn.Accepting += (sender, e) => { btnAcceptCount++; };
  35. // Click
  36. Application.RaiseKeyDownEvent (Key.Enter);
  37. break;
  38. default:
  39. Assert.Fail ();
  40. break;
  41. }
  42. }
  43. }
  44. [Fact]
  45. [AutoInitShutdown]
  46. public void KeyBindings_Esc_Closes ()
  47. {
  48. var result = 999;
  49. var iteration = 0;
  50. Application.Iteration += OnApplicationOnIteration;
  51. Application.Run ().Dispose ();
  52. Application.Iteration -= OnApplicationOnIteration;
  53. Assert.Equal (-1, result);
  54. return;
  55. void OnApplicationOnIteration (object s, IterationEventArgs a)
  56. {
  57. iteration++;
  58. switch (iteration)
  59. {
  60. case 1:
  61. result = MessageBox.Query (string.Empty, string.Empty, 0, false, "btn0", "btn1");
  62. Application.RequestStop ();
  63. break;
  64. case 2:
  65. Application.RaiseKeyDownEvent (Key.Esc);
  66. break;
  67. default:
  68. Assert.Fail ();
  69. break;
  70. }
  71. }
  72. }
  73. [Fact]
  74. [AutoInitShutdown]
  75. public void KeyBindings_Space_Causes_Focused_Button_Click_No_Accept ()
  76. {
  77. int result = -1;
  78. var iteration = 0;
  79. var btnAcceptCount = 0;
  80. Application.Iteration += OnApplicationOnIteration;
  81. Application.Run ().Dispose ();
  82. Application.Iteration -= OnApplicationOnIteration;
  83. Assert.Equal (1, result);
  84. Assert.Equal (1, btnAcceptCount);
  85. return;
  86. void OnApplicationOnIteration (object s, IterationEventArgs a)
  87. {
  88. iteration++;
  89. switch (iteration)
  90. {
  91. case 1:
  92. result = MessageBox.Query (string.Empty, string.Empty, 0, false, "btn0", "btn1");
  93. Application.RequestStop ();
  94. break;
  95. case 2:
  96. // Tab to btn2
  97. Application.RaiseKeyDownEvent (Key.Tab);
  98. var btn = Application.Navigation!.GetFocused () as Button;
  99. btn.Accepting += (sender, e) => { btnAcceptCount++; };
  100. Application.RaiseKeyDownEvent (Key.Space);
  101. break;
  102. default:
  103. Assert.Fail ();
  104. break;
  105. }
  106. }
  107. }
  108. [Theory]
  109. [InlineData (@"", false, false, 6, 6, 2, 2)]
  110. [InlineData (@"", false, true, 3, 6, 9, 3)]
  111. [InlineData (@"01234\n-----\n01234", false, false, 1, 6, 13, 3)]
  112. [InlineData (@"01234\n-----\n01234", true, false, 1, 5, 13, 4)]
  113. [InlineData (@"0123456789", false, false, 1, 6, 12, 3)]
  114. [InlineData (@"0123456789", false, true, 1, 5, 12, 4)]
  115. [InlineData (@"01234567890123456789", false, true, 1, 5, 13, 4)]
  116. [InlineData (@"01234567890123456789", true, true, 1, 5, 13, 5)]
  117. [InlineData (@"01234567890123456789\n01234567890123456789", false, true, 1, 5, 13, 4)]
  118. [InlineData (@"01234567890123456789\n01234567890123456789", true, true, 1, 4, 13, 7)]
  119. [AutoInitShutdown]
  120. public void Location_And_Size_Correct (string message, bool wrapMessage, bool hasButton, int expectedX, int expectedY, int expectedW, int expectedH)
  121. {
  122. int iterations = -1;
  123. Application.Driver!.SetScreenSize(15, 15); // 15 x 15 gives us enough room for a button with one char (9x1)
  124. Dialog.DefaultShadow = ShadowStyle.None;
  125. Button.DefaultShadow = ShadowStyle.None;
  126. var mbFrame = Rectangle.Empty;
  127. Application.Iteration += OnApplicationOnIteration;
  128. Application.Run ().Dispose ();
  129. Application.Iteration -= OnApplicationOnIteration;
  130. Assert.Equal (new (expectedX, expectedY, expectedW, expectedH), mbFrame);
  131. return;
  132. void OnApplicationOnIteration (object s, IterationEventArgs a)
  133. {
  134. iterations++;
  135. if (iterations == 0)
  136. {
  137. MessageBox.Query (string.Empty, message, 0, wrapMessage, hasButton ? ["0"] : []);
  138. Application.RequestStop ();
  139. }
  140. else if (iterations == 1)
  141. {
  142. mbFrame = Application.Running!.Frame;
  143. Application.RequestStop ();
  144. }
  145. }
  146. }
  147. [Fact]
  148. [AutoInitShutdown]
  149. public void Message_With_Spaces_WrapMessage_False ()
  150. {
  151. int iterations = -1;
  152. var top = new Toplevel ();
  153. top.BorderStyle = LineStyle.None;
  154. Application.Driver!.SetScreenSize(20, 10);
  155. var btn =
  156. $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} btn {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
  157. // Override CM
  158. MessageBox.DefaultButtonAlignment = Alignment.End;
  159. MessageBox.DefaultBorderStyle = LineStyle.Double;
  160. Dialog.DefaultShadow = ShadowStyle.None;
  161. Button.DefaultShadow = ShadowStyle.None;
  162. Application.Iteration += OnApplicationOnIteration;
  163. Application.Run (top);
  164. Application.Iteration -= OnApplicationOnIteration;
  165. top.Dispose ();
  166. return;
  167. void OnApplicationOnIteration (object s, IterationEventArgs a)
  168. {
  169. iterations++;
  170. if (iterations == 0)
  171. {
  172. var sb = new StringBuilder ();
  173. for (var i = 0; i < 17; i++)
  174. {
  175. sb.Append ("ff ");
  176. }
  177. MessageBox.Query (string.Empty, sb.ToString (), 0, false, "btn");
  178. Application.RequestStop ();
  179. }
  180. else if (iterations == 2)
  181. {
  182. DriverAssert.AssertDriverContentsWithFrameAre (
  183. @"
  184. ╔════════════════╗
  185. ║ ff ff ff ff ff ║
  186. ║ ⟦► btn ◄⟧║
  187. ╚════════════════╝",
  188. output);
  189. Application.RequestStop ();
  190. // Really long text
  191. MessageBox.Query (string.Empty, new ('f', 500), 0, false, "btn");
  192. }
  193. else if (iterations == 4)
  194. {
  195. DriverAssert.AssertDriverContentsWithFrameAre (
  196. @"
  197. ╔════════════════╗
  198. ║ffffffffffffffff║
  199. ║ ⟦► btn ◄⟧║
  200. ╚════════════════╝",
  201. output);
  202. Application.RequestStop ();
  203. }
  204. }
  205. }
  206. [Fact]
  207. [AutoInitShutdown]
  208. public void Message_With_Spaces_WrapMessage_True ()
  209. {
  210. int iterations = -1;
  211. var top = new Toplevel ();
  212. top.BorderStyle = LineStyle.None;
  213. Application.Driver!.SetScreenSize (20, 10);
  214. var btn =
  215. $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} btn {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
  216. // Override CM
  217. MessageBox.DefaultButtonAlignment = Alignment.End;
  218. MessageBox.DefaultBorderStyle = LineStyle.Double;
  219. Dialog.DefaultShadow = ShadowStyle.None;
  220. Button.DefaultShadow = ShadowStyle.None;
  221. Application.Iteration += OnApplicationOnIteration;
  222. Application.Run (top);
  223. Application.Iteration -= OnApplicationOnIteration;
  224. top.Dispose ();
  225. return;
  226. void OnApplicationOnIteration (object s, IterationEventArgs a)
  227. {
  228. iterations++;
  229. if (iterations == 0)
  230. {
  231. var sb = new StringBuilder ();
  232. for (var i = 0; i < 17; i++)
  233. {
  234. sb.Append ("ff ");
  235. }
  236. MessageBox.Query (string.Empty, sb.ToString (), 0, true, "btn");
  237. Application.RequestStop ();
  238. }
  239. else if (iterations == 2)
  240. {
  241. DriverAssert.AssertDriverContentsWithFrameAre (
  242. @"
  243. ╔══════════════╗
  244. ║ff ff ff ff ff║
  245. ║ff ff ff ff ff║
  246. ║ff ff ff ff ff║
  247. ║ ff ff ║
  248. ║ ⟦► btn ◄⟧║
  249. ╚══════════════╝",
  250. output);
  251. Application.RequestStop ();
  252. // Really long text
  253. MessageBox.Query (string.Empty, new ('f', 500), 0, true, "btn");
  254. }
  255. else if (iterations == 4)
  256. {
  257. DriverAssert.AssertDriverContentsWithFrameAre (
  258. @"
  259. ╔════════════════╗
  260. ║ffffffffffffffff║
  261. ║ffffffffffffffff║
  262. ║ffffffffffffffff║
  263. ║ffffffffffffffff║
  264. ║ffffffffffffffff║
  265. ║ffffffffffffffff║
  266. ║fffffff⟦► btn ◄⟧║
  267. ╚════════════════╝",
  268. output);
  269. Application.RequestStop ();
  270. }
  271. }
  272. }
  273. [Theory (Skip = "Bogus test: Never does anything")]
  274. [InlineData (0, 0, "1")]
  275. [InlineData (1, 1, "1")]
  276. [InlineData (7, 5, "1")]
  277. [InlineData (50, 50, "1")]
  278. [InlineData (0, 0, "message")]
  279. [InlineData (1, 1, "message")]
  280. [InlineData (7, 5, "message")]
  281. [InlineData (50, 50, "message")]
  282. [AutoInitShutdown]
  283. public void Size_Not_Default_Message (int height, int width, string message)
  284. {
  285. int iterations = -1;
  286. Application.Driver!.SetScreenSize(100, 100);
  287. Application.Iteration += (s, a) =>
  288. {
  289. iterations++;
  290. if (iterations == 0)
  291. {
  292. MessageBox.Query (height, width, string.Empty, message, null);
  293. Application.RequestStop ();
  294. }
  295. else if (iterations == 1)
  296. {
  297. AutoInitShutdownAttribute.RunIteration ();
  298. Assert.IsType<Dialog> (Application.Running);
  299. Assert.Equal (new (height, width), Application.Running.Frame.Size);
  300. Application.RequestStop ();
  301. }
  302. };
  303. }
  304. [Theory (Skip = "Bogus test: Never does anything")]
  305. [InlineData (0, 0, "1")]
  306. [InlineData (1, 1, "1")]
  307. [InlineData (7, 5, "1")]
  308. [InlineData (50, 50, "1")]
  309. [InlineData (0, 0, "message")]
  310. [InlineData (1, 1, "message")]
  311. [InlineData (7, 5, "message")]
  312. [InlineData (50, 50, "message")]
  313. [AutoInitShutdown]
  314. public void Size_Not_Default_Message_Button (int height, int width, string message)
  315. {
  316. int iterations = -1;
  317. Application.Driver?.SetScreenSize(100, 100);
  318. Application.Iteration += (s, a) =>
  319. {
  320. iterations++;
  321. if (iterations == 0)
  322. {
  323. MessageBox.Query (height, width, string.Empty, message, "_Ok");
  324. Application.RequestStop ();
  325. }
  326. else if (iterations == 1)
  327. {
  328. AutoInitShutdownAttribute.RunIteration ();
  329. Assert.IsType<Dialog> (Application.Running);
  330. Assert.Equal (new (height, width), Application.Running.Frame.Size);
  331. Application.RequestStop ();
  332. }
  333. };
  334. }
  335. [Theory (Skip = "Bogus test: Never does anything")]
  336. [InlineData (0, 0)]
  337. [InlineData (1, 1)]
  338. [InlineData (7, 5)]
  339. [InlineData (50, 50)]
  340. [AutoInitShutdown]
  341. public void Size_Not_Default_No_Message (int height, int width)
  342. {
  343. int iterations = -1;
  344. Application.Driver?.SetScreenSize(100, 100);
  345. Application.Iteration += (s, a) =>
  346. {
  347. iterations++;
  348. if (iterations == 0)
  349. {
  350. MessageBox.Query (height, width, string.Empty, string.Empty, null);
  351. Application.RequestStop ();
  352. }
  353. else if (iterations == 1)
  354. {
  355. AutoInitShutdownAttribute.RunIteration ();
  356. Assert.IsType<Dialog> (Application.Running);
  357. Assert.Equal (new (height, width), Application.Running.Frame.Size);
  358. Application.RequestStop ();
  359. }
  360. };
  361. }
  362. [Fact]
  363. [AutoInitShutdown]
  364. public void UICatalog_AboutBox ()
  365. {
  366. int iterations = -1;
  367. Application.Driver!.SetScreenSize (70, 15);
  368. // Override CM
  369. MessageBox.DefaultButtonAlignment = Alignment.End;
  370. MessageBox.DefaultBorderStyle = LineStyle.Double;
  371. Dialog.DefaultShadow = ShadowStyle.None;
  372. Button.DefaultShadow = ShadowStyle.None;
  373. Application.Iteration += OnApplicationOnIteration;
  374. var top = new Toplevel ();
  375. top.BorderStyle = LineStyle.Single;
  376. Application.Run (top);
  377. Application.Iteration -= OnApplicationOnIteration;
  378. top.Dispose ();
  379. return;
  380. void OnApplicationOnIteration (object s, IterationEventArgs a)
  381. {
  382. iterations++;
  383. if (iterations == 0)
  384. {
  385. MessageBox.Query (
  386. "",
  387. UICatalog.UICatalogTop.GetAboutBoxMessage (),
  388. wrapMessage: false,
  389. buttons: "_Ok");
  390. Application.RequestStop ();
  391. }
  392. else if (iterations == 2)
  393. {
  394. var expectedText = """
  395. ┌────────────────────────────────────────────────────────────────────┐
  396. │ ╔═══════════════════════════════════════════════════════════╗ │
  397. │ ║UI Catalog: A comprehensive sample library and test app for║ │
  398. │ ║ ║ │
  399. │ ║ _______ _ _ _____ _ ║ │
  400. │ ║|__ __| (_) | | / ____| (_) ║ │
  401. │ ║ | | ___ _ __ _ __ ___ _ _ __ __ _| || | __ _ _ _ ║ │
  402. │ ║ | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | | ║ │
  403. │ ║ | | __/ | | | | | | | | | | | (_| | || |__| | |_| | | ║ │
  404. │ ║ |_|\___|_| |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_| ║ │
  405. │ ║ ║ │
  406. │ ║ v2 - Pre-Alpha ║ │
  407. │ ║ ⟦► Ok ◄⟧║ │
  408. │ ╚═══════════════════════════════════════════════════════════╝ │
  409. └────────────────────────────────────────────────────────────────────┘
  410. """;
  411. DriverAssert.AssertDriverContentsAre (expectedText, output);
  412. Application.RequestStop ();
  413. }
  414. }
  415. }
  416. [Theory]
  417. [MemberData (nameof (AcceptingKeys))]
  418. [AutoInitShutdown]
  419. public void Button_IsDefault_True_Return_His_Index_On_Accepting (Key key)
  420. {
  421. Application.Iteration += OnApplicationOnIteration;
  422. int res = MessageBox.Query ("hey", "IsDefault", "Yes", "No");
  423. Application.Iteration -= OnApplicationOnIteration;
  424. Assert.Equal (0, res);
  425. return;
  426. void OnApplicationOnIteration (object o, IterationEventArgs iterationEventArgs) => Assert.True (Application.RaiseKeyDownEvent (key));
  427. }
  428. public static IEnumerable<object []> AcceptingKeys ()
  429. {
  430. yield return [Key.Enter];
  431. yield return [Key.Space];
  432. }
  433. }