AdornmentTests.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. using Xunit.Abstractions;
  2. namespace Terminal.Gui.ViewTests;
  3. public class AdornmentTests
  4. {
  5. private readonly ITestOutputHelper _output;
  6. public AdornmentTests (ITestOutputHelper output) { _output = output; }
  7. [Fact]
  8. public void Bounds_Location_Always_Empty_Size_Correct ()
  9. {
  10. var view = new View
  11. {
  12. X = 1,
  13. Y = 2,
  14. Width = 20,
  15. Height = 20
  16. };
  17. view.BeginInit ();
  18. view.EndInit ();
  19. Assert.Equal (new (1, 2, 20, 20), view.Frame);
  20. Assert.Equal (new (0, 0, 20, 20), view.Bounds);
  21. var marginThickness = 1;
  22. view.Margin.Thickness = new (marginThickness);
  23. Assert.Equal (new (0, 0, 18, 18), view.Bounds);
  24. var borderThickness = 2;
  25. view.Border.Thickness = new (borderThickness);
  26. Assert.Equal (new (0, 0, 14, 14), view.Bounds);
  27. var paddingThickness = 3;
  28. view.Padding.Thickness = new Thickness (paddingThickness);
  29. Assert.Equal (new (0, 0, 8, 8), view.Bounds);
  30. Assert.Equal (new (0, 0, view.Margin.Frame.Width, view.Margin.Frame.Height), view.Margin.Bounds);
  31. Assert.Equal (new (0, 0, view.Border.Frame.Width, view.Border.Frame.Height), view.Border.Bounds);
  32. Assert.Equal (new (0, 0, view.Padding.Frame.Width , view.Padding.Frame.Height), view.Padding.Bounds);
  33. }
  34. // Test that Adornment.Bounds_get override returns Frame.Size minus Thickness
  35. [Theory]
  36. [InlineData (0, 0, 0, 0, 0)]
  37. [InlineData (0, 0, 0, 1, 1)]
  38. [InlineData (0, 0, 0, 1, 0)]
  39. [InlineData (0, 0, 0, 0, 1)]
  40. [InlineData (1, 0, 0, 0, 0)]
  41. [InlineData (1, 0, 0, 1, 1)]
  42. [InlineData (1, 0, 0, 1, 0)]
  43. [InlineData (1, 0, 0, 0, 1)]
  44. [InlineData (1, 0, 0, 4, 4)]
  45. [InlineData (1, 0, 0, 4, 0)]
  46. [InlineData (1, 0, 0, 0, 4)]
  47. [InlineData (0, 1, 0, 0, 0)]
  48. [InlineData (0, 1, 0, 1, 1)]
  49. [InlineData (0, 1, 0, 1, 0)]
  50. [InlineData (0, 1, 0, 0, 1)]
  51. [InlineData (1, 1, 0, 0, 0)]
  52. [InlineData (1, 1, 0, 1, 1)]
  53. [InlineData (1, 1, 0, 1, 0)]
  54. [InlineData (1, 1, 0, 0, 1)]
  55. [InlineData (1, 1, 0, 4, 4)]
  56. [InlineData (1, 1, 0, 4, 0)]
  57. [InlineData (1, 1, 0, 0, 4)]
  58. [InlineData (0, 1, 1, 0, 0)]
  59. [InlineData (0, 1, 1, 1, 1)]
  60. [InlineData (0, 1, 1, 1, 0)]
  61. [InlineData (0, 1, 1, 0, 1)]
  62. [InlineData (1, 1, 1, 0, 0)]
  63. [InlineData (1, 1, 1, 1, 1)]
  64. [InlineData (1, 1, 1, 1, 0)]
  65. [InlineData (1, 1, 1, 0, 1)]
  66. [InlineData (1, 1, 1, 4, 4)]
  67. [InlineData (1, 1, 1, 4, 0)]
  68. [InlineData (1, 1, 1, 0, 4)]
  69. public void Bounds_Width_Is_Frame_Width (int thickness, int x, int y, int w, int h)
  70. {
  71. var adornment = new Adornment (null);
  72. adornment.Thickness = new Thickness (thickness);
  73. adornment.Frame = new Rectangle (x, y, w, h);
  74. Assert.Equal (new Rectangle (x, y, w, h), adornment.Frame);
  75. var expectedBounds = new Rectangle (0, 0, w, h);
  76. Assert.Equal (expectedBounds, adornment.Bounds);
  77. }
  78. // Test that Adornment.Bounds_get override uses Parent not SuperView
  79. [Fact]
  80. public void BoundsToScreen_Uses_Parent_Not_SuperView ()
  81. {
  82. var parent = new View { X = 1, Y = 2, Width = 10, Height = 10 };
  83. parent.BeginInit ();
  84. parent.EndInit ();
  85. Assert.Equal (new Rectangle (1, 2, 10, 10), parent.Frame);
  86. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Bounds);
  87. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Margin.Frame);
  88. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Margin.Bounds);
  89. Assert.Null (parent.Margin.SuperView);
  90. Rectangle boundsAsScreen = parent.Margin.BoundsToScreen (new Rectangle (1, 2, 5, 5));
  91. Assert.Equal (new Rectangle (2, 4, 5, 5), boundsAsScreen);
  92. }
  93. [Fact]
  94. public void Frames_are_Parent_SuperView_Relative ()
  95. {
  96. var view = new View
  97. {
  98. X = 1,
  99. Y = 2,
  100. Width = 20,
  101. Height = 31
  102. };
  103. var marginThickness = 1;
  104. view.Margin.Thickness = new Thickness (marginThickness);
  105. var borderThickness = 2;
  106. view.Border.Thickness = new Thickness (borderThickness);
  107. var paddingThickness = 3;
  108. view.Padding.Thickness = new Thickness (paddingThickness);
  109. view.BeginInit ();
  110. view.EndInit ();
  111. Assert.Equal (new Rectangle (1, 2, 20, 31), view.Frame);
  112. Assert.Equal (new Rectangle (0, 0, 8, 19), view.Bounds);
  113. // Margin.Frame is always the same as the view frame
  114. Assert.Equal (new Rectangle (0, 0, 20, 31), view.Margin.Frame);
  115. // Border.Frame is View.Frame minus the Margin thickness
  116. Assert.Equal (
  117. new Rectangle (marginThickness, marginThickness, view.Frame.Width - marginThickness * 2, view.Frame.Height - marginThickness * 2),
  118. view.Border.Frame);
  119. // Padding.Frame is View.Frame minus the Border thickness plus Margin thickness
  120. Assert.Equal (
  121. new Rectangle (
  122. marginThickness + borderThickness,
  123. marginThickness + borderThickness,
  124. view.Frame.Width - (marginThickness + borderThickness) * 2,
  125. view.Frame.Height - (marginThickness + borderThickness) * 2),
  126. view.Padding.Frame);
  127. }
  128. // Test that Adornment.FrameToScreen override retains Frame.Size
  129. [Theory]
  130. [InlineData (0, 0, 0)]
  131. [InlineData (0, 1, 1)]
  132. [InlineData (0, 10, 10)]
  133. [InlineData (1, 0, 0)]
  134. [InlineData (1, 1, 1)]
  135. [InlineData (1, 10, 10)]
  136. public void FrameToScreen_Retains_Frame_Size (int marginThickness, int w, int h)
  137. {
  138. var parent = new View { X = 1, Y = 2, Width = w, Height = h };
  139. parent.Margin.Thickness = new Thickness (marginThickness);
  140. parent.BeginInit ();
  141. parent.EndInit ();
  142. Assert.Equal (new Rectangle (1, 2, w, h), parent.Frame);
  143. Assert.Equal (new Rectangle (0, 0, w, h), parent.Margin.Frame);
  144. Assert.Equal (parent.Frame, parent.Margin.FrameToScreen ());
  145. }
  146. // Test that Adornment.FrameToScreen override returns Frame if Parent is null
  147. [Fact]
  148. public void FrameToScreen_Returns_Frame_If_Parent_Is_Null ()
  149. {
  150. var a = new Adornment
  151. {
  152. X = 1,
  153. Y = 2,
  154. Width = 3,
  155. Height = 4
  156. };
  157. Assert.Null (a.Parent);
  158. Assert.Equal (a.Frame, a.FrameToScreen ());
  159. }
  160. // Test that Adornment.FrameToScreen override returns correct location
  161. [Theory]
  162. [InlineData (0, 0, 0, 0)]
  163. [InlineData (0, 0, 1, 1)]
  164. [InlineData (0, 0, 10, 10)]
  165. [InlineData (1, 0, 0, 0)]
  166. [InlineData (1, 0, 1, 1)]
  167. [InlineData (1, 0, 10, 10)]
  168. [InlineData (0, 1, 0, 0)]
  169. [InlineData (0, 1, 1, 1)]
  170. [InlineData (0, 1, 10, 10)]
  171. [InlineData (1, 1, 0, 0)]
  172. [InlineData (1, 1, 1, 1)]
  173. [InlineData (1, 1, 10, 10)]
  174. public void FrameToScreen_Returns_Screen_Location (int marginThickness, int borderThickness, int x, int y)
  175. {
  176. var superView = new View
  177. {
  178. X = 1,
  179. Y = 1,
  180. Width = 20,
  181. Height = 20
  182. };
  183. superView.Margin.Thickness = new Thickness (marginThickness);
  184. superView.Border.Thickness = new Thickness (borderThickness);
  185. var view = new View { X = x, Y = y, Width = 1, Height = 1 };
  186. superView.Add (view);
  187. superView.BeginInit ();
  188. superView.EndInit ();
  189. Assert.Equal (new Rectangle (x, y, 1, 1), view.Frame);
  190. Assert.Equal (new Rectangle (0, 0, 20, 20), superView.Margin.Frame);
  191. Assert.Equal (
  192. new Rectangle (marginThickness, marginThickness, 20 - marginThickness * 2, 20 - marginThickness * 2),
  193. superView.Border.Frame
  194. );
  195. Assert.Equal (
  196. new Rectangle (superView.Frame.X + marginThickness, superView.Frame.Y + marginThickness, 20 - marginThickness * 2, 20 - marginThickness * 2),
  197. superView.Border.FrameToScreen ()
  198. );
  199. }
  200. // Test that Adornment.FrameToScreen override uses Parent not SuperView
  201. [Fact]
  202. public void FrameToScreen_Uses_Parent_Not_SuperView ()
  203. {
  204. var parent = new View { X = 1, Y = 2, Width = 10, Height = 10 };
  205. parent.BeginInit ();
  206. parent.EndInit ();
  207. Assert.Equal (new Rectangle (1, 2, 10, 10), parent.Frame);
  208. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Bounds);
  209. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Margin.Frame);
  210. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Margin.Bounds);
  211. Assert.Null (parent.Margin.SuperView);
  212. Assert.Equal (new Rectangle (1, 2, 10, 10), parent.Margin.FrameToScreen ());
  213. }
  214. [Fact]
  215. public void GetAdornmentsThickness ()
  216. {
  217. var view = new View ();
  218. Assert.Equal (Thickness.Empty, view.GetAdornmentsThickness ());
  219. view.Margin.Thickness = new Thickness (1);
  220. Assert.Equal (new Thickness (1), view.GetAdornmentsThickness ());
  221. view.Border.Thickness = new Thickness (1);
  222. Assert.Equal (new Thickness (2), view.GetAdornmentsThickness ());
  223. view.Padding.Thickness = new Thickness (1);
  224. Assert.Equal (new Thickness (3), view.GetAdornmentsThickness ());
  225. view.Padding.Thickness = new Thickness (2);
  226. Assert.Equal (new Thickness (4), view.GetAdornmentsThickness ());
  227. view.Padding.Thickness = new Thickness (1, 2, 3, 4);
  228. Assert.Equal (new Thickness (3, 4, 5, 6), view.GetAdornmentsThickness ());
  229. view.Margin.Thickness = new Thickness (1, 2, 3, 4);
  230. Assert.Equal (new Thickness (3, 5, 7, 9), view.GetAdornmentsThickness ());
  231. view.Dispose ();
  232. }
  233. [Fact]
  234. public void Setting_Bounds_Throws ()
  235. {
  236. var adornment = new Adornment (null);
  237. Assert.Throws<InvalidOperationException> (() => adornment.Bounds = new Rectangle (1, 2, 3, 4));
  238. }
  239. [Fact]
  240. public void Setting_SuperView_Throws ()
  241. {
  242. var adornment = new Adornment (null);
  243. Assert.Throws<NotImplementedException> (() => adornment.SuperView = new View ());
  244. }
  245. [Fact]
  246. public void Setting_SuperViewRendersLineCanvas_Throws ()
  247. {
  248. var adornment = new Adornment (null);
  249. Assert.Throws<NotImplementedException> (() => adornment.SuperViewRendersLineCanvas = true);
  250. }
  251. [Fact]
  252. public void Setting_Thickness_Changes_Parent_Bounds ()
  253. {
  254. var parent = new View { Width = 10, Height = 10 };
  255. parent.BeginInit ();
  256. parent.EndInit ();
  257. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Frame);
  258. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Bounds);
  259. parent.Margin.Thickness = new Thickness (1);
  260. Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Frame);
  261. Assert.Equal (new Rectangle (0, 0, 8, 8), parent.Bounds);
  262. }
  263. [Fact]
  264. public void Setting_Thickness_Raises_ThicknessChanged ()
  265. {
  266. var adornment = new Adornment (null);
  267. var super = new View ();
  268. var raised = false;
  269. adornment.ThicknessChanged += (s, e) =>
  270. {
  271. raised = true;
  272. Assert.Equal (Thickness.Empty, e.PreviousThickness);
  273. Assert.Equal (new Thickness (1, 2, 3, 4), e.Thickness);
  274. Assert.Equal (new Thickness (1, 2, 3, 4), adornment.Thickness);
  275. };
  276. adornment.Thickness = new Thickness (1, 2, 3, 4);
  277. Assert.True (raised);
  278. }
  279. }