ButtonTests.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. using System.ComponentModel;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class ButtonTests
  5. {
  6. private readonly ITestOutputHelper _output;
  7. public ButtonTests (ITestOutputHelper output) { _output = output; }
  8. // Test that Title and Text are the same
  9. [Fact]
  10. public void Text_Mirrors_Title ()
  11. {
  12. var view = new Button ();
  13. view.Title = "Hello";
  14. Assert.Equal ("Hello", view.Title);
  15. Assert.Equal ($"Hello", view.TitleTextFormatter.Text);
  16. Assert.Equal ("Hello", view.Text);
  17. Assert.Equal ($"{CM.Glyphs.LeftBracket} Hello {CM.Glyphs.RightBracket}", view.TextFormatter.Text);
  18. }
  19. [Fact]
  20. public void Title_Mirrors_Text ()
  21. {
  22. var view = new Button ();
  23. view.Text = "Hello";
  24. Assert.Equal ("Hello", view.Text);
  25. Assert.Equal ($"{CM.Glyphs.LeftBracket} Hello {CM.Glyphs.RightBracket}", view.TextFormatter.Text);
  26. Assert.Equal ("Hello", view.Title);
  27. Assert.Equal ($"Hello", view.TitleTextFormatter.Text);
  28. }
  29. // BUGBUG: This test is NOT a unit test and needs to be broken apart into
  30. // more specific tests (e.g. it tests Checkbox as well as Button)
  31. [Fact]
  32. [AutoInitShutdown]
  33. public void AutoSize_False_With_Fixed_Width ()
  34. {
  35. var tab = new View ();
  36. var lblWidth = 8;
  37. var view = new View
  38. {
  39. Y = 1,
  40. Width = lblWidth,
  41. Height = 1,
  42. TextAlignment = TextAlignment.Right,
  43. Text = "Find:"
  44. };
  45. tab.Add (view);
  46. var txtToFind = new TextField
  47. {
  48. X = Pos.Right (view) + 1, Y = Pos.Top (view), Width = 20, Text = "Testing buttons."
  49. };
  50. tab.Add (txtToFind);
  51. var btnFindNext = new Button
  52. {
  53. AutoSize = false,
  54. X = Pos.Right (txtToFind) + 1,
  55. Y = Pos.Top (view),
  56. Width = 20,
  57. Enabled = !string.IsNullOrEmpty (txtToFind.Text),
  58. TextAlignment = TextAlignment.Centered,
  59. IsDefault = true,
  60. Text = "Find _Next"
  61. };
  62. tab.Add (btnFindNext);
  63. var btnFindPrevious = new Button
  64. {
  65. AutoSize = false,
  66. X = Pos.Right (txtToFind) + 1,
  67. Y = Pos.Top (btnFindNext) + 1,
  68. Width = 20,
  69. Enabled = !string.IsNullOrEmpty (txtToFind.Text),
  70. TextAlignment = TextAlignment.Centered,
  71. Text = "Find _Previous"
  72. };
  73. tab.Add (btnFindPrevious);
  74. var btnCancel = new Button
  75. {
  76. AutoSize = false,
  77. X = Pos.Right (txtToFind) + 1,
  78. Y = Pos.Top (btnFindPrevious) + 2,
  79. Width = 20,
  80. TextAlignment = TextAlignment.Centered,
  81. Text = "Cancel"
  82. };
  83. tab.Add (btnCancel);
  84. var ckbMatchCase = new CheckBox { X = 0, Y = Pos.Top (txtToFind) + 2, Checked = true, Text = "Match c_ase" };
  85. tab.Add (ckbMatchCase);
  86. var ckbMatchWholeWord = new CheckBox
  87. {
  88. X = 0, Y = Pos.Top (ckbMatchCase) + 1, Checked = false, Text = "Match _whole word"
  89. };
  90. tab.Add (ckbMatchWholeWord);
  91. var tabView = new TabView { Width = Dim.Fill (), Height = Dim.Fill () };
  92. tabView.AddTab (new Tab { DisplayText = "Find", View = tab }, true);
  93. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  94. tab.Width = view.Width + txtToFind.Width + btnFindNext.Width + 2;
  95. tab.Height = btnFindNext.Height + btnFindPrevious.Height + btnCancel.Height + 4;
  96. win.Add (tabView);
  97. var top = new Toplevel ();
  98. top.Add (win);
  99. Application.Begin (top);
  100. ((FakeDriver)Application.Driver).SetBufferSize (54, 11);
  101. Assert.Equal (new Rectangle (0, 0, 54, 11), win.Frame);
  102. Assert.Equal (new Rectangle (0, 0, 52, 9), tabView.Frame);
  103. Assert.Equal (new Rectangle (0, 0, 50, 7), tab.Frame);
  104. Assert.Equal (new Rectangle (0, 1, 8, 1), view.Frame);
  105. Assert.Equal (new Rectangle (9, 1, 20, 1), txtToFind.Frame);
  106. Assert.Equal (0, txtToFind.ScrollOffset);
  107. Assert.Equal (16, txtToFind.CursorPosition);
  108. Assert.Equal (new (30, 1, 20, 1), btnFindNext.Frame);
  109. Assert.Equal (new (30, 2, 20, 1), btnFindPrevious.Frame);
  110. Assert.Equal (new (30, 4, 20, 1), btnCancel.Frame);
  111. // Assert.Equal (new (0, 3, 12, 1), ckbMatchCase.Frame);
  112. // Assert.Equal (new (0, 4, 18, 1), ckbMatchWholeWord.Frame);
  113. var btn1 =
  114. $"{
  115. CM.Glyphs.LeftBracket
  116. }{
  117. CM.Glyphs.LeftDefaultIndicator
  118. } Find Next {
  119. CM.Glyphs.RightDefaultIndicator
  120. }{
  121. CM.Glyphs.RightBracket
  122. }";
  123. var btn2 = $"{CM.Glyphs.LeftBracket} Find Previous {CM.Glyphs.RightBracket}";
  124. var btn3 = $"{CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket}";
  125. var expected = @$"
  126. ┌────────────────────────────────────────────────────┐
  127. │╭────╮ │
  128. ││Find│ │
  129. ││ ╰─────────────────────────────────────────────╮│
  130. ││ ││
  131. ││ Find: Testing buttons. {
  132. btn1
  133. } ││
  134. ││ {
  135. btn2
  136. } ││
  137. ││{
  138. CM.Glyphs.Checked
  139. } Match case ││
  140. ││{
  141. CM.Glyphs.UnChecked
  142. } Match whole word {
  143. btn3
  144. } ││
  145. │└──────────────────────────────────────────────────┘│
  146. └────────────────────────────────────────────────────┘
  147. ";
  148. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  149. }
  150. [Fact]
  151. [AutoInitShutdown]
  152. public void AutoSize_Stays_True_AnchorEnd ()
  153. {
  154. var btn = new Button { Y = Pos.Center (), Text = "Say Hello 你", AutoSize = true };
  155. var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
  156. btn.X = Pos.AnchorEnd () - Pos.Function (() => btn.TextFormatter.Text.GetColumns ());
  157. btn.X = Pos.AnchorEnd () - Pos.Function (() => btn.TextFormatter.Text.GetColumns ());
  158. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  159. win.Add (btn);
  160. var top = new Toplevel ();
  161. top.Add (win);
  162. Assert.True (btn.AutoSize);
  163. Application.Begin (top);
  164. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  165. var expected = @$"
  166. ┌────────────────────────────┐
  167. │ │
  168. │ {
  169. btnTxt
  170. }│
  171. │ │
  172. └────────────────────────────┘
  173. ";
  174. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  175. Assert.True (btn.AutoSize);
  176. btn.Text = "Say Hello 你 changed";
  177. btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
  178. Assert.True (btn.AutoSize);
  179. Application.Refresh ();
  180. expected = @$"
  181. ┌────────────────────────────┐
  182. │ │
  183. │ {
  184. btnTxt
  185. }│
  186. │ │
  187. └────────────────────────────┘
  188. ";
  189. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  190. }
  191. [Fact]
  192. [AutoInitShutdown]
  193. public void AutoSize_Stays_True_Center ()
  194. {
  195. var btn = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" };
  196. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  197. win.Add (btn);
  198. var top = new Toplevel ();
  199. top.Add (win);
  200. Assert.True (btn.AutoSize);
  201. Application.Begin (top);
  202. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  203. var expected = @$"
  204. ┌────────────────────────────┐
  205. │ │
  206. │ {
  207. CM.Glyphs.LeftBracket
  208. } Say Hello 你 {
  209. CM.Glyphs.RightBracket
  210. } │
  211. │ │
  212. └────────────────────────────┘
  213. ";
  214. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  215. Assert.True (btn.AutoSize);
  216. btn.Text = "Say Hello 你 changed";
  217. Assert.True (btn.AutoSize);
  218. Application.Refresh ();
  219. expected = @$"
  220. ┌────────────────────────────┐
  221. │ │
  222. │ {
  223. CM.Glyphs.LeftBracket
  224. } Say Hello 你 changed {
  225. CM.Glyphs.RightBracket
  226. } │
  227. │ │
  228. └────────────────────────────┘
  229. ";
  230. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  231. }
  232. [Fact]
  233. [AutoInitShutdown]
  234. public void AutoSize_Stays_True_With_EmptyText ()
  235. {
  236. var btn = new Button { X = Pos.Center (), Y = Pos.Center (), AutoSize = true };
  237. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  238. win.Add (btn);
  239. var top = new Toplevel ();
  240. top.Add (win);
  241. Assert.True (btn.AutoSize);
  242. btn.Text = "Say Hello 你";
  243. Assert.True (btn.AutoSize);
  244. Application.Begin (top);
  245. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  246. var expected = @$"
  247. ┌────────────────────────────┐
  248. │ │
  249. │ {
  250. CM.Glyphs.LeftBracket
  251. } Say Hello 你 {
  252. CM.Glyphs.RightBracket
  253. } │
  254. │ │
  255. └────────────────────────────┘
  256. ";
  257. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  258. }
  259. [Fact]
  260. [SetupFakeDriver]
  261. public void Button_AutoSize_False_With_Fixed_Width ()
  262. {
  263. ((FakeDriver)Application.Driver).SetBufferSize (20, 5);
  264. var top = new View { Width = 20, Height = 5 };
  265. var btn1 = new Button
  266. {
  267. AutoSize = false,
  268. X = Pos.Center (),
  269. Y = Pos.Center (),
  270. Width = 16,
  271. Height = 1,
  272. Text = "Open me!"
  273. };
  274. var btn2 = new Button
  275. {
  276. AutoSize = false,
  277. X = Pos.Center (),
  278. Y = Pos.Center () + 1,
  279. Width = 16,
  280. Height = 1,
  281. Text = "Close me!"
  282. };
  283. top.Add (btn1, btn2);
  284. top.BeginInit ();
  285. top.EndInit ();
  286. top.Draw ();
  287. Assert.Equal ("{Width=16, Height=1}", btn1.TextFormatter.Size.ToString ());
  288. Assert.Equal ("{Width=16, Height=1}", btn2.TextFormatter.Size.ToString ());
  289. TestHelpers.AssertDriverContentsWithFrameAre (
  290. @$"
  291. {
  292. CM.Glyphs.LeftBracket
  293. } {
  294. btn1.Text
  295. } {
  296. CM.Glyphs.RightBracket
  297. }
  298. {
  299. CM.Glyphs.LeftBracket
  300. } {
  301. btn2.Text
  302. } {
  303. CM.Glyphs.RightBracket
  304. }",
  305. _output
  306. );
  307. }
  308. [Fact]
  309. [AutoInitShutdown]
  310. public void Button_HotKeyChanged_EventFires ()
  311. {
  312. var btn = new Button { Text = "_Yar" };
  313. object sender = null;
  314. KeyChangedEventArgs args = null;
  315. btn.HotKeyChanged += (s, e) =>
  316. {
  317. sender = s;
  318. args = e;
  319. };
  320. btn.HotKeyChanged += (s, e) =>
  321. {
  322. sender = s;
  323. args = e;
  324. };
  325. btn.HotKey = KeyCode.R;
  326. Assert.Same (btn, sender);
  327. Assert.Equal (KeyCode.Y, args.OldKey);
  328. Assert.Equal (KeyCode.R, args.NewKey);
  329. btn.HotKey = KeyCode.R;
  330. Assert.Same (btn, sender);
  331. Assert.Equal (KeyCode.Y, args.OldKey);
  332. Assert.Equal (KeyCode.R, args.NewKey);
  333. }
  334. [Fact]
  335. [AutoInitShutdown]
  336. public void Button_HotKeyChanged_EventFires_WithNone ()
  337. {
  338. var btn = new Button ();
  339. object sender = null;
  340. KeyChangedEventArgs args = null;
  341. btn.HotKeyChanged += (s, e) =>
  342. {
  343. sender = s;
  344. args = e;
  345. };
  346. btn.HotKey = KeyCode.R;
  347. Assert.Same (btn, sender);
  348. Assert.Equal (KeyCode.Null, args.OldKey);
  349. Assert.Equal (KeyCode.R, args.NewKey);
  350. }
  351. [Fact]
  352. [SetupFakeDriver]
  353. public void Constructors_Defaults ()
  354. {
  355. var btn = new Button ();
  356. Assert.Equal (string.Empty, btn.Text);
  357. btn.BeginInit ();
  358. btn.EndInit ();
  359. Assert.Equal ($"{CM.Glyphs.LeftBracket} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
  360. Assert.False (btn.IsDefault);
  361. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  362. Assert.Equal ('_', btn.HotKeySpecifier.Value);
  363. Assert.True (btn.CanFocus);
  364. Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Bounds);
  365. Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Frame);
  366. Assert.Equal ($"{CM.Glyphs.LeftBracket} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
  367. Assert.False (btn.IsDefault);
  368. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  369. Assert.Equal ('_', btn.HotKeySpecifier.Value);
  370. Assert.True (btn.CanFocus);
  371. Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Bounds);
  372. Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Frame);
  373. Assert.Equal (string.Empty, btn.Title);
  374. Assert.Equal (KeyCode.Null, btn.HotKey);
  375. btn.Draw ();
  376. var expected = @$"
  377. {
  378. CM.Glyphs.LeftBracket
  379. } {
  380. CM.Glyphs.RightBracket
  381. }
  382. ";
  383. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  384. btn = new Button { Text = "_Test", IsDefault = true };
  385. btn.BeginInit ();
  386. btn.EndInit ();
  387. Assert.Equal ('_', btn.HotKeySpecifier.Value);
  388. Assert.Equal (Key.T, btn.HotKey);
  389. Assert.Equal ("_Test", btn.Text);
  390. Assert.Equal (
  391. $"{
  392. CM.Glyphs.LeftBracket
  393. }{
  394. CM.Glyphs.LeftDefaultIndicator
  395. } Test {
  396. CM.Glyphs.RightDefaultIndicator
  397. }{
  398. CM.Glyphs.RightBracket
  399. }",
  400. btn.TextFormatter.Format ()
  401. );
  402. Assert.True (btn.IsDefault);
  403. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  404. Assert.True (btn.CanFocus);
  405. Assert.Equal (new Rectangle (0, 0, 10, 1), btn.Bounds);
  406. Assert.Equal (new Rectangle (0, 0, 10, 1), btn.Frame);
  407. Assert.Equal (KeyCode.T, btn.HotKey);
  408. btn = new Button { X = 1, Y = 2, Text = "_abc", IsDefault = true };
  409. btn.BeginInit ();
  410. btn.EndInit ();
  411. Assert.Equal ("_abc", btn.Text);
  412. Assert.Equal (Key.A, btn.HotKey);
  413. Assert.Equal (
  414. $"{
  415. CM.Glyphs.LeftBracket
  416. }{
  417. CM.Glyphs.LeftDefaultIndicator
  418. } abc {
  419. CM.Glyphs.RightDefaultIndicator
  420. }{
  421. CM.Glyphs.RightBracket
  422. }",
  423. btn.TextFormatter.Format ()
  424. );
  425. Assert.True (btn.IsDefault);
  426. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  427. Assert.Equal ('_', btn.HotKeySpecifier.Value);
  428. Assert.True (btn.CanFocus);
  429. Application.Driver.ClearContents ();
  430. btn.Draw ();
  431. expected = @$"
  432. {
  433. CM.Glyphs.LeftBracket
  434. }{
  435. CM.Glyphs.LeftDefaultIndicator
  436. } abc {
  437. CM.Glyphs.RightDefaultIndicator
  438. }{
  439. CM.Glyphs.RightBracket
  440. }
  441. ";
  442. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  443. Assert.Equal (new Rectangle (0, 0, 9, 1), btn.Bounds);
  444. Assert.Equal (new Rectangle (1, 2, 9, 1), btn.Frame);
  445. }
  446. [Fact]
  447. [AutoInitShutdown]
  448. public void HotKeyChange_Works ()
  449. {
  450. var clicked = false;
  451. var btn = new Button { Text = "_Test" };
  452. btn.Accept += (s, e) => clicked = true;
  453. var top = new Toplevel ();
  454. top.Add (btn);
  455. Application.Begin (top);
  456. Assert.Equal (KeyCode.T, btn.HotKey);
  457. Assert.True (btn.NewKeyDownEvent (Key.T));
  458. Assert.True (clicked);
  459. clicked = false;
  460. Assert.True (btn.NewKeyDownEvent (Key.T.WithAlt));
  461. Assert.True (clicked);
  462. clicked = false;
  463. btn.HotKey = KeyCode.E;
  464. Assert.True (btn.NewKeyDownEvent (Key.E.WithAlt));
  465. Assert.True (clicked);
  466. }
  467. /// <summary>
  468. /// This test demonstrates how to change the activation key for Button as described in the README.md keyboard
  469. /// handling section
  470. /// </summary>
  471. [Fact]
  472. [AutoInitShutdown]
  473. public void KeyBindingExample ()
  474. {
  475. var pressed = 0;
  476. var btn = new Button { Text = "Press Me" };
  477. btn.Accept += (s, e) => pressed++;
  478. // The Button class supports the Default and Accept command
  479. Assert.Contains (Command.HotKey, btn.GetSupportedCommands ());
  480. Assert.Contains (Command.Accept, btn.GetSupportedCommands ());
  481. var top = new Toplevel ();
  482. top.Add (btn);
  483. Application.Begin (top);
  484. // default keybinding is Space which results in keypress
  485. Application.OnKeyDown (new Key ((KeyCode)' '));
  486. Assert.Equal (1, pressed);
  487. // remove the default keybinding (Space)
  488. btn.KeyBindings.Clear (Command.HotKey);
  489. btn.KeyBindings.Clear (Command.Accept);
  490. // After clearing the default keystroke the Space button no longer does anything for the Button
  491. Application.OnKeyDown (new Key ((KeyCode)' '));
  492. Assert.Equal (1, pressed);
  493. // Set a new binding of b for the click (Accept) event
  494. btn.KeyBindings.Add (Key.B, Command.HotKey);
  495. btn.KeyBindings.Add (Key.B, Command.Accept);
  496. // now pressing B should call the button click event
  497. Application.OnKeyDown (Key.B);
  498. Assert.Equal (2, pressed);
  499. // now pressing Shift-B should NOT call the button click event
  500. Application.OnKeyDown (Key.B.WithShift);
  501. Assert.Equal (2, pressed);
  502. // now pressing Alt-B should NOT call the button click event
  503. Application.OnKeyDown (Key.B.WithAlt);
  504. Assert.Equal (2, pressed);
  505. // now pressing Shift-Alt-B should NOT call the button click event
  506. Application.OnKeyDown (Key.B.WithAlt.WithShift);
  507. Assert.Equal (2, pressed);
  508. }
  509. [Fact]
  510. [AutoInitShutdown]
  511. public void KeyBindings_Command ()
  512. {
  513. var clicked = false;
  514. var btn = new Button { Text = "_Test" };
  515. btn.Accept += (s, e) => clicked = true;
  516. var top = new Toplevel ();
  517. top.Add (btn);
  518. Application.Begin (top);
  519. // Hot key. Both alone and with alt
  520. Assert.Equal (KeyCode.T, btn.HotKey);
  521. Assert.True (btn.NewKeyDownEvent (Key.T));
  522. Assert.True (clicked);
  523. clicked = false;
  524. Assert.True (btn.NewKeyDownEvent (Key.T.WithAlt));
  525. Assert.True (clicked);
  526. clicked = false;
  527. Assert.True (btn.NewKeyDownEvent (btn.HotKey));
  528. Assert.True (clicked);
  529. clicked = false;
  530. Assert.True (btn.NewKeyDownEvent (btn.HotKey));
  531. Assert.True (clicked);
  532. clicked = false;
  533. // IsDefault = false
  534. // Space and Enter should work
  535. Assert.False (btn.IsDefault);
  536. Assert.True (btn.NewKeyDownEvent (Key.Enter));
  537. Assert.True (clicked);
  538. clicked = false;
  539. // IsDefault = true
  540. // Space and Enter should work
  541. btn.IsDefault = true;
  542. Assert.True (btn.NewKeyDownEvent (Key.Enter));
  543. Assert.True (clicked);
  544. clicked = false;
  545. // Toplevel does not handle Enter, so it should get passed on to button
  546. Assert.True (Application.Top.NewKeyDownEvent (Key.Enter));
  547. Assert.True (clicked);
  548. clicked = false;
  549. // Direct
  550. Assert.True (btn.NewKeyDownEvent (Key.Enter));
  551. Assert.True (clicked);
  552. clicked = false;
  553. Assert.True (btn.NewKeyDownEvent (Key.Space));
  554. Assert.True (clicked);
  555. clicked = false;
  556. Assert.True (btn.NewKeyDownEvent (new Key ((KeyCode)'T')));
  557. Assert.True (clicked);
  558. clicked = false;
  559. // Change hotkey:
  560. btn.Text = "Te_st";
  561. Assert.True (btn.NewKeyDownEvent (btn.HotKey));
  562. Assert.True (clicked);
  563. clicked = false;
  564. }
  565. [Fact]
  566. public void HotKey_Command_Accepts ()
  567. {
  568. var button = new Button ();
  569. var accepted = false;
  570. button.Accept += ButtonOnAccept;
  571. button.InvokeCommand (Command.HotKey);
  572. Assert.True (accepted);
  573. return;
  574. void ButtonOnAccept (object sender, CancelEventArgs e) { accepted = true; }
  575. }
  576. [Fact]
  577. public void Accept_Cancel_Event_OnAccept_Returns_True ()
  578. {
  579. var button = new Button ();
  580. var acceptInvoked = false;
  581. button.Accept += ButtonAccept;
  582. var ret = button.InvokeCommand (Command.Accept);
  583. Assert.True (ret);
  584. Assert.True (acceptInvoked);
  585. return;
  586. void ButtonAccept (object sender, CancelEventArgs e)
  587. {
  588. acceptInvoked = true;
  589. e.Cancel = true;
  590. }
  591. }
  592. [Fact]
  593. public void Setting_Empty_Text_Sets_HoKey_To_KeyNull ()
  594. {
  595. var super = new View ();
  596. var btn = new Button { Text = "_Test" };
  597. super.Add (btn);
  598. super.BeginInit ();
  599. super.EndInit ();
  600. Assert.Equal ("_Test", btn.Text);
  601. Assert.Equal (KeyCode.T, btn.HotKey);
  602. btn.Text = string.Empty;
  603. Assert.Equal ("", btn.Text);
  604. Assert.Equal (KeyCode.Null, btn.HotKey);
  605. btn.Text = string.Empty;
  606. Assert.Equal ("", btn.Text);
  607. Assert.Equal (KeyCode.Null, btn.HotKey);
  608. btn.Text = "Te_st";
  609. Assert.Equal ("Te_st", btn.Text);
  610. Assert.Equal (KeyCode.S, btn.HotKey);
  611. }
  612. [Fact]
  613. public void TestAssignTextToButton ()
  614. {
  615. View b = new Button { Text = "heya" };
  616. Assert.Equal ("heya", b.Text);
  617. Assert.Contains ("heya", b.TextFormatter.Text);
  618. b.Text = "heyb";
  619. Assert.Equal ("heyb", b.Text);
  620. Assert.Contains ("heyb", b.TextFormatter.Text);
  621. // with cast
  622. Assert.Equal ("heyb", ((Button)b).Text);
  623. }
  624. [Fact]
  625. [AutoInitShutdown]
  626. public void Update_Only_On_Or_After_Initialize ()
  627. {
  628. var btn = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" };
  629. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  630. win.Add (btn);
  631. var top = new Toplevel ();
  632. top.Add (win);
  633. Assert.False (btn.IsInitialized);
  634. Application.Begin (top);
  635. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  636. Assert.True (btn.IsInitialized);
  637. Assert.Equal ("Say Hello 你", btn.Text);
  638. Assert.Equal ($"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
  639. Assert.Equal (new Rectangle (0, 0, 16, 1), btn.Bounds);
  640. var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
  641. var expected = @$"
  642. ┌────────────────────────────┐
  643. │ │
  644. │ {
  645. btnTxt
  646. } │
  647. │ │
  648. └────────────────────────────┘
  649. ";
  650. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  651. Assert.Equal (new Rectangle (0, 0, 30, 5), pos);
  652. }
  653. [Fact]
  654. [AutoInitShutdown]
  655. public void Update_Parameterless_Only_On_Or_After_Initialize ()
  656. {
  657. var btn = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" };
  658. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  659. win.Add (btn);
  660. var top = new Toplevel ();
  661. top.Add (win);
  662. Assert.False (btn.IsInitialized);
  663. Application.Begin (top);
  664. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  665. Assert.True (btn.IsInitialized);
  666. Assert.Equal ("Say Hello 你", btn.Text);
  667. Assert.Equal ($"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
  668. Assert.Equal (new Rectangle (0, 0, 16, 1), btn.Bounds);
  669. var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
  670. var expected = @$"
  671. ┌────────────────────────────┐
  672. │ │
  673. │ {
  674. btnTxt
  675. } │
  676. │ │
  677. └────────────────────────────┘
  678. ";
  679. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  680. Assert.Equal (new Rectangle (0, 0, 30, 5), pos);
  681. }
  682. }