ShortcutTests.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. using JetBrains.Annotations;
  2. namespace Terminal.Gui.ViewsTests;
  3. [TestSubject (typeof (Shortcut))]
  4. public class ShortcutTests
  5. {
  6. [Fact]
  7. public void Constructor_Defaults ()
  8. {
  9. var shortcut = new Shortcut ();
  10. Assert.NotNull (shortcut);
  11. Assert.True (shortcut.CanFocus);
  12. Assert.IsType<DimAuto> (shortcut.Width);
  13. Assert.IsType<DimAuto> (shortcut.Height);
  14. // TOOD: more
  15. }
  16. [Theory]
  17. [InlineData ("", "", KeyCode.Null, 2)]
  18. [InlineData ("C", "", KeyCode.Null, 3)]
  19. [InlineData ("", "H", KeyCode.Null, 5)]
  20. [InlineData ("", "", KeyCode.K, 5)]
  21. [InlineData ("C", "", KeyCode.K, 6)]
  22. [InlineData ("C", "H", KeyCode.Null, 6)]
  23. [InlineData ("", "H", KeyCode.K, 8)]
  24. [InlineData ("C", "H", KeyCode.K, 9)]
  25. public void NaturalSize (string command, string help, KeyCode key, int expectedWidth)
  26. {
  27. var shortcut = new Shortcut
  28. {
  29. Title = command,
  30. HelpText = help,
  31. Key = key
  32. };
  33. Assert.IsType<DimAuto> (shortcut.Width);
  34. Assert.IsType<DimAuto> (shortcut.Height);
  35. //shortcut.BeginInit();
  36. //shortcut.EndInit ();
  37. // shortcut.LayoutSubviews ();
  38. shortcut.SetRelativeLayout (new (100, 100));
  39. // |0123456789
  40. // | C H K |
  41. Assert.Equal (expectedWidth, shortcut.Frame.Width);
  42. }
  43. [Theory]
  44. [InlineData (5, 0, 3, 6)]
  45. [InlineData (6, 0, 3, 6)]
  46. [InlineData (7, 0, 3, 6)]
  47. [InlineData (8, 0, 3, 6)]
  48. [InlineData (9, 0, 3, 6)]
  49. [InlineData (10, 0, 4, 7)]
  50. [InlineData (11, 0, 5, 8)]
  51. public void Set_Width_Layouts_Correctly (int width, int expectedCmdX, int expectedHelpX, int expectedKeyX)
  52. {
  53. var shortcut = new Shortcut
  54. {
  55. Width = width,
  56. Title = "C",
  57. Text = "H",
  58. Key = Key.K
  59. };
  60. shortcut.LayoutSubviews ();
  61. shortcut.SetRelativeLayout (new (100, 100));
  62. // 0123456789
  63. // -C--H--K-
  64. Assert.Equal (expectedCmdX, shortcut.CommandView.Frame.X);
  65. Assert.Equal (expectedHelpX, shortcut.HelpView.Frame.X);
  66. Assert.Equal (expectedKeyX, shortcut.KeyView.Frame.X);
  67. }
  68. [Fact]
  69. public void CommandView_Text_And_Title_Track ()
  70. {
  71. var shortcut = new Shortcut
  72. {
  73. Title = "T"
  74. };
  75. Assert.Equal (shortcut.Title, shortcut.CommandView.Text);
  76. shortcut = new ();
  77. shortcut.CommandView = new ()
  78. {
  79. Text = "T"
  80. };
  81. Assert.Equal (shortcut.Title, shortcut.CommandView.Text);
  82. }
  83. [Fact]
  84. public void HelpText_And_Text_Are_The_Same ()
  85. {
  86. var shortcut = new Shortcut
  87. {
  88. Text = "H"
  89. };
  90. Assert.Equal (shortcut.Text, shortcut.HelpText);
  91. shortcut = new ()
  92. {
  93. HelpText = "H"
  94. };
  95. Assert.Equal (shortcut.Text, shortcut.HelpText);
  96. }
  97. [Theory]
  98. [InlineData (KeyCode.Null, "")]
  99. [InlineData (KeyCode.F1, "F1")]
  100. public void KeyView_Text_Tracks_Key (KeyCode key, string expected)
  101. {
  102. var shortcut = new Shortcut
  103. {
  104. Key = key
  105. };
  106. Assert.Equal (expected, shortcut.KeyView.Text);
  107. }
  108. // Test Key
  109. [Fact]
  110. public void Key_Defaults_To_Empty ()
  111. {
  112. var shortcut = new Shortcut ();
  113. Assert.Equal (Key.Empty, shortcut.Key);
  114. }
  115. [Fact]
  116. public void Key_Can_Be_Set ()
  117. {
  118. var shortcut = new Shortcut ();
  119. shortcut.Key = Key.F1;
  120. Assert.Equal (Key.F1, shortcut.Key);
  121. }
  122. [Fact]
  123. public void Key_Can_Be_Set_To_Empty ()
  124. {
  125. var shortcut = new Shortcut ();
  126. shortcut.Key = Key.Empty;
  127. Assert.Equal (Key.Empty, shortcut.Key);
  128. }
  129. // Test KeyBindingScope
  130. // Test Key gets bound correctly
  131. [Fact]
  132. public void KeyBindingScope_Defaults_To_HotKey ()
  133. {
  134. var shortcut = new Shortcut ();
  135. Assert.Equal (KeyBindingScope.HotKey, shortcut.KeyBindingScope);
  136. }
  137. [Fact]
  138. public void KeyBindingScope_Can_Be_Set ()
  139. {
  140. var shortcut = new Shortcut ();
  141. shortcut.KeyBindingScope = KeyBindingScope.Application;
  142. Assert.Equal (KeyBindingScope.Application, shortcut.KeyBindingScope);
  143. }
  144. [Fact]
  145. public void Setting_Key_Binds_Key_To_CommandView_Accept ()
  146. {
  147. var shortcut = new Shortcut ();
  148. shortcut.Key = Key.F1;
  149. // TODO:
  150. }
  151. [Theory]
  152. [InlineData (Orientation.Horizontal)]
  153. [InlineData (Orientation.Vertical)]
  154. public void Orientation_SetsCorrectly (Orientation orientation)
  155. {
  156. var shortcut = new Shortcut
  157. {
  158. Orientation = orientation
  159. };
  160. Assert.Equal (orientation, shortcut.Orientation);
  161. }
  162. [Theory]
  163. [InlineData (AlignmentModes.StartToEnd)]
  164. [InlineData (AlignmentModes.EndToStart)]
  165. public void AlignmentModes_SetsCorrectly (AlignmentModes alignmentModes)
  166. {
  167. var shortcut = new Shortcut
  168. {
  169. AlignmentModes = alignmentModes
  170. };
  171. Assert.Equal (alignmentModes, shortcut.AlignmentModes);
  172. }
  173. [Fact]
  174. public void Action_SetsAndGetsCorrectly ()
  175. {
  176. var actionInvoked = false;
  177. var shortcut = new Shortcut
  178. {
  179. Action = () => { actionInvoked = true; }
  180. };
  181. shortcut.Action.Invoke ();
  182. Assert.True (actionInvoked);
  183. }
  184. [Fact]
  185. public void ColorScheme_SetsAndGetsCorrectly ()
  186. {
  187. var colorScheme = new ColorScheme ();
  188. var shortcut = new Shortcut
  189. {
  190. ColorScheme = colorScheme
  191. };
  192. Assert.Same (colorScheme, shortcut.ColorScheme);
  193. }
  194. [Fact]
  195. public void Subview_Visibility_Controlled_By_Removal ()
  196. {
  197. var shortcut = new Shortcut ();
  198. Assert.True (shortcut.CommandView.Visible);
  199. Assert.Contains (shortcut.CommandView, shortcut.Subviews);
  200. Assert.True (shortcut.HelpView.Visible);
  201. Assert.DoesNotContain (shortcut.HelpView, shortcut.Subviews);
  202. Assert.True (shortcut.KeyView.Visible);
  203. Assert.DoesNotContain (shortcut.KeyView, shortcut.Subviews);
  204. shortcut.HelpText = "help";
  205. Assert.True (shortcut.HelpView.Visible);
  206. Assert.Contains (shortcut.HelpView, shortcut.Subviews);
  207. Assert.True (shortcut.KeyView.Visible);
  208. Assert.DoesNotContain (shortcut.KeyView, shortcut.Subviews);
  209. shortcut.Key = Key.A;
  210. Assert.True (shortcut.HelpView.Visible);
  211. Assert.Contains (shortcut.HelpView, shortcut.Subviews);
  212. Assert.True (shortcut.KeyView.Visible);
  213. Assert.Contains (shortcut.KeyView, shortcut.Subviews);
  214. shortcut.HelpView.Visible = false;
  215. shortcut.ShowHide ();
  216. Assert.False (shortcut.HelpView.Visible);
  217. Assert.DoesNotContain (shortcut.HelpView, shortcut.Subviews);
  218. Assert.True (shortcut.KeyView.Visible);
  219. Assert.Contains (shortcut.KeyView, shortcut.Subviews);
  220. shortcut.KeyView.Visible = false;
  221. shortcut.ShowHide ();
  222. Assert.False (shortcut.HelpView.Visible);
  223. Assert.DoesNotContain (shortcut.HelpView, shortcut.Subviews);
  224. Assert.False (shortcut.KeyView.Visible);
  225. Assert.DoesNotContain (shortcut.KeyView, shortcut.Subviews);
  226. }
  227. [Fact]
  228. public void Focus_CanFocus_Default_Is_True ()
  229. {
  230. Shortcut shortcut = new ();
  231. shortcut.Key = Key.A;
  232. shortcut.Text = "Help";
  233. shortcut.Title = "Command";
  234. Assert.True (shortcut.CanFocus);
  235. Assert.False (shortcut.CommandView.CanFocus);
  236. }
  237. [Fact]
  238. public void Focus_CanFocus_CommandView_Add_Tracks ()
  239. {
  240. Shortcut shortcut = new ();
  241. Assert.True (shortcut.CanFocus);
  242. Assert.False (shortcut.CommandView.CanFocus);
  243. shortcut.CommandView = new () { CanFocus = true };
  244. Assert.False (shortcut.CommandView.CanFocus);
  245. shortcut.CommandView.CanFocus = true;
  246. Assert.True (shortcut.CommandView.CanFocus);
  247. shortcut.CanFocus = false;
  248. Assert.False (shortcut.CanFocus);
  249. Assert.True (shortcut.CommandView.CanFocus);
  250. shortcut.CommandView.CanFocus = false;
  251. Assert.False (shortcut.CanFocus);
  252. Assert.False (shortcut.CommandView.CanFocus);
  253. shortcut.CommandView.CanFocus = true;
  254. Assert.False (shortcut.CanFocus);
  255. Assert.True (shortcut.CommandView.CanFocus);
  256. }
  257. [Theory]
  258. // 0123456789
  259. // " C 0 A "
  260. [InlineData (-1, 0)]
  261. [InlineData (0, 1)]
  262. [InlineData (1, 1)]
  263. [InlineData (2, 1)]
  264. [InlineData (3, 1)]
  265. [InlineData (4, 1)]
  266. [InlineData (5, 1)]
  267. [InlineData (6, 1)]
  268. [InlineData (7, 1)]
  269. [InlineData (8, 1)]
  270. [InlineData (9, 0)]
  271. [AutoInitShutdown]
  272. public void MouseClick_Fires_Accept (int x, int expectedAccept)
  273. {
  274. var current = new Toplevel ();
  275. var shortcut = new Shortcut
  276. {
  277. Key = Key.A,
  278. Text = "0",
  279. Title = "C"
  280. };
  281. current.Add (shortcut);
  282. Application.Begin (current);
  283. var accepted = 0;
  284. shortcut.Accept += (s, e) => accepted++;
  285. Application.OnMouseEvent (
  286. new()
  287. {
  288. Position = new (x, 0),
  289. Flags = MouseFlags.Button1Clicked
  290. });
  291. Assert.Equal (expectedAccept, accepted);
  292. current.Dispose ();
  293. }
  294. [Theory]
  295. // 0123456789
  296. // " C 0 A "
  297. [InlineData (-1, 0, 0)]
  298. [InlineData (0, 1, 1)]
  299. [InlineData (1, 1, 1, Skip = "BUGBUG: This breaks. We need to fix the logic in the Shortcut class.")]
  300. [InlineData (2, 1, 1)]
  301. [InlineData (3, 1, 1)]
  302. [InlineData (4, 1, 1)]
  303. [InlineData (5, 1, 1)]
  304. [InlineData (6, 1, 1)]
  305. [InlineData (7, 1, 1)]
  306. [InlineData (8, 1, 1)]
  307. [InlineData (9, 0, 0)]
  308. [AutoInitShutdown]
  309. public void MouseClick_Button_CommandView_Fires_Accept (int x, int expectedAccept, int expectedButtonAccept)
  310. {
  311. var current = new Toplevel ();
  312. var shortcut = new Shortcut
  313. {
  314. Key = Key.A,
  315. Text = "0"
  316. };
  317. shortcut.CommandView = new Button
  318. {
  319. Title = "C",
  320. NoDecorations = true,
  321. NoPadding = true
  322. };
  323. var buttonAccepted = 0;
  324. shortcut.CommandView.Accept += (s, e) => { buttonAccepted++; };
  325. current.Add (shortcut);
  326. Application.Begin (current);
  327. var accepted = 0;
  328. shortcut.Accept += (s, e) => accepted++;
  329. //Assert.True (shortcut.HasFocus);
  330. Application.OnMouseEvent (
  331. new()
  332. {
  333. Position = new (x, 0),
  334. Flags = MouseFlags.Button1Clicked
  335. });
  336. Assert.Equal (expectedAccept, accepted);
  337. Assert.Equal (expectedButtonAccept, buttonAccepted);
  338. current.Dispose ();
  339. }
  340. [Theory]
  341. [InlineData (true, KeyCode.A, 1)]
  342. [InlineData (true, KeyCode.C, 1)]
  343. [InlineData (true, KeyCode.C | KeyCode.AltMask, 1)]
  344. [InlineData (true, KeyCode.Enter, 1)]
  345. [InlineData (true, KeyCode.Space, 0)]
  346. [InlineData (true, KeyCode.F1, 0)]
  347. [InlineData (false, KeyCode.A, 1)]
  348. [InlineData (false, KeyCode.C, 1)]
  349. [InlineData (false, KeyCode.C | KeyCode.AltMask, 1)]
  350. [InlineData (false, KeyCode.Enter, 0)]
  351. [InlineData (false, KeyCode.Space, 0)]
  352. [InlineData (false, KeyCode.F1, 0)]
  353. [AutoInitShutdown]
  354. public void KeyDown_Invokes_Accept (bool canFocus, KeyCode key, int expectedAccept)
  355. {
  356. var current = new Toplevel ();
  357. var shortcut = new Shortcut
  358. {
  359. Key = Key.A,
  360. Text = "0",
  361. Title = "_C",
  362. CanFocus = canFocus
  363. };
  364. current.Add (shortcut);
  365. Application.Begin (current);
  366. Assert.Equal (canFocus, shortcut.HasFocus);
  367. var accepted = 0;
  368. shortcut.Accept += (s, e) => accepted++;
  369. Application.OnKeyDown (key);
  370. Assert.Equal (expectedAccept, accepted);
  371. current.Dispose ();
  372. }
  373. [Theory]
  374. [InlineData (KeyCode.A, 1)]
  375. [InlineData (KeyCode.C, 1)]
  376. [InlineData (KeyCode.C | KeyCode.AltMask, 1)]
  377. [InlineData (KeyCode.Enter, 1)]
  378. [InlineData (KeyCode.Space, 0)]
  379. [InlineData (KeyCode.F1, 0)]
  380. [AutoInitShutdown]
  381. public void KeyDown_App_Scope_Invokes_Accept (KeyCode key, int expectedAccept)
  382. {
  383. var current = new Toplevel ();
  384. var shortcut = new Shortcut
  385. {
  386. Key = Key.A,
  387. KeyBindingScope = KeyBindingScope.Application,
  388. Text = "0",
  389. Title = "_C"
  390. };
  391. current.Add (shortcut);
  392. Application.Begin (current);
  393. var accepted = 0;
  394. shortcut.Accept += (s, e) => accepted++;
  395. Application.OnKeyDown (key);
  396. Assert.Equal (expectedAccept, accepted);
  397. current.Dispose ();
  398. }
  399. [Theory]
  400. [InlineData (true, KeyCode.A, 1)]
  401. [InlineData (true, KeyCode.C, 1)]
  402. [InlineData (true, KeyCode.C | KeyCode.AltMask, 1)]
  403. [InlineData (true, KeyCode.Enter, 1)]
  404. [InlineData (true, KeyCode.Space, 0)]
  405. [InlineData (true, KeyCode.F1, 0)]
  406. [InlineData (false, KeyCode.A, 1)]
  407. [InlineData (false, KeyCode.C, 1)]
  408. [InlineData (false, KeyCode.C | KeyCode.AltMask, 1)]
  409. [InlineData (false, KeyCode.Enter, 0)]
  410. [InlineData (false, KeyCode.Space, 0)]
  411. [InlineData (false, KeyCode.F1, 0)]
  412. [AutoInitShutdown]
  413. public void KeyDown_Invokes_Action (bool canFocus, KeyCode key, int expectedAction)
  414. {
  415. var current = new Toplevel ();
  416. var shortcut = new Shortcut
  417. {
  418. Key = Key.A,
  419. Text = "0",
  420. Title = "_C",
  421. CanFocus = canFocus
  422. };
  423. current.Add (shortcut);
  424. Application.Begin (current);
  425. Assert.Equal (canFocus, shortcut.HasFocus);
  426. var action = 0;
  427. shortcut.Action += () => action++;
  428. Application.OnKeyDown (key);
  429. Assert.Equal (expectedAction, action);
  430. current.Dispose ();
  431. }
  432. [Theory]
  433. [InlineData (true, KeyCode.A, 1)]
  434. [InlineData (true, KeyCode.C, 1)]
  435. [InlineData (true, KeyCode.C | KeyCode.AltMask, 1)]
  436. [InlineData (true, KeyCode.Enter, 1)]
  437. [InlineData (true, KeyCode.Space, 0)]
  438. [InlineData (true, KeyCode.F1, 0)]
  439. [InlineData (false, KeyCode.A, 1)]
  440. [InlineData (false, KeyCode.C, 1)]
  441. [InlineData (false, KeyCode.C | KeyCode.AltMask, 1)]
  442. [InlineData (false, KeyCode.Enter, 0)]
  443. [InlineData (false, KeyCode.Space, 0)]
  444. [InlineData (false, KeyCode.F1, 0)]
  445. [AutoInitShutdown]
  446. public void KeyDown_App_Scope_Invokes_Action (bool canFocus, KeyCode key, int expectedAction)
  447. {
  448. var current = new Toplevel ();
  449. var shortcut = new Shortcut
  450. {
  451. Key = Key.A,
  452. KeyBindingScope = KeyBindingScope.Application,
  453. Text = "0",
  454. Title = "_C",
  455. CanFocus = canFocus
  456. };
  457. current.Add (shortcut);
  458. Application.Begin (current);
  459. Assert.Equal (canFocus, shortcut.HasFocus);
  460. var action = 0;
  461. shortcut.Action += () => action++;
  462. Application.OnKeyDown (key);
  463. Assert.Equal (expectedAction, action);
  464. current.Dispose ();
  465. }
  466. }