ContextMenuTests.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. using Xunit;
  2. using Xunit.Abstractions;
  3. using GraphViewTests = Terminal.Gui.Views.GraphViewTests;
  4. namespace Terminal.Gui.Core {
  5. public class ContextMenuTests {
  6. readonly ITestOutputHelper output;
  7. public ContextMenuTests (ITestOutputHelper output)
  8. {
  9. this.output = output;
  10. }
  11. [Fact]
  12. [AutoInitShutdown]
  13. public void ContextMenu_Constructors ()
  14. {
  15. var cm = new ContextMenu ();
  16. Assert.Equal (new Point (0, 0), cm.Position);
  17. Assert.Empty (cm.MenuItens.Children);
  18. Assert.Null (cm.Host);
  19. cm.Position = new Point (20, 10);
  20. cm.MenuItens = new MenuBarItem (new MenuItem [] {
  21. new MenuItem ("First", "", null)
  22. });
  23. Assert.Equal (new Point (20, 10), cm.Position);
  24. Assert.Single (cm.MenuItens.Children);
  25. cm = new ContextMenu (5, 10,
  26. new MenuBarItem (new MenuItem [] {
  27. new MenuItem ("One", "", null),
  28. new MenuItem ("Two", "", null)
  29. })
  30. );
  31. Assert.Equal (new Point (5, 10), cm.Position);
  32. Assert.Equal (2, cm.MenuItens.Children.Length);
  33. Assert.Null (cm.Host);
  34. cm = new ContextMenu (new View () { X = 5, Y = 10 },
  35. new MenuBarItem (new MenuItem [] {
  36. new MenuItem ("One", "", null),
  37. new MenuItem ("Two", "", null)
  38. })
  39. );
  40. Assert.Equal (new Point (5, 10), cm.Position);
  41. Assert.Equal (2, cm.MenuItens.Children.Length);
  42. Assert.NotNull (cm.Host);
  43. }
  44. [Fact]
  45. [AutoInitShutdown]
  46. public void Show_Hide_IsShow ()
  47. {
  48. var cm = new ContextMenu (10, 5,
  49. new MenuBarItem (new MenuItem [] {
  50. new MenuItem ("One", "", null),
  51. new MenuItem ("Two", "", null)
  52. })
  53. );
  54. cm.Show ();
  55. Assert.True (ContextMenu.IsShow);
  56. Application.Begin (Application.Top);
  57. var expected = @"
  58. ┌──────┐
  59. │ One │
  60. │ Two │
  61. └──────┘
  62. ";
  63. GraphViewTests.AssertDriverContentsAre (expected, output);
  64. cm.Hide ();
  65. Assert.False (ContextMenu.IsShow);
  66. Application.Refresh ();
  67. expected = "";
  68. GraphViewTests.AssertDriverContentsAre (expected, output);
  69. }
  70. [Fact]
  71. [AutoInitShutdown]
  72. public void Position_Changing ()
  73. {
  74. var cm = new ContextMenu (10, 5,
  75. new MenuBarItem (new MenuItem [] {
  76. new MenuItem ("One", "", null),
  77. new MenuItem ("Two", "", null)
  78. })
  79. );
  80. cm.Show ();
  81. Application.Begin (Application.Top);
  82. var expected = @"
  83. ┌──────┐
  84. │ One │
  85. │ Two │
  86. └──────┘
  87. ";
  88. GraphViewTests.AssertDriverContentsAre (expected, output);
  89. cm.Position = new Point (5, 10);
  90. cm.Show ();
  91. Application.Refresh ();
  92. expected = @"
  93. ┌──────┐
  94. │ One │
  95. │ Two │
  96. └──────┘
  97. ";
  98. GraphViewTests.AssertDriverContentsAre (expected, output);
  99. }
  100. [Fact]
  101. [AutoInitShutdown]
  102. public void MenuItens_Changing ()
  103. {
  104. var cm = new ContextMenu (10, 5,
  105. new MenuBarItem (new MenuItem [] {
  106. new MenuItem ("One", "", null),
  107. new MenuItem ("Two", "", null)
  108. })
  109. );
  110. cm.Show ();
  111. Application.Begin (Application.Top);
  112. var expected = @"
  113. ┌──────┐
  114. │ One │
  115. │ Two │
  116. └──────┘
  117. ";
  118. GraphViewTests.AssertDriverContentsAre (expected, output);
  119. cm.MenuItens = new MenuBarItem (new MenuItem [] {
  120. new MenuItem ("First", "", null),
  121. new MenuItem ("Second", "", null),
  122. new MenuItem ("Third", "", null)
  123. });
  124. cm.Show ();
  125. Application.Refresh ();
  126. expected = @"
  127. ┌─────────┐
  128. │ First │
  129. │ Second │
  130. │ Third │
  131. └─────────┘
  132. ";
  133. GraphViewTests.AssertDriverContentsAre (expected, output);
  134. }
  135. [Fact, AutoInitShutdown]
  136. public void Key_Changing ()
  137. {
  138. var lbl = new Label ("Original");
  139. var cm = new ContextMenu ();
  140. lbl.KeyPress += (e) => {
  141. if (e.KeyEvent.Key == cm.Key) {
  142. lbl.Text = "Replaced";
  143. e.Handled = true;
  144. }
  145. };
  146. var top = Application.Top;
  147. top.Add (lbl);
  148. Application.Begin (top);
  149. Assert.True (lbl.ProcessKey (new KeyEvent (cm.Key, new KeyModifiers ())));
  150. Assert.Equal ("Replaced", lbl.Text);
  151. lbl.Text = "Original";
  152. cm.Key = Key.Space | Key.CtrlMask;
  153. Assert.True (lbl.ProcessKey (new KeyEvent (cm.Key, new KeyModifiers ())));
  154. Assert.Equal ("Replaced", lbl.Text);
  155. }
  156. [Fact, AutoInitShutdown]
  157. public void MouseFlags_Changing ()
  158. {
  159. var lbl = new Label ("Original");
  160. var cm = new ContextMenu ();
  161. lbl.MouseClick += (e) => {
  162. if (e.MouseEvent.Flags == cm.MouseFlags) {
  163. lbl.Text = "Replaced";
  164. e.Handled = true;
  165. }
  166. };
  167. var top = Application.Top;
  168. top.Add (lbl);
  169. Application.Begin (top);
  170. Assert.True (lbl.OnMouseEvent (new MouseEvent () { Flags = cm.MouseFlags }));
  171. Assert.Equal ("Replaced", lbl.Text);
  172. lbl.Text = "Original";
  173. cm.MouseFlags = MouseFlags.Button2Clicked;
  174. Assert.True (lbl.OnMouseEvent (new MouseEvent () { Flags = cm.MouseFlags }));
  175. Assert.Equal ("Replaced", lbl.Text);
  176. }
  177. [Fact, AutoInitShutdown]
  178. public void KeyChanged_Event ()
  179. {
  180. var oldKey = Key.Null;
  181. var cm = new ContextMenu ();
  182. cm.KeyChanged += (e) => oldKey = e;
  183. cm.Key = Key.Space | Key.CtrlMask;
  184. Assert.Equal (Key.Space | Key.CtrlMask, cm.Key);
  185. Assert.Equal (Key.F10 | Key.ShiftMask, oldKey);
  186. }
  187. [Fact, AutoInitShutdown]
  188. public void MouseFlagsChanged_Event ()
  189. {
  190. var oldMouseFlags = new MouseFlags ();
  191. var cm = new ContextMenu ();
  192. cm.MouseFlagsChanged += (e) => oldMouseFlags = e;
  193. cm.MouseFlags = MouseFlags.Button2Clicked;
  194. Assert.Equal (MouseFlags.Button2Clicked, cm.MouseFlags);
  195. Assert.Equal (MouseFlags.Button3Clicked, oldMouseFlags);
  196. }
  197. [Fact, AutoInitShutdown]
  198. public void Show_Ensures_Display_Inside_The_Container_But_Preserves_Position ()
  199. {
  200. var cm = new ContextMenu (80, 25,
  201. new MenuBarItem (new MenuItem [] {
  202. new MenuItem ("One", "", null),
  203. new MenuItem ("Two", "", null)
  204. })
  205. );
  206. Assert.Equal (new Point (80, 25), cm.Position);
  207. cm.Show ();
  208. Assert.Equal (new Point (80, 25), cm.Position);
  209. Application.Begin (Application.Top);
  210. var expected = @"
  211. ┌──────┐
  212. │ One │
  213. │ Two │
  214. └──────┘
  215. ";
  216. var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  217. Assert.Equal (new Rect (72, 21, 80, 4), pos);
  218. cm.Hide ();
  219. Assert.Equal (new Point (80, 25), cm.Position);
  220. }
  221. [Fact, AutoInitShutdown]
  222. public void Show_Ensures_Display_Inside_The_Container_Without_Overlap_The_Host ()
  223. {
  224. var view = new View ("View") {
  225. X = Pos.AnchorEnd (10),
  226. Y = Pos.AnchorEnd (1),
  227. Width = 10,
  228. Height = 1
  229. };
  230. var cm = new ContextMenu (view,
  231. new MenuBarItem (new MenuItem [] {
  232. new MenuItem ("One", "", null),
  233. new MenuItem ("Two", "", null)
  234. })
  235. );
  236. Application.Top.Add (view);
  237. Application.Begin (Application.Top);
  238. Assert.Equal (new Rect (70, 24, 10, 1), view.Frame);
  239. Assert.Equal (new Point (0, 0), cm.Position);
  240. cm.Show ();
  241. Assert.Equal (new Point (70, 24), cm.Position);
  242. Application.Top.Redraw (Application.Top.Bounds);
  243. var expected = @"
  244. ┌──────┐
  245. │ One │
  246. │ Two │
  247. └──────┘
  248. View
  249. ";
  250. var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  251. Assert.Equal (new Rect (70, 20, 78, 5), pos);
  252. cm.Hide ();
  253. Assert.Equal (new Point (70, 24), cm.Position);
  254. }
  255. [Fact, AutoInitShutdown]
  256. public void Show_Display_Below_The_Bottom_Host_If_Has_Enough_Space ()
  257. {
  258. var view = new View ("View") { X = 10, Y = 5, Width = 10, Height = 1 };
  259. var cm = new ContextMenu (view,
  260. new MenuBarItem (new MenuItem [] {
  261. new MenuItem ("One", "", null),
  262. new MenuItem ("Two", "", null)
  263. })
  264. );
  265. Application.Top.Add (view);
  266. Application.Begin (Application.Top);
  267. Assert.Equal (new Point (10, 5), cm.Position);
  268. cm.Show ();
  269. Application.Top.Redraw (Application.Top.Bounds);
  270. Assert.Equal (new Point (10, 5), cm.Position);
  271. var expected = @"
  272. View
  273. ┌──────┐
  274. │ One │
  275. │ Two │
  276. └──────┘
  277. ";
  278. var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  279. Assert.Equal (new Rect (10, 5, 18, 5), pos);
  280. cm.Hide ();
  281. Assert.Equal (new Point (10, 5), cm.Position);
  282. cm.Host.X = 5;
  283. cm.Host.Y = 10;
  284. cm.Host.Height = 3;
  285. cm.Show ();
  286. Application.Top.Redraw (Application.Top.Bounds);
  287. Assert.Equal (new Point (5, 12), cm.Position);
  288. expected = @"
  289. View
  290. ┌──────┐
  291. │ One │
  292. │ Two │
  293. └──────┘
  294. ";
  295. pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  296. Assert.Equal (new Rect (5, 10, 13, 7), pos);
  297. cm.Hide ();
  298. Assert.Equal (new Point (5, 12), cm.Position);
  299. }
  300. [Fact, AutoInitShutdown]
  301. public void Show_Display_At_Zero_If_The_Toplevel_Width_Is_Less_Than_The_Menu_Width ()
  302. {
  303. var cm = new ContextMenu (0, 0,
  304. new MenuBarItem (new MenuItem [] {
  305. new MenuItem ("One", "", null),
  306. new MenuItem ("Two", "", null)
  307. })
  308. );
  309. Assert.Equal (new Point (0, 0), cm.Position);
  310. cm.Show ();
  311. Assert.Equal (new Point (0, 0), cm.Position);
  312. Application.Begin (Application.Top);
  313. ((FakeDriver)Application.Driver).SetBufferSize (5, 25);
  314. var expected = @"
  315. ┌────
  316. │ One
  317. │ Two
  318. └────
  319. ";
  320. var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  321. Assert.Equal (new Rect (0, 1, 5, 4), pos);
  322. cm.Hide ();
  323. Assert.Equal (new Point (0, 0), cm.Position);
  324. }
  325. [Fact, AutoInitShutdown]
  326. public void Show_Display_At_Zero_If_The_Toplevel_Height_Is_Less_Than_The_Menu_Height ()
  327. {
  328. var cm = new ContextMenu (0, 0,
  329. new MenuBarItem (new MenuItem [] {
  330. new MenuItem ("One", "", null),
  331. new MenuItem ("Two", "", null)
  332. })
  333. );
  334. Assert.Equal (new Point (0, 0), cm.Position);
  335. cm.Show ();
  336. Assert.Equal (new Point (0, 0), cm.Position);
  337. Application.Begin (Application.Top);
  338. ((FakeDriver)Application.Driver).SetBufferSize (80, 4);
  339. var expected = @"
  340. ┌──────┐
  341. │ One │
  342. │ Two │
  343. ";
  344. var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  345. Assert.Equal (new Rect (0, 1, 8, 3), pos);
  346. cm.Hide ();
  347. Assert.Equal (new Point (0, 0), cm.Position);
  348. }
  349. [Fact, AutoInitShutdown]
  350. public void Hide_Is_Invoke_At_Container_Closing ()
  351. {
  352. var cm = new ContextMenu (80, 25,
  353. new MenuBarItem (new MenuItem [] {
  354. new MenuItem ("One", "", null),
  355. new MenuItem ("Two", "", null)
  356. })
  357. );
  358. var top = Application.Top;
  359. Application.Begin (top);
  360. top.Running = true;
  361. Assert.False (ContextMenu.IsShow);
  362. cm.Show ();
  363. Assert.True (ContextMenu.IsShow);
  364. top.RequestStop ();
  365. Assert.False (ContextMenu.IsShow);
  366. }
  367. [Fact, AutoInitShutdown]
  368. public void ForceMinimumPosToZero_True_False ()
  369. {
  370. var cm = new ContextMenu (-1, -2,
  371. new MenuBarItem (new MenuItem [] {
  372. new MenuItem ("One", "", null),
  373. new MenuItem ("Two", "", null)
  374. })
  375. );
  376. Assert.Equal (new Point (-1, -2), cm.Position);
  377. cm.Show ();
  378. Assert.Equal (new Point (-1, -2), cm.Position);
  379. Application.Begin (Application.Top);
  380. var expected = @"
  381. ┌──────┐
  382. │ One │
  383. │ Two │
  384. └──────┘
  385. ";
  386. var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  387. Assert.Equal (new Rect (0, 1, 8, 4), pos);
  388. cm.ForceMinimumPosToZero = false;
  389. cm.Show ();
  390. Assert.Equal (new Point (-1, -2), cm.Position);
  391. Application.Refresh ();
  392. expected = @"
  393. One │
  394. Two │
  395. ──────┘
  396. ";
  397. pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  398. Assert.Equal (new Rect (1, 0, 7, 3), pos);
  399. }
  400. [Fact, AutoInitShutdown]
  401. public void ContextMenu_Is_Closed_If_Another_MenuBar_Is_Open_Or_Vice_Versa ()
  402. {
  403. var cm = new ContextMenu (10, 5,
  404. new MenuBarItem (new MenuItem [] {
  405. new MenuItem ("One", "", null),
  406. new MenuItem ("Two", "", null)
  407. })
  408. );
  409. var menu = new MenuBar (new MenuBarItem [] {
  410. new MenuBarItem ("File", "", null),
  411. new MenuBarItem ("Edit", "", null)
  412. });
  413. Application.Top.Add (menu);
  414. Assert.Null (Application.mouseGrabView);
  415. cm.Show ();
  416. Assert.True (ContextMenu.IsShow);
  417. Assert.Equal (cm.MenuBar, Application.mouseGrabView);
  418. Assert.False (menu.IsMenuOpen);
  419. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  420. Assert.False (ContextMenu.IsShow);
  421. Assert.Equal (menu, Application.mouseGrabView);
  422. Assert.True (menu.IsMenuOpen);
  423. cm.Show ();
  424. Assert.True (ContextMenu.IsShow);
  425. Assert.Equal (cm.MenuBar, Application.mouseGrabView);
  426. Assert.False (menu.IsMenuOpen);
  427. Assert.False (menu.OnKeyDown (new KeyEvent (Key.Null, new KeyModifiers () { Alt = true })));
  428. Assert.True (menu.OnKeyUp (new KeyEvent (Key.Null, new KeyModifiers () { Alt = true })));
  429. Assert.False (ContextMenu.IsShow);
  430. Assert.Equal (menu, Application.mouseGrabView);
  431. Assert.True (menu.IsMenuOpen);
  432. cm.Show ();
  433. Assert.True (ContextMenu.IsShow);
  434. Assert.Equal (cm.MenuBar, Application.mouseGrabView);
  435. Assert.False (menu.IsMenuOpen);
  436. Assert.False (menu.MouseEvent (new MouseEvent () { X = 1, Flags = MouseFlags.ReportMousePosition, View = menu }));
  437. Assert.True (ContextMenu.IsShow);
  438. Assert.Equal (cm.MenuBar, Application.mouseGrabView);
  439. Assert.False (menu.IsMenuOpen);
  440. Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, Flags = MouseFlags.Button1Clicked, View = menu }));
  441. Assert.False (ContextMenu.IsShow);
  442. Assert.Equal (menu, Application.mouseGrabView);
  443. Assert.True (menu.IsMenuOpen);
  444. }
  445. [Fact, AutoInitShutdown]
  446. public void ContextMenu_On_Toplevel_With_A_MenuBar_TextField_StatusBar ()
  447. {
  448. var menu = new MenuBar (new MenuBarItem [] {
  449. new MenuBarItem ("File", "", null),
  450. new MenuBarItem ("Edit", "", null)
  451. });
  452. var label = new Label ("Label:") {
  453. X = 2,
  454. Y = 3
  455. };
  456. var tf = new TextField ("TextField") {
  457. X = Pos.Right (label) + 1,
  458. Y = Pos.Top (label),
  459. Width = 20
  460. };
  461. var statusBar = new StatusBar (new StatusItem [] {
  462. new StatusItem(Key.F1, "~F1~ Help", null),
  463. new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", null)
  464. });
  465. Application.Top.Add (menu, label, tf, statusBar);
  466. Application.Begin (Application.Top);
  467. ((FakeDriver)Application.Driver).SetBufferSize (45, 17);
  468. Assert.Equal (new Rect (9, 3, 20, 1), tf.Frame);
  469. Assert.True (tf.HasFocus);
  470. tf.ContextMenu.Show ();
  471. Assert.True (ContextMenu.IsShow);
  472. Assert.Equal (new Point (9, 3), tf.ContextMenu.Position);
  473. Application.Top.Redraw (Application.Top.Bounds);
  474. var expected = @"
  475. File Edit
  476. Label: TextField
  477. ┌────────────────────────────┐
  478. │ Select All Ctrl+T │
  479. │ Delete All Ctrl+Shift+D │
  480. │ Copy Ctrl+C │
  481. │ Cut Ctrl+X │
  482. │ Paste Ctrl+V │
  483. │ Undo Ctrl+Z │
  484. │ Redo Ctrl+Y │
  485. └────────────────────────────┘
  486. F1 Help │ ^Q Quit
  487. ";
  488. var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  489. Assert.Equal (new Rect (2, 0, 39, 17), pos);
  490. }
  491. [Fact, AutoInitShutdown]
  492. public void ContextMenu_On_Toplevel_With_A_MenuBar_Window_TextField_StatusBar ()
  493. {
  494. var menu = new MenuBar (new MenuBarItem [] {
  495. new MenuBarItem ("File", "", null),
  496. new MenuBarItem ("Edit", "", null)
  497. });
  498. var label = new Label ("Label:") {
  499. X = 2,
  500. Y = 3
  501. };
  502. var tf = new TextField ("TextField") {
  503. X = Pos.Right (label) + 1,
  504. Y = Pos.Top (label),
  505. Width = 20
  506. };
  507. var win = new Window ("Window");
  508. win.Add (label, tf);
  509. var statusBar = new StatusBar (new StatusItem [] {
  510. new StatusItem(Key.F1, "~F1~ Help", null),
  511. new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", null)
  512. });
  513. Application.Top.Add (menu, win, statusBar);
  514. Application.Begin (Application.Top);
  515. ((FakeDriver)Application.Driver).SetBufferSize (45, 17);
  516. Assert.Equal (new Rect (9, 3, 20, 1), tf.Frame);
  517. Assert.True (tf.HasFocus);
  518. tf.ContextMenu.Show ();
  519. Assert.True (ContextMenu.IsShow);
  520. Assert.Equal (new Point (10, 5), tf.ContextMenu.Position);
  521. Application.Top.Redraw (Application.Top.Bounds);
  522. var expected = @"
  523. File Edit
  524. ┌ Window ───────────────────────────────────┐
  525. │ │
  526. │ │
  527. │ │
  528. │ Label: TextField │
  529. │ ┌────────────────────────────┐ │
  530. │ │ Select All Ctrl+T │ │
  531. │ │ Delete All Ctrl+Shift+D │ │
  532. │ │ Copy Ctrl+C │ │
  533. │ │ Cut Ctrl+X │ │
  534. │ │ Paste Ctrl+V │ │
  535. │ │ Undo Ctrl+Z │ │
  536. │ │ Redo Ctrl+Y │ │
  537. │ └────────────────────────────┘ │
  538. └───────────────────────────────────────────┘
  539. F1 Help │ ^Q Quit
  540. ";
  541. var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
  542. Assert.Equal (new Rect (2, 0, 45, 17), pos);
  543. }
  544. }
  545. }