ButtonTests.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  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. 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 += () => 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 += () => 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 += () => 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 btn = new Button ("Test");
  168. Assert.Equal ("Test", btn.Text);
  169. Assert.Equal (Key.T, btn.HotKey);
  170. btn.Text = string.Empty;
  171. Assert.Equal ("", btn.Text);
  172. Assert.Equal (Key.Null, btn.HotKey);
  173. btn.Text = "Te_st";
  174. Assert.Equal ("Te_st", btn.Text);
  175. Assert.Equal (Key.S, btn.HotKey);
  176. }
  177. [Fact, AutoInitShutdown]
  178. public void Update_Only_On_Or_After_Initialize ()
  179. {
  180. var btn = new Button ("Say Hello 你") {
  181. X = Pos.Center (),
  182. Y = Pos.Center ()
  183. };
  184. var win = new Window ("Test Demo 你") {
  185. Width = Dim.Fill (),
  186. Height = Dim.Fill ()
  187. };
  188. win.Add (btn);
  189. Application.Top.Add (win);
  190. Assert.False (btn.IsInitialized);
  191. Application.Begin (Application.Top);
  192. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  193. Assert.True (btn.IsInitialized);
  194. Assert.Equal ("Say Hello 你", btn.Text);
  195. Assert.Equal ("[ Say Hello 你 ]", btn.TextFormatter.Text);
  196. Assert.Equal (new Rect (0, 0, 16, 1), btn.Bounds);
  197. var expected = @"
  198. ┌ Test Demo 你 ──────────────┐
  199. │ │
  200. │ [ Say Hello 你 ] │
  201. │ │
  202. └────────────────────────────┘
  203. ";
  204. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  205. Assert.Equal (new Rect (0, 0, 30, 5), pos);
  206. }
  207. [Fact, AutoInitShutdown]
  208. public void Update_Parameterless_Only_On_Or_After_Initialize ()
  209. {
  210. var btn = new Button () {
  211. X = Pos.Center (),
  212. Y = Pos.Center (),
  213. Text = "Say Hello 你"
  214. };
  215. var win = new Window () {
  216. Width = Dim.Fill (),
  217. Height = Dim.Fill (),
  218. Title = "Test Demo 你"
  219. };
  220. win.Add (btn);
  221. Application.Top.Add (win);
  222. Assert.False (btn.IsInitialized);
  223. Application.Begin (Application.Top);
  224. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  225. Assert.True (btn.IsInitialized);
  226. Assert.Equal ("Say Hello 你", btn.Text);
  227. Assert.Equal ("[ Say Hello 你 ]", btn.TextFormatter.Text);
  228. Assert.Equal (new Rect (0, 0, 16, 1), btn.Bounds);
  229. var expected = @"
  230. ┌ Test Demo 你 ──────────────┐
  231. │ │
  232. │ [ Say Hello 你 ] │
  233. │ │
  234. └────────────────────────────┘
  235. ";
  236. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  237. Assert.Equal (new Rect (0, 0, 30, 5), pos);
  238. }
  239. [Fact, AutoInitShutdown]
  240. public void AutoSize_Stays_True_With_EmptyText ()
  241. {
  242. var btn = new Button () {
  243. X = Pos.Center (),
  244. Y = Pos.Center (),
  245. AutoSize = true
  246. };
  247. var win = new Window () {
  248. Width = Dim.Fill (),
  249. Height = Dim.Fill (),
  250. Title = "Test Demo 你"
  251. };
  252. win.Add (btn);
  253. Application.Top.Add (win);
  254. Assert.True (btn.AutoSize);
  255. btn.Text = "Say Hello 你";
  256. Assert.True (btn.AutoSize);
  257. Application.Begin (Application.Top);
  258. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  259. var expected = @"
  260. ┌ Test Demo 你 ──────────────┐
  261. │ │
  262. │ [ Say Hello 你 ] │
  263. │ │
  264. └────────────────────────────┘
  265. ";
  266. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  267. }
  268. [Fact, AutoInitShutdown]
  269. public void AutoSize_Stays_True_Center ()
  270. {
  271. var btn = new Button () {
  272. X = Pos.Center (),
  273. Y = Pos.Center (),
  274. Text = "Say Hello 你"
  275. };
  276. var win = new Window () {
  277. Width = Dim.Fill (),
  278. Height = Dim.Fill (),
  279. Title = "Test Demo 你"
  280. };
  281. win.Add (btn);
  282. Application.Top.Add (win);
  283. Assert.True (btn.AutoSize);
  284. Application.Begin (Application.Top);
  285. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  286. var expected = @"
  287. ┌ Test Demo 你 ──────────────┐
  288. │ │
  289. │ [ Say Hello 你 ] │
  290. │ │
  291. └────────────────────────────┘
  292. ";
  293. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  294. Assert.True (btn.AutoSize);
  295. btn.Text = "Say Hello 你 changed";
  296. Assert.True (btn.AutoSize);
  297. Application.Refresh ();
  298. expected = @"
  299. ┌ Test Demo 你 ──────────────┐
  300. │ │
  301. │ [ Say Hello 你 changed ] │
  302. │ │
  303. └────────────────────────────┘
  304. ";
  305. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  306. }
  307. [Fact, AutoInitShutdown]
  308. public void AutoSize_Stays_True_AnchorEnd ()
  309. {
  310. var btn = new Button () {
  311. Y = Pos.Center (),
  312. Text = "Say Hello 你",
  313. AutoSize = true
  314. };
  315. btn.X = Pos.AnchorEnd () - Pos.Function (() => TextFormatter.GetTextWidth (btn.TextFormatter.Text));
  316. var win = new Window () {
  317. Width = Dim.Fill (),
  318. Height = Dim.Fill (),
  319. Title = "Test Demo 你"
  320. };
  321. win.Add (btn);
  322. Application.Top.Add (win);
  323. Assert.True (btn.AutoSize);
  324. Application.Begin (Application.Top);
  325. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  326. var expected = @"
  327. ┌ Test Demo 你 ──────────────┐
  328. │ │
  329. │ [ Say Hello 你 ]│
  330. │ │
  331. └────────────────────────────┘
  332. ";
  333. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  334. Assert.True (btn.AutoSize);
  335. btn.Text = "Say Hello 你 changed";
  336. Assert.True (btn.AutoSize);
  337. Application.Refresh ();
  338. expected = @"
  339. ┌ Test Demo 你 ──────────────┐
  340. │ │
  341. │ [ Say Hello 你 changed ]│
  342. │ │
  343. └────────────────────────────┘
  344. ";
  345. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  346. }
  347. [Fact, AutoInitShutdown]
  348. public void AutoSize_False_With_Fixed_Width ()
  349. {
  350. var tab = new View ();
  351. var lblWidth = 8;
  352. var label = new Label ("Find:") {
  353. Y = 1,
  354. Width = lblWidth,
  355. TextAlignment = TextAlignment.Right,
  356. AutoSize = false
  357. };
  358. tab.Add (label);
  359. var txtToFind = new TextField ("Testing buttons.") {
  360. X = Pos.Right (label) + 1,
  361. Y = Pos.Top (label),
  362. Width = 20
  363. };
  364. tab.Add (txtToFind);
  365. var btnFindNext = new Button ("Find _Next") {
  366. X = Pos.Right (txtToFind) + 1,
  367. Y = Pos.Top (label),
  368. Width = 20,
  369. Enabled = !txtToFind.Text.IsEmpty,
  370. TextAlignment = TextAlignment.Centered,
  371. IsDefault = true,
  372. AutoSize = false
  373. };
  374. tab.Add (btnFindNext);
  375. var btnFindPrevious = new Button ("Find _Previous") {
  376. X = Pos.Right (txtToFind) + 1,
  377. Y = Pos.Top (btnFindNext) + 1,
  378. Width = 20,
  379. Enabled = !txtToFind.Text.IsEmpty,
  380. TextAlignment = TextAlignment.Centered,
  381. AutoSize = false
  382. };
  383. tab.Add (btnFindPrevious);
  384. var btnCancel = new Button ("Cancel") {
  385. X = Pos.Right (txtToFind) + 1,
  386. Y = Pos.Top (btnFindPrevious) + 2,
  387. Width = 20,
  388. TextAlignment = TextAlignment.Centered,
  389. AutoSize = false
  390. };
  391. tab.Add (btnCancel);
  392. var ckbMatchCase = new CheckBox ("Match c_ase") {
  393. X = 0,
  394. Y = Pos.Top (txtToFind) + 2,
  395. Checked = true
  396. };
  397. tab.Add (ckbMatchCase);
  398. var ckbMatchWholeWord = new CheckBox ("Match _whole word") {
  399. X = 0,
  400. Y = Pos.Top (ckbMatchCase) + 1,
  401. Checked = false
  402. };
  403. tab.Add (ckbMatchWholeWord);
  404. var tabView = new TabView () {
  405. Width = Dim.Fill (),
  406. Height = Dim.Fill ()
  407. };
  408. tabView.AddTab (new TabView.Tab ("Find", tab), true);
  409. var win = new Window ("Find") {
  410. Width = Dim.Fill (),
  411. Height = Dim.Fill ()
  412. };
  413. tab.Width = label.Width + txtToFind.Width + btnFindNext.Width + 2;
  414. tab.Height = btnFindNext.Height + btnFindPrevious.Height + btnCancel.Height + 4;
  415. win.Add (tabView);
  416. Application.Top.Add (win);
  417. Application.Begin (Application.Top);
  418. ((FakeDriver)Application.Driver).SetBufferSize (54, 11);
  419. Assert.Equal (new Rect (0, 0, 54, 11), win.Frame);
  420. Assert.Equal (new Rect (0, 0, 52, 9), tabView.Frame);
  421. Assert.Equal (new Rect (0, 0, 50, 7), tab.Frame);
  422. Assert.Equal (new Rect (0, 1, 8, 1), label.Frame);
  423. Assert.Equal (new Rect (9, 1, 20, 1), txtToFind.Frame);
  424. Assert.Equal (0, txtToFind.ScrollOffset);
  425. Assert.Equal (16, txtToFind.CursorPosition);
  426. Assert.Equal (new Rect (30, 1, 20, 1), btnFindNext.Frame);
  427. Assert.Equal (new Rect (30, 2, 20, 1), btnFindPrevious.Frame);
  428. Assert.Equal (new Rect (30, 4, 20, 1), btnCancel.Frame);
  429. Assert.Equal (new Rect (0, 3, 12, 1), ckbMatchCase.Frame);
  430. Assert.Equal (new Rect (0, 4, 18, 1), ckbMatchWholeWord.Frame);
  431. var expected = @"
  432. ┌ Find ──────────────────────────────────────────────┐
  433. │┌────┐ │
  434. ││Find│ │
  435. ││ └─────────────────────────────────────────────┐│
  436. ││ ││
  437. ││ Find: Testing buttons. [◦ Find Next ◦] ││
  438. ││ [ Find Previous ] ││
  439. ││√ Match case ││
  440. ││╴ Match whole word [ Cancel ] ││
  441. │└──────────────────────────────────────────────────┘│
  442. └────────────────────────────────────────────────────┘
  443. ";
  444. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  445. }
  446. [Fact, AutoInitShutdown]
  447. public void Pos_Center_Layout_AutoSize_True ()
  448. {
  449. var button = new Button ("Process keys") {
  450. X = Pos.Center (),
  451. Y = Pos.Center (),
  452. IsDefault = true
  453. };
  454. var win = new Window () {
  455. Width = Dim.Fill (),
  456. Height = Dim.Fill ()
  457. };
  458. win.Add (button);
  459. Application.Top.Add (win);
  460. Application.Begin (Application.Top);
  461. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  462. Assert.True (button.AutoSize);
  463. Assert.Equal (new Rect (5, 1, 18, 1), button.Frame);
  464. var expected = @"
  465. ┌────────────────────────────┐
  466. │ │
  467. │ [◦ Process keys ◦] │
  468. │ │
  469. └────────────────────────────┘
  470. ";
  471. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  472. }
  473. [Fact, AutoInitShutdown]
  474. public void Pos_Center_Layout_AutoSize_False ()
  475. {
  476. var button = new Button ("Process keys") {
  477. X = Pos.Center (),
  478. Y = Pos.Center (),
  479. Width = 20,
  480. IsDefault = true,
  481. AutoSize = false
  482. };
  483. var win = new Window () {
  484. Width = Dim.Fill (),
  485. Height = Dim.Fill ()
  486. };
  487. win.Add (button);
  488. Application.Top.Add (win);
  489. Application.Begin (Application.Top);
  490. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  491. Assert.False (button.AutoSize);
  492. Assert.Equal (new Rect (4, 1, 20, 1), button.Frame);
  493. var expected = @"
  494. ┌────────────────────────────┐
  495. │ │
  496. │ [◦ Process keys ◦] │
  497. │ │
  498. └────────────────────────────┘
  499. ";
  500. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  501. }
  502. }
  503. }