MessageBoxTests.cs 21 KB

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