TabViewTests.cs 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525
  1. using System.Globalization;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class TabViewTests (ITestOutputHelper output)
  5. {
  6. [Fact]
  7. public void AddTab_SameTabMoreThanOnce ()
  8. {
  9. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  10. Assert.Equal (2, tv.Tabs.Count);
  11. // Tab is already part of the control so shouldn't result in duplication
  12. tv.AddTab (tab1, false);
  13. tv.AddTab (tab1, false);
  14. tv.AddTab (tab1, false);
  15. tv.AddTab (tab1, false);
  16. Assert.Equal (2, tv.Tabs.Count);
  17. // Shutdown must be called to safely clean up Application if Init has been called
  18. Application.Shutdown ();
  19. }
  20. [Fact]
  21. public void AddTwoTabs_SecondIsSelected ()
  22. {
  23. InitFakeDriver ();
  24. var tv = new TabView ();
  25. Tab tab1;
  26. Tab tab2;
  27. tv.AddTab (tab1 = new () { DisplayText = "Tab1", View = new TextField { Text = "hi" } }, false);
  28. tv.AddTab (tab2 = new () { DisplayText = "Tab1", View = new Label { Text = "hi2" } }, true);
  29. Assert.Equal (2, tv.Tabs.Count);
  30. Assert.Equal (tab2, tv.SelectedTab);
  31. Application.Shutdown ();
  32. }
  33. [Fact]
  34. public void EnsureSelectedTabVisible_MustScroll ()
  35. {
  36. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  37. // Make tab width small to force only one tab visible at once
  38. tv.Width = 4;
  39. tv.SelectedTab = tab1;
  40. Assert.Equal (0, tv.TabScrollOffset);
  41. tv.EnsureSelectedTabIsVisible ();
  42. Assert.Equal (0, tv.TabScrollOffset);
  43. // Asking to show tab2 should automatically move scroll offset accordingly
  44. tv.SelectedTab = tab2;
  45. Assert.Equal (1, tv.TabScrollOffset);
  46. // Shutdown must be called to safely clean up Application if Init has been called
  47. Application.Shutdown ();
  48. }
  49. [Fact]
  50. public void EnsureSelectedTabVisible_NullSelect ()
  51. {
  52. TabView tv = GetTabView ();
  53. tv.SelectedTab = null;
  54. Assert.Null (tv.SelectedTab);
  55. Assert.Equal (0, tv.TabScrollOffset);
  56. tv.EnsureSelectedTabIsVisible ();
  57. Assert.Null (tv.SelectedTab);
  58. Assert.Equal (0, tv.TabScrollOffset);
  59. Application.Shutdown ();
  60. }
  61. [Fact]
  62. public void EnsureValidScrollOffsets_TabScrollOffset ()
  63. {
  64. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  65. // Make tab width small to force only one tab visible at once
  66. tv.Width = 4;
  67. tv.SelectedTab = tab1;
  68. Assert.Equal (0, tv.TabScrollOffset);
  69. tv.TabScrollOffset = 10;
  70. tv.SelectedTab = tab2;
  71. Assert.Equal (1, tv.TabScrollOffset);
  72. tv.TabScrollOffset = -1;
  73. tv.SelectedTab = tab1;
  74. Assert.Equal (0, tv.TabScrollOffset);
  75. // Shutdown must be called to safely clean up Application if Init has been called
  76. Application.Shutdown ();
  77. }
  78. [Fact]
  79. [AutoInitShutdown]
  80. public void MouseClick_ChangesTab ()
  81. {
  82. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  83. tv.Width = 20;
  84. tv.Height = 5;
  85. tv.Draw ();
  86. View tabRow = tv.Subviews [0];
  87. Assert.Equal ("TabRowView", tabRow.GetType ().Name);
  88. TestHelpers.AssertDriverContentsAre (
  89. @"
  90. ╭────┬────╮
  91. │Tab1│Tab2│
  92. │ ╰────┴────────╮
  93. │hi │
  94. └──────────────────┘
  95. ",
  96. output
  97. );
  98. Tab clicked = null;
  99. tv.TabClicked += (s, e) => { clicked = e.Tab; };
  100. var top = new Toplevel ();
  101. top.Add (tv);
  102. Application.Begin (top);
  103. MouseEventArgs args;
  104. // Waving mouse around does not trigger click
  105. for (var i = 0; i < 100; i++)
  106. {
  107. args = new () { ScreenPosition = new (i, 1), Flags = MouseFlags.ReportMousePosition };
  108. Application.RaiseMouseEvent (args);
  109. Application.LayoutAndDraw ();
  110. Assert.Null (clicked);
  111. Assert.Equal (tab1, tv.SelectedTab);
  112. }
  113. args = new () { ScreenPosition = new (3, 1), Flags = MouseFlags.Button1Clicked };
  114. Application.RaiseMouseEvent (args);
  115. Application.LayoutAndDraw ();
  116. Assert.Equal (tab1, clicked);
  117. Assert.Equal (tab1, tv.SelectedTab);
  118. // Click to tab2
  119. args = new () { ScreenPosition = new (6, 1), Flags = MouseFlags.Button1Clicked };
  120. Application.RaiseMouseEvent (args);
  121. Application.LayoutAndDraw ();
  122. Assert.Equal (tab2, clicked);
  123. Assert.Equal (tab2, tv.SelectedTab);
  124. // cancel navigation
  125. tv.TabClicked += (s, e) =>
  126. {
  127. clicked = e.Tab;
  128. e.MouseEvent.Handled = true;
  129. };
  130. args = new () { ScreenPosition = new (3, 1), Flags = MouseFlags.Button1Clicked };
  131. Application.RaiseMouseEvent (args);
  132. Application.LayoutAndDraw ();
  133. // Tab 1 was clicked but event handler blocked navigation
  134. Assert.Equal (tab1, clicked);
  135. Assert.Equal (tab2, tv.SelectedTab);
  136. args = new () { ScreenPosition = new (12, 1), Flags = MouseFlags.Button1Clicked };
  137. Application.RaiseMouseEvent (args);
  138. Application.LayoutAndDraw ();
  139. // Clicking beyond last tab should raise event with null Tab
  140. Assert.Null (clicked);
  141. Assert.Equal (tab2, tv.SelectedTab);
  142. top.Dispose ();
  143. }
  144. [Fact]
  145. [AutoInitShutdown]
  146. public void MouseClick_Right_Left_Arrows_ChangesTab ()
  147. {
  148. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  149. tv.Width = 7;
  150. tv.Height = 5;
  151. tv.Draw ();
  152. View tabRow = tv.Subviews [0];
  153. Assert.Equal ("TabRowView", tabRow.GetType ().Name);
  154. TestHelpers.AssertDriverContentsAre (
  155. @"
  156. ╭────╮
  157. │Tab1│
  158. │ ╰►
  159. │hi │
  160. └─────┘
  161. ",
  162. output
  163. );
  164. Tab clicked = null;
  165. tv.TabClicked += (s, e) => { clicked = e.Tab; };
  166. Tab oldChanged = null;
  167. Tab newChanged = null;
  168. tv.SelectedTabChanged += (s, e) =>
  169. {
  170. oldChanged = e.OldTab;
  171. newChanged = e.NewTab;
  172. };
  173. var top = new Toplevel ();
  174. top.Add (tv);
  175. Application.Begin (top);
  176. // Click the right arrow
  177. var args = new MouseEventArgs { ScreenPosition = new (6, 2), Flags = MouseFlags.Button1Clicked };
  178. Application.RaiseMouseEvent (args);
  179. Application.LayoutAndDraw ();
  180. Assert.Null (clicked);
  181. Assert.Equal (tab1, oldChanged);
  182. Assert.Equal (tab2, newChanged);
  183. Assert.Equal (tab2, tv.SelectedTab);
  184. TestHelpers.AssertDriverContentsAre (
  185. @"
  186. ╭────╮
  187. │Tab2│
  188. ◄ ╰╮
  189. │hi2 │
  190. └─────┘
  191. ",
  192. output
  193. );
  194. // Click the left arrow
  195. args = new () { ScreenPosition = new (0, 2), Flags = MouseFlags.Button1Clicked };
  196. Application.RaiseMouseEvent (args);
  197. Application.LayoutAndDraw ();
  198. Assert.Null (clicked);
  199. Assert.Equal (tab2, oldChanged);
  200. Assert.Equal (tab1, newChanged);
  201. Assert.Equal (tab1, tv.SelectedTab);
  202. TestHelpers.AssertDriverContentsAre (
  203. @"
  204. ╭────╮
  205. │Tab1│
  206. │ ╰►
  207. │hi │
  208. └─────┘
  209. ",
  210. output
  211. );
  212. top.Dispose ();
  213. }
  214. [Fact]
  215. [AutoInitShutdown]
  216. public void MouseClick_Right_Left_Arrows_ChangesTab_With_Border ()
  217. {
  218. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  219. tv.Width = 9;
  220. tv.Height = 7;
  221. Assert.Equal (LineStyle.None, tv.BorderStyle);
  222. tv.BorderStyle = LineStyle.Single;
  223. tv.Layout ();
  224. tv.Draw ();
  225. View tabRow = tv.Subviews [0];
  226. Assert.Equal ("TabRowView", tabRow.GetType ().Name);
  227. TestHelpers.AssertDriverContentsAre (
  228. @"
  229. ┌───────┐
  230. │╭────╮ │
  231. ││Tab1│ │
  232. ││ ╰►│
  233. ││hi ││
  234. │└─────┘│
  235. └───────┘
  236. ",
  237. output
  238. );
  239. Tab clicked = null;
  240. tv.TabClicked += (s, e) => { clicked = e.Tab; };
  241. Tab oldChanged = null;
  242. Tab newChanged = null;
  243. tv.SelectedTabChanged += (s, e) =>
  244. {
  245. oldChanged = e.OldTab;
  246. newChanged = e.NewTab;
  247. };
  248. var top = new Toplevel ();
  249. top.Add (tv);
  250. Application.Begin (top);
  251. // Click the right arrow
  252. var args = new MouseEventArgs { ScreenPosition = new (7, 3), Flags = MouseFlags.Button1Clicked };
  253. Application.RaiseMouseEvent (args);
  254. Application.LayoutAndDraw ();
  255. Assert.Null (clicked);
  256. Assert.Equal (tab1, oldChanged);
  257. Assert.Equal (tab2, newChanged);
  258. Assert.Equal (tab2, tv.SelectedTab);
  259. TestHelpers.AssertDriverContentsAre (
  260. @"
  261. ┌───────┐
  262. │╭────╮ │
  263. ││Tab2│ │
  264. │◄ ╰╮│
  265. ││hi2 ││
  266. │└─────┘│
  267. └───────┘
  268. ",
  269. output
  270. );
  271. // Click the left arrow
  272. args = new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked };
  273. Application.RaiseMouseEvent (args);
  274. Application.LayoutAndDraw ();
  275. Assert.Null (clicked);
  276. Assert.Equal (tab2, oldChanged);
  277. Assert.Equal (tab1, newChanged);
  278. Assert.Equal (tab1, tv.SelectedTab);
  279. TestHelpers.AssertDriverContentsAre (
  280. @"
  281. ┌───────┐
  282. │╭────╮ │
  283. ││Tab1│ │
  284. ││ ╰►│
  285. ││hi ││
  286. │└─────┘│
  287. └───────┘
  288. ",
  289. output
  290. );
  291. top.Dispose ();
  292. }
  293. [Fact]
  294. [SetupFakeDriver]
  295. public void ProcessKey_Down_Up_Right_Left_Home_End_PageDown_PageUp_F6 ()
  296. {
  297. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  298. tv.Width = 7;
  299. tv.Height = 5;
  300. var btn = new Button
  301. {
  302. Id = "btn",
  303. Y = Pos.Bottom (tv) + 1,
  304. Height = 1,
  305. Width = 7,
  306. Text = "Ok"
  307. };
  308. Toplevel top = new ();
  309. top.Add (tv, btn);
  310. Application.Begin (top);
  311. // Is the selected tab view hosting focused
  312. Assert.Equal (tab1, tv.SelectedTab);
  313. Assert.Equal (tv, top.Focused);
  314. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  315. Assert.Equal (tv.SelectedTab.View, top.Focused.MostFocused);
  316. // Press the cursor up key to focus the selected tab
  317. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  318. Application.LayoutAndDraw ();
  319. // Is the selected tab focused
  320. Assert.Equal (tab1, tv.SelectedTab);
  321. Assert.Equal (tv, top.Focused);
  322. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  323. Tab oldChanged = null;
  324. Tab newChanged = null;
  325. tv.SelectedTabChanged += (s, e) =>
  326. {
  327. oldChanged = e.OldTab;
  328. newChanged = e.NewTab;
  329. };
  330. // Press the cursor right key to select the next tab
  331. Assert.True (Application.RaiseKeyDownEvent (Key.CursorRight));
  332. Application.LayoutAndDraw ();
  333. Assert.Equal (tab1, oldChanged);
  334. Assert.Equal (tab2, newChanged);
  335. Assert.Equal (tab2, tv.SelectedTab);
  336. Assert.Equal (tv, top.Focused);
  337. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  338. // Press the cursor down key. Since the selected tab has no focusable views, the focus should move to the next view in the toplevel
  339. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  340. Assert.Equal (tab2, tv.SelectedTab);
  341. Assert.Equal (btn, top.MostFocused);
  342. // Add a focusable subview to Selected Tab View which is a Label with CanFocus as false
  343. var btnSubView = new View ()
  344. {
  345. Id = "btnSubView",
  346. Title = "_Subview",
  347. CanFocus = true
  348. };
  349. tv.SelectedTab.View.Add (btnSubView);
  350. Assert.False (tv.SelectedTab.View.CanFocus);
  351. // Press cursor up. Should focus the subview in the selected tab.
  352. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  353. Assert.Equal (tab2, tv.SelectedTab);
  354. Assert.NotEqual (btnSubView, top.MostFocused);
  355. Assert.Equal (tab2, top.MostFocused);
  356. tv.SelectedTab.View.CanFocus = true;
  357. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  358. Assert.Equal (tab2, tv.SelectedTab);
  359. Assert.Equal (btnSubView, top.MostFocused);
  360. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  361. // TabRowView now has TabGroup which only F6 is allowed
  362. Assert.NotEqual (tab2, top.MostFocused);
  363. Assert.Equal (btn, top.MostFocused);
  364. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  365. Assert.Equal (btnSubView, top.MostFocused);
  366. Assert.True (Application.RaiseKeyDownEvent (Key.F6));
  367. Assert.Equal (tab2, top.MostFocused);
  368. // Press the cursor down key twice.
  369. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  370. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  371. Assert.Equal (btn, top.MostFocused);
  372. // Press the cursor down key again will focus next view in the toplevel, which is the TabView
  373. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  374. Assert.Equal (tab2, tv.SelectedTab);
  375. Assert.Equal (tv, top.Focused);
  376. // Due to the RestoreFocus method prioritize the _previouslyFocused, so btnSubView will be focused again
  377. Assert.Equal (btnSubView, tv.MostFocused);
  378. // Press the cursor up key to focus the selected tab which it's the only way to do that
  379. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  380. Assert.Equal (tab2, tv.SelectedTab);
  381. Assert.Equal (btn, top.Focused);
  382. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  383. Assert.Equal (tv, top.Focused);
  384. Assert.Equal (btnSubView, top.MostFocused);
  385. Assert.True (Application.RaiseKeyDownEvent (Key.F6));
  386. Assert.Equal (tv, top.Focused);
  387. Assert.Equal (tab2, top.Focused.MostFocused);
  388. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  389. // Press the cursor left key to select the previous tab
  390. Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft));
  391. Application.LayoutAndDraw ();
  392. Assert.Equal (tab2, oldChanged);
  393. Assert.Equal (tab1, newChanged);
  394. Assert.Equal (tab1, tv.SelectedTab);
  395. Assert.Equal (tv, top.Focused);
  396. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  397. Assert.Equal (tab1, top.Focused.MostFocused);
  398. // Press the end key to select the last tab
  399. Assert.True (Application.RaiseKeyDownEvent (Key.End));
  400. Application.LayoutAndDraw ();
  401. Assert.Equal (tab1, oldChanged);
  402. Assert.Equal (tab2, newChanged);
  403. Assert.Equal (tab2, tv.SelectedTab);
  404. Assert.Equal (tv, top.Focused);
  405. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  406. // Press the home key to select the first tab
  407. Assert.True (Application.RaiseKeyDownEvent (Key.Home));
  408. Application.LayoutAndDraw ();
  409. Assert.Equal (tab2, oldChanged);
  410. Assert.Equal (tab1, newChanged);
  411. Assert.Equal (tab1, tv.SelectedTab);
  412. Assert.Equal (tv, top.Focused);
  413. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  414. // Press the page down key to select the next set of tabs
  415. Assert.True (Application.RaiseKeyDownEvent (Key.PageDown));
  416. Application.LayoutAndDraw ();
  417. Assert.Equal (tab1, oldChanged);
  418. Assert.Equal (tab2, newChanged);
  419. Assert.Equal (tab2, tv.SelectedTab);
  420. Assert.Equal (tv, top.Focused);
  421. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  422. // Press the page up key to select the previous set of tabs
  423. Assert.True (Application.RaiseKeyDownEvent (Key.PageUp));
  424. Application.LayoutAndDraw ();
  425. Assert.Equal (tab2, oldChanged);
  426. Assert.Equal (tab1, newChanged);
  427. Assert.Equal (tab1, tv.SelectedTab);
  428. Assert.Equal (tv, top.Focused);
  429. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  430. top.Dispose ();
  431. }
  432. [Fact]
  433. public void RemoveAllTabs_ClearsSelection ()
  434. {
  435. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  436. tv.SelectedTab = tab1;
  437. tv.RemoveTab (tab1);
  438. tv.RemoveTab (tab2);
  439. Assert.Null (tv.SelectedTab);
  440. // Shutdown must be called to safely clean up Application if Init has been called
  441. Application.Shutdown ();
  442. }
  443. [Fact]
  444. public void RemoveTab_ChangesSelection ()
  445. {
  446. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  447. tv.SelectedTab = tab1;
  448. tv.RemoveTab (tab1);
  449. Assert.Equal (tab2, tv.SelectedTab);
  450. // Shutdown must be called to safely clean up Application if Init has been called
  451. Application.Shutdown ();
  452. }
  453. [Fact]
  454. public void RemoveTab_MultipleCalls_NotAnError ()
  455. {
  456. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  457. tv.SelectedTab = tab1;
  458. // Repeated calls to remove a tab that is not part of
  459. // the collection should be ignored
  460. tv.RemoveTab (tab1);
  461. tv.RemoveTab (tab1);
  462. tv.RemoveTab (tab1);
  463. tv.RemoveTab (tab1);
  464. Assert.Equal (tab2, tv.SelectedTab);
  465. // Shutdown must be called to safely clean up Application if Init has been called
  466. Application.Shutdown ();
  467. }
  468. [Fact]
  469. public void SelectedTabChanged_Called ()
  470. {
  471. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  472. tv.SelectedTab = tab1;
  473. Tab oldTab = null;
  474. Tab newTab = null;
  475. var called = 0;
  476. tv.SelectedTabChanged += (s, e) =>
  477. {
  478. oldTab = e.OldTab;
  479. newTab = e.NewTab;
  480. called++;
  481. };
  482. tv.SelectedTab = tab2;
  483. Assert.Equal (1, called);
  484. Assert.Equal (tab1, oldTab);
  485. Assert.Equal (tab2, newTab);
  486. // Shutdown must be called to safely clean up Application if Init has been called
  487. Application.Shutdown ();
  488. }
  489. [Fact]
  490. [SetupFakeDriver]
  491. public void ShowTopLine_False_TabsOnBottom_False_TestTabView_Width3 ()
  492. {
  493. TabView tv = GetTabView (out _, out _, false);
  494. tv.Width = 3;
  495. tv.Height = 5;
  496. tv.Style = new () { ShowTopLine = false };
  497. tv.ApplyStyleChanges ();
  498. tv.Layout ();
  499. tv.Draw ();
  500. TestHelpers.AssertDriverContentsWithFrameAre (
  501. @"
  502. ││
  503. │╰►
  504. │h│
  505. │ │
  506. └─┘",
  507. output
  508. );
  509. }
  510. [Fact]
  511. [SetupFakeDriver]
  512. public void ShowTopLine_False_TabsOnBottom_False_TestTabView_Width4 ()
  513. {
  514. TabView tv = GetTabView (out _, out _, false);
  515. tv.Width = 4;
  516. tv.Height = 5;
  517. tv.Style = new () { ShowTopLine = false };
  518. tv.ApplyStyleChanges ();
  519. tv.Layout ();
  520. tv.Draw ();
  521. TestHelpers.AssertDriverContentsWithFrameAre (
  522. @"
  523. │T│
  524. │ ╰►
  525. │hi│
  526. │ │
  527. └──┘",
  528. output
  529. );
  530. }
  531. [Fact]
  532. [SetupFakeDriver]
  533. public void ShowTopLine_False_TabsOnBottom_False_TestThinTabView_WithLongNames ()
  534. {
  535. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  536. tv.Width = 10;
  537. tv.Height = 5;
  538. tv.Style = new () { ShowTopLine = false };
  539. tv.ApplyStyleChanges ();
  540. // Test two tab names that fit
  541. tab1.DisplayText = "12";
  542. tab2.DisplayText = "13";
  543. // Ensures that the tab bar subview gets the bounds of the parent TabView
  544. tv.Layout ();
  545. tv.Draw ();
  546. TestHelpers.AssertDriverContentsWithFrameAre (
  547. @"
  548. │12│13│
  549. │ ╰──┴──╮
  550. │hi │
  551. │ │
  552. └────────┘",
  553. output
  554. );
  555. tv.SelectedTab = tab2;
  556. Assert.Equal (tab2, tv.Subviews.First (v => v.Id.Contains ("tabRowView")).MostFocused);
  557. tv.Layout ();
  558. View.SetClipToScreen ();
  559. tv.Draw ();
  560. TestHelpers.AssertDriverContentsWithFrameAre (
  561. @"
  562. │12│13│
  563. ├──╯ ╰──╮
  564. │hi2 │
  565. │ │
  566. └────────┘",
  567. output
  568. );
  569. tv.SelectedTab = tab1;
  570. // Test first tab name too long
  571. tab1.DisplayText = "12345678910";
  572. tab2.DisplayText = "13";
  573. tv.Layout ();
  574. View.SetClipToScreen ();
  575. tv.Draw ();
  576. TestHelpers.AssertDriverContentsWithFrameAre (
  577. @"
  578. │1234567│
  579. │ ╰►
  580. │hi │
  581. │ │
  582. └────────┘",
  583. output
  584. );
  585. //switch to tab2
  586. tv.SelectedTab = tab2;
  587. tv.Layout ();
  588. View.SetClipToScreen ();
  589. tv.Draw ();
  590. TestHelpers.AssertDriverContentsWithFrameAre (
  591. @"
  592. │13│
  593. ◄ ╰─────╮
  594. │hi2 │
  595. │ │
  596. └────────┘",
  597. output
  598. );
  599. // now make both tabs too long
  600. tab1.DisplayText = "12345678910";
  601. tab2.DisplayText = "abcdefghijklmnopq";
  602. tv.Layout ();
  603. View.SetClipToScreen ();
  604. tv.Draw ();
  605. TestHelpers.AssertDriverContentsWithFrameAre (
  606. @"
  607. │abcdefg│
  608. ◄ ╰╮
  609. │hi2 │
  610. │ │
  611. └────────┘",
  612. output
  613. );
  614. }
  615. [Fact]
  616. [SetupFakeDriver]
  617. public void ShowTopLine_False_TabsOnBottom_True_TestTabView_Width3 ()
  618. {
  619. TabView tv = GetTabView (out _, out _, false);
  620. tv.Width = 3;
  621. tv.Height = 5;
  622. tv.Style = new () { ShowTopLine = false, TabsOnBottom = true };
  623. tv.ApplyStyleChanges ();
  624. tv.Layout ();
  625. tv.Draw ();
  626. TestHelpers.AssertDriverContentsWithFrameAre (
  627. @"
  628. ┌─┐
  629. │h│
  630. │ │
  631. │╭►
  632. ││ ",
  633. output
  634. );
  635. }
  636. [Fact]
  637. [SetupFakeDriver]
  638. public void ShowTopLine_False_TabsOnBottom_True_TestTabView_Width4 ()
  639. {
  640. TabView tv = GetTabView (out _, out _, false);
  641. tv.Width = 4;
  642. tv.Height = 5;
  643. tv.Style = new () { ShowTopLine = false, TabsOnBottom = true };
  644. tv.ApplyStyleChanges ();
  645. tv.Layout ();
  646. tv.Draw ();
  647. TestHelpers.AssertDriverContentsWithFrameAre (
  648. @"
  649. ┌──┐
  650. │hi│
  651. │ │
  652. │ ╭►
  653. │T│ ",
  654. output
  655. );
  656. }
  657. [Fact]
  658. [SetupFakeDriver]
  659. public void ShowTopLine_False_TabsOnBottom_True_TestThinTabView_WithLongNames ()
  660. {
  661. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  662. tv.Width = 10;
  663. tv.Height = 5;
  664. tv.Style = new () { ShowTopLine = false, TabsOnBottom = true };
  665. tv.ApplyStyleChanges ();
  666. tv.Layout ();
  667. // Test two tab names that fit
  668. tab1.DisplayText = "12";
  669. tab2.DisplayText = "13";
  670. tv.Layout ();
  671. tv.Draw ();
  672. TestHelpers.AssertDriverContentsWithFrameAre (
  673. @"
  674. ┌────────┐
  675. │hi │
  676. │ │
  677. │ ╭──┬──╯
  678. │12│13│ ",
  679. output
  680. );
  681. tv.SelectedTab = tab2;
  682. Assert.Equal (tab2, tv.Subviews.First (v => v.Id.Contains ("tabRowView")).MostFocused);
  683. tv.Layout ();
  684. View.SetClipToScreen ();
  685. tv.Draw ();
  686. TestHelpers.AssertDriverContentsWithFrameAre (
  687. @"
  688. ┌────────┐
  689. │hi2 │
  690. │ │
  691. ├──╮ ╭──╯
  692. │12│13│ ",
  693. output
  694. );
  695. tv.SelectedTab = tab1;
  696. // Test first tab name too long
  697. tab1.DisplayText = "12345678910";
  698. tab2.DisplayText = "13";
  699. tv.Layout ();
  700. View.SetClipToScreen ();
  701. tv.Draw ();
  702. TestHelpers.AssertDriverContentsWithFrameAre (
  703. @"
  704. ┌────────┐
  705. │hi │
  706. │ │
  707. │ ╭►
  708. │1234567│ ",
  709. output
  710. );
  711. //switch to tab2
  712. tv.SelectedTab = tab2;
  713. tv.Layout ();
  714. View.SetClipToScreen ();
  715. tv.Draw ();
  716. TestHelpers.AssertDriverContentsWithFrameAre (
  717. @"
  718. ┌────────┐
  719. │hi2 │
  720. │ │
  721. ◄ ╭─────╯
  722. │13│ ",
  723. output
  724. );
  725. // now make both tabs too long
  726. tab1.DisplayText = "12345678910";
  727. tab2.DisplayText = "abcdefghijklmnopq";
  728. tv.Layout ();
  729. View.SetClipToScreen ();
  730. tv.Draw ();
  731. TestHelpers.AssertDriverContentsWithFrameAre (
  732. @"
  733. ┌────────┐
  734. │hi2 │
  735. │ │
  736. ◄ ╭╯
  737. │abcdefg│ ",
  738. output
  739. );
  740. }
  741. [Fact]
  742. [SetupFakeDriver]
  743. public void ShowTopLine_True_TabsOnBottom_False_TestTabView_Width3 ()
  744. {
  745. TabView tv = GetTabView (out _, out _, false);
  746. tv.Width = 3;
  747. tv.Height = 5;
  748. tv.Layout ();
  749. tv.Draw ();
  750. TestHelpers.AssertDriverContentsWithFrameAre (
  751. @"
  752. ╭╮
  753. ││
  754. │╰►
  755. │h│
  756. └─┘",
  757. output
  758. );
  759. }
  760. [Fact]
  761. [SetupFakeDriver]
  762. public void ShowTopLine_True_TabsOnBottom_False_TestTabView_Width4 ()
  763. {
  764. TabView tv = GetTabView (out _, out _, false);
  765. tv.Width = 4;
  766. tv.Height = 5;
  767. tv.Layout ();
  768. View.SetClipToScreen ();
  769. tv.Draw ();
  770. TestHelpers.AssertDriverContentsWithFrameAre (
  771. @"
  772. ╭─╮
  773. │T│
  774. │ ╰►
  775. │hi│
  776. └──┘",
  777. output
  778. );
  779. }
  780. [Fact]
  781. [SetupFakeDriver]
  782. public void ShowTopLine_True_TabsOnBottom_False_TestThinTabView_WithLongNames ()
  783. {
  784. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  785. tv.Width = 10;
  786. tv.Height = 5;
  787. // Test two tab names that fit
  788. tab1.DisplayText = "12";
  789. tab2.DisplayText = "13";
  790. tv.Layout ();
  791. tv.Draw ();
  792. TestHelpers.AssertDriverContentsWithFrameAre (
  793. @"
  794. ╭──┬──╮
  795. │12│13│
  796. │ ╰──┴──╮
  797. │hi │
  798. └────────┘",
  799. output
  800. );
  801. tv.SelectedTab = tab2;
  802. tv.Layout ();
  803. View.SetClipToScreen ();
  804. tv.Draw ();
  805. TestHelpers.AssertDriverContentsWithFrameAre (
  806. @"
  807. ╭──┬──╮
  808. │12│13│
  809. ├──╯ ╰──╮
  810. │hi2 │
  811. └────────┘",
  812. output
  813. );
  814. tv.SelectedTab = tab1;
  815. // Test first tab name too long
  816. tab1.DisplayText = "12345678910";
  817. tab2.DisplayText = "13";
  818. tv.Layout ();
  819. View.SetClipToScreen ();
  820. tv.Draw ();
  821. TestHelpers.AssertDriverContentsWithFrameAre (
  822. @"
  823. ╭───────╮
  824. │1234567│
  825. │ ╰►
  826. │hi │
  827. └────────┘",
  828. output
  829. );
  830. //switch to tab2
  831. tv.SelectedTab = tab2;
  832. tv.Layout ();
  833. View.SetClipToScreen ();
  834. tv.Draw ();
  835. TestHelpers.AssertDriverContentsWithFrameAre (
  836. @"
  837. ╭──╮
  838. │13│
  839. ◄ ╰─────╮
  840. │hi2 │
  841. └────────┘",
  842. output
  843. );
  844. // now make both tabs too long
  845. tab1.DisplayText = "12345678910";
  846. tab2.DisplayText = "abcdefghijklmnopq";
  847. tv.Layout ();
  848. View.SetClipToScreen ();
  849. tv.Draw ();
  850. TestHelpers.AssertDriverContentsWithFrameAre (
  851. @"
  852. ╭───────╮
  853. │abcdefg│
  854. ◄ ╰╮
  855. │hi2 │
  856. └────────┘",
  857. output
  858. );
  859. }
  860. [Fact]
  861. [SetupFakeDriver]
  862. public void ShowTopLine_True_TabsOnBottom_False_With_Unicode ()
  863. {
  864. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  865. tv.Width = 20;
  866. tv.Height = 5;
  867. tab1.DisplayText = "Tab0";
  868. tab2.DisplayText = "Les Mise" + char.ConvertFromUtf32 (int.Parse ("0301", NumberStyles.HexNumber)) + "rables";
  869. tv.Layout ();
  870. tv.Draw ();
  871. TestHelpers.AssertDriverContentsWithFrameAre (
  872. @"
  873. ╭────╮
  874. │Tab0│
  875. │ ╰─────────────►
  876. │hi │
  877. └──────────────────┘",
  878. output
  879. );
  880. tv.SelectedTab = tab2;
  881. tv.Layout ();
  882. View.SetClipToScreen ();
  883. tv.Draw ();
  884. TestHelpers.AssertDriverContentsWithFrameAre (
  885. @"
  886. ╭──────────────╮
  887. │Les Misérables│
  888. ◄ ╰───╮
  889. │hi2 │
  890. └──────────────────┘",
  891. output
  892. );
  893. }
  894. [Fact]
  895. [SetupFakeDriver]
  896. public void ShowTopLine_True_TabsOnBottom_True_TestTabView_Width3 ()
  897. {
  898. TabView tv = GetTabView (out _, out _, false);
  899. tv.Width = 3;
  900. tv.Height = 5;
  901. tv.Style = new () { TabsOnBottom = true };
  902. tv.ApplyStyleChanges ();
  903. tv.Layout ();
  904. tv.Draw ();
  905. TestHelpers.AssertDriverContentsWithFrameAre (
  906. @"
  907. ┌─┐
  908. │h│
  909. │╭►
  910. ││
  911. ╰╯ ",
  912. output
  913. );
  914. }
  915. [Fact]
  916. [SetupFakeDriver]
  917. public void ShowTopLine_True_TabsOnBottom_True_TestTabView_Width4 ()
  918. {
  919. TabView tv = GetTabView (out _, out _, false);
  920. tv.Width = 4;
  921. tv.Height = 5;
  922. tv.Style = new () { TabsOnBottom = true };
  923. tv.ApplyStyleChanges ();
  924. tv.Layout ();
  925. tv.Draw ();
  926. TestHelpers.AssertDriverContentsWithFrameAre (
  927. @"
  928. ┌──┐
  929. │hi│
  930. │ ╭►
  931. │T│
  932. ╰─╯ ",
  933. output
  934. );
  935. }
  936. [Fact]
  937. [SetupFakeDriver]
  938. public void ShowTopLine_True_TabsOnBottom_True_TestThinTabView_WithLongNames ()
  939. {
  940. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  941. tv.Width = 10;
  942. tv.Height = 5;
  943. tv.Style = new () { TabsOnBottom = true };
  944. tv.ApplyStyleChanges ();
  945. tv.Layout ();
  946. // Test two tab names that fit
  947. tab1.DisplayText = "12";
  948. tab2.DisplayText = "13";
  949. tv.Layout ();
  950. tv.Draw ();
  951. TestHelpers.AssertDriverContentsWithFrameAre (
  952. @"
  953. ┌────────┐
  954. │hi │
  955. │ ╭──┬──╯
  956. │12│13│
  957. ╰──┴──╯ ",
  958. output
  959. );
  960. // Test first tab name too long
  961. tab1.DisplayText = "12345678910";
  962. tab2.DisplayText = "13";
  963. tv.Layout ();
  964. View.SetClipToScreen ();
  965. tv.Draw ();
  966. TestHelpers.AssertDriverContentsWithFrameAre (
  967. @"
  968. ┌────────┐
  969. │hi │
  970. │ ╭►
  971. │1234567│
  972. ╰───────╯ ",
  973. output
  974. );
  975. //switch to tab2
  976. tv.SelectedTab = tab2;
  977. tv.Layout ();
  978. View.SetClipToScreen ();
  979. tv.Draw ();
  980. TestHelpers.AssertDriverContentsWithFrameAre (
  981. @"
  982. ┌────────┐
  983. │hi2 │
  984. ◄ ╭─────╯
  985. │13│
  986. ╰──╯ ",
  987. output
  988. );
  989. // now make both tabs too long
  990. tab1.DisplayText = "12345678910";
  991. tab2.DisplayText = "abcdefghijklmnopq";
  992. tv.Layout ();
  993. View.SetClipToScreen ();
  994. tv.Draw ();
  995. TestHelpers.AssertDriverContentsWithFrameAre (
  996. @"
  997. ┌────────┐
  998. │hi2 │
  999. ◄ ╭╯
  1000. │abcdefg│
  1001. ╰───────╯ ",
  1002. output
  1003. );
  1004. }
  1005. [Fact]
  1006. [SetupFakeDriver]
  1007. public void ShowTopLine_True_TabsOnBottom_True_With_Unicode ()
  1008. {
  1009. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  1010. tv.Width = 20;
  1011. tv.Height = 5;
  1012. tv.Style = new () { TabsOnBottom = true };
  1013. tv.ApplyStyleChanges ();
  1014. tab1.DisplayText = "Tab0";
  1015. tab2.DisplayText = "Les Mise" + char.ConvertFromUtf32 (int.Parse ("0301", NumberStyles.HexNumber)) + "rables";
  1016. tv.Layout ();
  1017. tv.Draw ();
  1018. TestHelpers.AssertDriverContentsWithFrameAre (
  1019. @"
  1020. ┌──────────────────┐
  1021. │hi │
  1022. │ ╭─────────────►
  1023. │Tab0│
  1024. ╰────╯ ",
  1025. output
  1026. );
  1027. tv.SelectedTab = tab2;
  1028. tv.Layout ();
  1029. View.SetClipToScreen ();
  1030. tv.Draw ();
  1031. TestHelpers.AssertDriverContentsWithFrameAre (
  1032. @"
  1033. ┌──────────────────┐
  1034. │hi2 │
  1035. ◄ ╭───╯
  1036. │Les Misérables│
  1037. ╰──────────────╯ ",
  1038. output
  1039. );
  1040. }
  1041. [Fact]
  1042. public void SwitchTabBy_NormalUsage ()
  1043. {
  1044. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1045. Tab tab3;
  1046. Tab tab4;
  1047. Tab tab5;
  1048. tv.AddTab (tab3 = new (), false);
  1049. tv.AddTab (tab4 = new (), false);
  1050. tv.AddTab (tab5 = new (), false);
  1051. tv.SelectedTab = tab1;
  1052. var called = 0;
  1053. tv.SelectedTabChanged += (s, e) => { called++; };
  1054. tv.SwitchTabBy (1);
  1055. Assert.Equal (1, called);
  1056. Assert.Equal (tab2, tv.SelectedTab);
  1057. //reset called counter
  1058. called = 0;
  1059. // go right 2
  1060. tv.SwitchTabBy (2);
  1061. // even though we go right 2 indexes the event should only be called once
  1062. Assert.Equal (1, called);
  1063. Assert.Equal (tab4, tv.SelectedTab);
  1064. // Shutdown must be called to safely clean up Application if Init has been called
  1065. Application.Shutdown ();
  1066. }
  1067. [Fact]
  1068. public void SwitchTabBy_OutOfTabsRange ()
  1069. {
  1070. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1071. tv.SelectedTab = tab1;
  1072. tv.SwitchTabBy (500);
  1073. Assert.Equal (tab2, tv.SelectedTab);
  1074. tv.SwitchTabBy (-500);
  1075. Assert.Equal (tab1, tv.SelectedTab);
  1076. // Shutdown must be called to safely clean up Application if Init has been called
  1077. Application.Shutdown ();
  1078. }
  1079. [Fact]
  1080. public void RemoveTab_ThatHasFocus ()
  1081. {
  1082. TabView tv = GetTabView (out Tab _, out Tab tab2);
  1083. tv.SelectedTab = tab2;
  1084. tab2.HasFocus = true;
  1085. Assert.Equal (2, tv.Tabs.Count);
  1086. foreach (Tab t in tv.Tabs.ToArray ())
  1087. {
  1088. tv.RemoveTab (t);
  1089. }
  1090. Assert.Empty (tv.Tabs);
  1091. // Shutdown must be called to safely clean up Application if Init has been called
  1092. Application.Shutdown ();
  1093. }
  1094. [Fact]
  1095. [SetupFakeDriver]
  1096. public void Add_Three_TabsOnTop_ChangesTab ()
  1097. {
  1098. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  1099. Tab tab3;
  1100. tv.AddTab (
  1101. tab3 = new () { Id = "tab3", DisplayText = "Tab3", View = new TextView { Id = "tab3.TextView", Width = 3, Height = 1, Text = "hi3" } },
  1102. false);
  1103. tv.Width = 20;
  1104. tv.Height = 5;
  1105. tv.Layout ();
  1106. tv.Draw ();
  1107. Assert.Equal (tab1, tv.SelectedTab);
  1108. TestHelpers.AssertDriverContentsAre (
  1109. @"
  1110. ╭────┬────┬────╮
  1111. │Tab1│Tab2│Tab3│
  1112. │ ╰────┴────┴───╮
  1113. │hi │
  1114. └──────────────────┘
  1115. ",
  1116. output
  1117. );
  1118. tv.SelectedTab = tab2;
  1119. tv.Layout ();
  1120. View.SetClipToScreen ();
  1121. tv.Draw ();
  1122. TestHelpers.AssertDriverContentsWithFrameAre (
  1123. @"
  1124. ╭────┬────┬────╮
  1125. │Tab1│Tab2│Tab3│
  1126. ├────╯ ╰────┴───╮
  1127. │hi2 │
  1128. └──────────────────┘
  1129. ",
  1130. output
  1131. );
  1132. tv.SelectedTab = tab3;
  1133. tv.Layout ();
  1134. View.SetClipToScreen ();
  1135. tv.Draw ();
  1136. TestHelpers.AssertDriverContentsWithFrameAre (
  1137. @"
  1138. ╭────┬────┬────╮
  1139. │Tab1│Tab2│Tab3│
  1140. ├────┴────╯ ╰───╮
  1141. │hi3 │
  1142. └──────────────────┘
  1143. ",
  1144. output
  1145. );
  1146. }
  1147. [Fact]
  1148. [SetupFakeDriver]
  1149. public void Add_Three_TabsOnBottom_ChangesTab ()
  1150. {
  1151. TabView tv = GetTabView (out Tab tab1, out Tab tab2, false);
  1152. Tab tab3;
  1153. tv.AddTab (
  1154. tab3 = new () { Id = "tab3", DisplayText = "Tab3", View = new TextView { Id = "tab3.TextView", Width = 3, Height = 1, Text = "hi3" } },
  1155. false);
  1156. tv.Width = 20;
  1157. tv.Height = 5;
  1158. tv.Style = new () { TabsOnBottom = true };
  1159. tv.ApplyStyleChanges ();
  1160. tv.Layout ();
  1161. tv.Draw ();
  1162. Assert.Equal (tab1, tv.SelectedTab);
  1163. TestHelpers.AssertDriverContentsAre (
  1164. @"
  1165. ┌──────────────────┐
  1166. │hi │
  1167. │ ╭────┬────┬───╯
  1168. │Tab1│Tab2│Tab3│
  1169. ╰────┴────┴────╯
  1170. ",
  1171. output
  1172. );
  1173. tv.SelectedTab = tab2;
  1174. tv.Layout ();
  1175. View.SetClipToScreen ();
  1176. tv.Draw ();
  1177. TestHelpers.AssertDriverContentsWithFrameAre (
  1178. @"
  1179. ┌──────────────────┐
  1180. │hi2 │
  1181. ├────╮ ╭────┬───╯
  1182. │Tab1│Tab2│Tab3│
  1183. ╰────┴────┴────╯
  1184. ",
  1185. output
  1186. );
  1187. tv.SelectedTab = tab3;
  1188. tv.Layout ();
  1189. View.SetClipToScreen ();
  1190. tv.Draw ();
  1191. TestHelpers.AssertDriverContentsWithFrameAre (
  1192. @"
  1193. ┌──────────────────┐
  1194. │hi3 │
  1195. ├────┬────╮ ╭───╯
  1196. │Tab1│Tab2│Tab3│
  1197. ╰────┴────┴────╯
  1198. ",
  1199. output
  1200. );
  1201. }
  1202. [Fact]
  1203. [SetupFakeDriver]
  1204. public void Tab_Get_Focus_By_Press_F6 ()
  1205. {
  1206. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1207. tv.Width = 20;
  1208. tv.Height = 5;
  1209. Toplevel top = new ();
  1210. top.Add (tv);
  1211. Application.Begin (top);
  1212. Assert.False (tab1.HasFocus);
  1213. Assert.True (Application.RaiseKeyDownEvent (Key.F6));
  1214. Assert.True (tab1.HasFocus);
  1215. top.Dispose ();
  1216. }
  1217. private TabView GetTabView () { return GetTabView (out _, out _); }
  1218. private TabView GetTabView (out Tab tab1, out Tab tab2, bool initFakeDriver = true)
  1219. {
  1220. if (initFakeDriver)
  1221. {
  1222. InitFakeDriver ();
  1223. }
  1224. var tv = new TabView () { Id = "tv " };
  1225. tv.BeginInit ();
  1226. tv.EndInit ();
  1227. tv.ColorScheme = new ();
  1228. tv.AddTab (
  1229. tab1 = new () { Id = "tab1", DisplayText = "Tab1", View = new TextField { Id = "tab1.TextField", Width = 2, Text = "hi" } },
  1230. false
  1231. );
  1232. tv.AddTab (tab2 = new () { Id = "tab2", DisplayText = "Tab2", View = new Label { Id = "tab1.Label", Text = "hi2" } }, false);
  1233. return tv;
  1234. }
  1235. private void InitFakeDriver ()
  1236. {
  1237. ConfigurationManager.Locations = ConfigLocations.Default;
  1238. ConfigurationManager.Reset ();
  1239. var driver = new FakeDriver ();
  1240. Application.Init (driver);
  1241. driver.Init ();
  1242. }
  1243. }