AppendAutocompleteTests.cs 7.6 KB

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