AbsoluteLayoutTests.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. using Xunit.Abstractions;
  2. //using GraphViewTests = Terminal.Gui.Views.GraphViewTests;
  3. // Alias Console to MockConsole so we don't accidentally use Console
  4. namespace Terminal.Gui.ViewTests;
  5. public class AbsoluteLayoutTests
  6. {
  7. private readonly ITestOutputHelper _output;
  8. public AbsoluteLayoutTests (ITestOutputHelper output) { _output = output; }
  9. [Fact]
  10. [TestRespondersDisposed]
  11. public void AbsoluteLayout_Change_Frame ()
  12. {
  13. var frame = new Rectangle (1, 2, 3, 4);
  14. var newFrame = new Rectangle (1, 2, 30, 40);
  15. var v = new View ();
  16. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  17. v.Dispose ();
  18. v = new View { Frame = frame };
  19. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  20. v.Frame = newFrame;
  21. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  22. Assert.Equal (newFrame, v.Frame);
  23. Assert.Equal (
  24. new Rectangle (0, 0, newFrame.Width, newFrame.Height),
  25. v.Viewport
  26. ); // With Absolute Bounds *is* deterministic before Layout
  27. Assert.Equal (Pos.At (1), v.X);
  28. Assert.Equal (Pos.At (2), v.Y);
  29. Assert.Equal (Dim.Sized (30), v.Width);
  30. Assert.Equal (Dim.Sized (40), v.Height);
  31. v.Dispose ();
  32. v = new View { X = frame.X, Y = frame.Y, Text = "v" };
  33. v.Frame = newFrame;
  34. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  35. Assert.Equal (newFrame, v.Frame);
  36. Assert.Equal (
  37. new Rectangle (0, 0, newFrame.Width, newFrame.Height),
  38. v.Viewport
  39. ); // With Absolute Bounds *is* deterministic before Layout
  40. Assert.Equal (Pos.At (1), v.X);
  41. Assert.Equal (Pos.At (2), v.Y);
  42. Assert.Equal (Dim.Sized (30), v.Width);
  43. Assert.Equal (Dim.Sized (40), v.Height);
  44. v.Dispose ();
  45. newFrame = new Rectangle (10, 20, 30, 40);
  46. v = new View { Frame = frame };
  47. v.Frame = newFrame;
  48. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  49. Assert.Equal (newFrame, v.Frame);
  50. Assert.Equal (
  51. new Rectangle (0, 0, newFrame.Width, newFrame.Height),
  52. v.Viewport
  53. ); // With Absolute Bounds *is* deterministic before Layout
  54. Assert.Equal (Pos.At (10), v.X);
  55. Assert.Equal (Pos.At (20), v.Y);
  56. Assert.Equal (Dim.Sized (30), v.Width);
  57. Assert.Equal (Dim.Sized (40), v.Height);
  58. v.Dispose ();
  59. v = new View { X = frame.X, Y = frame.Y, Text = "v" };
  60. v.Frame = newFrame;
  61. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  62. Assert.Equal (newFrame, v.Frame);
  63. Assert.Equal (
  64. new Rectangle (0, 0, newFrame.Width, newFrame.Height),
  65. v.Viewport
  66. ); // With Absolute Bounds *is* deterministic before Layout
  67. Assert.Equal (Pos.At (10), v.X);
  68. Assert.Equal (Pos.At (20), v.Y);
  69. Assert.Equal (Dim.Sized (30), v.Width);
  70. Assert.Equal (Dim.Sized (40), v.Height);
  71. v.Dispose ();
  72. }
  73. [Fact]
  74. [TestRespondersDisposed]
  75. public void AbsoluteLayout_Change_Height_or_Width_Absolute ()
  76. {
  77. var frame = new Rectangle (1, 2, 3, 4);
  78. var newFrame = new Rectangle (1, 2, 30, 40);
  79. var v = new View { Frame = frame };
  80. v.Height = newFrame.Height;
  81. v.Width = newFrame.Width;
  82. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  83. Assert.Equal (newFrame, v.Frame);
  84. Assert.Equal (
  85. new Rectangle (0, 0, newFrame.Width, newFrame.Height),
  86. v.Viewport
  87. ); // With Absolute Bounds *is* deterministic before Layout
  88. Assert.Equal (Pos.At (1), v.X);
  89. Assert.Equal (Pos.At (2), v.Y);
  90. Assert.Equal ($"Absolute({newFrame.Height})", v.Height.ToString ());
  91. Assert.Equal ($"Absolute({newFrame.Width})", v.Width.ToString ());
  92. v.Dispose ();
  93. }
  94. [Fact]
  95. [TestRespondersDisposed]
  96. public void AbsoluteLayout_Change_Height_or_Width_MakesComputed ()
  97. {
  98. var v = new View { Frame = Rectangle.Empty };
  99. v.Height = Dim.Fill ();
  100. v.Width = Dim.Fill ();
  101. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  102. v.Dispose ();
  103. }
  104. [Fact]
  105. [TestRespondersDisposed]
  106. public void AbsoluteLayout_Change_X_or_Y_Absolute ()
  107. {
  108. var frame = new Rectangle (1, 2, 3, 4);
  109. var newFrame = new Rectangle (10, 20, 3, 4);
  110. var v = new View { Frame = frame };
  111. v.X = newFrame.X;
  112. v.Y = newFrame.Y;
  113. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  114. Assert.Equal (newFrame, v.Frame);
  115. Assert.Equal (
  116. new Rectangle (0, 0, newFrame.Width, newFrame.Height),
  117. v.Viewport
  118. ); // With Absolute Bounds *is* deterministic before Layout
  119. Assert.Equal ($"Absolute({newFrame.X})", v.X.ToString ());
  120. Assert.Equal ($"Absolute({newFrame.Y})", v.Y.ToString ());
  121. Assert.Equal (Dim.Sized (3), v.Width);
  122. Assert.Equal (Dim.Sized (4), v.Height);
  123. v.Dispose ();
  124. }
  125. [Fact]
  126. [TestRespondersDisposed]
  127. public void AbsoluteLayout_Change_X_or_Y_MakesComputed ()
  128. {
  129. var v = new View { Frame = Rectangle.Empty };
  130. v.X = Pos.Center ();
  131. v.Y = Pos.Center ();
  132. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  133. v.Dispose ();
  134. }
  135. [Fact]
  136. [TestRespondersDisposed]
  137. public void AbsoluteLayout_Change_X_Y_Height_Width_Absolute ()
  138. {
  139. var v = new View { Frame = Rectangle.Empty };
  140. v.X = 1;
  141. v.Y = 2;
  142. v.Height = 3;
  143. v.Width = 4;
  144. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  145. v.Dispose ();
  146. v = new View { Frame = Rectangle.Empty };
  147. v.X = Pos.Center ();
  148. v.Y = Pos.Center ();
  149. v.Width = Dim.Fill ();
  150. v.Height = Dim.Fill ();
  151. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  152. v.Dispose ();
  153. v = new View { Frame = Rectangle.Empty };
  154. v.X = Pos.Center ();
  155. v.Y = Pos.Center ();
  156. v.Width = Dim.Fill ();
  157. v.Height = Dim.Fill ();
  158. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  159. v.X = 1;
  160. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  161. v.Dispose ();
  162. v = new View { Frame = Rectangle.Empty };
  163. v.X = Pos.Center ();
  164. v.Y = Pos.Center ();
  165. v.Width = Dim.Fill ();
  166. v.Height = Dim.Fill ();
  167. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  168. v.Y = 2;
  169. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  170. v.Dispose ();
  171. v = new View { Frame = Rectangle.Empty };
  172. v.X = Pos.Center ();
  173. v.Y = Pos.Center ();
  174. v.Width = Dim.Fill ();
  175. v.Height = Dim.Fill ();
  176. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  177. v.Width = 3;
  178. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  179. v.Dispose ();
  180. v = new View { Frame = Rectangle.Empty };
  181. v.X = Pos.Center ();
  182. v.Y = Pos.Center ();
  183. v.Width = Dim.Fill ();
  184. v.Height = Dim.Fill ();
  185. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  186. v.Height = 3;
  187. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  188. v.Dispose ();
  189. v = new View { Frame = Rectangle.Empty };
  190. v.X = Pos.Center ();
  191. v.Y = Pos.Center ();
  192. v.Width = Dim.Fill ();
  193. v.Height = Dim.Fill ();
  194. Assert.True (v.LayoutStyle == LayoutStyle.Computed);
  195. v.X = 1;
  196. v.Y = 2;
  197. v.Height = 3;
  198. v.Width = 4;
  199. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  200. v.Dispose ();
  201. }
  202. [Fact]
  203. [TestRespondersDisposed]
  204. public void AbsoluteLayout_Constructor ()
  205. {
  206. var v = new View ();
  207. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  208. v.Dispose ();
  209. var frame = Rectangle.Empty;
  210. v = new View { Frame = frame };
  211. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  212. Assert.Equal (frame, v.Frame);
  213. Assert.Equal (
  214. new Rectangle (0, 0, frame.Width, frame.Height),
  215. v.Viewport
  216. ); // With Absolute Bounds *is* deterministic before Layout
  217. Assert.Equal (Pos.At (0), v.X);
  218. Assert.Equal (Pos.At (0), v.Y);
  219. Assert.Equal (Dim.Sized (0), v.Width);
  220. Assert.Equal (Dim.Sized (0), v.Height);
  221. v.Dispose ();
  222. frame = new Rectangle (1, 2, 3, 4);
  223. v = new View { Frame = frame };
  224. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  225. Assert.Equal (frame, v.Frame);
  226. Assert.Equal (
  227. new Rectangle (0, 0, frame.Width, frame.Height),
  228. v.Viewport
  229. ); // With Absolute Bounds *is* deterministic before Layout
  230. Assert.Equal (Pos.At (1), v.X);
  231. Assert.Equal (Pos.At (2), v.Y);
  232. Assert.Equal (Dim.Sized (3), v.Width);
  233. Assert.Equal (Dim.Sized (4), v.Height);
  234. v.Dispose ();
  235. v = new View { Frame = frame, Text = "v" };
  236. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  237. Assert.Equal (frame, v.Frame);
  238. Assert.Equal (
  239. new Rectangle (0, 0, frame.Width, frame.Height),
  240. v.Viewport
  241. ); // With Absolute Bounds *is* deterministic before Layout
  242. Assert.Equal (Pos.At (1), v.X);
  243. Assert.Equal (Pos.At (2), v.Y);
  244. Assert.Equal (Dim.Sized (3), v.Width);
  245. Assert.Equal (Dim.Sized (4), v.Height);
  246. v.Dispose ();
  247. v = new View { X = frame.X, Y = frame.Y, Text = "v" };
  248. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  249. // BUGBUG: v2 - I think the default size should be 0,0 not 1,1
  250. // That is correct it should be 0,0 because AutoSize is false
  251. // and the size wasn't set on the initializer
  252. Assert.Equal (new Rectangle (frame.X, frame.Y, 0, 0), v.Frame);
  253. Assert.Equal (new Rectangle (0, 0, 0, 0), v.Viewport); // With Absolute Bounds *is* deterministic before Layout
  254. Assert.Equal (Pos.At (1), v.X);
  255. Assert.Equal (Pos.At (2), v.Y);
  256. Assert.Equal (Dim.Sized (0), v.Width);
  257. Assert.Equal (Dim.Sized (0), v.Height);
  258. v.Dispose ();
  259. v = new View ();
  260. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  261. Assert.Equal (new Rectangle (0, 0, 0, 0), v.Frame);
  262. Assert.Equal (new Rectangle (0, 0, 0, 0), v.Viewport); // With Absolute Bounds *is* deterministic before Layout
  263. Assert.Equal (Pos.At (0), v.X);
  264. Assert.Equal (Pos.At (0), v.Y);
  265. Assert.Equal (Dim.Sized (0), v.Width);
  266. Assert.Equal (Dim.Sized (0), v.Height);
  267. v.Dispose ();
  268. v = new View { X = frame.X, Y = frame.Y, Width = frame.Width, Height = frame.Height };
  269. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  270. Assert.Equal (new Rectangle (frame.X, frame.Y, 3, 4), v.Frame);
  271. Assert.Equal (new Rectangle (0, 0, 3, 4), v.Viewport); // With Absolute Bounds *is* deterministic before Layout
  272. Assert.Equal (Pos.At (1), v.X);
  273. Assert.Equal (Pos.At (2), v.Y);
  274. Assert.Equal (Dim.Sized (3), v.Width);
  275. Assert.Equal (Dim.Sized (4), v.Height);
  276. v.Dispose ();
  277. }
  278. [Fact]
  279. [TestRespondersDisposed]
  280. public void AbsoluteLayout_LayoutSubviews ()
  281. {
  282. var superRect = new Rectangle (0, 0, 100, 100);
  283. var super = new View { Frame = superRect, Text = "super" };
  284. Assert.True (super.LayoutStyle == LayoutStyle.Absolute);
  285. var v1 = new View { X = 0, Y = 0, Width = 10, Height = 10 };
  286. Assert.True (v1.LayoutStyle == LayoutStyle.Absolute);
  287. var v2 = new View { X = 10, Y = 10, Width = 10, Height = 10 };
  288. Assert.True (v2.LayoutStyle == LayoutStyle.Absolute);
  289. super.Add (v1, v2);
  290. Assert.True (v1.LayoutStyle == LayoutStyle.Absolute);
  291. Assert.True (v2.LayoutStyle == LayoutStyle.Absolute);
  292. super.LayoutSubviews ();
  293. Assert.Equal (new Rectangle (0, 0, 10, 10), v1.Frame);
  294. Assert.Equal (new Rectangle (10, 10, 10, 10), v2.Frame);
  295. super.Dispose ();
  296. }
  297. [Fact]
  298. public void AbsoluteLayout_Setting_Bounds_Location_NotEmpty ()
  299. {
  300. // TODO: Should we enforce Bounds.X/Y == 0? The code currently ignores value.X/Y which is
  301. // TODO: correct behavior, but is silent. Perhaps an exception?
  302. var frame = new Rectangle (1, 2, 3, 4);
  303. var newBounds = new Rectangle (10, 20, 30, 40);
  304. var view = new View { Frame = frame };
  305. view.Viewport = newBounds;
  306. Assert.Equal (new Rectangle (0, 0, 30, 40), view.Viewport);
  307. Assert.Equal (new Rectangle (1, 2, 30, 40), view.Frame);
  308. }
  309. [Fact]
  310. public void AbsoluteLayout_Setting_Bounds_Sets_Frame ()
  311. {
  312. var frame = new Rectangle (1, 2, 3, 4);
  313. var newBounds = new Rectangle (0, 0, 30, 40);
  314. var v = new View { Frame = frame };
  315. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  316. v.Viewport = newBounds;
  317. Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
  318. Assert.Equal (newBounds, v.Viewport);
  319. Assert.Equal (new Rectangle (1, 2, newBounds.Width, newBounds.Height), v.Frame);
  320. Assert.Equal (new Rectangle (0, 0, newBounds.Width, newBounds.Height), v.Viewport);
  321. Assert.Equal (Pos.At (1), v.X);
  322. Assert.Equal (Pos.At (2), v.Y);
  323. Assert.Equal (Dim.Sized (30), v.Width);
  324. Assert.Equal (Dim.Sized (40), v.Height);
  325. newBounds = new Rectangle (0, 0, 3, 4);
  326. v.Viewport = newBounds;
  327. Assert.Equal (newBounds, v.Viewport);
  328. Assert.Equal (new Rectangle (1, 2, newBounds.Width, newBounds.Height), v.Frame);
  329. Assert.Equal (new Rectangle (0, 0, newBounds.Width, newBounds.Height), v.Viewport);
  330. Assert.Equal (Pos.At (1), v.X);
  331. Assert.Equal (Pos.At (2), v.Y);
  332. Assert.Equal (Dim.Sized (3), v.Width);
  333. Assert.Equal (Dim.Sized (4), v.Height);
  334. v.BorderStyle = LineStyle.Single;
  335. // Bounds should shrink
  336. Assert.Equal (new Rectangle (0, 0, 1, 2), v.Viewport);
  337. // Frame should not change
  338. Assert.Equal (new Rectangle (1, 2, 3, 4), v.Frame);
  339. Assert.Equal (Pos.At (1), v.X);
  340. Assert.Equal (Pos.At (2), v.Y);
  341. Assert.Equal (Dim.Sized (3), v.Width);
  342. Assert.Equal (Dim.Sized (4), v.Height);
  343. // Now set bounds bigger as before
  344. newBounds = new Rectangle (0, 0, 3, 4);
  345. v.Viewport = newBounds;
  346. Assert.Equal (newBounds, v.Viewport);
  347. // Frame grows because there's now a border
  348. Assert.Equal (new Rectangle (1, 2, 5, 6), v.Frame);
  349. Assert.Equal (new Rectangle (0, 0, newBounds.Width, newBounds.Height), v.Viewport);
  350. Assert.Equal (Pos.At (1), v.X);
  351. Assert.Equal (Pos.At (2), v.Y);
  352. Assert.Equal (Dim.Sized (5), v.Width);
  353. Assert.Equal (Dim.Sized (6), v.Height);
  354. }
  355. }