ScrollBarTests.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. using Xunit.Abstractions;
  2. using static Unix.Terminal.Delegates;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class ScrollBarTests
  5. {
  6. public ScrollBarTests (ITestOutputHelper output) { _output = output; }
  7. private readonly ITestOutputHelper _output;
  8. [Fact]
  9. [AutoInitShutdown]
  10. public void AutoHideScrollBar_CheckScrollBarVisibility ()
  11. {
  12. var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), Size = 30 };
  13. View scrollBarSuperView = ScrollBarSuperView ();
  14. scrollBarSuperView.Add (scrollBar);
  15. Application.Begin ((scrollBarSuperView.SuperView as Toplevel)!);
  16. Assert.Equal (Orientation.Vertical, scrollBar.Orientation);
  17. //Assert.True (scrollBar.ShowScrollIndicator);
  18. Assert.True (scrollBar.Visible);
  19. Assert.Equal ("Absolute(2)", scrollBar.Width!.ToString ());
  20. Assert.Equal (2, scrollBar.Viewport.Width);
  21. Assert.Equal ("Fill(Absolute(0))", scrollBar.Height!.ToString ());
  22. Assert.Equal (25, scrollBar.Viewport.Height);
  23. scrollBar.Size = 10;
  24. //Assert.False (scrollBar.ShowScrollIndicator);
  25. Assert.False (scrollBar.Visible);
  26. scrollBar.Size = 30;
  27. //Assert.True (scrollBar.ShowScrollIndicator);
  28. Assert.True (scrollBar.Visible);
  29. scrollBar.AutoHide = false;
  30. //Assert.True (scrollBar.ShowScrollIndicator);
  31. Assert.True (scrollBar.Visible);
  32. scrollBar.Size = 10;
  33. //Assert.True (scrollBar.ShowScrollIndicator);
  34. Assert.True (scrollBar.Visible);
  35. scrollBarSuperView.SuperView!.Dispose ();
  36. }
  37. [Fact]
  38. public void Constructor_Defaults ()
  39. {
  40. var scrollBar = new ScrollBar ();
  41. Assert.False (scrollBar.CanFocus);
  42. Assert.Equal (Orientation.Vertical, scrollBar.Orientation);
  43. Assert.Equal (0, scrollBar.Size);
  44. Assert.Equal (0, scrollBar.SliderPosition);
  45. Assert.True (scrollBar.AutoHide);
  46. }
  47. [Fact]
  48. public void OnOrientationChanged_Keeps_Size ()
  49. {
  50. var scroll = new Scroll ();
  51. scroll.Layout ();
  52. scroll.Size = 1;
  53. scroll.Orientation = Orientation.Horizontal;
  54. Assert.Equal (1, scroll.Size);
  55. }
  56. [Fact]
  57. public void OnOrientationChanged_Sets_Position_To_0 ()
  58. {
  59. View super = new View ()
  60. {
  61. Id = "super",
  62. Width = 10,
  63. Height = 10
  64. };
  65. var scrollBar = new ScrollBar ()
  66. {
  67. };
  68. super.Add (scrollBar);
  69. scrollBar.Layout ();
  70. scrollBar.SliderPosition = 1;
  71. scrollBar.Orientation = Orientation.Horizontal;
  72. Assert.Equal (0, scrollBar.SliderPosition);
  73. }
  74. [Fact]
  75. public void SliderPosition_Event_Cancelables ()
  76. {
  77. var changingCount = 0;
  78. var changedCount = 0;
  79. var scrollBar = new ScrollBar { };
  80. scrollBar.Layout ();
  81. scrollBar.Size = scrollBar.Viewport.Height * 2;
  82. scrollBar.Layout ();
  83. scrollBar.SliderPositionChanging += (s, e) =>
  84. {
  85. if (changingCount == 0)
  86. {
  87. e.Cancel = true;
  88. }
  89. changingCount++;
  90. };
  91. scrollBar.SliderPositionChanged += (s, e) => changedCount++;
  92. scrollBar.SliderPosition = 1;
  93. Assert.Equal (0, scrollBar.SliderPosition);
  94. Assert.Equal (1, changingCount);
  95. Assert.Equal (0, changedCount);
  96. scrollBar.SliderPosition = 1;
  97. Assert.Equal (1, scrollBar.SliderPosition);
  98. Assert.Equal (2, changingCount);
  99. Assert.Equal (1, changedCount);
  100. }
  101. [Fact]
  102. public void ContentPosition_Event_Cancelables ()
  103. {
  104. var changingCount = 0;
  105. var changedCount = 0;
  106. var scrollBar = new ScrollBar { };
  107. scrollBar.Layout ();
  108. scrollBar.Size = scrollBar.Viewport.Height * 2;
  109. scrollBar.Layout ();
  110. scrollBar.ContentPositionChanging += (s, e) =>
  111. {
  112. if (changingCount == 0)
  113. {
  114. e.Cancel = true;
  115. }
  116. changingCount++;
  117. };
  118. scrollBar.ContentPositionChanged += (s, e) => changedCount++;
  119. scrollBar.ContentPosition = 1;
  120. Assert.Equal (0, scrollBar.ContentPosition);
  121. Assert.Equal (1, changingCount);
  122. Assert.Equal (0, changedCount);
  123. scrollBar.ContentPosition = 1;
  124. Assert.Equal (1, scrollBar.ContentPosition);
  125. Assert.Equal (2, changingCount);
  126. Assert.Equal (1, changedCount);
  127. }
  128. [Fact (Skip = "Disabled - Will put this feature in View")]
  129. [AutoInitShutdown]
  130. public void KeepContentInAllViewport_True_False ()
  131. {
  132. var view = new View { Width = Dim.Fill (), Height = Dim.Fill () };
  133. view.Padding.Thickness = new (0, 0, 2, 0);
  134. view.SetContentSize (new (view.Viewport.Width, 30));
  135. var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), Size = view.GetContentSize ().Height };
  136. scrollBar.SliderPositionChanged += (_, e) => view.Viewport = view.Viewport with { Y = e.CurrentValue };
  137. view.Padding.Add (scrollBar);
  138. var top = new Toplevel ();
  139. top.Add (view);
  140. Application.Begin (top);
  141. Assert.False (scrollBar.KeepContentInAllViewport);
  142. scrollBar.KeepContentInAllViewport = true;
  143. Assert.Equal (80, view.Padding.Viewport.Width);
  144. Assert.Equal (25, view.Padding.Viewport.Height);
  145. Assert.Equal (2, scrollBar.Viewport.Width);
  146. Assert.Equal (25, scrollBar.Viewport.Height);
  147. Assert.Equal (30, scrollBar.Size);
  148. scrollBar.KeepContentInAllViewport = false;
  149. scrollBar.SliderPosition = 50;
  150. Assert.Equal (scrollBar.SliderPosition, scrollBar.Size - 1);
  151. Assert.Equal (scrollBar.SliderPosition, view.Viewport.Y);
  152. Assert.Equal (29, scrollBar.SliderPosition);
  153. Assert.Equal (29, view.Viewport.Y);
  154. top.Dispose ();
  155. }
  156. [Theory (Skip = "Disabled - Will put this feature in View")]
  157. [AutoInitShutdown]
  158. [InlineData (Orientation.Vertical)]
  159. [InlineData (Orientation.Horizontal)]
  160. public void Moving_Mouse_Outside_Host_Ensures_Correct_Location_KeepContentInAllViewport_True (Orientation orientation)
  161. {
  162. var scrollBar = new ScrollBar
  163. {
  164. X = 10, Y = 10, Width = orientation == Orientation.Vertical ? 1 : 10, Height = orientation == Orientation.Vertical ? 10 : 1, Size = 20,
  165. SliderPosition = 5, Orientation = orientation, KeepContentInAllViewport = true
  166. };
  167. var top = new Toplevel ();
  168. top.Add (scrollBar);
  169. RunState rs = Application.Begin (top);
  170. var scroll = (Scroll)scrollBar.Subviews.FirstOrDefault (x => x is Scroll);
  171. Rectangle scrollSliderFrame = scroll!.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame;
  172. Assert.Equal (scrollSliderFrame, orientation == Orientation.Vertical ? new (0, 2, 1, 4) : new (2, 0, 4, 1));
  173. Application.RaiseMouseEvent (new () { ScreenPosition = orientation == Orientation.Vertical ? new (10, 14) : new (14, 10), Flags = MouseFlags.Button1Pressed });
  174. Application.RunIteration (ref rs);
  175. Application.RaiseMouseEvent (
  176. new ()
  177. {
  178. ScreenPosition = orientation == Orientation.Vertical ? new (10, 0) : new (0, 10),
  179. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  180. });
  181. Application.RunIteration (ref rs);
  182. Assert.Equal (new (0, 0), scroll.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame.Location);
  183. Application.RaiseMouseEvent (
  184. new ()
  185. {
  186. ScreenPosition = orientation == Orientation.Vertical ? new (0, 25) : new (80, 0),
  187. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  188. });
  189. Application.RunIteration (ref rs);
  190. Assert.Equal (
  191. orientation == Orientation.Vertical ? new (0, 4) : new (4, 0),
  192. scroll.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame.Location);
  193. }
  194. [Fact]
  195. public void Size_Cannot_Be_Negative ()
  196. {
  197. var scrollBar = new ScrollBar { Height = 10, Size = -1 };
  198. Assert.Equal (0, scrollBar.Size);
  199. scrollBar.Size = -10;
  200. Assert.Equal (0, scrollBar.Size);
  201. }
  202. [Fact]
  203. public void SizeChanged_Event ()
  204. {
  205. var count = 0;
  206. var scrollBar = new ScrollBar ();
  207. scrollBar.SizeChanged += (s, e) => count++;
  208. scrollBar.Size = 10;
  209. Assert.Equal (10, scrollBar.Size);
  210. Assert.Equal (1, count);
  211. }
  212. [Theory]
  213. [SetupFakeDriver]
  214. [InlineData (
  215. 10,
  216. 1,
  217. 20,
  218. 0,
  219. Orientation.Horizontal,
  220. @"
  221. ┌──────────┐
  222. │◄███░░░░░►│
  223. └──────────┘")]
  224. [InlineData (
  225. 10,
  226. 3,
  227. 20,
  228. 1,
  229. Orientation.Horizontal,
  230. @"
  231. ┌──────────┐
  232. │ ░███░░░░ │
  233. │◄░███░░░░►│
  234. │ ░███░░░░ │
  235. └──────────┘")]
  236. [InlineData (
  237. 3,
  238. 10,
  239. 20,
  240. 0,
  241. Orientation.Vertical,
  242. @"
  243. ┌───┐
  244. │ ▲ │
  245. │███│
  246. │███│
  247. │███│
  248. │░░░│
  249. │░░░│
  250. │░░░│
  251. │░░░│
  252. │░░░│
  253. │ ▼ │
  254. └───┘")]
  255. [InlineData (
  256. 6,
  257. 10,
  258. 20,
  259. 1,
  260. Orientation.Vertical,
  261. @"
  262. ┌──────┐
  263. │ ▲ │
  264. │░░░░░░│
  265. │██████│
  266. │██████│
  267. │██████│
  268. │░░░░░░│
  269. │░░░░░░│
  270. │░░░░░░│
  271. │░░░░░░│
  272. │ ▼ │
  273. └──────┘")]
  274. public void Draws_Correctly (int superViewportWidth, int superViewportHeight, int sliderSize, int sliderPosition, Orientation orientation, string expected)
  275. {
  276. var super = new Window
  277. {
  278. Id = "super",
  279. Width = superViewportWidth + 2,
  280. Height = superViewportHeight + 2
  281. };
  282. var scrollBar = new ScrollBar
  283. {
  284. Orientation = orientation,
  285. };
  286. if (orientation == Orientation.Vertical)
  287. {
  288. scrollBar.Width = Dim.Fill ();
  289. }
  290. else
  291. {
  292. scrollBar.Height = Dim.Fill ();
  293. }
  294. super.Add (scrollBar);
  295. scrollBar.Size = sliderSize;
  296. scrollBar.Layout ();
  297. scrollBar.SliderPosition = sliderPosition;
  298. super.BeginInit ();
  299. super.EndInit ();
  300. super.Layout ();
  301. super.Draw ();
  302. _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  303. }
  304. private View ScrollBarSuperView ()
  305. {
  306. var view = new View
  307. {
  308. Width = Dim.Fill (),
  309. Height = Dim.Fill ()
  310. };
  311. var top = new Toplevel ();
  312. top.Add (view);
  313. return view;
  314. }
  315. [Theory]
  316. [CombinatorialData]
  317. [AutoInitShutdown]
  318. public void Mouse_Click_DecrementButton_Decrements ([CombinatorialRange (1, 3, 1)] int increment, Orientation orientation)
  319. {
  320. var top = new Toplevel ()
  321. {
  322. Id = "top",
  323. Width = 10,
  324. Height = 10
  325. };
  326. var scrollBar = new ScrollBar
  327. {
  328. Id = "scrollBar",
  329. Orientation = orientation,
  330. Size = 20,
  331. Increment = increment
  332. };
  333. top.Add (scrollBar);
  334. RunState rs = Application.Begin (top);
  335. scrollBar.SliderPosition = 5;
  336. Application.RunIteration (ref rs);
  337. Assert.Equal (5, scrollBar.SliderPosition);
  338. Assert.Equal (12, scrollBar.ContentPosition);
  339. int initialPos = scrollBar.ContentPosition;
  340. Application.RaiseMouseEvent (new ()
  341. {
  342. ScreenPosition = new (0, 0),
  343. Flags = MouseFlags.Button1Clicked
  344. });
  345. Application.RunIteration (ref rs);
  346. Assert.Equal (initialPos - increment, scrollBar.ContentPosition);
  347. Application.ResetState (true);
  348. }
  349. [Theory]
  350. [CombinatorialData]
  351. [AutoInitShutdown]
  352. public void Mouse_Click_IncrementButton_Increments ([CombinatorialRange (1, 3, 1)] int increment, Orientation orientation)
  353. {
  354. var top = new Toplevel ()
  355. {
  356. Id = "top",
  357. Width = 10,
  358. Height = 10
  359. };
  360. var scrollBar = new ScrollBar
  361. {
  362. Id = "scrollBar",
  363. Orientation = orientation,
  364. Size = 20,
  365. Increment = increment
  366. };
  367. top.Add (scrollBar);
  368. RunState rs = Application.Begin (top);
  369. scrollBar.SliderPosition = 0;
  370. Application.RunIteration (ref rs);
  371. Assert.Equal (0, scrollBar.SliderPosition);
  372. Assert.Equal (0, scrollBar.ContentPosition);
  373. int initialPos = scrollBar.ContentPosition;
  374. Application.RaiseMouseEvent (new ()
  375. {
  376. ScreenPosition = orientation == Orientation.Vertical ? new (0, scrollBar.Frame.Height - 1) : new (scrollBar.Frame.Width - 1, 0),
  377. Flags = MouseFlags.Button1Clicked
  378. });
  379. Application.RunIteration (ref rs);
  380. Assert.Equal (initialPos + increment, scrollBar.ContentPosition);
  381. Application.ResetState (true);
  382. }
  383. }