AdvanceFocusTests.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. using Xunit.Abstractions;
  2. namespace Terminal.Gui.ViewTests;
  3. public class AdvanceFocusTests (ITestOutputHelper _output)
  4. {
  5. [Fact]
  6. public void Subviews_TabIndexes_AreEqual ()
  7. {
  8. var r = new View ();
  9. var v1 = new View { CanFocus = true };
  10. var v2 = new View { CanFocus = true };
  11. var v3 = new View { CanFocus = true };
  12. r.Add (v1, v2, v3);
  13. Assert.True (r.Subviews.IndexOf (v1) == 0);
  14. Assert.True (r.Subviews.IndexOf (v2) == 1);
  15. Assert.True (r.Subviews.IndexOf (v3) == 2);
  16. Assert.True (r.TabIndexes.IndexOf (v1) == 0);
  17. Assert.True (r.TabIndexes.IndexOf (v2) == 1);
  18. Assert.True (r.TabIndexes.IndexOf (v3) == 2);
  19. Assert.Equal (r.Subviews.IndexOf (v1), r.TabIndexes.IndexOf (v1));
  20. Assert.Equal (r.Subviews.IndexOf (v2), r.TabIndexes.IndexOf (v2));
  21. Assert.Equal (r.Subviews.IndexOf (v3), r.TabIndexes.IndexOf (v3));
  22. r.Dispose ();
  23. }
  24. [Fact]
  25. public void TabIndex_Invert_Order ()
  26. {
  27. var r = new View ();
  28. var v1 = new View { Id = "1", CanFocus = true };
  29. var v2 = new View { Id = "2", CanFocus = true };
  30. var v3 = new View { Id = "3", CanFocus = true };
  31. r.Add (v1, v2, v3);
  32. v1.TabIndex = 2;
  33. v2.TabIndex = 1;
  34. v3.TabIndex = 0;
  35. Assert.True (r.TabIndexes.IndexOf (v1) == 2);
  36. Assert.True (r.TabIndexes.IndexOf (v2) == 1);
  37. Assert.True (r.TabIndexes.IndexOf (v3) == 0);
  38. Assert.True (r.Subviews.IndexOf (v1) == 0);
  39. Assert.True (r.Subviews.IndexOf (v2) == 1);
  40. Assert.True (r.Subviews.IndexOf (v3) == 2);
  41. }
  42. [Fact]
  43. public void TabIndex_Invert_Order_Added_One_By_One_Does_Not_Do_What_Is_Expected ()
  44. {
  45. var r = new View ();
  46. var v1 = new View { Id = "1", CanFocus = true };
  47. r.Add (v1);
  48. v1.TabIndex = 2;
  49. var v2 = new View { Id = "2", CanFocus = true };
  50. r.Add (v2);
  51. v2.TabIndex = 1;
  52. var v3 = new View { Id = "3", CanFocus = true };
  53. r.Add (v3);
  54. v3.TabIndex = 0;
  55. Assert.False (r.TabIndexes.IndexOf (v1) == 2);
  56. Assert.True (r.TabIndexes.IndexOf (v1) == 1);
  57. Assert.False (r.TabIndexes.IndexOf (v2) == 1);
  58. Assert.True (r.TabIndexes.IndexOf (v2) == 2);
  59. // Only the last is in the expected index
  60. Assert.True (r.TabIndexes.IndexOf (v3) == 0);
  61. Assert.True (r.Subviews.IndexOf (v1) == 0);
  62. Assert.True (r.Subviews.IndexOf (v2) == 1);
  63. Assert.True (r.Subviews.IndexOf (v3) == 2);
  64. }
  65. [Fact]
  66. public void TabIndex_Invert_Order_Mixed ()
  67. {
  68. var r = new View ();
  69. var vl1 = new View { Id = "vl1" };
  70. var v1 = new View { Id = "v1", CanFocus = true };
  71. var vl2 = new View { Id = "vl2" };
  72. var v2 = new View { Id = "v2", CanFocus = true };
  73. var vl3 = new View { Id = "vl3" };
  74. var v3 = new View { Id = "v3", CanFocus = true };
  75. r.Add (vl1, v1, vl2, v2, vl3, v3);
  76. v1.TabIndex = 2;
  77. v2.TabIndex = 1;
  78. v3.TabIndex = 0;
  79. Assert.True (r.TabIndexes.IndexOf (v1) == 4);
  80. Assert.True (r.TabIndexes.IndexOf (v2) == 2);
  81. Assert.True (r.TabIndexes.IndexOf (v3) == 0);
  82. Assert.True (r.Subviews.IndexOf (v1) == 1);
  83. Assert.True (r.Subviews.IndexOf (v2) == 3);
  84. Assert.True (r.Subviews.IndexOf (v3) == 5);
  85. }
  86. [Fact]
  87. public void TabIndex_Set_CanFocus_False ()
  88. {
  89. var r = new View ();
  90. var v1 = new View { CanFocus = true };
  91. var v2 = new View { CanFocus = true };
  92. var v3 = new View { CanFocus = true };
  93. r.Add (v1, v2, v3);
  94. v1.CanFocus = false;
  95. v1.TabIndex = 0;
  96. Assert.True (r.Subviews.IndexOf (v1) == 0);
  97. Assert.True (r.TabIndexes.IndexOf (v1) == 0);
  98. Assert.NotEqual (-1, v1.TabIndex);
  99. r.Dispose ();
  100. }
  101. [Fact]
  102. public void TabIndex_Set_CanFocus_False_To_True ()
  103. {
  104. var r = new View ();
  105. var v1 = new View ();
  106. var v2 = new View { CanFocus = true };
  107. var v3 = new View { CanFocus = true };
  108. r.Add (v1, v2, v3);
  109. v1.CanFocus = true;
  110. v1.TabIndex = 1;
  111. Assert.True (r.Subviews.IndexOf (v1) == 0);
  112. Assert.True (r.TabIndexes.IndexOf (v1) == 1);
  113. r.Dispose ();
  114. }
  115. [Fact]
  116. public void TabIndex_Set_CanFocus_HigherValues ()
  117. {
  118. var r = new View ();
  119. var v1 = new View { CanFocus = true };
  120. var v2 = new View { CanFocus = true };
  121. var v3 = new View { CanFocus = true };
  122. r.Add (v1, v2, v3);
  123. v1.TabIndex = 3;
  124. Assert.True (r.Subviews.IndexOf (v1) == 0);
  125. Assert.True (r.TabIndexes.IndexOf (v1) == 2);
  126. r.Dispose ();
  127. }
  128. [Fact]
  129. public void TabIndex_Set_CanFocus_LowerValues ()
  130. {
  131. var r = new View ();
  132. var v1 = new View { CanFocus = true };
  133. var v2 = new View { CanFocus = true };
  134. var v3 = new View { CanFocus = true };
  135. r.Add (v1, v2, v3);
  136. //v1.TabIndex = -1;
  137. Assert.True (r.Subviews.IndexOf (v1) == 0);
  138. Assert.True (r.TabIndexes.IndexOf (v1) == 0);
  139. r.Dispose ();
  140. }
  141. [Fact]
  142. public void TabIndex_Set_CanFocus_ValidValues ()
  143. {
  144. var r = new View ();
  145. var v1 = new View { CanFocus = true };
  146. var v2 = new View { CanFocus = true };
  147. var v3 = new View { CanFocus = true };
  148. r.Add (v1, v2, v3);
  149. v1.TabIndex = 1;
  150. Assert.True (r.Subviews.IndexOf (v1) == 0);
  151. Assert.True (r.TabIndexes.IndexOf (v1) == 1);
  152. v1.TabIndex = 2;
  153. Assert.True (r.Subviews.IndexOf (v1) == 0);
  154. Assert.True (r.TabIndexes.IndexOf (v1) == 2);
  155. r.Dispose ();
  156. }
  157. [Theory]
  158. [CombinatorialData]
  159. public void TabStop_And_CanFocus_Are_Decoupled (bool canFocus, TabBehavior tabStop)
  160. {
  161. var view = new View { CanFocus = canFocus, TabStop = tabStop };
  162. Assert.Equal (canFocus, view.CanFocus);
  163. Assert.Equal (tabStop, view.TabStop);
  164. }
  165. [Fact]
  166. public void AdvanceFocus_With_CanFocus_Are_All_True ()
  167. {
  168. var top = new View () { Id = "top", CanFocus = true };
  169. var v1 = new View { Id = "v1", CanFocus = true };
  170. var v2 = new View { Id = "v2", CanFocus = true };
  171. var v3 = new View { Id = "v3", CanFocus = true };
  172. top.Add (v1, v2, v3);
  173. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  174. Assert.True (v1.HasFocus);
  175. Assert.False (v2.HasFocus);
  176. Assert.False (v3.HasFocus);
  177. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  178. Assert.False (v1.HasFocus);
  179. Assert.True (v2.HasFocus);
  180. Assert.False (v3.HasFocus);
  181. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  182. Assert.False (v1.HasFocus);
  183. Assert.False (v2.HasFocus);
  184. Assert.True (v3.HasFocus);
  185. top.Dispose ();
  186. }
  187. [Fact]
  188. public void AdvanceFocus_CanFocus_Mixed ()
  189. {
  190. var r = new View ();
  191. var v1 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  192. var v2 = new View { CanFocus = false, TabStop = TabBehavior.TabStop };
  193. var v3 = new View { CanFocus = false, TabStop = TabBehavior.NoStop };
  194. r.Add (v1, v2, v3);
  195. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  196. Assert.False (v1.HasFocus);
  197. Assert.False (v2.HasFocus);
  198. Assert.False (v3.HasFocus);
  199. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  200. Assert.False (v1.HasFocus);
  201. Assert.False (v2.HasFocus);
  202. Assert.False (v3.HasFocus);
  203. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  204. Assert.False (v1.HasFocus);
  205. Assert.False (v2.HasFocus);
  206. Assert.False (v3.HasFocus);
  207. r.Dispose ();
  208. }
  209. [Theory]
  210. [CombinatorialData]
  211. public void AdvanceFocus_Change_CanFocus_Works ([CombinatorialValues (TabBehavior.NoStop, TabBehavior.TabStop, TabBehavior.TabGroup)] TabBehavior behavior)
  212. {
  213. var r = new View () { CanFocus = true };
  214. var v1 = new View ();
  215. var v2 = new View ();
  216. var v3 = new View ();
  217. Assert.True (r.CanFocus);
  218. Assert.False (v1.CanFocus);
  219. Assert.False (v2.CanFocus);
  220. Assert.False (v3.CanFocus);
  221. r.Add (v1, v2, v3);
  222. r.AdvanceFocus (NavigationDirection.Forward, behavior);
  223. Assert.False (v1.HasFocus);
  224. Assert.False (v2.HasFocus);
  225. Assert.False (v3.HasFocus);
  226. v1.CanFocus = true;
  227. v1.TabStop = behavior;
  228. r.AdvanceFocus (NavigationDirection.Forward, behavior);
  229. Assert.True (v1.HasFocus);
  230. Assert.False (v2.HasFocus);
  231. Assert.False (v3.HasFocus);
  232. v2.CanFocus = true;
  233. v2.TabStop = behavior;
  234. r.AdvanceFocus (NavigationDirection.Forward, behavior);
  235. Assert.False (v1.HasFocus);
  236. Assert.True (v2.HasFocus);
  237. Assert.False (v3.HasFocus);
  238. v3.CanFocus = true;
  239. v3.TabStop = behavior;
  240. r.AdvanceFocus (NavigationDirection.Forward, behavior);
  241. Assert.False (v1.HasFocus);
  242. Assert.False (v2.HasFocus);
  243. Assert.True (v3.HasFocus);
  244. r.Dispose ();
  245. }
  246. [Fact]
  247. public void AdvanceFocus_NoStop_And_CanFocus_True_No_Focus ()
  248. {
  249. var r = new View ();
  250. var v1 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  251. var v2 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  252. var v3 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  253. r.Add (v1, v2, v3);
  254. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  255. Assert.False (v1.HasFocus);
  256. Assert.False (v2.HasFocus);
  257. Assert.False (v3.HasFocus);
  258. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  259. Assert.False (v1.HasFocus);
  260. Assert.False (v2.HasFocus);
  261. Assert.False (v3.HasFocus);
  262. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  263. Assert.False (v1.HasFocus);
  264. Assert.False (v2.HasFocus);
  265. Assert.False (v3.HasFocus);
  266. r.Dispose ();
  267. }
  268. [Fact]
  269. public void AdvanceFocus_NoStop_Change_Enables_Stop ()
  270. {
  271. var r = new View { CanFocus = true };
  272. var v1 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  273. var v2 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  274. var v3 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  275. r.Add (v1, v2, v3);
  276. v1.TabStop = TabBehavior.TabStop;
  277. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  278. Assert.True (v1.HasFocus);
  279. Assert.False (v2.HasFocus);
  280. Assert.False (v3.HasFocus);
  281. v2.TabStop = TabBehavior.TabStop;
  282. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  283. Assert.False (v1.HasFocus);
  284. Assert.True (v2.HasFocus);
  285. Assert.False (v3.HasFocus);
  286. v3.TabStop = TabBehavior.TabStop;
  287. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  288. Assert.False (v1.HasFocus);
  289. Assert.False (v2.HasFocus);
  290. Assert.True (v3.HasFocus);
  291. r.Dispose ();
  292. }
  293. [Fact]
  294. public void AdvacneFocus_NoStop_Prevents_Stop ()
  295. {
  296. var r = new View ();
  297. var v1 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  298. var v2 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  299. var v3 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  300. r.Add (v1, v2, v3);
  301. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  302. Assert.False (v1.HasFocus);
  303. Assert.False (v2.HasFocus);
  304. Assert.False (v3.HasFocus);
  305. }
  306. [Fact]
  307. public void AdvanceFocus_Null_And_CanFocus_False_No_Advance ()
  308. {
  309. var r = new View ();
  310. var v1 = new View ();
  311. var v2 = new View ();
  312. var v3 = new View ();
  313. Assert.False (v1.CanFocus);
  314. Assert.Null (v1.TabStop);
  315. r.Add (v1, v2, v3);
  316. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  317. Assert.False (v1.HasFocus);
  318. Assert.False (v2.HasFocus);
  319. Assert.False (v3.HasFocus);
  320. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  321. Assert.False (v1.HasFocus);
  322. Assert.False (v2.HasFocus);
  323. Assert.False (v3.HasFocus);
  324. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  325. Assert.False (v1.HasFocus);
  326. Assert.False (v2.HasFocus);
  327. Assert.False (v3.HasFocus);
  328. r.Dispose ();
  329. }
  330. }