ButtonTests.cs 19 KB

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