SplitContainerTests.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. using System;
  2. using System.Linq;
  3. using Terminal.Gui;
  4. using Xunit;
  5. using Xunit.Abstractions;
  6. namespace UnitTests {
  7. public class SplitContainerTests {
  8. readonly ITestOutputHelper output;
  9. public SplitContainerTests (ITestOutputHelper output)
  10. {
  11. this.output = output;
  12. }
  13. [Fact, AutoInitShutdown]
  14. public void TestSplitContainer_Vertical ()
  15. {
  16. var splitContainer = Get11By3SplitContainer (out var line);
  17. splitContainer.Redraw (splitContainer.Bounds);
  18. string looksLike =
  19. @"
  20. 11111│22222
  21. │ ";
  22. TestHelpers.AssertDriverContentsAre (looksLike, output);
  23. // Keyboard movement on splitter should have no effect if it is not focused
  24. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  25. splitContainer.SetNeedsDisplay ();
  26. splitContainer.Redraw (splitContainer.Bounds);
  27. TestHelpers.AssertDriverContentsAre (looksLike, output);
  28. }
  29. [Fact, AutoInitShutdown]
  30. public void TestSplitContainer_Vertical_WithBorder ()
  31. {
  32. var splitContainer = Get11By3SplitContainer (out var line, true);
  33. splitContainer.Redraw (splitContainer.Bounds);
  34. string looksLike =
  35. @"
  36. ┌────┬────┐
  37. │1111│2222│
  38. └────┴────┘";
  39. TestHelpers.AssertDriverContentsAre (looksLike, output);
  40. // Keyboard movement on splitter should have no effect if it is not focused
  41. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  42. splitContainer.SetNeedsDisplay ();
  43. splitContainer.Redraw (splitContainer.Bounds);
  44. TestHelpers.AssertDriverContentsAre (looksLike, output);
  45. }
  46. [Fact, AutoInitShutdown]
  47. public void TestSplitContainer_Vertical_Focused ()
  48. {
  49. var splitContainer = Get11By3SplitContainer (out var line);
  50. SetInputFocusLine (splitContainer);
  51. splitContainer.Redraw (splitContainer.Bounds);
  52. string looksLike =
  53. @"
  54. 11111│22222
  55. │ ";
  56. TestHelpers.AssertDriverContentsAre (looksLike, output);
  57. // Now while focused move the splitter 1 unit right
  58. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  59. splitContainer.Redraw (splitContainer.Bounds);
  60. looksLike =
  61. @"
  62. 111111│2222
  63. │ ";
  64. TestHelpers.AssertDriverContentsAre (looksLike, output);
  65. // and 2 to the left
  66. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  67. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  68. splitContainer.Redraw (splitContainer.Bounds);
  69. looksLike =
  70. @"
  71. 1111│222222
  72. │ ";
  73. TestHelpers.AssertDriverContentsAre (looksLike, output);
  74. }
  75. [Fact, AutoInitShutdown]
  76. public void TestSplitContainer_Vertical_Focused_WithBorder ()
  77. {
  78. var splitContainer = Get11By3SplitContainer (out var line, true);
  79. SetInputFocusLine (splitContainer);
  80. splitContainer.Redraw (splitContainer.Bounds);
  81. string looksLike =
  82. @"
  83. ┌────┬────┐
  84. │1111◊2222│
  85. └────┴────┘";
  86. TestHelpers.AssertDriverContentsAre (looksLike, output);
  87. // Now while focused move the splitter 1 unit right
  88. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  89. splitContainer.Redraw (splitContainer.Bounds);
  90. looksLike =
  91. @"
  92. ┌─────┬───┐
  93. │11111◊222│
  94. └─────┴───┘";
  95. TestHelpers.AssertDriverContentsAre (looksLike, output);
  96. // and 2 to the left
  97. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  98. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  99. splitContainer.Redraw (splitContainer.Bounds);
  100. looksLike =
  101. @"
  102. ┌───┬─────┐
  103. │111◊22222│
  104. └───┴─────┘";
  105. TestHelpers.AssertDriverContentsAre (looksLike, output);
  106. }
  107. [Fact, AutoInitShutdown]
  108. public void TestSplitContainer_Vertical_Focused_50PercentSplit ()
  109. {
  110. var splitContainer = Get11By3SplitContainer (out var line);
  111. SetInputFocusLine (splitContainer);
  112. splitContainer.SplitterDistance = Pos.Percent (50);
  113. Assert.IsType<Pos.PosFactor> (splitContainer.SplitterDistance);
  114. splitContainer.Redraw (splitContainer.Bounds);
  115. string looksLike =
  116. @"
  117. 11111│22222
  118. │ ";
  119. TestHelpers.AssertDriverContentsAre (looksLike, output);
  120. // Now while focused move the splitter 1 unit right
  121. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  122. splitContainer.Redraw (splitContainer.Bounds);
  123. looksLike =
  124. @"
  125. 111111│2222
  126. │ ";
  127. TestHelpers.AssertDriverContentsAre (looksLike, output);
  128. // Even when moving the splitter location it should stay a Percentage based one
  129. Assert.IsType<Pos.PosFactor> (splitContainer.SplitterDistance);
  130. // and 2 to the left
  131. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  132. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  133. splitContainer.Redraw (splitContainer.Bounds);
  134. looksLike =
  135. @"
  136. 1111│222222
  137. │ ";
  138. TestHelpers.AssertDriverContentsAre (looksLike, output);
  139. // Even when moving the splitter location it should stay a Percentage based one
  140. Assert.IsType<Pos.PosFactor> (splitContainer.SplitterDistance);
  141. }
  142. [Fact, AutoInitShutdown]
  143. public void TestSplitContainer_Horizontal ()
  144. {
  145. var splitContainer = Get11By3SplitContainer (out var line);
  146. splitContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  147. splitContainer.Redraw (splitContainer.Bounds);
  148. string looksLike =
  149. @"
  150. 11111111111
  151. ───────────
  152. 22222222222";
  153. TestHelpers.AssertDriverContentsAre (looksLike, output);
  154. // Keyboard movement on splitter should have no effect if it is not focused
  155. line.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()));
  156. splitContainer.SetNeedsDisplay ();
  157. splitContainer.Redraw (splitContainer.Bounds);
  158. TestHelpers.AssertDriverContentsAre (looksLike, output);
  159. }
  160. [Fact, AutoInitShutdown]
  161. public void TestSplitContainer_Vertical_Panel1MinSize_Absolute ()
  162. {
  163. var splitContainer = Get11By3SplitContainer (out var line);
  164. SetInputFocusLine (splitContainer);
  165. splitContainer.Panel1MinSize = 6;
  166. // distance is too small (below 6)
  167. splitContainer.SplitterDistance = 2;
  168. // Should bound the value to the minimum distance
  169. Assert.Equal (6, splitContainer.SplitterDistance);
  170. splitContainer.Redraw (splitContainer.Bounds);
  171. // so should ignore the 2 distance and stick to 6
  172. string looksLike =
  173. @"
  174. 111111│2222
  175. │ ";
  176. TestHelpers.AssertDriverContentsAre (looksLike, output);
  177. // Keyboard movement on splitter should have no effect because it
  178. // would take us below the minimum splitter size
  179. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  180. splitContainer.SetNeedsDisplay ();
  181. splitContainer.Redraw (splitContainer.Bounds);
  182. TestHelpers.AssertDriverContentsAre (looksLike, output);
  183. // but we can continue to move the splitter right if we want
  184. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  185. splitContainer.SetNeedsDisplay ();
  186. splitContainer.Redraw (splitContainer.Bounds);
  187. looksLike =
  188. @"
  189. 1111111│222
  190. │ ";
  191. TestHelpers.AssertDriverContentsAre (looksLike, output);
  192. }
  193. [Fact, AutoInitShutdown]
  194. public void TestSplitContainer_Vertical_Panel1MinSize_Absolute_WithBorder ()
  195. {
  196. var splitContainer = Get11By3SplitContainer (out var line,true);
  197. SetInputFocusLine (splitContainer);
  198. splitContainer.Panel1MinSize = 5;
  199. // distance is too small (below 5)
  200. splitContainer.SplitterDistance = 2;
  201. // Should bound the value to the minimum distance
  202. Assert.Equal (5, splitContainer.SplitterDistance);
  203. splitContainer.Redraw (splitContainer.Bounds);
  204. // so should ignore the 2 distance and stick to 5
  205. string looksLike =
  206. @"
  207. ┌─────┬───┐
  208. │11111◊222│
  209. └─────┴───┘";
  210. TestHelpers.AssertDriverContentsAre (looksLike, output);
  211. // Keyboard movement on splitter should have no effect because it
  212. // would take us below the minimum splitter size
  213. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  214. splitContainer.SetNeedsDisplay ();
  215. splitContainer.Redraw (splitContainer.Bounds);
  216. TestHelpers.AssertDriverContentsAre (looksLike, output);
  217. // but we can continue to move the splitter right if we want
  218. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  219. splitContainer.SetNeedsDisplay ();
  220. splitContainer.Redraw (splitContainer.Bounds);
  221. looksLike =
  222. @"
  223. ┌──────┬──┐
  224. │111111◊22│
  225. └──────┴──┘";
  226. TestHelpers.AssertDriverContentsAre (looksLike, output);
  227. }
  228. [Fact, AutoInitShutdown]
  229. public void TestSplitContainer_Vertical_Panel2MinSize_Absolute ()
  230. {
  231. var splitContainer = Get11By3SplitContainer (out var line);
  232. SetInputFocusLine (splitContainer);
  233. splitContainer.Panel2MinSize = 6;
  234. // distance leaves too little space for panel2 (less than 6 would remain)
  235. splitContainer.SplitterDistance = 8;
  236. // Should bound the value to the minimum distance
  237. Assert.Equal (4, splitContainer.SplitterDistance);
  238. splitContainer.Redraw (splitContainer.Bounds);
  239. // so should ignore the 2 distance and stick to 6
  240. string looksLike =
  241. @"
  242. 1111│222222
  243. │ ";
  244. TestHelpers.AssertDriverContentsAre (looksLike, output);
  245. // Keyboard movement on splitter should have no effect because it
  246. // would take us below the minimum splitter size
  247. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  248. splitContainer.SetNeedsDisplay ();
  249. splitContainer.Redraw (splitContainer.Bounds);
  250. TestHelpers.AssertDriverContentsAre (looksLike, output);
  251. // but we can continue to move the splitter left if we want
  252. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  253. splitContainer.SetNeedsDisplay ();
  254. splitContainer.Redraw (splitContainer.Bounds);
  255. looksLike =
  256. @"
  257. 111│2222222
  258. │ ";
  259. TestHelpers.AssertDriverContentsAre (looksLike, output);
  260. }
  261. [Fact, AutoInitShutdown]
  262. public void TestSplitContainer_Vertical_Panel2MinSize_Absolute_WithBorder ()
  263. {
  264. var splitContainer = Get11By3SplitContainer (out var line, true);
  265. SetInputFocusLine (splitContainer);
  266. splitContainer.Panel2MinSize = 5;
  267. // distance leaves too little space for panel2 (less than 5 would remain)
  268. splitContainer.SplitterDistance = 8;
  269. // Should bound the value to the minimum distance
  270. Assert.Equal (3, splitContainer.SplitterDistance);
  271. splitContainer.Redraw (splitContainer.Bounds);
  272. // so should ignore the 2 distance and stick to 6
  273. string looksLike =
  274. @"
  275. ┌───┬─────┐
  276. │111◊22222│
  277. └───┴─────┘";
  278. TestHelpers.AssertDriverContentsAre (looksLike, output);
  279. // Keyboard movement on splitter should have no effect because it
  280. // would take us below the minimum splitter size
  281. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  282. splitContainer.SetNeedsDisplay ();
  283. splitContainer.Redraw (splitContainer.Bounds);
  284. TestHelpers.AssertDriverContentsAre (looksLike, output);
  285. // but we can continue to move the splitter left if we want
  286. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  287. splitContainer.SetNeedsDisplay ();
  288. splitContainer.Redraw (splitContainer.Bounds);
  289. looksLike =
  290. @"
  291. ┌──┬──────┐
  292. │11◊222222│
  293. └──┴──────┘";
  294. TestHelpers.AssertDriverContentsAre (looksLike, output);
  295. }
  296. [Fact, AutoInitShutdown]
  297. public void TestSplitContainer_Horizontal_Focused ()
  298. {
  299. var splitContainer = Get11By3SplitContainer (out var line);
  300. splitContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  301. SetInputFocusLine (splitContainer);
  302. splitContainer.Redraw (splitContainer.Bounds);
  303. string looksLike =
  304. @"
  305. 11111111111
  306. ─────◊─────
  307. 22222222222";
  308. TestHelpers.AssertDriverContentsAre (looksLike, output);
  309. // Now move splitter line down
  310. line.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()));
  311. splitContainer.Redraw (splitContainer.Bounds);
  312. looksLike =
  313. @"
  314. 11111111111
  315. ─────◊─────";
  316. TestHelpers.AssertDriverContentsAre (looksLike, output);
  317. // And 2 up
  318. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  319. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  320. splitContainer.Redraw (splitContainer.Bounds);
  321. looksLike =
  322. @"
  323. ─────◊─────
  324. 22222222222";
  325. TestHelpers.AssertDriverContentsAre (looksLike, output);
  326. }
  327. [Fact, AutoInitShutdown]
  328. public void TestSplitContainer_Horizontal_Panel1MinSize_Absolute ()
  329. {
  330. var splitContainer = Get11By3SplitContainer (out var line);
  331. splitContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  332. SetInputFocusLine (splitContainer);
  333. splitContainer.Panel1MinSize = 1;
  334. // 0 should not be allowed because it brings us below minimum size of Panel1
  335. splitContainer.SplitterDistance = 0;
  336. Assert.Equal ((Pos)1, splitContainer.SplitterDistance);
  337. splitContainer.Redraw (splitContainer.Bounds);
  338. string looksLike =
  339. @"
  340. 11111111111
  341. ─────◊─────
  342. 22222222222";
  343. TestHelpers.AssertDriverContentsAre (looksLike, output);
  344. // Now move splitter line down (allowed
  345. line.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()));
  346. splitContainer.Redraw (splitContainer.Bounds);
  347. looksLike =
  348. @"
  349. 11111111111
  350. ─────◊─────";
  351. TestHelpers.AssertDriverContentsAre (looksLike, output);
  352. // And up 2 (only 1 is allowed because of minimum size of 1 on panel1)
  353. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  354. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  355. splitContainer.Redraw (splitContainer.Bounds);
  356. looksLike =
  357. @"
  358. 11111111111
  359. ─────◊─────
  360. 22222222222";
  361. TestHelpers.AssertDriverContentsAre (looksLike, output);
  362. }
  363. [Fact, AutoInitShutdown]
  364. public void TestSplitContainer_CannotSetSplitterPosToFuncEtc ()
  365. {
  366. var splitContainer = Get11By3SplitContainer ();
  367. var ex = Assert.Throws<ArgumentException> (() => splitContainer.SplitterDistance = Pos.Right (splitContainer));
  368. Assert.Equal ("Only Percent and Absolute values are supported for SplitterDistance property. Passed value was PosCombine", ex.Message);
  369. ex = Assert.Throws<ArgumentException> (() => splitContainer.SplitterDistance = Pos.Function (() => 1));
  370. Assert.Equal ("Only Percent and Absolute values are supported for SplitterDistance property. Passed value was PosFunc", ex.Message);
  371. // Also not allowed because this results in a PosCombine
  372. ex = Assert.Throws<ArgumentException> (() => splitContainer.SplitterDistance = Pos.Percent (50) - 1);
  373. Assert.Equal ("Only Percent and Absolute values are supported for SplitterDistance property. Passed value was PosCombine", ex.Message);
  374. }
  375. private LineView GetSplitContainerLineView (SplitContainer splitContainer)
  376. {
  377. return splitContainer.Subviews [0].Subviews.OfType<LineView> ().Single ();
  378. }
  379. private void SetInputFocusLine (SplitContainer splitContainer)
  380. {
  381. var line = GetSplitContainerLineView (splitContainer);
  382. line.SetFocus ();
  383. Assert.True (line.HasFocus);
  384. }
  385. private SplitContainer Get11By3SplitContainer(out LineView line, bool withBorder = false)
  386. {
  387. var split = Get11By3SplitContainer (withBorder);
  388. line = GetSplitContainerLineView (split);
  389. return split;
  390. }
  391. private SplitContainer Get11By3SplitContainer (bool withBorder = false)
  392. {
  393. var container = new SplitContainer () {
  394. Width = 11,
  395. Height = 3,
  396. };
  397. if (!withBorder) {
  398. container.Border.BorderStyle = BorderStyle.None;
  399. container.Border.DrawMarginFrame = false;
  400. }
  401. container.Panel1.Add (new Label (new string ('1', 100)));
  402. container.Panel2.Add (new Label (new string ('2', 100)));
  403. container.Panel1MinSize = 0;
  404. container.Panel2MinSize = 0;
  405. Application.Top.Add (container);
  406. container.ColorScheme = new ColorScheme ();
  407. container.LayoutSubviews ();
  408. container.BeginInit ();
  409. container.EndInit ();
  410. return container;
  411. }
  412. }
  413. }