AppendAutocompleteTests.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. using Xunit.Abstractions;
  2. namespace Terminal.Gui.TextTests;
  3. public class AppendAutocompleteTests
  4. {
  5. private readonly ITestOutputHelper output;
  6. public AppendAutocompleteTests (ITestOutputHelper output) { this.output = output; }
  7. [Fact]
  8. [AutoInitShutdown]
  9. public void TestAutoAppend_AfterCloseKey_NoAutocomplete ()
  10. {
  11. TextField tf = GetTextFieldsInViewSuggesting ("fish");
  12. // f is typed and suggestion is "fish"
  13. Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
  14. tf.Draw ();
  15. tf.PositionCursor ();
  16. TestHelpers.AssertDriverContentsAre ("fish", output);
  17. Assert.Equal ("f", tf.Text);
  18. // When cancelling autocomplete
  19. Application.Driver.SendKeys ('e', ConsoleKey.Escape, false, false, false);
  20. // Suggestion should disappear
  21. tf.Draw ();
  22. TestHelpers.AssertDriverContentsAre ("f", output);
  23. Assert.Equal ("f", tf.Text);
  24. // Still has focus though
  25. Assert.Same (tf, Application.Top.Focused);
  26. // But can tab away
  27. Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
  28. Assert.NotSame (tf, Application.Top.Focused);
  29. }
  30. [Fact]
  31. [AutoInitShutdown]
  32. public void TestAutoAppend_AfterCloseKey_ReappearsOnLetter ()
  33. {
  34. TextField tf = GetTextFieldsInViewSuggesting ("fish");
  35. // f is typed and suggestion is "fish"
  36. Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
  37. tf.Draw ();
  38. tf.PositionCursor ();
  39. TestHelpers.AssertDriverContentsAre ("fish", output);
  40. Assert.Equal ("f", tf.Text);
  41. // When cancelling autocomplete
  42. Application.Driver.SendKeys ('\0', ConsoleKey.Escape, false, false, false);
  43. // Suggestion should disappear
  44. tf.Draw ();
  45. TestHelpers.AssertDriverContentsAre ("f", output);
  46. Assert.Equal ("f", tf.Text);
  47. // Should reappear when you press next letter
  48. Application.Driver.SendKeys ('i', ConsoleKey.I, false, false, false);
  49. tf.Draw ();
  50. tf.PositionCursor ();
  51. TestHelpers.AssertDriverContentsAre ("fish", output);
  52. Assert.Equal ("fi", tf.Text);
  53. }
  54. [Theory]
  55. [AutoInitShutdown]
  56. [InlineData (ConsoleKey.UpArrow)]
  57. [InlineData (ConsoleKey.DownArrow)]
  58. public void TestAutoAppend_CycleSelections (ConsoleKey cycleKey)
  59. {
  60. TextField tf = GetTextFieldsInViewSuggesting ("fish", "friend");
  61. // f is typed and suggestion is "fish"
  62. Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
  63. tf.Draw ();
  64. tf.PositionCursor ();
  65. TestHelpers.AssertDriverContentsAre ("fish", output);
  66. Assert.Equal ("f", tf.Text);
  67. // When cycling autocomplete
  68. Application.Driver.SendKeys (' ', cycleKey, false, false, false);
  69. tf.Draw ();
  70. tf.PositionCursor ();
  71. TestHelpers.AssertDriverContentsAre ("friend", output);
  72. Assert.Equal ("f", tf.Text);
  73. // Should be able to cycle in circles endlessly
  74. Application.Driver.SendKeys (' ', cycleKey, false, false, false);
  75. tf.Draw ();
  76. tf.PositionCursor ();
  77. TestHelpers.AssertDriverContentsAre ("fish", output);
  78. Assert.Equal ("f", tf.Text);
  79. }
  80. [Fact]
  81. [AutoInitShutdown]
  82. public void TestAutoAppend_NoRender_WhenCursorNotAtEnd ()
  83. {
  84. TextField tf = GetTextFieldsInViewSuggesting ("fish");
  85. // f is typed and suggestion is "fish"
  86. Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
  87. tf.Draw ();
  88. tf.PositionCursor ();
  89. TestHelpers.AssertDriverContentsAre ("fish", output);
  90. Assert.Equal ("f", tf.Text);
  91. // add a space then go back 1
  92. Application.Driver.SendKeys (' ', ConsoleKey.Spacebar, false, false, false);
  93. Application.Driver.SendKeys ('<', ConsoleKey.LeftArrow, false, false, false);
  94. tf.Draw ();
  95. TestHelpers.AssertDriverContentsAre ("f", output);
  96. Assert.Equal ("f ", tf.Text);
  97. }
  98. [Fact]
  99. [AutoInitShutdown]
  100. public void TestAutoAppend_NoRender_WhenNoMatch ()
  101. {
  102. TextField tf = GetTextFieldsInViewSuggesting ("fish");
  103. // f is typed and suggestion is "fish"
  104. Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
  105. tf.Draw ();
  106. tf.PositionCursor ();
  107. TestHelpers.AssertDriverContentsAre ("fish", output);
  108. Assert.Equal ("f", tf.Text);
  109. // x is typed and suggestion should disappear
  110. Application.Driver.SendKeys ('x', ConsoleKey.X, false, false, false);
  111. tf.Draw ();
  112. TestHelpers.AssertDriverContentsAre ("fx", output);
  113. Assert.Equal ("fx", tf.Text);
  114. }
  115. [Fact]
  116. [AutoInitShutdown]
  117. public void TestAutoAppend_ShowThenAccept_CasesDiffer ()
  118. {
  119. TextField tf = GetTextFieldsInView ();
  120. tf.Autocomplete = new AppendAutocomplete (tf);
  121. var generator = (SingleWordSuggestionGenerator)tf.Autocomplete.SuggestionGenerator;
  122. generator.AllSuggestions = new List<string> { "FISH" };
  123. tf.Draw ();
  124. tf.PositionCursor ();
  125. TestHelpers.AssertDriverContentsAre ("", output);
  126. tf.NewKeyDownEvent (Key.M);
  127. tf.NewKeyDownEvent (Key.Y);
  128. tf.NewKeyDownEvent (Key.Space);
  129. tf.NewKeyDownEvent (Key.F);
  130. Assert.Equal ("my f", tf.Text);
  131. // Even though there is no match on case we should still get the suggestion
  132. tf.Draw ();
  133. tf.PositionCursor ();
  134. TestHelpers.AssertDriverContentsAre ("my fISH", output);
  135. Assert.Equal ("my f", tf.Text);
  136. // When tab completing the case of the whole suggestion should be applied
  137. Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
  138. tf.Draw ();
  139. TestHelpers.AssertDriverContentsAre ("my FISH", output);
  140. Assert.Equal ("my FISH", tf.Text);
  141. }
  142. [Fact]
  143. [AutoInitShutdown]
  144. public void TestAutoAppend_ShowThenAccept_MatchCase ()
  145. {
  146. TextField tf = GetTextFieldsInView ();
  147. tf.Autocomplete = new AppendAutocomplete (tf);
  148. var generator = (SingleWordSuggestionGenerator)tf.Autocomplete.SuggestionGenerator;
  149. generator.AllSuggestions = new List<string> { "fish" };
  150. tf.Draw ();
  151. tf.PositionCursor ();
  152. TestHelpers.AssertDriverContentsAre ("", output);
  153. tf.NewKeyDownEvent (new Key ('f'));
  154. tf.Draw ();
  155. tf.PositionCursor ();
  156. TestHelpers.AssertDriverContentsAre ("fish", output);
  157. Assert.Equal ("f", tf.Text);
  158. Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
  159. tf.Draw ();
  160. TestHelpers.AssertDriverContentsAre ("fish", output);
  161. Assert.Equal ("fish", tf.Text);
  162. // Tab should autcomplete but not move focus
  163. Assert.Same (tf, Application.Top.Focused);
  164. // Second tab should move focus (nothing to autocomplete)
  165. Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
  166. Assert.NotSame (tf, Application.Top.Focused);
  167. }
  168. [Theory]
  169. [AutoInitShutdown]
  170. [InlineData ("ffffffffffffffffffffffffff", "ffffffffff")]
  171. [InlineData ("f234567890", "f234567890")]
  172. [InlineData ("fisérables", "fisérables")]
  173. public void TestAutoAppendRendering_ShouldNotOverspill (string overspillUsing, string expectRender)
  174. {
  175. TextField tf = GetTextFieldsInViewSuggesting (overspillUsing);
  176. // f is typed we should only see 'f' up to size of View (10)
  177. Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
  178. tf.Draw ();
  179. tf.PositionCursor ();
  180. TestHelpers.AssertDriverContentsAre (expectRender, output);
  181. Assert.Equal ("f", tf.Text);
  182. }
  183. private TextField GetTextFieldsInView ()
  184. {
  185. var tf = new TextField { Width = 10 };
  186. var tf2 = new TextField { Y = 1, Width = 10 };
  187. Toplevel top = new ();
  188. top.Add (tf);
  189. top.Add (tf2);
  190. Application.Begin (top);
  191. Assert.Same (tf, top.Focused);
  192. return tf;
  193. }
  194. private TextField GetTextFieldsInViewSuggesting (params string [] suggestions)
  195. {
  196. TextField tf = GetTextFieldsInView ();
  197. tf.Autocomplete = new AppendAutocomplete (tf);
  198. var generator = (SingleWordSuggestionGenerator)tf.Autocomplete.SuggestionGenerator;
  199. generator.AllSuggestions = suggestions.ToList ();
  200. tf.Draw ();
  201. tf.PositionCursor ();
  202. TestHelpers.AssertDriverContentsAre ("", output);
  203. return tf;
  204. }
  205. }