ClipboardTests.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4. using Xunit;
  5. using Xunit.Abstractions;
  6. using static AutoInitShutdownAttribute;
  7. namespace Terminal.Gui.ConsoleDrivers {
  8. public class ClipboardTests {
  9. readonly ITestOutputHelper output;
  10. public ClipboardTests (ITestOutputHelper output)
  11. {
  12. this.output = output;
  13. }
  14. [Fact, AutoInitShutdown (useFakeClipboard: true, fakeClipboardAlwaysThrowsNotSupportedException: true)]
  15. public void IClipboard_GetClipBoardData_Throws_NotSupportedException ()
  16. {
  17. IClipboard iclip = Application.Driver.Clipboard;
  18. Assert.Throws<NotSupportedException> (() => iclip.GetClipboardData ());
  19. }
  20. [Fact, AutoInitShutdown (useFakeClipboard: true, fakeClipboardAlwaysThrowsNotSupportedException: true)]
  21. public void IClipboard_SetClipBoardData_Throws_NotSupportedException ()
  22. {
  23. IClipboard iclip = Application.Driver.Clipboard;
  24. Assert.Throws<NotSupportedException> (() => iclip.SetClipboardData ("foo"));
  25. }
  26. [Fact, AutoInitShutdown (useFakeClipboard: true)]
  27. public void Contents_Fake_Gets_Sets ()
  28. {
  29. if (!Clipboard.IsSupported) {
  30. output.WriteLine ($"The Clipboard not supported on this platform.");
  31. return;
  32. }
  33. var clipText = "The Contents_Gets_Sets unit test pasted this to the OS clipboard.";
  34. Clipboard.Contents = clipText;
  35. Application.Iteration += () => Application.RequestStop ();
  36. Application.Run ();
  37. Assert.Equal (clipText, Clipboard.Contents.ToString ());
  38. }
  39. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  40. public void Contents_Gets_Sets ()
  41. {
  42. if (!Clipboard.IsSupported) {
  43. output.WriteLine ($"The Clipboard not supported on this platform.");
  44. return;
  45. }
  46. var clipText = "The Contents_Gets_Sets unit test pasted this to the OS clipboard.";
  47. Clipboard.Contents = clipText;
  48. Application.Iteration += () => Application.RequestStop ();
  49. Application.Run ();
  50. Assert.Equal (clipText, Clipboard.Contents.ToString ());
  51. }
  52. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  53. public void Contents_Gets_Sets_When_IsSupportedFalse ()
  54. {
  55. if (!Clipboard.IsSupported) {
  56. output.WriteLine ($"The Clipboard not supported on this platform.");
  57. return;
  58. }
  59. var clipText = "The Contents_Gets_Sets unit test pasted this to the OS clipboard.";
  60. Clipboard.Contents = clipText;
  61. Application.Iteration += () => Application.RequestStop ();
  62. Application.Run ();
  63. Assert.Equal (clipText, Clipboard.Contents.ToString ());
  64. }
  65. [Fact, AutoInitShutdown (useFakeClipboard: true)]
  66. public void Contents_Fake_Gets_Sets_When_IsSupportedFalse ()
  67. {
  68. if (!Clipboard.IsSupported) {
  69. output.WriteLine ($"The Clipboard not supported on this platform.");
  70. return;
  71. }
  72. var clipText = "The Contents_Gets_Sets unit test pasted this to the OS clipboard.";
  73. Clipboard.Contents = clipText;
  74. Application.Iteration += () => Application.RequestStop ();
  75. Application.Run ();
  76. Assert.Equal (clipText, Clipboard.Contents.ToString ());
  77. }
  78. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  79. public void IsSupported_Get ()
  80. {
  81. if (Clipboard.IsSupported) {
  82. Assert.True (Clipboard.IsSupported);
  83. } else {
  84. Assert.False (Clipboard.IsSupported);
  85. }
  86. }
  87. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  88. public void TryGetClipboardData_Gets_From_OS_Clipboard ()
  89. {
  90. var clipText = "The TryGetClipboardData_Gets_From_OS_Clipboard unit test pasted this to the OS clipboard.";
  91. Clipboard.Contents = clipText;
  92. Application.Iteration += () => Application.RequestStop ();
  93. Application.Run ();
  94. if (Clipboard.IsSupported) {
  95. Assert.True (Clipboard.TryGetClipboardData (out string result));
  96. Assert.Equal (clipText, result);
  97. } else {
  98. Assert.False (Clipboard.TryGetClipboardData (out string result));
  99. Assert.NotEqual (clipText, result);
  100. }
  101. }
  102. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  103. public void TrySetClipboardData_Sets_The_OS_Clipboard ()
  104. {
  105. var clipText = "The TrySetClipboardData_Sets_The_OS_Clipboard unit test pasted this to the OS clipboard.";
  106. if (Clipboard.IsSupported) {
  107. Assert.True (Clipboard.TrySetClipboardData (clipText));
  108. } else {
  109. Assert.False (Clipboard.TrySetClipboardData (clipText));
  110. }
  111. Application.Iteration += () => Application.RequestStop ();
  112. Application.Run ();
  113. if (Clipboard.IsSupported) {
  114. Assert.Equal (clipText, Clipboard.Contents);
  115. } else {
  116. Assert.NotEqual (clipText, Clipboard.Contents);
  117. }
  118. }
  119. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  120. public void Contents_Copies_From_OS_Clipboard ()
  121. {
  122. if (!Clipboard.IsSupported) {
  123. output.WriteLine ($"The Clipboard not supported on this platform.");
  124. return;
  125. }
  126. var clipText = "The Contents_Copies_From_OS_Clipboard unit test pasted this to the OS clipboard.";
  127. var failed = false;
  128. var getClipText = "";
  129. Application.Iteration += () => {
  130. int exitCode = 0;
  131. string result = "";
  132. output.WriteLine ($"Pasting to OS clipboard: {clipText}...");
  133. if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
  134. (exitCode, result) = ClipboardProcessRunner.Process ("pwsh", $"-command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
  135. output.WriteLine ($" Windows: pwsh Set-Clipboard: exitCode = {exitCode}, result = {result}");
  136. getClipText = Clipboard.Contents.ToString ();
  137. } else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
  138. (exitCode, result) = ClipboardProcessRunner.Process ("pbcopy", string.Empty, clipText);
  139. output.WriteLine ($" OSX: pbcopy: exitCode = {exitCode}, result = {result}");
  140. getClipText = Clipboard.Contents.ToString ();
  141. } else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
  142. if (Is_WSL_Platform ()) {
  143. try {
  144. // This runs the WINDOWS version of powershell.exe via WSL.
  145. (exitCode, result) = ClipboardProcessRunner.Process ("powershell.exe", $"-noprofile -command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
  146. output.WriteLine ($" WSL: powershell.exe Set-Clipboard: exitCode = {exitCode}, result = {result}");
  147. } catch {
  148. failed = true;
  149. }
  150. if (!failed) {
  151. // If we set the OS clipboard via Powershell, then getting Contents should return the same text.
  152. getClipText = Clipboard.Contents.ToString ();
  153. output.WriteLine ($" WSL: Clipboard.Contents: {getClipText}");
  154. }
  155. Application.RequestStop ();
  156. return;
  157. }
  158. if (failed = xclipExists () == false) {
  159. // if xclip doesn't exist then exit.
  160. output.WriteLine ($" WSL: no xclip found.");
  161. Application.RequestStop ();
  162. return;
  163. }
  164. // If we get here, powershell didn't work and xclip exists...
  165. (exitCode, result) = ClipboardProcessRunner.Process ("bash", $"-c \"xclip -sel clip -i\"", clipText);
  166. output.WriteLine ($" Linux: bash xclip -sel clip -i: exitCode = {exitCode}, result = {result}");
  167. if (!failed) {
  168. getClipText = Clipboard.Contents.ToString ();
  169. output.WriteLine ($" Linux via xclip: Clipboard.Contents: {getClipText}");
  170. }
  171. }
  172. Application.RequestStop ();
  173. };
  174. Application.Run ();
  175. if (!failed) {
  176. Assert.Equal (clipText, getClipText);
  177. }
  178. }
  179. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  180. public void Contents_Pastes_To_OS_Clipboard ()
  181. {
  182. if (!Clipboard.IsSupported) {
  183. output.WriteLine ($"The Clipboard not supported on this platform.");
  184. return;
  185. }
  186. var clipText = "The Contents_Pastes_To_OS_Clipboard unit test pasted this via Clipboard.Contents.";
  187. var clipReadText = "";
  188. var failed = false;
  189. Application.Iteration += () => {
  190. Clipboard.Contents = clipText;
  191. int exitCode = 0;
  192. output.WriteLine ($"Getting OS clipboard...");
  193. if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
  194. (exitCode, clipReadText) = ClipboardProcessRunner.Process ("pwsh", "-noprofile -command \"Get-Clipboard\"");
  195. output.WriteLine ($" Windows: pwsh Get-Clipboard: exitCode = {exitCode}, result = {clipReadText}");
  196. } else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
  197. (exitCode, clipReadText) = ClipboardProcessRunner.Process ("pbpaste", "");
  198. output.WriteLine ($" OSX: pbpaste: exitCode = {exitCode}, result = {clipReadText}");
  199. } else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
  200. if (Is_WSL_Platform ()) {
  201. (exitCode, clipReadText) = ClipboardProcessRunner.Process ("powershell.exe", "-noprofile -command \"Get-Clipboard\"");
  202. output.WriteLine ($" WSL: powershell.exe Get-Clipboard: exitCode = {exitCode}, result = {clipReadText}");
  203. if (exitCode == 0) {
  204. Application.RequestStop ();
  205. return;
  206. }
  207. failed = true;
  208. }
  209. if (failed = xclipExists () == false) {
  210. // xclip doesn't exist then exit.
  211. Application.RequestStop ();
  212. return;
  213. }
  214. (exitCode, clipReadText) = ClipboardProcessRunner.Process ("bash", $"-c \"xclip -sel clip -o\"");
  215. output.WriteLine ($" Linux: bash xclip -sel clip -o: exitCode = {exitCode}, result = {clipReadText}");
  216. Assert.Equal (0, exitCode);
  217. }
  218. Application.RequestStop ();
  219. };
  220. Application.Run ();
  221. if (!failed) {
  222. Assert.Equal (clipText, clipReadText.TrimEnd ());
  223. }
  224. }
  225. bool Is_WSL_Platform ()
  226. {
  227. var (_, result) = ClipboardProcessRunner.Process ("bash", $"-c \"uname -a\"");
  228. return result.Contains ("microsoft") && result.Contains ("WSL");
  229. }
  230. bool xclipExists ()
  231. {
  232. try {
  233. var (_, result) = ClipboardProcessRunner.Process ("bash", $"-c \"which xclip\"");
  234. return result.TrimEnd () != "";
  235. } catch (System.Exception) {
  236. return false;
  237. }
  238. }
  239. }
  240. }