FileDialogTests.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.IO.Abstractions.TestingHelpers;
  5. using System.Linq;
  6. using Terminal.Gui;
  7. using Xunit;
  8. using Xunit.Abstractions;
  9. namespace Terminal.Gui.FileServicesTests {
  10. public class FileDialogTests {
  11. readonly ITestOutputHelper output;
  12. public FileDialogTests (ITestOutputHelper output)
  13. {
  14. this.output = output;
  15. }
  16. [Fact, AutoInitShutdown]
  17. public void OnLoad_TextBoxIsFocused ()
  18. {
  19. var dlg = GetInitializedFileDialog ();
  20. var tf = dlg.Subviews.FirstOrDefault (t => t.HasFocus);
  21. Assert.NotNull (tf);
  22. Assert.IsType<TextField> (tf);
  23. }
  24. [Fact, AutoInitShutdown]
  25. public void DirectTyping_Allowed ()
  26. {
  27. var dlg = GetInitializedFileDialog ();
  28. var tf = dlg.Subviews.OfType<TextField> ().First (t => t.HasFocus);
  29. tf.ClearAllSelection ();
  30. tf.CursorPosition = tf.Text.Length;
  31. Assert.True (tf.HasFocus);
  32. SendSlash ();
  33. Assert.Equal (
  34. new DirectoryInfo (Environment.CurrentDirectory + Path.DirectorySeparatorChar).FullName,
  35. new DirectoryInfo (dlg.Path + Path.DirectorySeparatorChar).FullName
  36. );
  37. // continue typing the rest of the path
  38. Send ("bob");
  39. Send ('.', ConsoleKey.OemPeriod, false);
  40. Send ("csv");
  41. Assert.True (dlg.Canceled);
  42. Send ('\n', ConsoleKey.Enter, false);
  43. Assert.False (dlg.Canceled);
  44. Assert.Equal ("bob.csv", Path.GetFileName (dlg.Path));
  45. }
  46. private void SendSlash ()
  47. {
  48. if (Path.DirectorySeparatorChar == '/') {
  49. Send ('/', ConsoleKey.Separator, false);
  50. } else {
  51. Send ('\\', ConsoleKey.Separator, false);
  52. }
  53. }
  54. [Fact, AutoInitShutdown]
  55. public void DirectTyping_AutoComplete ()
  56. {
  57. var dlg = GetInitializedFileDialog ();
  58. var openIn = Path.Combine (Environment.CurrentDirectory, "zz");
  59. Directory.CreateDirectory (openIn);
  60. var expectedDest = Path.Combine (openIn, "xx");
  61. Directory.CreateDirectory (expectedDest);
  62. dlg.Path = openIn + Path.DirectorySeparatorChar;
  63. Send ("x");
  64. // nothing selected yet
  65. Assert.True (dlg.Canceled);
  66. Assert.Equal ("x", Path.GetFileName (dlg.Path));
  67. // complete auto typing
  68. Send ('\t', ConsoleKey.Tab, false);
  69. // but do not close dialog
  70. Assert.True (dlg.Canceled);
  71. Assert.EndsWith ("xx" + Path.DirectorySeparatorChar, dlg.Path);
  72. // press enter again to confirm the dialog
  73. Send ('\n', ConsoleKey.Enter, false);
  74. Assert.False (dlg.Canceled);
  75. Assert.EndsWith ("xx" + Path.DirectorySeparatorChar, dlg.Path);
  76. }
  77. [Fact, AutoInitShutdown]
  78. public void DoNotConfirmSelectionWhenFindFocused ()
  79. {
  80. var dlg = GetInitializedFileDialog ();
  81. var openIn = Path.Combine (Environment.CurrentDirectory, "zz");
  82. Directory.CreateDirectory (openIn);
  83. dlg.Path = openIn + Path.DirectorySeparatorChar;
  84. Send ('f', ConsoleKey.F, false, false, true);
  85. Assert.IsType<TextField> (dlg.MostFocused);
  86. var tf = (TextField)dlg.MostFocused;
  87. Assert.Equal ("Enter Search", tf.Caption);
  88. // Dialog has not yet been confirmed with a choice
  89. Assert.True (dlg.Canceled);
  90. //pressing enter while search focused should not confirm path
  91. Send ('\n', ConsoleKey.Enter, false);
  92. Assert.True (dlg.Canceled);
  93. // tabbing out of search
  94. Send ('\t', ConsoleKey.Tab, false);
  95. //should allow enter to confirm path
  96. Send ('\n', ConsoleKey.Enter, false);
  97. // Dialog has not yet been confirmed with a choice
  98. Assert.False (dlg.Canceled);
  99. }
  100. [Fact, AutoInitShutdown]
  101. public void TestDirectoryContents_Linux ()
  102. {
  103. if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform (System.Runtime.InteropServices.OSPlatform.Windows)) {
  104. // Cannot run test except on linux :(
  105. // See: https://github.com/TestableIO/System.IO.Abstractions/issues/800
  106. return;
  107. }
  108. // Arrange
  109. var fileSystem = new MockFileSystem (new Dictionary<string, MockFileData> (), "/");
  110. fileSystem.MockTime (() => new DateTime (2010, 01, 01, 11, 12, 43));
  111. fileSystem.AddFile (@"/myfile.txt", new MockFileData ("Testing is meh.") { LastWriteTime = new DateTime (2001, 01, 01, 11, 12, 11) });
  112. fileSystem.AddFile (@"/demo/jQuery.js", new MockFileData ("some js") { LastWriteTime = new DateTime (2001, 01, 01, 11, 44, 42) });
  113. fileSystem.AddFile (@"/demo/image.gif", new MockFileData (new byte [] { 0x12, 0x34, 0x56, 0xd2 }) { LastWriteTime = new DateTime (2002, 01, 01, 22, 42, 10) });
  114. var m = (MockDirectoryInfo)fileSystem.DirectoryInfo.New (@"/demo/subfolder");
  115. m.Create ();
  116. m.LastWriteTime = new DateTime (2002, 01, 01, 22, 42, 10);
  117. fileSystem.AddFile (@"/demo/subfolder/image2.gif", new MockFileData (new byte [] { 0x12, 0x34, 0x56, 0xd2 }) { LastWriteTime = new DateTime (2002, 01, 01, 22, 42, 10) });
  118. var fd = new FileDialog (fileSystem) {
  119. Height = 15
  120. };
  121. fd.Path = @"/demo/";
  122. Begin (fd);
  123. fd.Title = string.Empty;
  124. fd.Redraw (fd.Bounds);
  125. fd.Style.DateFormat = "yyyy-MM-dd hh:mm:ss";
  126. string expected =
  127. @"
  128. ┌──────────────────────────────────────────────────────────────────┐
  129. │/demo/ │
  130. │[▲] │
  131. │┌────────────┬──────────┬──────────────────────────────┬─────────┐│
  132. ││Filename (▲)│Size │Modified │Type ││
  133. │├────────────┼──────────┼──────────────────────────────┼─────────┤│
  134. ││.. │ │ │dir ││
  135. ││\subfolder │ │2002-01-01T22:42:10 │dir ││
  136. ││image.gif │4.00 bytes│2002-01-01T22:42:10 │.gif ││
  137. ││jQuery.js │7.00 bytes│2001-01-01T11:44:42 │.js ││
  138. │ │
  139. │ │
  140. │ │
  141. │[ ►► ] Enter Search [ Cancel ] [ Ok ] │
  142. └──────────────────────────────────────────────────────────────────┘
  143. ";
  144. TestHelpers.AssertDriverContentsAre (expected, output, true);
  145. }
  146. [Fact, AutoInitShutdown]
  147. public void TestDirectoryContents_Windows ()
  148. {
  149. if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform (System.Runtime.InteropServices.OSPlatform.Windows)) {
  150. // Can only run this test on windows :(
  151. // See: https://github.com/TestableIO/System.IO.Abstractions/issues/800
  152. return;
  153. }
  154. // Arrange
  155. var fileSystem = new MockFileSystem (new Dictionary<string, MockFileData> (), @"c:\");
  156. fileSystem.MockTime (() => new DateTime (2010, 01, 01, 11, 12, 43));
  157. fileSystem.AddFile (@"c:\myfile.txt", new MockFileData ("Testing is meh.") { LastWriteTime = new DateTime (2001, 01, 01, 11, 12, 11) });
  158. fileSystem.AddFile (@"c:\demo\jQuery.js", new MockFileData ("some js") { LastWriteTime = new DateTime (2001, 01, 01, 11, 44, 42) });
  159. fileSystem.AddFile (@"c:\demo\image.gif", new MockFileData (new byte [] { 0x12, 0x34, 0x56, 0xd2 }) { LastWriteTime = new DateTime (2002, 01, 01, 22, 42, 10) });
  160. var m = (MockDirectoryInfo)fileSystem.DirectoryInfo.New (@"c:\demo\subfolder");
  161. m.Create ();
  162. m.LastWriteTime = new DateTime (2002, 01, 01, 22, 42, 10);
  163. fileSystem.AddFile (@"c:\demo\subfolder\image2.gif", new MockFileData (new byte [] { 0x12, 0x34, 0x56, 0xd2 }) { LastWriteTime = new DateTime (2002, 01, 01, 22, 42, 10) });
  164. var fd = new FileDialog (fileSystem) {
  165. Height = 15
  166. };
  167. fd.Path = @"c:\demo\";
  168. Begin (fd);
  169. fd.Title = string.Empty;
  170. fd.Redraw (fd.Bounds);
  171. fd.Style.DateFormat = "yyyy-MM-dd hh:mm:ss";
  172. string expected =
  173. @"
  174. ┌──────────────────────────────────────────────────────────────────┐
  175. │c:\demo\ │
  176. │[▲] │
  177. │┌────────────┬──────────┬──────────────────────────────┬─────────┐│
  178. ││Filename (▲)│Size │Modified │Type ││
  179. │├────────────┼──────────┼──────────────────────────────┼─────────┤│
  180. ││.. │ │ │dir ││
  181. ││\subfolder │ │2002-01-01T22:42:10 │dir ││
  182. ││image.gif │4.00 bytes│2002-01-01T22:42:10 │.gif ││
  183. ││jQuery.js │7.00 bytes│2001-01-01T11:44:42 │.js ││
  184. │ │
  185. │ │
  186. │ │
  187. │[ ►► ] Enter Search [ Cancel ] [ Ok ] │
  188. └──────────────────────────────────────────────────────────────────┘
  189. ";
  190. TestHelpers.AssertDriverContentsAre (expected, output, true);
  191. }
  192. [Theory, AutoInitShutdown]
  193. [InlineData (true)]
  194. [InlineData (false)]
  195. public void CancelSelection (bool cancel)
  196. {
  197. var dlg = GetInitializedFileDialog ();
  198. var openIn = Path.Combine (Environment.CurrentDirectory, "zz");
  199. Directory.CreateDirectory (openIn);
  200. dlg.Path = openIn + Path.DirectorySeparatorChar;
  201. dlg.FilesSelected += (s, e) => e.Cancel = cancel;
  202. //pressing enter will complete the current selection
  203. // unless the event cancels the confirm
  204. Send ('\n', ConsoleKey.Enter, false);
  205. Assert.Equal (cancel, dlg.Canceled);
  206. }
  207. private void Send (char ch, ConsoleKey ck, bool shift = false, bool alt = false, bool control = false)
  208. {
  209. Application.Driver.SendKeys (ch, ck, shift, alt, control);
  210. }
  211. private void Send (string chars)
  212. {
  213. foreach (var ch in chars) {
  214. Application.Driver.SendKeys (ch, ConsoleKey.NoName, false, false, false);
  215. }
  216. }
  217. /*
  218. [Fact, AutoInitShutdown]
  219. public void Autocomplete_NoSuggestion_WhenTextMatchesExactly ()
  220. {
  221. var tb = new TextFieldWithAppendAutocomplete ();
  222. ForceFocus (tb);
  223. tb.Text = "/bob/fish";
  224. tb.CursorPosition = tb.Text.Length;
  225. tb.GenerateSuggestions (null, "fish", "fishes");
  226. // should not report success for autocompletion because we already have that exact
  227. // string
  228. Assert.False (tb.AcceptSelectionIfAny ());
  229. }
  230. [Fact, AutoInitShutdown]
  231. public void Autocomplete_AcceptSuggstion ()
  232. {
  233. var tb = new TextFieldWithAppendAutocomplete ();
  234. ForceFocus (tb);
  235. tb.Text = @"/bob/fi";
  236. tb.CursorPosition = tb.Text.Length;
  237. tb.GenerateSuggestions (null, "fish", "fishes");
  238. Assert.True (tb.AcceptSelectionIfAny ());
  239. Assert.Equal (@"/bob/fish", tb.Text);
  240. }*/
  241. private FileDialog GetInitializedFileDialog ()
  242. {
  243. var dlg = new FileDialog ();
  244. Begin (dlg);
  245. return dlg;
  246. }
  247. private void Begin (FileDialog dlg)
  248. {
  249. dlg.BeginInit ();
  250. dlg.EndInit ();
  251. Application.Begin (dlg);
  252. }
  253. }
  254. }