ButtonTests.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. using System;
  2. using Xunit;
  3. using Xunit.Abstractions;
  4. namespace Terminal.Gui.ViewTests {
  5. public class ButtonTests {
  6. readonly ITestOutputHelper output;
  7. public ButtonTests (ITestOutputHelper output)
  8. {
  9. this.output = output;
  10. }
  11. [Fact, AutoInitShutdown]
  12. public void Constructors_Defaults ()
  13. {
  14. var btn = new Button ();
  15. Assert.Equal (string.Empty, btn.Text);
  16. var top = Application.Top;
  17. top.Add (btn);
  18. var rs = Application.Begin (top);
  19. Assert.Equal ("[ ]", btn.TextFormatter.Text);
  20. Assert.False (btn.IsDefault);
  21. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  22. Assert.Equal ('_', btn.HotKeySpecifier);
  23. Assert.True (btn.CanFocus);
  24. Assert.Equal (new Rect (0, 0, 4, 1), btn.Frame);
  25. Assert.Equal (Key.Null, btn.HotKey);
  26. var expected = @"
  27. [ ]
  28. ";
  29. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  30. Application.End (rs);
  31. btn = new Button ("ARGS", true) { Text = "Test" };
  32. Assert.Equal ("Test", btn.Text);
  33. top.Add (btn);
  34. rs = Application.Begin (top);
  35. Assert.Equal ("[◦ Test ◦]", btn.TextFormatter.Text);
  36. Assert.True (btn.IsDefault);
  37. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  38. Assert.Equal ('_', btn.HotKeySpecifier);
  39. Assert.True (btn.CanFocus);
  40. Assert.Equal (new Rect (0, 0, 10, 1), btn.Frame);
  41. Assert.Equal (Key.T, btn.HotKey);
  42. expected = @"
  43. [◦ Test ◦]
  44. ";
  45. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  46. Application.End (rs);
  47. btn = new Button (3, 4, "Test", true);
  48. Assert.Equal ("Test", btn.Text);
  49. top.Add (btn);
  50. rs = Application.Begin (top);
  51. Assert.Equal ("[◦ Test ◦]", btn.TextFormatter.Text);
  52. Assert.True (btn.IsDefault);
  53. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  54. Assert.Equal ('_', btn.HotKeySpecifier);
  55. Assert.True (btn.CanFocus);
  56. Assert.Equal (new Rect (3, 4, 10, 1), btn.Frame);
  57. Assert.Equal (Key.T, btn.HotKey);
  58. expected = @"
  59. [◦ Test ◦]
  60. ";
  61. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  62. Application.End (rs);
  63. }
  64. [Fact]
  65. [AutoInitShutdown]
  66. public void KeyBindings_Command ()
  67. {
  68. var clicked = false;
  69. Button btn = new Button ("Test");
  70. btn.Clicked += () => clicked = true;
  71. Application.Top.Add (btn);
  72. Application.Begin (Application.Top);
  73. Assert.Equal (Key.T, btn.HotKey);
  74. Assert.False (btn.ProcessHotKey (new KeyEvent (Key.T, new KeyModifiers ())));
  75. Assert.False (clicked);
  76. Assert.True (btn.ProcessHotKey (new KeyEvent (Key.T | Key.AltMask, new KeyModifiers () { Alt = true })));
  77. Assert.True (clicked);
  78. clicked = false;
  79. Assert.False (btn.IsDefault);
  80. Assert.False (btn.ProcessColdKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  81. Assert.False (clicked);
  82. btn.IsDefault = true;
  83. Assert.True (btn.ProcessColdKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  84. Assert.True (clicked);
  85. clicked = false;
  86. Assert.True (btn.ProcessColdKey (new KeyEvent (Key.AltMask | Key.T, new KeyModifiers ())));
  87. Assert.True (clicked);
  88. clicked = false;
  89. Assert.True (btn.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  90. Assert.True (clicked);
  91. clicked = false;
  92. Assert.True (btn.ProcessKey (new KeyEvent (Key.Space, new KeyModifiers ())));
  93. Assert.True (clicked);
  94. clicked = false;
  95. Assert.True (btn.ProcessKey (new KeyEvent ((Key)'t', new KeyModifiers ())));
  96. Assert.True (clicked);
  97. clicked = false;
  98. Assert.True (btn.ProcessKey (new KeyEvent (Key.Space | btn.HotKey, new KeyModifiers ())));
  99. Assert.True (clicked);
  100. btn.Text = "Te_st";
  101. clicked = false;
  102. Assert.True (btn.ProcessKey (new KeyEvent (Key.Space | btn.HotKey, new KeyModifiers ())));
  103. Assert.True (clicked);
  104. }
  105. [Fact]
  106. [AutoInitShutdown]
  107. public void ChangeHotKey ()
  108. {
  109. var clicked = false;
  110. Button btn = new Button ("Test");
  111. btn.Clicked += () => clicked = true;
  112. Application.Top.Add (btn);
  113. Application.Begin (Application.Top);
  114. Assert.Equal (Key.T, btn.HotKey);
  115. Assert.False (btn.ProcessHotKey (new KeyEvent (Key.T, new KeyModifiers ())));
  116. Assert.False (clicked);
  117. Assert.True (btn.ProcessHotKey (new KeyEvent (Key.T | Key.AltMask, new KeyModifiers () { Alt = true })));
  118. Assert.True (clicked);
  119. clicked = false;
  120. btn.HotKey = Key.E;
  121. Assert.True (btn.ProcessHotKey (new KeyEvent (Key.E | Key.AltMask, new KeyModifiers () { Alt = true })));
  122. Assert.True (clicked);
  123. }
  124. /// <summary>
  125. /// This test demonstrates how to change the activation key for Button
  126. /// as described in the README.md keyboard handling section
  127. /// </summary>
  128. [Fact]
  129. [AutoInitShutdown]
  130. public void KeyBindingExample ()
  131. {
  132. int pressed = 0;
  133. var btn = new Button ("Press Me");
  134. btn.Clicked += () => pressed++;
  135. // The Button class supports the Accept command
  136. Assert.Contains (Command.Accept, btn.GetSupportedCommands ());
  137. Application.Top.Add (btn);
  138. Application.Begin (Application.Top);
  139. // default keybinding is Enter which results in keypress
  140. Application.Driver.SendKeys ('\n', ConsoleKey.Enter, false, false, false);
  141. Assert.Equal (1, pressed);
  142. // remove the default keybinding (Enter)
  143. btn.ClearKeybinding (Command.Accept);
  144. // After clearing the default keystroke the Enter button no longer does anything for the Button
  145. Application.Driver.SendKeys ('\n', ConsoleKey.Enter, false, false, false);
  146. Assert.Equal (1, pressed);
  147. // Set a new binding of b for the click (Accept) event
  148. btn.AddKeyBinding (Key.b, Command.Accept);
  149. // now pressing B should call the button click event
  150. Application.Driver.SendKeys ('b', ConsoleKey.B, false, false, false);
  151. Assert.Equal (2, pressed);
  152. }
  153. [Fact]
  154. public void TestAssignTextToButton ()
  155. {
  156. View b = new Button () { Text = "heya" };
  157. Assert.Equal ("heya", b.Text);
  158. Assert.True (b.TextFormatter.Text.Contains ("heya"));
  159. b.Text = "heyb";
  160. Assert.Equal ("heyb", b.Text);
  161. Assert.True (b.TextFormatter.Text.Contains ("heyb"));
  162. // with cast
  163. Assert.Equal ("heyb", ((Button)b).Text);
  164. }
  165. [Fact]
  166. public void Setting_Empty_Text_Sets_HoKey_To_KeyNull ()
  167. {
  168. var btn = new Button ("Test");
  169. Assert.Equal ("Test", btn.Text);
  170. Assert.Equal (Key.T, btn.HotKey);
  171. btn.Text = string.Empty;
  172. Assert.Equal ("", btn.Text);
  173. Assert.Equal (Key.Null, btn.HotKey);
  174. btn.Text = "Te_st";
  175. Assert.Equal ("Te_st", btn.Text);
  176. Assert.Equal (Key.S, btn.HotKey);
  177. }
  178. [Fact, AutoInitShutdown]
  179. public void Update_Only_On_Or_After_Initialize ()
  180. {
  181. var btn = new Button ("Say Hello 你") {
  182. X = Pos.Center (),
  183. Y = Pos.Center ()
  184. };
  185. var win = new Window ("Test Demo 你") {
  186. Width = Dim.Fill (),
  187. Height = Dim.Fill ()
  188. };
  189. win.Add (btn);
  190. Application.Top.Add (win);
  191. Assert.False (btn.IsInitialized);
  192. Application.Begin (Application.Top);
  193. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  194. Assert.True (btn.IsInitialized);
  195. Assert.Equal ("Say Hello 你", btn.Text);
  196. Assert.Equal ("[ Say Hello 你 ]", btn.TextFormatter.Text);
  197. Assert.Equal (new Rect (0, 0, 16, 1), btn.Bounds);
  198. var expected = @"
  199. ┌ Test Demo 你 ──────────────┐
  200. │ │
  201. │ [ Say Hello 你 ] │
  202. │ │
  203. └────────────────────────────┘
  204. ";
  205. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  206. Assert.Equal (new Rect (0, 0, 30, 5), pos);
  207. }
  208. [Fact, AutoInitShutdown]
  209. public void Update_Parameterless_Only_On_Or_After_Initialize ()
  210. {
  211. var btn = new Button () {
  212. X = Pos.Center (),
  213. Y = Pos.Center (),
  214. Text = "Say Hello 你"
  215. };
  216. var win = new Window () {
  217. Width = Dim.Fill (),
  218. Height = Dim.Fill (),
  219. Title = "Test Demo 你"
  220. };
  221. win.Add (btn);
  222. Application.Top.Add (win);
  223. Assert.False (btn.IsInitialized);
  224. Application.Begin (Application.Top);
  225. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  226. Assert.True (btn.IsInitialized);
  227. Assert.Equal ("Say Hello 你", btn.Text);
  228. Assert.Equal ("[ Say Hello 你 ]", btn.TextFormatter.Text);
  229. Assert.Equal (new Rect (0, 0, 16, 1), btn.Bounds);
  230. var expected = @"
  231. ┌ Test Demo 你 ──────────────┐
  232. │ │
  233. │ [ Say Hello 你 ] │
  234. │ │
  235. └────────────────────────────┘
  236. ";
  237. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  238. Assert.Equal (new Rect (0, 0, 30, 5), pos);
  239. }
  240. [Fact, AutoInitShutdown]
  241. public void AutoSize_Stays_True_With_EmptyText ()
  242. {
  243. var btn = new Button () {
  244. X = Pos.Center (),
  245. Y = Pos.Center (),
  246. AutoSize = true
  247. };
  248. var win = new Window () {
  249. Width = Dim.Fill (),
  250. Height = Dim.Fill (),
  251. Title = "Test Demo 你"
  252. };
  253. win.Add (btn);
  254. Application.Top.Add (win);
  255. Assert.True (btn.AutoSize);
  256. btn.Text = "Say Hello 你";
  257. Assert.True (btn.AutoSize);
  258. Application.Begin (Application.Top);
  259. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  260. var expected = @"
  261. ┌ Test Demo 你 ──────────────┐
  262. │ │
  263. │ [ Say Hello 你 ] │
  264. │ │
  265. └────────────────────────────┘
  266. ";
  267. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  268. }
  269. [Fact, AutoInitShutdown]
  270. public void AutoSize_Stays_True_Center ()
  271. {
  272. var btn = new Button () {
  273. X = Pos.Center (),
  274. Y = Pos.Center (),
  275. Text = "Say Hello 你"
  276. };
  277. var win = new Window () {
  278. Width = Dim.Fill (),
  279. Height = Dim.Fill (),
  280. Title = "Test Demo 你"
  281. };
  282. win.Add (btn);
  283. Application.Top.Add (win);
  284. Assert.True (btn.AutoSize);
  285. Application.Begin (Application.Top);
  286. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  287. var expected = @"
  288. ┌ Test Demo 你 ──────────────┐
  289. │ │
  290. │ [ Say Hello 你 ] │
  291. │ │
  292. └────────────────────────────┘
  293. ";
  294. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  295. Assert.True (btn.AutoSize);
  296. btn.Text = "Say Hello 你 changed";
  297. Assert.True (btn.AutoSize);
  298. Application.Refresh ();
  299. expected = @"
  300. ┌ Test Demo 你 ──────────────┐
  301. │ │
  302. │ [ Say Hello 你 changed ] │
  303. │ │
  304. └────────────────────────────┘
  305. ";
  306. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  307. }
  308. [Fact, AutoInitShutdown]
  309. public void AutoSize_Stays_True_AnchorEnd ()
  310. {
  311. var btn = new Button () {
  312. Y = Pos.Center (),
  313. Text = "Say Hello 你",
  314. AutoSize = true
  315. };
  316. btn.X = Pos.AnchorEnd () - Pos.Function (() => TextFormatter.GetTextWidth (btn.TextFormatter.Text));
  317. var win = new Window () {
  318. Width = Dim.Fill (),
  319. Height = Dim.Fill (),
  320. Title = "Test Demo 你"
  321. };
  322. win.Add (btn);
  323. Application.Top.Add (win);
  324. Assert.True (btn.AutoSize);
  325. Application.Begin (Application.Top);
  326. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  327. var expected = @"
  328. ┌ Test Demo 你 ──────────────┐
  329. │ │
  330. │ [ Say Hello 你 ]│
  331. │ │
  332. └────────────────────────────┘
  333. ";
  334. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  335. Assert.True (btn.AutoSize);
  336. btn.Text = "Say Hello 你 changed";
  337. Assert.True (btn.AutoSize);
  338. Application.Refresh ();
  339. expected = @"
  340. ┌ Test Demo 你 ──────────────┐
  341. │ │
  342. │ [ Say Hello 你 changed ]│
  343. │ │
  344. └────────────────────────────┘
  345. ";
  346. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  347. }
  348. [Fact, AutoInitShutdown]
  349. public void AutoSize_False_With_Fixed_Width ()
  350. {
  351. var tab = new View ();
  352. var lblWidth = 8;
  353. var label = new Label ("Find:") {
  354. Y = 1,
  355. Width = lblWidth,
  356. TextAlignment = TextAlignment.Right,
  357. AutoSize = false
  358. };
  359. tab.Add (label);
  360. var txtToFind = new TextField ("Testing buttons.") {
  361. X = Pos.Right (label) + 1,
  362. Y = Pos.Top (label),
  363. Width = 20
  364. };
  365. tab.Add (txtToFind);
  366. var btnFindNext = new Button ("Find _Next") {
  367. X = Pos.Right (txtToFind) + 1,
  368. Y = Pos.Top (label),
  369. Width = 20,
  370. Enabled = !txtToFind.Text.IsEmpty,
  371. TextAlignment = TextAlignment.Centered,
  372. IsDefault = true,
  373. AutoSize = false
  374. };
  375. tab.Add (btnFindNext);
  376. var btnFindPrevious = new Button ("Find _Previous") {
  377. X = Pos.Right (txtToFind) + 1,
  378. Y = Pos.Top (btnFindNext) + 1,
  379. Width = 20,
  380. Enabled = !txtToFind.Text.IsEmpty,
  381. TextAlignment = TextAlignment.Centered,
  382. AutoSize = false
  383. };
  384. tab.Add (btnFindPrevious);
  385. var btnCancel = new Button ("Cancel") {
  386. X = Pos.Right (txtToFind) + 1,
  387. Y = Pos.Top (btnFindPrevious) + 2,
  388. Width = 20,
  389. TextAlignment = TextAlignment.Centered,
  390. AutoSize = false
  391. };
  392. tab.Add (btnCancel);
  393. var ckbMatchCase = new CheckBox ("Match c_ase") {
  394. X = 0,
  395. Y = Pos.Top (txtToFind) + 2,
  396. Checked = true
  397. };
  398. tab.Add (ckbMatchCase);
  399. var ckbMatchWholeWord = new CheckBox ("Match _whole word") {
  400. X = 0,
  401. Y = Pos.Top (ckbMatchCase) + 1,
  402. Checked = false
  403. };
  404. tab.Add (ckbMatchWholeWord);
  405. var tabView = new TabView () {
  406. Width = Dim.Fill (),
  407. Height = Dim.Fill ()
  408. };
  409. tabView.AddTab (new TabView.Tab ("Find", tab), true);
  410. var win = new Window ("Find") {
  411. Width = Dim.Fill (),
  412. Height = Dim.Fill ()
  413. };
  414. tab.Width = label.Width + txtToFind.Width + btnFindNext.Width + 2;
  415. tab.Height = btnFindNext.Height + btnFindPrevious.Height + btnCancel.Height + 4;
  416. win.Add (tabView);
  417. Application.Top.Add (win);
  418. Application.Begin (Application.Top);
  419. ((FakeDriver)Application.Driver).SetBufferSize (54, 11);
  420. Assert.Equal (new Rect (0, 0, 54, 11), win.Frame);
  421. Assert.Equal (new Rect (0, 0, 52, 9), tabView.Frame);
  422. Assert.Equal (new Rect (0, 0, 50, 7), tab.Frame);
  423. Assert.Equal (new Rect (0, 1, 8, 1), label.Frame);
  424. Assert.Equal (new Rect (9, 1, 20, 1), txtToFind.Frame);
  425. Assert.Equal (0, txtToFind.ScrollOffset);
  426. Assert.Equal (16, txtToFind.CursorPosition);
  427. Assert.Equal (new Rect (30, 1, 20, 1), btnFindNext.Frame);
  428. Assert.Equal (new Rect (30, 2, 20, 1), btnFindPrevious.Frame);
  429. Assert.Equal (new Rect (30, 4, 20, 1), btnCancel.Frame);
  430. Assert.Equal (new Rect (0, 3, 12, 1), ckbMatchCase.Frame);
  431. Assert.Equal (new Rect (0, 4, 18, 1), ckbMatchWholeWord.Frame);
  432. var expected = @"
  433. ┌ Find ──────────────────────────────────────────────┐
  434. │┌────┐ │
  435. ││Find│ │
  436. ││ └─────────────────────────────────────────────┐│
  437. ││ ││
  438. ││ Find: Testing buttons. [◦ Find Next ◦] ││
  439. ││ [ Find Previous ] ││
  440. ││√ Match case ││
  441. ││╴ Match whole word [ Cancel ] ││
  442. │└──────────────────────────────────────────────────┘│
  443. └────────────────────────────────────────────────────┘
  444. ";
  445. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  446. }
  447. [Fact, AutoInitShutdown]
  448. public void Pos_Center_Layout_AutoSize_True ()
  449. {
  450. var button = new Button ("Process keys") {
  451. X = Pos.Center (),
  452. Y = Pos.Center (),
  453. IsDefault = true
  454. };
  455. var win = new Window () {
  456. Width = Dim.Fill (),
  457. Height = Dim.Fill ()
  458. };
  459. win.Add (button);
  460. Application.Top.Add (win);
  461. Application.Begin (Application.Top);
  462. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  463. Assert.True (button.AutoSize);
  464. Assert.Equal (new Rect (5, 1, 18, 1), button.Frame);
  465. var expected = @"
  466. ┌────────────────────────────┐
  467. │ │
  468. │ [◦ Process keys ◦] │
  469. │ │
  470. └────────────────────────────┘
  471. ";
  472. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  473. }
  474. [Fact, AutoInitShutdown]
  475. public void Pos_Center_Layout_AutoSize_False ()
  476. {
  477. var button = new Button ("Process keys") {
  478. X = Pos.Center (),
  479. Y = Pos.Center (),
  480. Width = 20,
  481. IsDefault = true,
  482. AutoSize = false
  483. };
  484. var win = new Window () {
  485. Width = Dim.Fill (),
  486. Height = Dim.Fill ()
  487. };
  488. win.Add (button);
  489. Application.Top.Add (win);
  490. Application.Begin (Application.Top);
  491. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  492. Assert.False (button.AutoSize);
  493. Assert.Equal (new Rect (4, 1, 20, 1), button.Frame);
  494. var expected = @"
  495. ┌────────────────────────────┐
  496. │ │
  497. │ [◦ Process keys ◦] │
  498. │ │
  499. └────────────────────────────┘
  500. ";
  501. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  502. }
  503. [Fact, AutoInitShutdown]
  504. public void IsDefault_True_Does_Not_Get_The_Focus_On_Enter_Key ()
  505. {
  506. var wasClicked = false;
  507. var view = new View { CanFocus = true };
  508. var btn = new Button { Text = "Ok", IsDefault = true };
  509. btn.Clicked += () => wasClicked = true;
  510. Application.Top.Add (view, btn);
  511. Application.Begin (Application.Top);
  512. Assert.True (view.HasFocus);
  513. Application.Top.ProcessColdKey (new KeyEvent (Key.Enter, new KeyModifiers ()));
  514. Assert.True (view.HasFocus);
  515. Assert.True (wasClicked);
  516. }
  517. }
  518. }