AppendAutocompleteTests.cs 7.5 KB

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