ButtonTests.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  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. Application.Top.Add (win);
  98. Application.Begin (Application.Top);
  99. ((FakeDriver)Application.Driver).SetBufferSize (54, 11);
  100. Assert.Equal (new Rectangle (0, 0, 54, 11), win.Frame);
  101. Assert.Equal (new Rectangle (0, 0, 52, 9), tabView.Frame);
  102. Assert.Equal (new Rectangle (0, 0, 50, 7), tab.Frame);
  103. Assert.Equal (new Rectangle (0, 1, 8, 1), view.Frame);
  104. Assert.Equal (new Rectangle (9, 1, 20, 1), txtToFind.Frame);
  105. Assert.Equal (0, txtToFind.ScrollOffset);
  106. Assert.Equal (16, txtToFind.CursorPosition);
  107. Assert.Equal (new (30, 1, 20, 1), btnFindNext.Frame);
  108. Assert.Equal (new (30, 2, 20, 1), btnFindPrevious.Frame);
  109. Assert.Equal (new (30, 4, 20, 1), btnCancel.Frame);
  110. // Assert.Equal (new (0, 3, 12, 1), ckbMatchCase.Frame);
  111. // Assert.Equal (new (0, 4, 18, 1), ckbMatchWholeWord.Frame);
  112. var btn1 =
  113. $"{
  114. CM.Glyphs.LeftBracket
  115. }{
  116. CM.Glyphs.LeftDefaultIndicator
  117. } Find Next {
  118. CM.Glyphs.RightDefaultIndicator
  119. }{
  120. CM.Glyphs.RightBracket
  121. }";
  122. var btn2 = $"{CM.Glyphs.LeftBracket} Find Previous {CM.Glyphs.RightBracket}";
  123. var btn3 = $"{CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket}";
  124. var expected = @$"
  125. ┌────────────────────────────────────────────────────┐
  126. │╭────╮ │
  127. ││Find│ │
  128. ││ ╰─────────────────────────────────────────────╮│
  129. ││ ││
  130. ││ Find: Testing buttons. {
  131. btn1
  132. } ││
  133. ││ {
  134. btn2
  135. } ││
  136. ││{
  137. CM.Glyphs.Checked
  138. } Match case ││
  139. ││{
  140. CM.Glyphs.UnChecked
  141. } Match whole word {
  142. btn3
  143. } ││
  144. │└──────────────────────────────────────────────────┘│
  145. └────────────────────────────────────────────────────┘
  146. ";
  147. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  148. }
  149. [Fact]
  150. [AutoInitShutdown]
  151. public void AutoSize_Stays_True_AnchorEnd ()
  152. {
  153. var btn = new Button { Y = Pos.Center (), Text = "Say Hello 你", AutoSize = true };
  154. var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
  155. btn.X = Pos.AnchorEnd () - Pos.Function (() => btn.TextFormatter.Text.GetColumns ());
  156. btn.X = Pos.AnchorEnd () - Pos.Function (() => btn.TextFormatter.Text.GetColumns ());
  157. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  158. win.Add (btn);
  159. Application.Top.Add (win);
  160. Assert.True (btn.AutoSize);
  161. Assert.True (btn.AutoSize);
  162. Application.Begin (Application.Top);
  163. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  164. var expected = @$"
  165. ┌────────────────────────────┐
  166. │ │
  167. │ {
  168. btnTxt
  169. }│
  170. │ │
  171. └────────────────────────────┘
  172. ";
  173. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  174. Assert.True (btn.AutoSize);
  175. btn.Text = "Say Hello 你 changed";
  176. btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
  177. Assert.True (btn.AutoSize);
  178. Application.Refresh ();
  179. expected = @$"
  180. ┌────────────────────────────┐
  181. │ │
  182. │ {
  183. btnTxt
  184. }│
  185. │ │
  186. └────────────────────────────┘
  187. ";
  188. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  189. }
  190. [Fact]
  191. [AutoInitShutdown]
  192. public void AutoSize_Stays_True_Center ()
  193. {
  194. var btn = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" };
  195. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  196. win.Add (btn);
  197. Application.Top.Add (win);
  198. Assert.True (btn.AutoSize);
  199. Assert.True (btn.AutoSize);
  200. Application.Begin (Application.Top);
  201. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  202. var expected = @$"
  203. ┌────────────────────────────┐
  204. │ │
  205. │ {
  206. CM.Glyphs.LeftBracket
  207. } Say Hello 你 {
  208. CM.Glyphs.RightBracket
  209. } │
  210. │ │
  211. └────────────────────────────┘
  212. ";
  213. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  214. Assert.True (btn.AutoSize);
  215. btn.Text = "Say Hello 你 changed";
  216. Assert.True (btn.AutoSize);
  217. Application.Refresh ();
  218. expected = @$"
  219. ┌────────────────────────────┐
  220. │ │
  221. │ {
  222. CM.Glyphs.LeftBracket
  223. } Say Hello 你 changed {
  224. CM.Glyphs.RightBracket
  225. } │
  226. │ │
  227. └────────────────────────────┘
  228. ";
  229. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  230. }
  231. [Fact]
  232. [AutoInitShutdown]
  233. public void AutoSize_Stays_True_With_EmptyText ()
  234. {
  235. var btn = new Button { X = Pos.Center (), Y = Pos.Center (), AutoSize = true };
  236. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  237. win.Add (btn);
  238. Application.Top.Add (win);
  239. Assert.True (btn.AutoSize);
  240. Assert.True (btn.AutoSize);
  241. btn.Text = "Say Hello 你";
  242. btn.Text = "Say Hello 你";
  243. Assert.True (btn.AutoSize);
  244. Assert.True (btn.AutoSize);
  245. Application.Begin (Application.Top);
  246. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  247. var expected = @$"
  248. ┌────────────────────────────┐
  249. │ │
  250. │ {
  251. CM.Glyphs.LeftBracket
  252. } Say Hello 你 {
  253. CM.Glyphs.RightBracket
  254. } │
  255. │ │
  256. └────────────────────────────┘
  257. ";
  258. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  259. }
  260. [Fact]
  261. [SetupFakeDriver]
  262. public void Button_AutoSize_False_With_Fixed_Width ()
  263. {
  264. ((FakeDriver)Application.Driver).SetBufferSize (20, 5);
  265. var top = new View { Width = 20, Height = 5 };
  266. var btn1 = new Button
  267. {
  268. AutoSize = false,
  269. X = Pos.Center (),
  270. Y = Pos.Center (),
  271. Width = 16,
  272. Height = 1,
  273. Text = "Open me!"
  274. };
  275. var btn2 = new Button
  276. {
  277. AutoSize = false,
  278. X = Pos.Center (),
  279. Y = Pos.Center () + 1,
  280. Width = 16,
  281. Height = 1,
  282. Text = "Close me!"
  283. };
  284. top.Add (btn1, btn2);
  285. top.BeginInit ();
  286. top.EndInit ();
  287. top.Draw ();
  288. Assert.Equal ("{Width=16, Height=1}", btn1.TextFormatter.Size.ToString ());
  289. Assert.Equal ("{Width=16, Height=1}", btn2.TextFormatter.Size.ToString ());
  290. TestHelpers.AssertDriverContentsWithFrameAre (
  291. @$"
  292. {
  293. CM.Glyphs.LeftBracket
  294. } {
  295. btn1.Text
  296. } {
  297. CM.Glyphs.RightBracket
  298. }
  299. {
  300. CM.Glyphs.LeftBracket
  301. } {
  302. btn2.Text
  303. } {
  304. CM.Glyphs.RightBracket
  305. }",
  306. _output
  307. );
  308. }
  309. [Fact]
  310. [AutoInitShutdown]
  311. public void Button_HotKeyChanged_EventFires ()
  312. {
  313. var btn = new Button { Text = "_Yar" };
  314. object sender = null;
  315. KeyChangedEventArgs args = null;
  316. btn.HotKeyChanged += (s, e) =>
  317. {
  318. sender = s;
  319. args = e;
  320. };
  321. btn.HotKeyChanged += (s, e) =>
  322. {
  323. sender = s;
  324. args = e;
  325. };
  326. btn.HotKey = KeyCode.R;
  327. Assert.Same (btn, sender);
  328. Assert.Equal (KeyCode.Y, args.OldKey);
  329. Assert.Equal (KeyCode.R, args.NewKey);
  330. btn.HotKey = KeyCode.R;
  331. Assert.Same (btn, sender);
  332. Assert.Equal (KeyCode.Y, args.OldKey);
  333. Assert.Equal (KeyCode.R, args.NewKey);
  334. }
  335. [Fact]
  336. [AutoInitShutdown]
  337. public void Button_HotKeyChanged_EventFires_WithNone ()
  338. {
  339. var btn = new Button ();
  340. object sender = null;
  341. KeyChangedEventArgs args = null;
  342. btn.HotKeyChanged += (s, e) =>
  343. {
  344. sender = s;
  345. args = e;
  346. };
  347. btn.HotKey = KeyCode.R;
  348. Assert.Same (btn, sender);
  349. Assert.Equal (KeyCode.Null, args.OldKey);
  350. Assert.Equal (KeyCode.R, args.NewKey);
  351. }
  352. [Fact]
  353. [SetupFakeDriver]
  354. public void Constructors_Defaults ()
  355. {
  356. var btn = new Button ();
  357. Assert.Equal (string.Empty, btn.Text);
  358. btn.BeginInit ();
  359. btn.EndInit ();
  360. Assert.Equal ($"{CM.Glyphs.LeftBracket} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
  361. Assert.False (btn.IsDefault);
  362. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  363. Assert.Equal ('_', btn.HotKeySpecifier.Value);
  364. Assert.True (btn.CanFocus);
  365. Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Bounds);
  366. Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Frame);
  367. Assert.Equal ($"{CM.Glyphs.LeftBracket} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
  368. Assert.False (btn.IsDefault);
  369. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  370. Assert.Equal ('_', btn.HotKeySpecifier.Value);
  371. Assert.True (btn.CanFocus);
  372. Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Bounds);
  373. Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Frame);
  374. Assert.Equal (string.Empty, btn.Title);
  375. Assert.Equal (KeyCode.Null, btn.HotKey);
  376. btn.Draw ();
  377. var expected = @$"
  378. {
  379. CM.Glyphs.LeftBracket
  380. } {
  381. CM.Glyphs.RightBracket
  382. }
  383. ";
  384. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  385. btn = new Button { Text = "_Test", IsDefault = true };
  386. btn.BeginInit ();
  387. btn.EndInit ();
  388. Assert.Equal ('_', btn.HotKeySpecifier.Value);
  389. Assert.Equal (Key.T, btn.HotKey);
  390. Assert.Equal ("_Test", btn.Text);
  391. Assert.Equal (
  392. $"{
  393. CM.Glyphs.LeftBracket
  394. }{
  395. CM.Glyphs.LeftDefaultIndicator
  396. } Test {
  397. CM.Glyphs.RightDefaultIndicator
  398. }{
  399. CM.Glyphs.RightBracket
  400. }",
  401. btn.TextFormatter.Format ()
  402. );
  403. Assert.True (btn.IsDefault);
  404. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  405. Assert.True (btn.CanFocus);
  406. Assert.Equal (new Rectangle (0, 0, 10, 1), btn.Bounds);
  407. Assert.Equal (new Rectangle (0, 0, 10, 1), btn.Frame);
  408. Assert.Equal (KeyCode.T, btn.HotKey);
  409. btn = new Button { X = 1, Y = 2, Text = "_abc", IsDefault = true };
  410. btn.BeginInit ();
  411. btn.EndInit ();
  412. Assert.Equal ("_abc", btn.Text);
  413. Assert.Equal (Key.A, btn.HotKey);
  414. Assert.Equal (
  415. $"{
  416. CM.Glyphs.LeftBracket
  417. }{
  418. CM.Glyphs.LeftDefaultIndicator
  419. } abc {
  420. CM.Glyphs.RightDefaultIndicator
  421. }{
  422. CM.Glyphs.RightBracket
  423. }",
  424. btn.TextFormatter.Format ()
  425. );
  426. Assert.True (btn.IsDefault);
  427. Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
  428. Assert.Equal ('_', btn.HotKeySpecifier.Value);
  429. Assert.True (btn.CanFocus);
  430. Application.Driver.ClearContents ();
  431. btn.Draw ();
  432. expected = @$"
  433. {
  434. CM.Glyphs.LeftBracket
  435. }{
  436. CM.Glyphs.LeftDefaultIndicator
  437. } abc {
  438. CM.Glyphs.RightDefaultIndicator
  439. }{
  440. CM.Glyphs.RightBracket
  441. }
  442. ";
  443. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  444. Assert.Equal (new Rectangle (0, 0, 9, 1), btn.Bounds);
  445. Assert.Equal (new Rectangle (1, 2, 9, 1), btn.Frame);
  446. }
  447. [Fact]
  448. [AutoInitShutdown]
  449. public void HotKeyChange_Works ()
  450. {
  451. var clicked = false;
  452. var btn = new Button { Text = "_Test" };
  453. btn.Accept += (s, e) => clicked = true;
  454. Application.Top.Add (btn);
  455. Application.Begin (Application.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. Application.Top.Add (btn);
  482. Application.Begin (Application.Top);
  483. Application.Top.Add (btn);
  484. Application.Begin (Application.Top);
  485. // default keybinding is Space which results in keypress
  486. Application.OnKeyDown (new Key ((KeyCode)' '));
  487. Assert.Equal (1, pressed);
  488. // remove the default keybinding (Space)
  489. btn.KeyBindings.Clear (Command.HotKey);
  490. btn.KeyBindings.Clear (Command.Accept);
  491. // After clearing the default keystroke the Space button no longer does anything for the Button
  492. Application.OnKeyDown (new Key ((KeyCode)' '));
  493. Assert.Equal (1, pressed);
  494. // Set a new binding of b for the click (Accept) event
  495. btn.KeyBindings.Add (Key.B, Command.HotKey);
  496. btn.KeyBindings.Add (Key.B, Command.Accept);
  497. // now pressing B should call the button click event
  498. Application.OnKeyDown (Key.B);
  499. Assert.Equal (2, pressed);
  500. // now pressing Shift-B should NOT call the button click event
  501. Application.OnKeyDown (Key.B.WithShift);
  502. Assert.Equal (2, pressed);
  503. // now pressing Alt-B should NOT call the button click event
  504. Application.OnKeyDown (Key.B.WithAlt);
  505. Assert.Equal (2, pressed);
  506. // now pressing Shift-Alt-B should NOT call the button click event
  507. Application.OnKeyDown (Key.B.WithAlt.WithShift);
  508. Assert.Equal (2, pressed);
  509. }
  510. [Fact]
  511. [AutoInitShutdown]
  512. public void KeyBindings_Command ()
  513. {
  514. var clicked = false;
  515. var btn = new Button { Text = "_Test" };
  516. btn.Accept += (s, e) => clicked = true;
  517. Application.Top.Add (btn);
  518. Application.Begin (Application.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.OnAccept ();
  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. Application.Top.Add (win);
  632. Assert.False (btn.IsInitialized);
  633. Assert.False (btn.IsInitialized);
  634. Application.Begin (Application.Top);
  635. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  636. Application.Begin (Application.Top);
  637. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  638. Assert.True (btn.IsInitialized);
  639. Assert.Equal ("Say Hello 你", btn.Text);
  640. Assert.Equal ($"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
  641. Assert.Equal (new Rectangle (0, 0, 16, 1), btn.Bounds);
  642. var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
  643. var expected = @$"
  644. ┌────────────────────────────┐
  645. │ │
  646. │ {
  647. btnTxt
  648. } │
  649. │ │
  650. └────────────────────────────┘
  651. ";
  652. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  653. Assert.Equal (new Rectangle (0, 0, 30, 5), pos);
  654. }
  655. [Fact]
  656. [AutoInitShutdown]
  657. public void Update_Parameterless_Only_On_Or_After_Initialize ()
  658. {
  659. var btn = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" };
  660. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  661. win.Add (btn);
  662. Application.Top.Add (win);
  663. Assert.False (btn.IsInitialized);
  664. Assert.False (btn.IsInitialized);
  665. Application.Begin (Application.Top);
  666. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  667. Application.Begin (Application.Top);
  668. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  669. Assert.True (btn.IsInitialized);
  670. Assert.Equal ("Say Hello 你", btn.Text);
  671. Assert.Equal ($"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
  672. Assert.Equal (new Rectangle (0, 0, 16, 1), btn.Bounds);
  673. var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
  674. var expected = @$"
  675. ┌────────────────────────────┐
  676. │ │
  677. │ {
  678. btnTxt
  679. } │
  680. │ │
  681. └────────────────────────────┘
  682. ";
  683. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  684. Assert.Equal (new Rectangle (0, 0, 30, 5), pos);
  685. }
  686. }