SplitContainerTests.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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.Panels [0].MinSize = 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_Horizontal_Focused ()
  195. {
  196. var splitContainer = Get11By3SplitContainer (out var line);
  197. splitContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  198. SetInputFocusLine (splitContainer);
  199. splitContainer.Redraw (splitContainer.Bounds);
  200. string looksLike =
  201. @"
  202. 11111111111
  203. ─────◊─────
  204. 22222222222";
  205. TestHelpers.AssertDriverContentsAre (looksLike, output);
  206. // Now move splitter line down
  207. line.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()));
  208. splitContainer.Redraw (splitContainer.Bounds);
  209. looksLike =
  210. @"
  211. 11111111111
  212. ─────◊─────";
  213. TestHelpers.AssertDriverContentsAre (looksLike, output);
  214. // And 2 up
  215. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  216. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  217. splitContainer.Redraw (splitContainer.Bounds);
  218. looksLike =
  219. @"
  220. ─────◊─────
  221. 22222222222";
  222. TestHelpers.AssertDriverContentsAre (looksLike, output);
  223. }
  224. [Fact, AutoInitShutdown]
  225. public void TestSplitContainer_Horizontal_Panel1MinSize_Absolute ()
  226. {
  227. var splitContainer = Get11By3SplitContainer (out var line);
  228. splitContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  229. SetInputFocusLine (splitContainer);
  230. splitContainer.Panels [0].MinSize = 1;
  231. // 0 should not be allowed because it brings us below minimum size of Panel1
  232. splitContainer.SplitterDistance = 0;
  233. Assert.Equal ((Pos)1, splitContainer.SplitterDistance);
  234. splitContainer.Redraw (splitContainer.Bounds);
  235. string looksLike =
  236. @"
  237. 11111111111
  238. ─────◊─────
  239. 22222222222";
  240. TestHelpers.AssertDriverContentsAre (looksLike, output);
  241. // Now move splitter line down (allowed
  242. line.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()));
  243. splitContainer.Redraw (splitContainer.Bounds);
  244. looksLike =
  245. @"
  246. 11111111111
  247. ─────◊─────";
  248. TestHelpers.AssertDriverContentsAre (looksLike, output);
  249. // And up 2 (only 1 is allowed because of minimum size of 1 on panel1)
  250. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  251. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  252. splitContainer.Redraw (splitContainer.Bounds);
  253. looksLike =
  254. @"
  255. 11111111111
  256. ─────◊─────
  257. 22222222222";
  258. TestHelpers.AssertDriverContentsAre (looksLike, output);
  259. }
  260. [Fact, AutoInitShutdown]
  261. public void TestSplitContainer_CannotSetSplitterPosToFuncEtc ()
  262. {
  263. var splitContainer = Get11By3SplitContainer ();
  264. var ex = Assert.Throws<ArgumentException> (() => splitContainer.SplitterDistance = Pos.Right (splitContainer));
  265. Assert.Equal ("Only Percent and Absolute values are supported for SplitterDistance property. Passed value was PosCombine", ex.Message);
  266. ex = Assert.Throws<ArgumentException> (() => splitContainer.SplitterDistance = Pos.Function (() => 1));
  267. Assert.Equal ("Only Percent and Absolute values are supported for SplitterDistance property. Passed value was PosFunc", ex.Message);
  268. // Also not allowed because this results in a PosCombine
  269. ex = Assert.Throws<ArgumentException> (() => splitContainer.SplitterDistance = Pos.Percent (50) - 1);
  270. Assert.Equal ("Only Percent and Absolute values are supported for SplitterDistance property. Passed value was PosCombine", ex.Message);
  271. }
  272. private LineView GetSplitContainerLineView (SplitContainer splitContainer)
  273. {
  274. return splitContainer.Subviews [0].Subviews.OfType<LineView> ().Single ();
  275. }
  276. private void SetInputFocusLine (SplitContainer splitContainer)
  277. {
  278. var line = GetSplitContainerLineView (splitContainer);
  279. line.SetFocus ();
  280. Assert.True (line.HasFocus);
  281. }
  282. private SplitContainer Get11By3SplitContainer(out LineView line, bool withBorder = false)
  283. {
  284. var split = Get11By3SplitContainer (withBorder);
  285. line = GetSplitContainerLineView (split);
  286. return split;
  287. }
  288. private SplitContainer Get11By3SplitContainer (bool withBorder = false)
  289. {
  290. var container = new SplitContainer () {
  291. Width = 11,
  292. Height = 3,
  293. };
  294. if (!withBorder) {
  295. container.Border.BorderStyle = BorderStyle.None;
  296. container.Border.DrawMarginFrame = false;
  297. }
  298. container.Panels [0].Add (new Label (new string ('1', 100)));
  299. container.Panels [1].Add (new Label (new string ('2', 100)));
  300. Application.Top.Add (container);
  301. container.ColorScheme = new ColorScheme ();
  302. container.LayoutSubviews ();
  303. container.BeginInit ();
  304. container.EndInit ();
  305. return container;
  306. }
  307. }
  308. }