ClipboardTests.cs 7.6 KB

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