ScrollBarViewTests.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. using System;
  2. using System.Diagnostics;
  3. using System.Reflection;
  4. using Xunit;
  5. namespace Terminal.Gui.Views {
  6. public class ScrollBarViewTests {
  7. // This class enables test functions annoated with the [InitShutdown] attribute
  8. // to have a function called before the test function is called and after.
  9. //
  10. // This is necessary because a) Application is a singleton and Init/Shutdown must be called
  11. // as a pair, and b) all unit test functions should be atomic.
  12. [AttributeUsage (AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  13. public class InitShutdown : Xunit.Sdk.BeforeAfterTestAttribute {
  14. public override void Before (MethodInfo methodUnderTest)
  15. {
  16. Debug.WriteLine ($"Before: {methodUnderTest.Name}");
  17. if (_hostView != null) {
  18. throw new InvalidOperationException ("After did not run.");
  19. }
  20. Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
  21. var top = Application.Top;
  22. ScrollBarViewTests._hostView = new HostView () {
  23. Width = Dim.Fill (),
  24. Height = Dim.Fill (),
  25. Top = 0,
  26. Lines = 30,
  27. Left = 0,
  28. Cols = 100
  29. };
  30. top.Add (ScrollBarViewTests._hostView);
  31. }
  32. public override void After (MethodInfo methodUnderTest)
  33. {
  34. Debug.WriteLine ($"After: {methodUnderTest.Name}");
  35. ScrollBarViewTests._hostView = null;
  36. Application.Shutdown ();
  37. }
  38. }
  39. public class HostView : View {
  40. public int Top { get; set; }
  41. public int Lines { get; set; }
  42. public int Left { get; set; }
  43. public int Cols { get; set; }
  44. }
  45. private static HostView _hostView;
  46. private ScrollBarView _scrollBar;
  47. private bool _added;
  48. private void AddHandlers ()
  49. {
  50. if (!_added) {
  51. _hostView.DrawContent += _hostView_DrawContent;
  52. _scrollBar.ChangedPosition += _scrollBar_ChangedPosition;
  53. _scrollBar.OtherScrollBarView.ChangedPosition += _scrollBar_OtherScrollBarView_ChangedPosition;
  54. }
  55. _added = true;
  56. }
  57. private void RemoveHandlers ()
  58. {
  59. if (_added) {
  60. _hostView.DrawContent -= _hostView_DrawContent;
  61. _scrollBar.ChangedPosition -= _scrollBar_ChangedPosition;
  62. _scrollBar.OtherScrollBarView.ChangedPosition -= _scrollBar_OtherScrollBarView_ChangedPosition;
  63. }
  64. _added = false;
  65. }
  66. private void _hostView_DrawContent (Rect obj)
  67. {
  68. _scrollBar.Size = _hostView.Lines;
  69. _scrollBar.Position = _hostView.Top;
  70. _scrollBar.OtherScrollBarView.Size = _hostView.Cols;
  71. _scrollBar.OtherScrollBarView.Position = _hostView.Left;
  72. _scrollBar.Refresh ();
  73. }
  74. private void _scrollBar_ChangedPosition ()
  75. {
  76. _hostView.Top = _scrollBar.Position;
  77. if (_hostView.Top != _scrollBar.Position) {
  78. _scrollBar.Position = _hostView.Top;
  79. }
  80. _hostView.SetNeedsDisplay ();
  81. }
  82. private void _scrollBar_OtherScrollBarView_ChangedPosition ()
  83. {
  84. _hostView.Left = _scrollBar.OtherScrollBarView.Position;
  85. if (_hostView.Left != _scrollBar.OtherScrollBarView.Position) {
  86. _scrollBar.OtherScrollBarView.Position = _hostView.Left;
  87. }
  88. _hostView.SetNeedsDisplay ();
  89. }
  90. [Fact]
  91. [InitShutdown]
  92. public void Hosting_A_Null_View_To_A_ScrollBarView_Throws_ArgumentNullException ()
  93. {
  94. Assert.Throws<ArgumentNullException> ("The host parameter can't be null.",
  95. () => new ScrollBarView (null, true));
  96. Assert.Throws<ArgumentNullException> ("The host parameter can't be null.",
  97. () => new ScrollBarView (null, false));
  98. }
  99. [Fact]
  100. [InitShutdown]
  101. public void Hosting_A_Null_SuperView_View_To_A_ScrollBarView_Throws_ArgumentNullException ()
  102. {
  103. Assert.Throws<ArgumentNullException> ("The host SuperView parameter can't be null.",
  104. () => new ScrollBarView (new View (), true));
  105. Assert.Throws<ArgumentNullException> ("The host SuperView parameter can't be null.",
  106. () => new ScrollBarView (new View (), false));
  107. }
  108. [Fact]
  109. [InitShutdown]
  110. public void Hosting_Two_Vertical_ScrollBarView_Throws_ArgumentException ()
  111. {
  112. var top = new Toplevel ();
  113. var host = new View ();
  114. top.Add (host);
  115. var v = new ScrollBarView (host, true);
  116. var h = new ScrollBarView (host, true);
  117. Assert.Throws<ArgumentException> (null, () => v.OtherScrollBarView = h);
  118. Assert.Throws<ArgumentException> (null, () => h.OtherScrollBarView = v);
  119. }
  120. [Fact]
  121. [InitShutdown]
  122. public void Hosting_Two_Horizontal_ScrollBarView_Throws_ArgumentException ()
  123. {
  124. var top = new Toplevel ();
  125. var host = new View ();
  126. top.Add (host);
  127. var v = new ScrollBarView (host, false);
  128. var h = new ScrollBarView (host, false);
  129. Assert.Throws<ArgumentException> (null, () => v.OtherScrollBarView = h);
  130. Assert.Throws<ArgumentException> (null, () => h.OtherScrollBarView = v);
  131. }
  132. [Fact]
  133. [InitShutdown]
  134. public void Scrolling_With_Default_Constructor_Do_Not_Scroll ()
  135. {
  136. var sbv = new ScrollBarView {
  137. Position = 1
  138. };
  139. Assert.NotEqual (1, sbv.Position);
  140. Assert.Equal (0, sbv.Position);
  141. }
  142. [Fact]
  143. [InitShutdown]
  144. public void Hosting_A_View_To_A_ScrollBarView ()
  145. {
  146. RemoveHandlers ();
  147. _scrollBar = new ScrollBarView (_hostView, true);
  148. Assert.True (_scrollBar.IsVertical);
  149. Assert.False (_scrollBar.OtherScrollBarView.IsVertical);
  150. Assert.Equal (_scrollBar.Position, _hostView.Top);
  151. Assert.NotEqual (_scrollBar.Size, _hostView.Lines);
  152. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  153. Assert.NotEqual (_scrollBar.OtherScrollBarView.Size, _hostView.Cols);
  154. AddHandlers ();
  155. _hostView.SuperView.LayoutSubviews ();
  156. _hostView.Redraw (_hostView.Bounds);
  157. Assert.Equal (_scrollBar.Position, _hostView.Top);
  158. Assert.Equal (_scrollBar.Size, _hostView.Lines + 1);
  159. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  160. Assert.Equal (_scrollBar.OtherScrollBarView.Size, _hostView.Cols + 1);
  161. }
  162. [Fact]
  163. [InitShutdown]
  164. public void ChangedPosition_Update_The_Hosted_View ()
  165. {
  166. Hosting_A_View_To_A_ScrollBarView ();
  167. AddHandlers ();
  168. _scrollBar.Position = 2;
  169. Assert.Equal (_scrollBar.Position, _hostView.Top);
  170. _scrollBar.OtherScrollBarView.Position = 5;
  171. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  172. }
  173. [Fact]
  174. [InitShutdown]
  175. public void ChangedPosition_Scrolling ()
  176. {
  177. Hosting_A_View_To_A_ScrollBarView ();
  178. AddHandlers ();
  179. for (int i = 0; i < _scrollBar.Size; i++) {
  180. _scrollBar.Position += 1;
  181. Assert.Equal (_scrollBar.Position, _hostView.Top);
  182. }
  183. for (int i = _scrollBar.Size - 1; i >= 0; i--) {
  184. _scrollBar.Position -= 1;
  185. Assert.Equal (_scrollBar.Position, _hostView.Top);
  186. }
  187. for (int i = 0; i < _scrollBar.OtherScrollBarView.Size; i++) {
  188. _scrollBar.OtherScrollBarView.Position += i;
  189. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  190. }
  191. for (int i = _scrollBar.OtherScrollBarView.Size - 1; i >= 0; i--) {
  192. _scrollBar.OtherScrollBarView.Position -= 1;
  193. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  194. }
  195. }
  196. [Fact]
  197. [InitShutdown]
  198. public void ChangedPosition_Negative_Value ()
  199. {
  200. Hosting_A_View_To_A_ScrollBarView ();
  201. AddHandlers ();
  202. _scrollBar.Position = -20;
  203. Assert.Equal (0, _scrollBar.Position);
  204. Assert.Equal (_scrollBar.Position, _hostView.Top);
  205. _scrollBar.OtherScrollBarView.Position = -50;
  206. Assert.Equal (0, _scrollBar.OtherScrollBarView.Position);
  207. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  208. }
  209. [Fact]
  210. [InitShutdown]
  211. public void DrawContent_Update_The_ScrollBarView_Position ()
  212. {
  213. Hosting_A_View_To_A_ScrollBarView ();
  214. AddHandlers ();
  215. _hostView.Top = 3;
  216. _hostView.Redraw (_hostView.Bounds);
  217. Assert.Equal (_scrollBar.Position, _hostView.Top);
  218. _hostView.Left = 6;
  219. _hostView.Redraw (_hostView.Bounds);
  220. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  221. }
  222. [Fact]
  223. [InitShutdown]
  224. public void OtherScrollBarView_Not_Null ()
  225. {
  226. Hosting_A_View_To_A_ScrollBarView ();
  227. AddHandlers ();
  228. Assert.NotNull (_scrollBar.OtherScrollBarView);
  229. Assert.NotEqual (_scrollBar, _scrollBar.OtherScrollBarView);
  230. Assert.Equal (_scrollBar.OtherScrollBarView.OtherScrollBarView, _scrollBar);
  231. }
  232. [Fact]
  233. [InitShutdown]
  234. public void ShowScrollIndicator_Check ()
  235. {
  236. Hosting_A_View_To_A_ScrollBarView ();
  237. AddHandlers ();
  238. Assert.True (_scrollBar.ShowScrollIndicator);
  239. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  240. }
  241. [Fact]
  242. [InitShutdown]
  243. public void KeepContentAlwaysInViewport_True ()
  244. {
  245. Hosting_A_View_To_A_ScrollBarView ();
  246. AddHandlers ();
  247. Assert.Equal (80, _hostView.Bounds.Width);
  248. Assert.Equal (25, _hostView.Bounds.Height);
  249. Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width);
  250. Assert.Equal (24, _scrollBar.Bounds.Height);
  251. Assert.Equal (31, _scrollBar.Size);
  252. Assert.Equal (101, _scrollBar.OtherScrollBarView.Size);
  253. Assert.True (_scrollBar.ShowScrollIndicator);
  254. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  255. Assert.True (_scrollBar.Visible);
  256. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  257. _scrollBar.Position = 50;
  258. Assert.Equal (_scrollBar.Position, _scrollBar.Size - _scrollBar.Bounds.Height);
  259. Assert.Equal (_scrollBar.Position, _hostView.Top);
  260. Assert.Equal (7, _scrollBar.Position);
  261. Assert.Equal (7, _hostView.Top);
  262. Assert.True (_scrollBar.ShowScrollIndicator);
  263. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  264. Assert.True (_scrollBar.Visible);
  265. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  266. _scrollBar.OtherScrollBarView.Position = 150;
  267. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _scrollBar.OtherScrollBarView.Size - _scrollBar.OtherScrollBarView.Bounds.Width);
  268. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  269. Assert.Equal (22, _scrollBar.OtherScrollBarView.Position);
  270. Assert.Equal (22, _hostView.Left);
  271. Assert.True (_scrollBar.ShowScrollIndicator);
  272. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  273. Assert.True (_scrollBar.Visible);
  274. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  275. }
  276. [Fact]
  277. [InitShutdown]
  278. public void KeepContentAlwaysInViewport_False ()
  279. {
  280. Hosting_A_View_To_A_ScrollBarView ();
  281. AddHandlers ();
  282. _scrollBar.KeepContentAlwaysInViewport = false;
  283. _scrollBar.Position = 50;
  284. Assert.Equal (_scrollBar.Position, _scrollBar.Size - 1);
  285. Assert.Equal (_scrollBar.Position, _hostView.Top);
  286. Assert.Equal (30, _scrollBar.Position);
  287. Assert.Equal (30, _hostView.Top);
  288. _scrollBar.OtherScrollBarView.Position = 150;
  289. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _scrollBar.OtherScrollBarView.Size - 1);
  290. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  291. Assert.Equal (100, _scrollBar.OtherScrollBarView.Position);
  292. Assert.Equal (100, _hostView.Left);
  293. }
  294. [Fact]
  295. [InitShutdown]
  296. public void AutoHideScrollBars_Check ()
  297. {
  298. Hosting_A_View_To_A_ScrollBarView ();
  299. AddHandlers ();
  300. _hostView.Redraw (_hostView.Bounds);
  301. Assert.True (_scrollBar.ShowScrollIndicator);
  302. Assert.True (_scrollBar.Visible);
  303. Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
  304. Assert.Equal (1, _scrollBar.Bounds.Width);
  305. Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
  306. _scrollBar.Height.ToString ());
  307. Assert.Equal (24, _scrollBar.Bounds.Height);
  308. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  309. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  310. Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
  311. _scrollBar.OtherScrollBarView.Width.ToString ());
  312. Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width);
  313. Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  314. Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
  315. _hostView.Lines = 10;
  316. _hostView.Redraw (_hostView.Bounds);
  317. Assert.False (_scrollBar.ShowScrollIndicator);
  318. Assert.False (_scrollBar.Visible);
  319. Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
  320. Assert.Equal (1, _scrollBar.Bounds.Width);
  321. Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
  322. _scrollBar.Height.ToString ());
  323. Assert.Equal (24, _scrollBar.Bounds.Height);
  324. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  325. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  326. Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))",
  327. _scrollBar.OtherScrollBarView.Width.ToString ());
  328. Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
  329. Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  330. Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
  331. _hostView.Cols = 60;
  332. _hostView.Redraw (_hostView.Bounds);
  333. Assert.False (_scrollBar.ShowScrollIndicator);
  334. Assert.False (_scrollBar.Visible);
  335. Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
  336. Assert.Equal (1, _scrollBar.Bounds.Width);
  337. Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
  338. _scrollBar.Height.ToString ());
  339. Assert.Equal (24, _scrollBar.Bounds.Height);
  340. Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  341. Assert.False (_scrollBar.OtherScrollBarView.Visible);
  342. Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))",
  343. _scrollBar.OtherScrollBarView.Width.ToString ());
  344. Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
  345. Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  346. Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
  347. _hostView.Lines = 40;
  348. _hostView.Redraw (_hostView.Bounds);
  349. Assert.True (_scrollBar.ShowScrollIndicator);
  350. Assert.True (_scrollBar.Visible);
  351. Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
  352. Assert.Equal (1, _scrollBar.Bounds.Width);
  353. Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))",
  354. _scrollBar.Height.ToString ());
  355. Assert.Equal (25, _scrollBar.Bounds.Height);
  356. Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  357. Assert.False (_scrollBar.OtherScrollBarView.Visible);
  358. Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))",
  359. _scrollBar.OtherScrollBarView.Width.ToString ());
  360. Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
  361. Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  362. Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
  363. _hostView.Cols = 120;
  364. _hostView.Redraw (_hostView.Bounds);
  365. Assert.True (_scrollBar.ShowScrollIndicator);
  366. Assert.True (_scrollBar.Visible);
  367. Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
  368. Assert.Equal (1, _scrollBar.Bounds.Width);
  369. Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
  370. _scrollBar.Height.ToString ());
  371. Assert.Equal (24, _scrollBar.Bounds.Height);
  372. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  373. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  374. Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
  375. _scrollBar.OtherScrollBarView.Width.ToString ());
  376. Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width);
  377. Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  378. Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
  379. }
  380. }
  381. }