MessageBoxTests.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. using System.Text;
  2. using Xunit;
  3. using Xunit.Abstractions;
  4. namespace Terminal.Gui.DialogTests;
  5. public class MessageBoxTests {
  6. readonly ITestOutputHelper _output;
  7. public MessageBoxTests (ITestOutputHelper output) => _output = output;
  8. [Fact]
  9. [AutoInitShutdown]
  10. public void Size_Default ()
  11. {
  12. var iterations = -1;
  13. Application.Begin (Application.Top);
  14. ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
  15. Application.Iteration += (s, a) => {
  16. iterations++;
  17. if (iterations == 0) {
  18. MessageBox.Query (string.Empty, string.Empty, null);
  19. Application.RequestStop ();
  20. } else if (iterations == 1) {
  21. Application.Refresh ();
  22. Assert.IsType<Dialog> (Application.Current);
  23. // Default size is Percent(60)
  24. Assert.Equal (new Size ((int)(100 * .60), 5), Application.Current.Frame.Size);
  25. Application.RequestStop ();
  26. }
  27. };
  28. Application.Run ();
  29. }
  30. [Fact]
  31. [AutoInitShutdown]
  32. public void Location_Default ()
  33. {
  34. var iterations = -1;
  35. Application.Begin (Application.Top);
  36. ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
  37. Application.Iteration += (s, a) => {
  38. iterations++;
  39. if (iterations == 0) {
  40. MessageBox.Query (string.Empty, string.Empty, null);
  41. Application.RequestStop ();
  42. } else if (iterations == 1) {
  43. Application.Refresh ();
  44. Assert.IsType<Dialog> (Application.Current);
  45. // Default location is centered, so
  46. // X = (100 / 2) - (60 / 2) = 20
  47. // Y = (100 / 2) - (5 / 2) = 47
  48. Assert.Equal (new Point (20, 47), Application.Current.Frame.Location);
  49. Application.RequestStop ();
  50. }
  51. };
  52. Application.Run ();
  53. }
  54. [Theory]
  55. [InlineData (0, 0)]
  56. [InlineData (1, 1)]
  57. [InlineData (7, 5)]
  58. [InlineData (50, 50)]
  59. [AutoInitShutdown]
  60. public void Size_Not_Default_No_Message (int height, int width)
  61. {
  62. var iterations = -1;
  63. Application.Begin (Application.Top);
  64. ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
  65. Application.Iteration += (s, a) => {
  66. iterations++;
  67. if (iterations == 0) {
  68. MessageBox.Query (height, width, string.Empty, string.Empty, null);
  69. Application.RequestStop ();
  70. } else if (iterations == 1) {
  71. Application.Refresh ();
  72. Assert.IsType<Dialog> (Application.Current);
  73. Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
  74. Application.RequestStop ();
  75. }
  76. };
  77. }
  78. [Theory]
  79. [InlineData (0, 0, "1")]
  80. [InlineData (1, 1, "1")]
  81. [InlineData (7, 5, "1")]
  82. [InlineData (50, 50, "1")]
  83. [InlineData (0, 0, "message")]
  84. [InlineData (1, 1, "message")]
  85. [InlineData (7, 5, "message")]
  86. [InlineData (50, 50, "message")]
  87. [AutoInitShutdown]
  88. public void Size_Not_Default_Message (int height, int width, string message)
  89. {
  90. var iterations = -1;
  91. Application.Begin (Application.Top);
  92. ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
  93. Application.Iteration += (s, a) => {
  94. iterations++;
  95. if (iterations == 0) {
  96. MessageBox.Query (height, width, string.Empty, message, null);
  97. Application.RequestStop ();
  98. } else if (iterations == 1) {
  99. Application.Refresh ();
  100. Assert.IsType<Dialog> (Application.Current);
  101. Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
  102. Application.RequestStop ();
  103. }
  104. };
  105. }
  106. [Theory]
  107. [InlineData (0, 0, "1")]
  108. [InlineData (1, 1, "1")]
  109. [InlineData (7, 5, "1")]
  110. [InlineData (50, 50, "1")]
  111. [InlineData (0, 0, "message")]
  112. [InlineData (1, 1, "message")]
  113. [InlineData (7, 5, "message")]
  114. [InlineData (50, 50, "message")]
  115. [AutoInitShutdown]
  116. public void Size_Not_Default_Message_Button (int height, int width, string message)
  117. {
  118. var iterations = -1;
  119. Application.Begin (Application.Top);
  120. ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
  121. Application.Iteration += (s, a) => {
  122. iterations++;
  123. if (iterations == 0) {
  124. MessageBox.Query (height, width, string.Empty, message, "_Ok");
  125. Application.RequestStop ();
  126. } else if (iterations == 1) {
  127. Application.Refresh ();
  128. Assert.IsType<Dialog> (Application.Current);
  129. Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
  130. Application.RequestStop ();
  131. }
  132. };
  133. }
  134. [Fact]
  135. [AutoInitShutdown]
  136. public void Size_None_No_Buttons ()
  137. {
  138. var iterations = -1;
  139. Application.Begin (Application.Top);
  140. Application.Iteration += (s, a) => {
  141. iterations++;
  142. if (iterations == 0) {
  143. MessageBox.Query ("Title", "Message");
  144. Application.RequestStop ();
  145. } else if (iterations == 1) {
  146. Application.Refresh ();
  147. TestHelpers.AssertDriverContentsWithFrameAre (@"
  148. ┌┤Title├───────────────────────────────────────┐
  149. │ Message │
  150. │ │
  151. │ │
  152. └──────────────────────────────────────────────┘
  153. ", _output);
  154. Application.RequestStop ();
  155. }
  156. };
  157. Application.Run ();
  158. }
  159. [Fact]
  160. [AutoInitShutdown]
  161. public void Size_No_With_Button ()
  162. {
  163. Application.Top.BorderStyle = LineStyle.Double;
  164. var iterations = -1;
  165. Application.Begin (Application.Top);
  166. var aboutMessage = new StringBuilder ();
  167. aboutMessage.AppendLine (@"0123456789012345678901234567890123456789");
  168. aboutMessage.AppendLine (@"https://github.com/gui-cs/Terminal.Gui");
  169. var message = aboutMessage.ToString ();
  170. var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
  171. ((FakeDriver)Application.Driver).SetBufferSize (40 + 4, 8);
  172. Application.Iteration += (s, a) => {
  173. iterations++;
  174. if (iterations == 0) {
  175. MessageBox.Query (string.Empty, message, "_Ok");
  176. Application.RequestStop ();
  177. } else if (iterations == 1) {
  178. Application.Refresh ();
  179. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  180. ╔══════════════════════════════════════════╗
  181. ║┌────────────────────────────────────────┐║
  182. ║│0123456789012345678901234567890123456789│║
  183. ║│ https://github.com/gui-cs/Terminal.Gui │║
  184. ║│ │║
  185. ║│ {btn} │║
  186. ║└────────────────────────────────────────┘║
  187. ╚══════════════════════════════════════════╝
  188. ", _output);
  189. Application.RequestStop ();
  190. }
  191. };
  192. Application.Run ();
  193. }
  194. [Fact]
  195. [AutoInitShutdown]
  196. public void Size_Tiny_Fixed_Size ()
  197. {
  198. var iterations = -1;
  199. Application.Begin (Application.Top);
  200. Application.Iteration += (s, a) => {
  201. iterations++;
  202. if (iterations == 0) {
  203. MessageBox.Query (7, 5, string.Empty, "Message", "_Ok");
  204. Application.RequestStop ();
  205. } else if (iterations == 1) {
  206. Application.Refresh ();
  207. Assert.Equal (new Size (7, 5), Application.Current.Frame.Size);
  208. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  209. ┌─────┐
  210. │Messa│
  211. │ ge │
  212. │ Ok {CM.Glyphs.RightDefaultIndicator}│
  213. └─────┘
  214. ", _output);
  215. Application.RequestStop ();
  216. }
  217. };
  218. Application.Run ();
  219. }
  220. [Fact]
  221. [AutoInitShutdown]
  222. public void Size_JustBigEnough_Fixed_Size ()
  223. {
  224. var iterations = -1;
  225. Application.Begin (Application.Top);
  226. var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
  227. Application.Iteration += (s, a) => {
  228. iterations++;
  229. if (iterations == 0) {
  230. MessageBox.Query (11, 5, string.Empty, "Message", "_Ok");
  231. Application.RequestStop ();
  232. } else if (iterations == 1) {
  233. Application.Refresh ();
  234. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  235. ┌─────────┐
  236. │ Message │
  237. │ │
  238. │{btn} │
  239. └─────────┘
  240. ", _output);
  241. Application.RequestStop ();
  242. }
  243. };
  244. Application.Run ();
  245. }
  246. [Fact]
  247. [AutoInitShutdown]
  248. public void Message_Long_Without_Spaces_WrapMessage_True ()
  249. {
  250. var iterations = -1;
  251. Application.Begin (Application.Top);
  252. Application.Top.BorderStyle = LineStyle.Double;
  253. ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
  254. var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
  255. Application.Iteration += (s, a) => {
  256. iterations++;
  257. if (iterations == 0) {
  258. // 50 characters should make the height of the wrapped text 7
  259. MessageBox.Query (string.Empty, new string ('f', 50), 0, true, "btn");
  260. Application.RequestStop ();
  261. } else if (iterations == 1) {
  262. Application.Refresh ();
  263. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  264. ╔══════════════════╗
  265. ║┌────────────────┐║
  266. ║│ffffffffffffffff│║
  267. ║│ffffffffffffffff│║
  268. ║│ffffffffffffffff│║
  269. ║│ ff │║
  270. ║│ │║
  271. ║│ {btn} │║
  272. ║└────────────────┘║
  273. ╚══════════════════╝", _output);
  274. Assert.Equal (new Size (20 - 2, 10 - 2), Application.Current.Frame.Size);
  275. Application.RequestStop ();
  276. // Really long text
  277. MessageBox.Query (string.Empty, new string ('f', 500), 0, true, "btn");
  278. } else if (iterations == 2) {
  279. Application.Refresh ();
  280. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  281. ╔┌────────────────┐╗
  282. ║│ffffffffffffffff│║
  283. ║│ffffffffffffffff│║
  284. ║│ffffffffffffffff│║
  285. ║│ffffffffffffffff│║
  286. ║│ffffffffffffffff│║
  287. ║│ffffffffffffffff│║
  288. ║│ffffffffffffffff│║
  289. ║│ {btn} │║
  290. ╚└────────────────┘╝", _output);
  291. Application.RequestStop ();
  292. }
  293. };
  294. Application.Run ();
  295. }
  296. [Fact]
  297. [AutoInitShutdown]
  298. public void Message_With_Spaces_WrapMessage_True ()
  299. {
  300. var iterations = -1;
  301. Application.Begin (Application.Top);
  302. Application.Top.BorderStyle = LineStyle.Double;
  303. ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
  304. var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
  305. Application.Iteration += (s, a) => {
  306. iterations++;
  307. if (iterations == 0) {
  308. var sb = new StringBuilder ();
  309. for (var i = 0; i < 17; i++) {
  310. sb.Append ("ff ");
  311. }
  312. MessageBox.Query (string.Empty, sb.ToString (), 0, true, "btn");
  313. Application.RequestStop ();
  314. } else if (iterations == 1) {
  315. Application.Refresh ();
  316. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  317. ╔══════════════════╗
  318. ║ ┌──────────────┐ ║
  319. ║ │ff ff ff ff ff│ ║
  320. ║ │ff ff ff ff ff│ ║
  321. ║ │ff ff ff ff ff│ ║
  322. ║ │ ff ff │ ║
  323. ║ │ │ ║
  324. ║ │ {btn} │ ║
  325. ║ └──────────────┘ ║
  326. ╚══════════════════╝", _output);
  327. Application.RequestStop ();
  328. // Really long text
  329. MessageBox.Query (string.Empty, new string ('f', 500), 0, true, "btn");
  330. } else if (iterations == 2) {
  331. Application.Refresh ();
  332. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  333. ╔┌────────────────┐╗
  334. ║│ffffffffffffffff│║
  335. ║│ffffffffffffffff│║
  336. ║│ffffffffffffffff│║
  337. ║│ffffffffffffffff│║
  338. ║│ffffffffffffffff│║
  339. ║│ffffffffffffffff│║
  340. ║│ffffffffffffffff│║
  341. ║│ {btn} │║
  342. ╚└────────────────┘╝", _output);
  343. Application.RequestStop ();
  344. }
  345. };
  346. Application.Run ();
  347. }
  348. [Fact]
  349. [AutoInitShutdown]
  350. public void Message_Without_Spaces_WrapMessage_False ()
  351. {
  352. var iterations = -1;
  353. Application.Begin (Application.Top);
  354. Application.Top.BorderStyle = LineStyle.Double;
  355. ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
  356. var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
  357. Application.Iteration += (s, a) => {
  358. iterations++;
  359. if (iterations == 0) {
  360. MessageBox.Query (string.Empty, new string ('f', 50), 0, false, "btn");
  361. Application.RequestStop ();
  362. } else if (iterations == 1) {
  363. Application.Refresh ();
  364. TestHelpers.AssertDriverContentsWithFrameAre (@"
  365. ╔══════════════════╗
  366. ║ ║
  367. ────────────────────
  368. ffffffffffffffffffff
  369. ⟦► btn ◄⟧
  370. ────────────────────
  371. ║ ║
  372. ║ ║
  373. ╚══════════════════╝", _output);
  374. Application.RequestStop ();
  375. // Really long text
  376. MessageBox.Query (string.Empty, new string ('f', 500), 0, false, "btn");
  377. } else if (iterations == 2) {
  378. Application.Refresh ();
  379. TestHelpers.AssertDriverContentsWithFrameAre (@"
  380. ╔══════════════════╗
  381. ║ ║
  382. ────────────────────
  383. ffffffffffffffffffff
  384. ⟦► btn ◄⟧
  385. ────────────────────
  386. ║ ║
  387. ║ ║
  388. ╚══════════════════╝", _output);
  389. Application.RequestStop ();
  390. }
  391. };
  392. Application.Run ();
  393. }
  394. [Fact]
  395. [AutoInitShutdown]
  396. public void Message_With_Spaces_WrapMessage_False ()
  397. {
  398. var iterations = -1;
  399. Application.Begin (Application.Top);
  400. Application.Top.BorderStyle = LineStyle.Double;
  401. ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
  402. var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
  403. Application.Iteration += (s, a) => {
  404. iterations++;
  405. if (iterations == 0) {
  406. var sb = new StringBuilder ();
  407. for (var i = 0; i < 17; i++) {
  408. sb.Append ("ff ");
  409. }
  410. MessageBox.Query (string.Empty, sb.ToString (), 0, false, "btn");
  411. Application.RequestStop ();
  412. } else if (iterations == 1) {
  413. Application.Refresh ();
  414. TestHelpers.AssertDriverContentsWithFrameAre (@"
  415. ╔══════════════════╗
  416. ║ ║
  417. ────────────────────
  418. ff ff ff ff ff ff ff
  419. ⟦► btn ◄⟧
  420. ────────────────────
  421. ║ ║
  422. ║ ║
  423. ╚══════════════════╝", _output);
  424. Application.RequestStop ();
  425. // Really long text
  426. MessageBox.Query (string.Empty, new string ('f', 500), 0, false, "btn");
  427. } else if (iterations == 2) {
  428. Application.Refresh ();
  429. TestHelpers.AssertDriverContentsWithFrameAre (@"
  430. ╔══════════════════╗
  431. ║ ║
  432. ────────────────────
  433. ffffffffffffffffffff
  434. ⟦► btn ◄⟧
  435. ────────────────────
  436. ║ ║
  437. ║ ║
  438. ╚══════════════════╝", _output);
  439. Application.RequestStop ();
  440. }
  441. };
  442. Application.Run ();
  443. }
  444. [Theory]
  445. [AutoInitShutdown]
  446. [InlineData (" ", true, 1)]
  447. [InlineData (" ", false, 1)]
  448. [InlineData ("", true, 1)]
  449. [InlineData ("", false, 1)]
  450. [InlineData ("\n", true, 1)]
  451. [InlineData ("\n", false, 1)]
  452. [InlineData (" \n", true, 1)]
  453. [InlineData (" \n", false, 2)]
  454. public void Message_Empty_Or_A_NewLline_WrapMessagge_True_Or_False (string message, bool wrapMessage, int linesLength)
  455. {
  456. var iterations = -1;
  457. Application.Begin (Application.Top);
  458. Application.Iteration += (s, a) => {
  459. iterations++;
  460. if (iterations == 0) {
  461. MessageBox.Query (string.Empty, message, 0, wrapMessage, "ok");
  462. Application.RequestStop ();
  463. } else if (iterations == 1) {
  464. Application.Refresh ();
  465. if (linesLength == 1) {
  466. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  467. ┌──────────────────────────────────────────────┐
  468. │ │
  469. │ │
  470. │ {CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket} │
  471. └──────────────────────────────────────────────┘", _output);
  472. } else {
  473. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  474. ┌──────────────────────────────────────────────┐
  475. │ │
  476. │ │
  477. │ │
  478. │ {CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket} │
  479. └──────────────────────────────────────────────┘", _output);
  480. }
  481. Application.RequestStop ();
  482. }
  483. };
  484. Application.Run ();
  485. }
  486. [Fact]
  487. [AutoInitShutdown]
  488. public void KeyBindings_Esc_Closes ()
  489. {
  490. Application.Begin (Application.Top);
  491. var result = 999;
  492. var iteration = 0;
  493. Application.Iteration += (s, a) => {
  494. iteration++;
  495. switch (iteration) {
  496. case 1:
  497. result = MessageBox.Query (title: string.Empty, message: string.Empty, defaultButton: 0, wrapMessage: false, "btn0", "btn1");
  498. Application.RequestStop ();
  499. break;
  500. case 2:
  501. Application.OnKeyDown (Key.Esc);
  502. break;
  503. default:
  504. Assert.Fail ();
  505. break;
  506. }
  507. };
  508. Application.Run ();
  509. Assert.Equal (-1, result);
  510. }
  511. [Fact]
  512. [AutoInitShutdown]
  513. public void KeyBindings_Enter_Causes_Focused_Button_Click ()
  514. {
  515. Application.Begin (Application.Top);
  516. var result = -1;
  517. var iteration = 0;
  518. Application.Iteration += (s, a) => {
  519. iteration++;
  520. switch (iteration) {
  521. case 1:
  522. result = MessageBox.Query (title: string.Empty, message: string.Empty, defaultButton: 0, wrapMessage: false, "btn0", "btn1");
  523. Application.RequestStop ();
  524. break;
  525. case 2:
  526. // Tab to btn2
  527. Application.OnKeyDown (Key.Tab);
  528. Application.OnKeyDown (Key.Enter);
  529. break;
  530. default:
  531. Assert.Fail ();
  532. break;
  533. }
  534. };
  535. Application.Run ();
  536. Assert.Equal (1, result);
  537. }
  538. [Fact]
  539. [AutoInitShutdown]
  540. public void KeyBindings_Space_Causes_Focused_Button_Click ()
  541. {
  542. Application.Begin (Application.Top);
  543. var result = -1;
  544. var iteration = 0;
  545. Application.Iteration += (s, a) => {
  546. iteration++;
  547. switch (iteration) {
  548. case 1:
  549. result = MessageBox.Query (title: string.Empty, message: string.Empty, defaultButton: 0, wrapMessage: false, "btn0", "btn1");
  550. Application.RequestStop ();
  551. break;
  552. case 2:
  553. // Tab to btn2
  554. Application.OnKeyDown (Key.Tab);
  555. Application.OnKeyDown (Key.Space);
  556. break;
  557. default:
  558. Assert.Fail ();
  559. break;
  560. }
  561. };
  562. Application.Run ();
  563. Assert.Equal (1, result);
  564. }
  565. }