ClipboardTests.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4. using Xunit;
  5. using Xunit.Abstractions;
  6. namespace Terminal.Gui.ConsoleDrivers {
  7. public class ClipboardTests {
  8. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  9. public void Contents_Gets_Sets ()
  10. {
  11. var clipText = "This is a clipboard unit test.";
  12. Clipboard.Contents = clipText;
  13. Application.Iteration += () => Application.RequestStop ();
  14. Application.Run ();
  15. Assert.Equal (clipText, Clipboard.Contents);
  16. }
  17. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  18. public void IsSupported_Get ()
  19. {
  20. if (Clipboard.IsSupported) {
  21. Assert.True (Clipboard.IsSupported);
  22. } else {
  23. Assert.False (Clipboard.IsSupported);
  24. }
  25. }
  26. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  27. public void TryGetClipboardData_Gets_From_OS_Clipboard ()
  28. {
  29. var clipText = "Trying to get from the OS clipboard.";
  30. Clipboard.Contents = clipText;
  31. Application.Iteration += () => Application.RequestStop ();
  32. Application.Run ();
  33. if (Clipboard.IsSupported) {
  34. Assert.True (Clipboard.TryGetClipboardData (out string result));
  35. Assert.Equal (clipText, result);
  36. } else {
  37. Assert.False (Clipboard.TryGetClipboardData (out string result));
  38. Assert.NotEqual (clipText, result);
  39. }
  40. }
  41. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  42. public void TrySetClipboardData_Sets_The_OS_Clipboard ()
  43. {
  44. var clipText = "Trying to set the OS clipboard.";
  45. if (Clipboard.IsSupported) {
  46. Assert.True (Clipboard.TrySetClipboardData (clipText));
  47. } else {
  48. Assert.False (Clipboard.TrySetClipboardData (clipText));
  49. }
  50. Application.Iteration += () => Application.RequestStop ();
  51. Application.Run ();
  52. if (Clipboard.IsSupported) {
  53. Assert.Equal (clipText, Clipboard.Contents);
  54. } else {
  55. Assert.NotEqual (clipText, Clipboard.Contents);
  56. }
  57. }
  58. private static string RunClipboardProcess (string cmd, string args, string writeText = null)
  59. {
  60. string output = string.Empty;
  61. using (Process process = new Process {
  62. StartInfo = new ProcessStartInfo {
  63. FileName = cmd,
  64. Arguments = args,
  65. RedirectStandardOutput = true,
  66. RedirectStandardError = true,
  67. RedirectStandardInput = true
  68. }
  69. }) {
  70. process.Start ();
  71. if (string.IsNullOrEmpty (writeText)) {
  72. process.StandardInput.Write (writeText);
  73. process.StandardInput.Close ();
  74. }
  75. process.WaitForExit ();
  76. if (process.ExitCode > 0) {
  77. var error = $@"RunClipboardProcess failed. Command line: {cmd} {args}.
  78. Output: {process.StandardOutput.ReadToEnd ()}
  79. Error: {process.StandardError.ReadToEnd ()}";
  80. throw new InvalidOperationException (error);
  81. }
  82. output = process.StandardOutput.ReadToEnd ().TrimEnd ();
  83. process.StandardOutput.Close ();
  84. }
  85. return output;
  86. }
  87. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  88. public void Contents_Gets_From_OS_Clipboard ()
  89. {
  90. var clipText = "This is a clipboard unit test to get clipboard from OS.";
  91. var failed = false;
  92. var getClipText = "";
  93. Application.Iteration += () => {
  94. if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
  95. RunClipboardProcess ("pwsh", $"-command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
  96. getClipText = Clipboard.Contents.ToString ();
  97. } else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
  98. RunClipboardProcess ("pbcopy", string.Empty, clipText);
  99. getClipText = Clipboard.Contents.ToString ();
  100. } else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
  101. if (Is_WSL_Platform ()) {
  102. try {
  103. // This runs the WINDOWS version of powershell.exe via WSL.
  104. RunClipboardProcess ("powershell.exe", $"-noprofile -command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
  105. } catch {
  106. failed = true;
  107. }
  108. if (!failed) {
  109. getClipText = Clipboard.Contents.ToString ();
  110. }
  111. Application.RequestStop ();
  112. return;
  113. }
  114. if (failed = xclipExists () == false) {
  115. // xclip doesn't exist then exit.
  116. Application.RequestStop ();
  117. return;
  118. }
  119. // If we get here, powershell didn't work and xclip exists...
  120. RunClipboardProcess ("bash", $"-c \"xclip -sel clip -i\"", clipText);
  121. if (!failed) {
  122. getClipText = Clipboard.Contents.ToString ();
  123. }
  124. }
  125. Application.RequestStop ();
  126. };
  127. Application.Run ();
  128. if (!failed) {
  129. Assert.Equal (clipText, getClipText);
  130. }
  131. }
  132. [Fact, AutoInitShutdown (useFakeClipboard: false)]
  133. public void Contents_Sets_The_OS_Clipboard ()
  134. {
  135. var clipText = "This is a clipboard unit test to set the OS clipboard.";
  136. var clipReadText = "";
  137. var failed = false;
  138. Application.Iteration += () => {
  139. Clipboard.Contents = clipText;
  140. if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
  141. clipReadText = RunClipboardProcess ("pwsh", "-noprofile -command \"Get-Clipboard\"");
  142. } else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
  143. clipReadText = RunClipboardProcess ("pbpaste", "");
  144. } else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
  145. if (Is_WSL_Platform ()) {
  146. try {
  147. clipReadText = RunClipboardProcess ("/opt/microsoft/powershell/7/pwsh", "-noprofile -command \"Get-Clipboard\"");
  148. } catch {
  149. failed = true;
  150. }
  151. Application.RequestStop ();
  152. }
  153. if (failed = xclipExists () == false) {
  154. // xclip doesn't exist then exit.
  155. Application.RequestStop ();
  156. return;
  157. }
  158. clipReadText = RunClipboardProcess ("bash", $"-c \"xclip -sel clip -o\"");
  159. }
  160. Application.RequestStop ();
  161. };
  162. Application.Run ();
  163. if (!failed) {
  164. Assert.Equal (clipText, clipReadText);
  165. }
  166. }
  167. bool Is_WSL_Platform ()
  168. {
  169. var result = RunClipboardProcess ("bash", $"-c \"uname -a\"");
  170. return result.Contains ("microsoft") && result.Contains ("WSL");
  171. }
  172. bool xclipExists ()
  173. {
  174. try {
  175. var result = RunClipboardProcess ("bash", $"-c \"which xclip\"");
  176. return result.TrimEnd () != "";
  177. } catch (System.Exception) {
  178. return false;
  179. }
  180. }
  181. }
  182. }