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