MessageBoxTests.cs 22 KB

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