SubviewTests.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. using System.Text;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewTests;
  4. public class SubviewTests
  5. {
  6. private readonly ITestOutputHelper _output;
  7. public SubviewTests (ITestOutputHelper output) { _output = output; }
  8. [Fact]
  9. [TestRespondersDisposed]
  10. public void Added_Removed ()
  11. {
  12. var v = new View { Frame = new Rectangle (0, 0, 10, 24) };
  13. var t = new View ();
  14. v.Added += (s, e) =>
  15. {
  16. Assert.Same (v.SuperView, e.Parent);
  17. Assert.Same (t, e.Parent);
  18. Assert.Same (v, e.Child);
  19. };
  20. v.Removed += (s, e) =>
  21. {
  22. Assert.Same (t, e.Parent);
  23. Assert.Same (v, e.Child);
  24. Assert.True (v.SuperView == null);
  25. };
  26. t.Add (v);
  27. Assert.True (t.Subviews.Count == 1);
  28. t.Remove (v);
  29. Assert.True (t.Subviews.Count == 0);
  30. t.Dispose ();
  31. v.Dispose ();
  32. }
  33. [Fact]
  34. [AutoInitShutdown]
  35. public void GetTopSuperView_Test ()
  36. {
  37. var v1 = new View ();
  38. var fv1 = new FrameView ();
  39. fv1.Add (v1);
  40. var tf1 = new TextField ();
  41. var w1 = new Window ();
  42. w1.Add (fv1, tf1);
  43. var top1 = new Toplevel ();
  44. top1.Add (w1);
  45. var v2 = new View ();
  46. var fv2 = new FrameView ();
  47. fv2.Add (v2);
  48. var tf2 = new TextField ();
  49. var w2 = new Window ();
  50. w2.Add (fv2, tf2);
  51. var top2 = new Toplevel ();
  52. top2.Add (w2);
  53. Assert.Equal (top1, v1.GetTopSuperView ());
  54. Assert.Equal (top2, v2.GetTopSuperView ());
  55. v1.Dispose ();
  56. fv1.Dispose ();
  57. tf1.Dispose ();
  58. w1.Dispose ();
  59. top1.Dispose ();
  60. v2.Dispose ();
  61. fv2.Dispose ();
  62. tf2.Dispose ();
  63. w2.Dispose ();
  64. top2.Dispose ();
  65. }
  66. [Fact]
  67. [TestRespondersDisposed]
  68. public void Initialized_Event_Comparing_With_Added_Event ()
  69. {
  70. Application.Init (new FakeDriver ());
  71. var top = new Toplevel { Id = "0" }; // Frame: 0, 0, 80, 25; Viewport: 0, 0, 80, 25
  72. var winAddedToTop = new Window
  73. {
  74. Id = "t", Width = Dim.Fill (), Height = Dim.Fill ()
  75. }; // Frame: 0, 0, 80, 25; Viewport: 0, 0, 78, 23
  76. var v1AddedToWin = new View
  77. {
  78. Id = "v1", Width = Dim.Fill (), Height = Dim.Fill ()
  79. }; // Frame: 1, 1, 78, 23 (because Windows has a border)
  80. var v2AddedToWin = new View
  81. {
  82. Id = "v2", Width = Dim.Fill (), Height = Dim.Fill ()
  83. }; // Frame: 1, 1, 78, 23 (because Windows has a border)
  84. var svAddedTov1 = new View
  85. {
  86. Id = "sv1", Width = Dim.Fill (), Height = Dim.Fill ()
  87. }; // Frame: 1, 1, 78, 23 (same as it's superview v1AddedToWin)
  88. int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0;
  89. winAddedToTop.Added += (s, e) =>
  90. {
  91. Assert.Equal (e.Parent.Frame.Width, winAddedToTop.Frame.Width);
  92. Assert.Equal (e.Parent.Frame.Height, winAddedToTop.Frame.Height);
  93. };
  94. v1AddedToWin.Added += (s, e) =>
  95. {
  96. Assert.Equal (e.Parent.Frame.Width, v1AddedToWin.Frame.Width);
  97. Assert.Equal (e.Parent.Frame.Height, v1AddedToWin.Frame.Height);
  98. };
  99. v2AddedToWin.Added += (s, e) =>
  100. {
  101. Assert.Equal (e.Parent.Frame.Width, v2AddedToWin.Frame.Width);
  102. Assert.Equal (e.Parent.Frame.Height, v2AddedToWin.Frame.Height);
  103. };
  104. svAddedTov1.Added += (s, e) =>
  105. {
  106. Assert.Equal (e.Parent.Frame.Width, svAddedTov1.Frame.Width);
  107. Assert.Equal (e.Parent.Frame.Height, svAddedTov1.Frame.Height);
  108. };
  109. top.Initialized += (s, e) =>
  110. {
  111. tc++;
  112. Assert.Equal (1, tc);
  113. Assert.Equal (1, wc);
  114. Assert.Equal (1, v1c);
  115. Assert.Equal (1, v2c);
  116. Assert.Equal (1, sv1c);
  117. Assert.True (top.CanFocus);
  118. Assert.True (winAddedToTop.CanFocus);
  119. Assert.False (v1AddedToWin.CanFocus);
  120. Assert.False (v2AddedToWin.CanFocus);
  121. Assert.False (svAddedTov1.CanFocus);
  122. Application.Refresh ();
  123. };
  124. winAddedToTop.Initialized += (s, e) =>
  125. {
  126. wc++;
  127. Assert.Equal (top.Viewport.Width, winAddedToTop.Frame.Width);
  128. Assert.Equal (top.Viewport.Height, winAddedToTop.Frame.Height);
  129. };
  130. v1AddedToWin.Initialized += (s, e) =>
  131. {
  132. v1c++;
  133. // Top.Frame: 0, 0, 80, 25; Top.Viewport: 0, 0, 80, 25
  134. // BUGBUG: This is wrong, it should be 78, 23. This test has always been broken.
  135. // in no way should the v1AddedToWin.Frame be the same as the Top.Frame/Viewport
  136. // as it is a subview of winAddedToTop, which has a border!
  137. //Assert.Equal (top.Viewport.Width, v1AddedToWin.Frame.Width);
  138. //Assert.Equal (top.Viewport.Height, v1AddedToWin.Frame.Height);
  139. };
  140. v2AddedToWin.Initialized += (s, e) =>
  141. {
  142. v2c++;
  143. // Top.Frame: 0, 0, 80, 25; Top.Viewport: 0, 0, 80, 25
  144. // BUGBUG: This is wrong, it should be 78, 23. This test has always been broken.
  145. // in no way should the v2AddedToWin.Frame be the same as the Top.Frame/Viewport
  146. // as it is a subview of winAddedToTop, which has a border!
  147. //Assert.Equal (top.Viewport.Width, v2AddedToWin.Frame.Width);
  148. //Assert.Equal (top.Viewport.Height, v2AddedToWin.Frame.Height);
  149. };
  150. svAddedTov1.Initialized += (s, e) =>
  151. {
  152. sv1c++;
  153. // Top.Frame: 0, 0, 80, 25; Top.Viewport: 0, 0, 80, 25
  154. // BUGBUG: This is wrong, it should be 78, 23. This test has always been broken.
  155. // in no way should the svAddedTov1.Frame be the same as the Top.Frame/Viewport
  156. // because sv1AddedTov1 is a subview of v1AddedToWin, which is a subview of
  157. // winAddedToTop, which has a border!
  158. //Assert.Equal (top.Viewport.Width, svAddedTov1.Frame.Width);
  159. //Assert.Equal (top.Viewport.Height, svAddedTov1.Frame.Height);
  160. Assert.False (svAddedTov1.CanFocus);
  161. Assert.Throws<InvalidOperationException> (() => svAddedTov1.CanFocus = true);
  162. Assert.False (svAddedTov1.CanFocus);
  163. };
  164. v1AddedToWin.Add (svAddedTov1);
  165. winAddedToTop.Add (v1AddedToWin, v2AddedToWin);
  166. top.Add (winAddedToTop);
  167. Application.Iteration += (s, a) =>
  168. {
  169. Application.Refresh ();
  170. top.Running = false;
  171. };
  172. Application.Run (top);
  173. top.Dispose ();
  174. Application.Shutdown ();
  175. Assert.Equal (1, tc);
  176. Assert.Equal (1, wc);
  177. Assert.Equal (1, v1c);
  178. Assert.Equal (1, v2c);
  179. Assert.Equal (1, sv1c);
  180. Assert.True (top.CanFocus);
  181. Assert.True (winAddedToTop.CanFocus);
  182. Assert.False (v1AddedToWin.CanFocus);
  183. Assert.False (v2AddedToWin.CanFocus);
  184. Assert.False (svAddedTov1.CanFocus);
  185. v1AddedToWin.CanFocus = true;
  186. Assert.False (svAddedTov1.CanFocus); // False because sv1 was disposed and it isn't a subview of v1.
  187. }
  188. [Fact]
  189. [TestRespondersDisposed]
  190. public void Initialized_Event_Will_Be_Invoked_When_Added_Dynamically ()
  191. {
  192. Application.Init (new FakeDriver ());
  193. var t = new Toplevel { Id = "0" };
  194. var w = new Window { Id = "t", Width = Dim.Fill (), Height = Dim.Fill () };
  195. var v1 = new View { Id = "v1", Width = Dim.Fill (), Height = Dim.Fill () };
  196. var v2 = new View { Id = "v2", Width = Dim.Fill (), Height = Dim.Fill () };
  197. int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0;
  198. t.Initialized += (s, e) =>
  199. {
  200. tc++;
  201. Assert.Equal (1, tc);
  202. Assert.Equal (1, wc);
  203. Assert.Equal (1, v1c);
  204. Assert.Equal (1, v2c);
  205. Assert.Equal (0, sv1c); // Added after t in the Application.Iteration.
  206. Assert.True (t.CanFocus);
  207. Assert.True (w.CanFocus);
  208. Assert.False (v1.CanFocus);
  209. Assert.False (v2.CanFocus);
  210. Application.Refresh ();
  211. };
  212. w.Initialized += (s, e) =>
  213. {
  214. wc++;
  215. Assert.Equal (t.Viewport.Width, w.Frame.Width);
  216. Assert.Equal (t.Viewport.Height, w.Frame.Height);
  217. };
  218. v1.Initialized += (s, e) =>
  219. {
  220. v1c++;
  221. //Assert.Equal (t.Viewport.Width, v1.Frame.Width);
  222. //Assert.Equal (t.Viewport.Height, v1.Frame.Height);
  223. };
  224. v2.Initialized += (s, e) =>
  225. {
  226. v2c++;
  227. //Assert.Equal (t.Viewport.Width, v2.Frame.Width);
  228. //Assert.Equal (t.Viewport.Height, v2.Frame.Height);
  229. };
  230. w.Add (v1, v2);
  231. t.Add (w);
  232. Application.Iteration += (s, a) =>
  233. {
  234. var sv1 = new View { Id = "sv1", Width = Dim.Fill (), Height = Dim.Fill () };
  235. sv1.Initialized += (s, e) =>
  236. {
  237. sv1c++;
  238. Assert.NotEqual (t.Frame.Width, sv1.Frame.Width);
  239. Assert.NotEqual (t.Frame.Height, sv1.Frame.Height);
  240. Assert.False (sv1.CanFocus);
  241. Assert.Throws<InvalidOperationException> (() => sv1.CanFocus = true);
  242. Assert.False (sv1.CanFocus);
  243. };
  244. v1.Add (sv1);
  245. Application.Refresh ();
  246. t.Running = false;
  247. };
  248. Application.Run (t);
  249. t.Dispose ();
  250. Application.Shutdown ();
  251. Assert.Equal (1, tc);
  252. Assert.Equal (1, wc);
  253. Assert.Equal (1, v1c);
  254. Assert.Equal (1, v2c);
  255. Assert.Equal (1, sv1c);
  256. Assert.True (t.CanFocus);
  257. Assert.True (w.CanFocus);
  258. Assert.False (v1.CanFocus);
  259. Assert.False (v2.CanFocus);
  260. }
  261. [Fact]
  262. [TestRespondersDisposed]
  263. public void IsAdded_Added_Removed ()
  264. {
  265. var top = new Toplevel ();
  266. var view = new View ();
  267. Assert.False (view.IsAdded);
  268. top.Add (view);
  269. Assert.True (view.IsAdded);
  270. top.Remove (view);
  271. Assert.False (view.IsAdded);
  272. top.Dispose ();
  273. view.Dispose ();
  274. }
  275. // TODO: Consider a feature that will change the ContentSize to fit the subviews.
  276. [Fact]
  277. public void Add_Does_Not_Impact_ContentSize ()
  278. {
  279. var view = new View ();
  280. view.SetContentSize (new Size (1, 1));
  281. var subview = new View ()
  282. {
  283. X = 10,
  284. Y = 10
  285. };
  286. Assert.Equal (new Size (1, 1), view.GetContentSize ());
  287. view.Add (subview);
  288. Assert.Equal (new Size (1, 1), view.GetContentSize ());
  289. }
  290. [Fact]
  291. public void Remove_Does_Not_Impact_ContentSize ()
  292. {
  293. var view = new View ();
  294. view.SetContentSize (new Size (1, 1));
  295. var subview = new View ()
  296. {
  297. X = 10,
  298. Y = 10
  299. };
  300. Assert.Equal (new Size (1, 1), view.GetContentSize ());
  301. view.Add (subview);
  302. Assert.Equal (new Size (1, 1), view.GetContentSize ());
  303. view.SetContentSize (new Size (5, 5));
  304. Assert.Equal (new Size (5, 5), view.GetContentSize ());
  305. view.Remove (subview);
  306. Assert.Equal (new Size (5, 5), view.GetContentSize ());
  307. }
  308. }