GetViewsUnderLocationForRootTests.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #nullable enable
  2. namespace ViewBaseTests.Layout;
  3. [Trait ("Category", "Input")]
  4. public class GetViewsUnderLocationForRootTests
  5. {
  6. [Fact]
  7. public void ReturnsRoot_WhenPointInsideRoot_NoSubviews ()
  8. {
  9. Runnable top = new ()
  10. {
  11. Frame = new (0, 0, 10, 10)
  12. };
  13. List<View?> result = View.GetViewsUnderLocation (top, new (5, 5), ViewportSettingsFlags.TransparentMouse);
  14. Assert.Contains (top, result);
  15. }
  16. [Fact]
  17. public void ReturnsEmpty_WhenPointOutsideRoot ()
  18. {
  19. Runnable top = new ()
  20. {
  21. Frame = new (0, 0, 10, 10)
  22. };
  23. List<View?> result = View.GetViewsUnderLocation (top, new (20, 20), ViewportSettingsFlags.TransparentMouse);
  24. Assert.Empty (result);
  25. }
  26. [Fact]
  27. public void ReturnsSubview_WhenPointInsideSubview ()
  28. {
  29. Runnable top = new ()
  30. {
  31. Frame = new (0, 0, 10, 10)
  32. };
  33. View sub = new ()
  34. {
  35. X = 2, Y = 2, Width = 5, Height = 5
  36. };
  37. top.Add (sub);
  38. List<View?> result = View.GetViewsUnderLocation (top, new (3, 3), ViewportSettingsFlags.TransparentMouse);
  39. Assert.Contains (top, result);
  40. Assert.Contains (sub, result);
  41. Assert.Equal (sub, result.Last ());
  42. }
  43. [Fact]
  44. public void ReturnsTop_WhenPointInsideSubview_With_TransparentMouse ()
  45. {
  46. Runnable top = new ()
  47. {
  48. Frame = new (0, 0, 10, 10)
  49. };
  50. View sub = new ()
  51. {
  52. X = 2, Y = 2, Width = 5, Height = 5,
  53. ViewportSettings = ViewportSettingsFlags.TransparentMouse
  54. };
  55. top.Add (sub);
  56. List<View?> result = View.GetViewsUnderLocation (top, new (3, 3), ViewportSettingsFlags.TransparentMouse);
  57. Assert.Single (result);
  58. Assert.Contains (top, result);
  59. result = View.GetViewsUnderLocation (top, new (3, 3), ViewportSettingsFlags.None);
  60. Assert.Equal (2, result.Count);
  61. Assert.Contains (top, result);
  62. Assert.Contains (sub, result);
  63. }
  64. [Fact]
  65. public void ReturnsAdornment_WhenPointInMargin ()
  66. {
  67. Runnable top = new ()
  68. {
  69. Frame = new (0, 0, 10, 10)
  70. };
  71. top.Margin!.Thickness = new (1);
  72. top.Margin!.ViewportSettings = ViewportSettingsFlags.None;
  73. List<View?> result = View.GetViewsUnderLocation (top, new (0, 0), ViewportSettingsFlags.TransparentMouse);
  74. Assert.Contains (top, result);
  75. Assert.Contains (top.Margin, result);
  76. }
  77. [Fact]
  78. public void Returns_WhenPointIn_TransparentToMouseMargin_None ()
  79. {
  80. Runnable top = new ()
  81. {
  82. Frame = new (0, 0, 10, 10)
  83. };
  84. top.Margin!.Thickness = new (1);
  85. top.Margin!.ViewportSettings = ViewportSettingsFlags.TransparentMouse;
  86. List<View?> result = View.GetViewsUnderLocation (top, new (0, 0), ViewportSettingsFlags.TransparentMouse);
  87. Assert.DoesNotContain (top, result);
  88. Assert.DoesNotContain (top.Margin, result);
  89. }
  90. [Fact]
  91. public void Returns_WhenPointIn_NotTransparentToMouseMargin_Top_And_Margin ()
  92. {
  93. Runnable top = new ()
  94. {
  95. Frame = new (0, 0, 10, 10)
  96. };
  97. top.Margin!.Thickness = new (1);
  98. top.Margin!.ViewportSettings = ViewportSettingsFlags.None;
  99. List<View?> result = View.GetViewsUnderLocation (top, new (0, 0), ViewportSettingsFlags.TransparentMouse);
  100. Assert.Contains (top, result);
  101. Assert.Contains (top.Margin, result);
  102. }
  103. [Fact]
  104. public void ReturnsAdornment_WhenPointInBorder ()
  105. {
  106. Runnable top = new ()
  107. {
  108. Frame = new (0, 0, 10, 10)
  109. };
  110. top.Border!.Thickness = new (1);
  111. List<View?> result = View.GetViewsUnderLocation (top, new (0, 0), ViewportSettingsFlags.TransparentMouse);
  112. Assert.Contains (top, result);
  113. Assert.Contains (top.Border, result);
  114. }
  115. [Fact]
  116. public void ReturnsAdornment_WhenPointInPadding ()
  117. {
  118. Runnable top = new ()
  119. {
  120. Frame = new (0, 0, 10, 10)
  121. };
  122. top.Border!.Thickness = new (1);
  123. top.Padding!.Thickness = new (1);
  124. top.Layout ();
  125. List<View?> result = View.GetViewsUnderLocation (top, new (1, 1), ViewportSettingsFlags.TransparentMouse);
  126. Assert.Contains (top, result);
  127. Assert.Contains (top.Padding, result);
  128. }
  129. [Fact]
  130. public void HonorsIgnoreTransparentMouseParam ()
  131. {
  132. Runnable top = new ()
  133. {
  134. Frame = new (0, 0, 10, 10),
  135. ViewportSettings = ViewportSettingsFlags.TransparentMouse
  136. };
  137. List<View?> result = View.GetViewsUnderLocation (top, new (5, 5), ViewportSettingsFlags.TransparentMouse);
  138. Assert.Empty (result);
  139. result = View.GetViewsUnderLocation (top, new (5, 5), ViewportSettingsFlags.None);
  140. Assert.NotEmpty (result);
  141. }
  142. [Fact]
  143. public void ReturnsDeepestSubview_WhenNested ()
  144. {
  145. Runnable top = new ()
  146. {
  147. Frame = new (0, 0, 10, 10)
  148. };
  149. View sub1 = new ()
  150. {
  151. X = 1, Y = 1, Width = 8, Height = 8
  152. };
  153. View sub2 = new ()
  154. {
  155. X = 1, Y = 1, Width = 6, Height = 6
  156. };
  157. sub1.Add (sub2);
  158. top.Add (sub1);
  159. List<View?> result = View.GetViewsUnderLocation (top, new (3, 3), ViewportSettingsFlags.TransparentMouse);
  160. Assert.Contains (sub2, result);
  161. Assert.Equal (sub2, result.Last ());
  162. }
  163. [Fact]
  164. public void Returns_Subview_WhenPointIn_TransparentToMouseMargin_Top ()
  165. {
  166. Runnable top = new ()
  167. {
  168. Frame = new (0, 0, 20, 20)
  169. };
  170. View subView = new ()
  171. {
  172. Frame = new (0, 0, 5, 5)
  173. };
  174. subView.Margin!.Thickness = new (1);
  175. subView.Margin!.ViewportSettings = ViewportSettingsFlags.None;
  176. top.Add (subView);
  177. Assert.True (subView.Contains (new Point (4, 4)));
  178. List<View?> result = View.GetViewsUnderLocation (top, new (4, 4), ViewportSettingsFlags.TransparentMouse);
  179. Assert.Contains (top, result);
  180. Assert.Contains (subView.Margin, result);
  181. Assert.Contains (subView, result);
  182. subView.Margin!.ViewportSettings = ViewportSettingsFlags.TransparentMouse;
  183. result = View.GetViewsUnderLocation (top, new (4, 4), ViewportSettingsFlags.TransparentMouse);
  184. Assert.Contains (top, result);
  185. Assert.DoesNotContain (subView.Margin, result);
  186. Assert.DoesNotContain (subView, result);
  187. }
  188. [Theory]
  189. [InlineData ("Border")]
  190. [InlineData ("Padding")]
  191. public void Returns_Subview_Of_Adornment (string adornmentType)
  192. {
  193. // Arrange: top -> subView -> subView.[Adornment] -> adornmentSubView
  194. Runnable top = new ()
  195. {
  196. Frame = new (0, 0, 10, 10)
  197. };
  198. View subView = new ()
  199. {
  200. X = 0, Y = 0, Width = 8, Height = 8
  201. };
  202. top.Add (subView);
  203. View? adornment = null;
  204. switch (adornmentType)
  205. {
  206. case "Margin":
  207. subView.Margin!.Thickness = new (2);
  208. adornment = subView.Margin;
  209. break;
  210. case "Border":
  211. subView.Border!.Thickness = new (2);
  212. adornment = subView.Border;
  213. break;
  214. case "Padding":
  215. subView.Padding!.Thickness = new (2);
  216. adornment = subView.Padding;
  217. break;
  218. }
  219. subView.Layout ();
  220. // Add a child to the adornment
  221. View adornmentSubView = new ()
  222. {
  223. X = 0, Y = 0, Width = 2, Height = 2
  224. };
  225. adornment!.Add (adornmentSubView);
  226. // Set adornment ViewportSettings to None so it doesn't interfere with the test
  227. adornment.ViewportSettings = ViewportSettingsFlags.None;
  228. // Act: Point inside adornmentSubView (which is inside the adornment)
  229. var result = View.GetViewsUnderLocation (top, new (0, 0), ViewportSettingsFlags.TransparentMouse);
  230. // Assert: Should contain top, subView, adornment, and adornmentSubView
  231. Assert.Contains (top, result);
  232. Assert.Contains (subView, result);
  233. Assert.Contains (adornment, result);
  234. Assert.Contains (adornmentSubView, result);
  235. Assert.Equal (top, result [0]);
  236. Assert.Equal (adornmentSubView, result [^1]);
  237. }
  238. [Theory]
  239. [InlineData ("Border")]
  240. [InlineData ("Padding")]
  241. public void Returns_OnlyParentsSuperView_Of_Adornment_If_TransparentMouse (string adornmentType)
  242. {
  243. // Arrange: top -> subView -> subView.[Adornment] -> adornmentSubView
  244. Runnable top = new ()
  245. {
  246. Id = "top",
  247. Frame = new (0, 0, 10, 10)
  248. };
  249. View subView = new ()
  250. {
  251. Id = "subView",
  252. X = 0, Y = 0, Width = 8, Height = 8
  253. };
  254. top.Add (subView);
  255. View? adornment = null;
  256. switch (adornmentType)
  257. {
  258. case "Margin":
  259. subView.Margin!.Thickness = new (2);
  260. adornment = subView.Margin;
  261. break;
  262. case "Border":
  263. subView.Border!.Thickness = new (2);
  264. adornment = subView.Border;
  265. break;
  266. case "Padding":
  267. subView.Padding!.Thickness = new (2);
  268. adornment = subView.Padding;
  269. break;
  270. }
  271. subView.Layout ();
  272. // Add a child to the adornment
  273. View adornmentSubView = new ()
  274. {
  275. Id = "adornmentSubView",
  276. X = 0, Y = 0, Width = 2, Height = 2
  277. };
  278. adornment!.Add (adornmentSubView);
  279. adornment.ViewportSettings = ViewportSettingsFlags.TransparentMouse;
  280. // Act: Point inside adornmentSubView (which is inside the adornment)
  281. var result = View.GetViewsUnderLocation (top, new (0, 0), ViewportSettingsFlags.TransparentMouse);
  282. // Assert: Should contain top, subView, adornment, and adornmentSubView
  283. Assert.Contains (top, result);
  284. Assert.DoesNotContain (adornment, result);
  285. Assert.Contains (adornmentSubView, result);
  286. Assert.DoesNotContain (subView, result);
  287. Assert.Equal (top, result [0]);
  288. Assert.Equal (adornmentSubView, result [^1]);
  289. }
  290. }