LayoutTests.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. using Xunit.Abstractions;
  2. namespace Terminal.Gui.LayoutTests;
  3. public class LayoutTests (ITestOutputHelper output)
  4. {
  5. private readonly ITestOutputHelper _output = output;
  6. [Fact]
  7. public void LayoutSubviews_No_SuperView ()
  8. {
  9. var root = new View ();
  10. var first = new View
  11. {
  12. Id = "first",
  13. X = 1,
  14. Y = 2,
  15. Height = 3,
  16. Width = 4
  17. };
  18. root.Add (first);
  19. var second = new View { Id = "second" };
  20. root.Add (second);
  21. second.X = Pos.Right (first) + 1;
  22. root.LayoutSubviews ();
  23. Assert.Equal (6, second.Frame.X);
  24. root.Dispose ();
  25. first.Dispose ();
  26. second.Dispose ();
  27. }
  28. [Fact]
  29. public void Add_Does_Not_Call_LayoutSubviews ()
  30. {
  31. var superView = new View { Id = "superView" };
  32. var view = new View { Id = "view" };
  33. bool layoutStartedRaised = false;
  34. bool layoutCompleteRaised = false;
  35. superView.LayoutStarted += (sender, e) => layoutStartedRaised = true;
  36. superView.LayoutComplete += (sender, e) => layoutCompleteRaised = true;
  37. superView.Add (view);
  38. Assert.False (layoutStartedRaised);
  39. Assert.False (layoutCompleteRaised);
  40. superView.Remove(view);
  41. superView.BeginInit();
  42. superView.EndInit ();
  43. superView.Add (view);
  44. Assert.False (layoutStartedRaised);
  45. Assert.False (layoutCompleteRaised);
  46. }
  47. [Fact]
  48. public void BeginEndInit_Do_Not_Call_LayoutSubviews ()
  49. {
  50. var superView = new View { Id = "superView" };
  51. bool layoutStartedRaised = false;
  52. bool layoutCompleteRaised = false;
  53. superView.LayoutStarted += (sender, e) => layoutStartedRaised = true;
  54. superView.LayoutComplete += (sender, e) => layoutCompleteRaised = true;
  55. superView.BeginInit ();
  56. superView.EndInit ();
  57. Assert.False (layoutStartedRaised);
  58. Assert.False (layoutCompleteRaised);
  59. }
  60. [Fact]
  61. public void LayoutSubViews_Raises_LayoutStarted_LayoutComplete ()
  62. {
  63. var superView = new View { Id = "superView" };
  64. int layoutStartedRaised = 0;
  65. int layoutCompleteRaised = 0;
  66. superView.LayoutStarted += (sender, e) => layoutStartedRaised++;
  67. superView.LayoutComplete += (sender, e) => layoutCompleteRaised++;
  68. superView.LayoutSubviews ();
  69. Assert.Equal (1, layoutStartedRaised);
  70. Assert.Equal (1, layoutCompleteRaised);
  71. superView.BeginInit ();
  72. superView.EndInit ();
  73. superView.LayoutSubviews ();
  74. Assert.Equal (2, layoutStartedRaised);
  75. Assert.Equal (2, layoutCompleteRaised);
  76. }
  77. [Fact]
  78. public void LayoutSubviews_RootHas_SuperView ()
  79. {
  80. var top = new View ();
  81. var root = new View ();
  82. top.Add (root);
  83. var first = new View
  84. {
  85. Id = "first",
  86. X = 1,
  87. Y = 2,
  88. Height = 3,
  89. Width = 4
  90. };
  91. root.Add (first);
  92. var second = new View { Id = "second" };
  93. root.Add (second);
  94. second.X = Pos.Right (first) + 1;
  95. root.LayoutSubviews ();
  96. Assert.Equal (6, second.Frame.X);
  97. root.Dispose ();
  98. top.Dispose ();
  99. first.Dispose ();
  100. second.Dispose ();
  101. }
  102. [Fact]
  103. public void LayoutSubviews_ViewThatRefsSubView_Throws ()
  104. {
  105. var root = new View ();
  106. var super = new View ();
  107. root.Add (super);
  108. var sub = new View ();
  109. super.Add (sub);
  110. super.Width = Dim.Width (sub);
  111. Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
  112. root.Dispose ();
  113. super.Dispose ();
  114. }
  115. [Fact]
  116. public void TopologicalSort_Missing_Add ()
  117. {
  118. var root = new View ();
  119. var sub1 = new View ();
  120. root.Add (sub1);
  121. var sub2 = new View ();
  122. sub1.Width = Dim.Width (sub2);
  123. Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
  124. sub2.Width = Dim.Width (sub1);
  125. Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
  126. root.Dispose ();
  127. sub1.Dispose ();
  128. sub2.Dispose ();
  129. }
  130. [Fact]
  131. public void TopologicalSort_Recursive_Ref ()
  132. {
  133. var root = new View ();
  134. var sub1 = new View ();
  135. root.Add (sub1);
  136. var sub2 = new View ();
  137. root.Add (sub2);
  138. sub2.Width = Dim.Width (sub2);
  139. Exception exception = Record.Exception (root.LayoutSubviews);
  140. Assert.Null (exception);
  141. root.Dispose ();
  142. sub1.Dispose ();
  143. sub2.Dispose ();
  144. }
  145. [Fact]
  146. public void LayoutSubviews_Uses_ContentSize ()
  147. {
  148. var superView = new View ()
  149. {
  150. Width = 5,
  151. Height = 5,
  152. };
  153. superView.SetContentSize (new (10, 10));
  154. var view = new View ()
  155. {
  156. X = Pos.Center ()
  157. };
  158. superView.Add (view);
  159. superView.LayoutSubviews ();
  160. Assert.Equal (5, view.Frame.X);
  161. superView.Dispose ();
  162. }
  163. // Test OnLayoutStarted/OnLayoutComplete - ensure that they are called at right times
  164. [Fact]
  165. public void LayoutSubviews_LayoutStarted_Complete ()
  166. {
  167. var superView = new View ();
  168. var view = new View ();
  169. superView.Add (view);
  170. superView.BeginInit ();
  171. superView.EndInit ();
  172. var layoutStarted = false;
  173. var layoutComplete = false;
  174. var borderLayoutStarted = false;
  175. var borderLayoutComplete = false;
  176. view.LayoutStarted += (sender, e) => layoutStarted = true;
  177. view.LayoutComplete += (sender, e) => layoutComplete = true;
  178. view.Border.LayoutStarted += (sender, e) =>
  179. {
  180. Assert.True (layoutStarted);
  181. borderLayoutStarted = true;
  182. };
  183. view.Border.LayoutComplete += (sender, e) =>
  184. {
  185. Assert.True (layoutStarted);
  186. Assert.False (layoutComplete);
  187. borderLayoutComplete = true;
  188. };
  189. superView.LayoutSubviews ();
  190. Assert.True (borderLayoutStarted);
  191. Assert.True (borderLayoutComplete);
  192. Assert.True (layoutStarted);
  193. Assert.True (layoutComplete);
  194. superView.Dispose ();
  195. }
  196. }