KeyTests.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. using System;
  2. using System.Text;
  3. using Xunit;
  4. using Xunit.Abstractions;
  5. namespace Terminal.Gui.InputTests;
  6. public class KeyTests {
  7. readonly ITestOutputHelper _output;
  8. public KeyTests (ITestOutputHelper output) => _output = output;
  9. [Fact]
  10. public void Constructor_Default_ShouldSetKeyToNull ()
  11. {
  12. var eventArgs = new Key ();
  13. Assert.Equal (KeyCode.Null, eventArgs.KeyCode);
  14. }
  15. [Theory]
  16. [InlineData (KeyCode.Enter)]
  17. [InlineData (KeyCode.Esc)]
  18. [InlineData (KeyCode.A)]
  19. public void Constructor_WithKey_ShouldSetCorrectKey (KeyCode key)
  20. {
  21. var eventArgs = new Key (key);
  22. Assert.Equal (key, eventArgs.KeyCode);
  23. }
  24. [Theory]
  25. [InlineData ('a', KeyCode.A)]
  26. [InlineData ('A', KeyCode.A | KeyCode.ShiftMask)]
  27. [InlineData ('z', KeyCode.Z)]
  28. [InlineData ('Z', KeyCode.Z | KeyCode.ShiftMask)]
  29. [InlineData (' ', KeyCode.Space)]
  30. [InlineData ('1', KeyCode.D1)]
  31. [InlineData ('!', (KeyCode)'!')]
  32. [InlineData ('\n', KeyCode.Enter)]
  33. [InlineData ('\t', KeyCode.Tab)]
  34. [InlineData ('\r', (KeyCode)13)]
  35. [InlineData ('ó', (KeyCode)'ó')]
  36. [InlineData ('Ó', (KeyCode)'Ó')]
  37. [InlineData ('❿', (KeyCode)'❿')]
  38. [InlineData ('☑', (KeyCode)'☑')]
  39. [InlineData ('英', (KeyCode)'英')]
  40. [InlineData ('{', (KeyCode)'{')]
  41. [InlineData ('\'', (KeyCode)'\'')]
  42. [InlineData ('\xFFFF', (KeyCode)0xFFFF)]
  43. [InlineData ('\x0', (KeyCode)0x0)]
  44. public void Constructor_Char (char ch, KeyCode expectedKeyCode)
  45. {
  46. var key = new Key (ch);
  47. Assert.Equal (expectedKeyCode, key.KeyCode);
  48. }
  49. // TryParse
  50. [Theory]
  51. [InlineData ("a", KeyCode.A)]
  52. [InlineData ("Ctrl+A", KeyCode.A | KeyCode.CtrlMask)]
  53. [InlineData ("Alt+A", KeyCode.A | KeyCode.AltMask)]
  54. [InlineData ("Shift+A", KeyCode.A | KeyCode.ShiftMask)]
  55. [InlineData ("A", KeyCode.A | KeyCode.ShiftMask)]
  56. [InlineData ("â", (KeyCode)'â')]
  57. [InlineData ("Shift+â", (KeyCode)'â' | KeyCode.ShiftMask)]
  58. [InlineData ("Shift+Â", (KeyCode)'Â' | KeyCode.ShiftMask)]
  59. [InlineData ("Ctrl+Shift+CursorUp", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.CursorUp)]
  60. [InlineData ("Ctrl+Alt+Shift+CursorUp", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.CursorUp)]
  61. [InlineData ("ctrl+alt+shift+cursorup", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.CursorUp)]
  62. [InlineData ("CTRL+ALT+SHIFT+CURSORUP", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.CursorUp)]
  63. [InlineData ("Ctrl+Alt+Shift+Delete", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Delete)]
  64. [InlineData ("Ctrl+Alt+Shift+Enter", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Enter)]
  65. [InlineData ("Tab", KeyCode.Tab)]
  66. [InlineData ("Shift+Tab", KeyCode.Tab | KeyCode.ShiftMask)]
  67. [InlineData ("Ctrl+Tab", KeyCode.Tab | KeyCode.CtrlMask)]
  68. [InlineData ("Alt+Tab", KeyCode.Tab | KeyCode.AltMask)]
  69. [InlineData ("Ctrl+Shift+Tab", KeyCode.Tab | KeyCode.ShiftMask | KeyCode.CtrlMask)]
  70. [InlineData ("Ctrl+Alt+Tab", KeyCode.Tab | KeyCode.AltMask | KeyCode.CtrlMask)]
  71. [InlineData ("", KeyCode.Null)]
  72. [InlineData (" ", KeyCode.Space)]
  73. [InlineData ("Shift+ ", KeyCode.Space | KeyCode.ShiftMask)]
  74. [InlineData ("Ctrl+ ", KeyCode.Space | KeyCode.CtrlMask)]
  75. [InlineData ("Alt+ ", KeyCode.Space | KeyCode.AltMask)]
  76. [InlineData ("F1", KeyCode.F1)]
  77. [InlineData ("0", KeyCode.D0)]
  78. [InlineData ("9", KeyCode.D9)]
  79. [InlineData ("D0", KeyCode.D0)]
  80. [InlineData ("65", KeyCode.A | KeyCode.ShiftMask)]
  81. [InlineData ("97", KeyCode.A)]
  82. [InlineData ("Shift", KeyCode.ShiftKey)]
  83. [InlineData ("Ctrl", KeyCode.CtrlKey)]
  84. [InlineData ("Ctrl-A", KeyCode.A | KeyCode.CtrlMask)]
  85. [InlineData ("Alt-A", KeyCode.A | KeyCode.AltMask)]
  86. [InlineData ("A-Ctrl", KeyCode.A | KeyCode.CtrlMask)]
  87. [InlineData ("Alt-A-Ctrl", KeyCode.A | KeyCode.CtrlMask | KeyCode.AltMask)]
  88. public void Constructor_String_Valid (string keyString, Key expected)
  89. {
  90. Key key = new Key (keyString);
  91. Assert.Equal (((Key)expected).ToString (), key.ToString ());
  92. }
  93. [Theory]
  94. [InlineData("Barf")]
  95. public void Constructor_String_Invalid_Throws (string keyString)
  96. {
  97. Assert.Throws<ArgumentException> (() => new Key (keyString));
  98. }
  99. [Theory]
  100. [InlineData ('a', KeyCode.A)]
  101. [InlineData ('A', KeyCode.A | KeyCode.ShiftMask)]
  102. [InlineData ('z', KeyCode.Z)]
  103. [InlineData ('Z', KeyCode.Z | KeyCode.ShiftMask)]
  104. [InlineData (' ', KeyCode.Space)]
  105. [InlineData ('1', KeyCode.D1)]
  106. [InlineData ('!', (KeyCode)'!')]
  107. [InlineData ('\n', KeyCode.Enter)]
  108. [InlineData ('\t', KeyCode.Tab)]
  109. [InlineData ('\r', (KeyCode)13)]
  110. [InlineData ('ó', (KeyCode)'ó')]
  111. [InlineData ('Ó', (KeyCode)'Ó')]
  112. [InlineData ('❿', (KeyCode)'❿')]
  113. [InlineData ('☑', (KeyCode)'☑')]
  114. [InlineData ('英', (KeyCode)'英')]
  115. [InlineData ('{', (KeyCode)'{')]
  116. [InlineData ('\'', (KeyCode)'\'')]
  117. [InlineData ('\xFFFF', (KeyCode)0xFFFF)]
  118. [InlineData ('\x0', (KeyCode)0x0)]
  119. public void Cast_Char_To_Key (char ch, KeyCode expectedKeyCode)
  120. {
  121. var key = (Key)ch;
  122. Assert.Equal (expectedKeyCode, key.KeyCode);
  123. }
  124. // string cast operators
  125. [Fact]
  126. public void Cast_String_To_Key ()
  127. {
  128. var key = (Key)"Ctrl+Q";
  129. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, key.KeyCode);
  130. }
  131. [Fact]
  132. public void Cast_Key_ToString ()
  133. {
  134. var str = (string)Key.Q.WithCtrl;
  135. Assert.Equal ("Ctrl+Q", str);
  136. }
  137. // IsValid
  138. [Theory]
  139. [InlineData (KeyCode.A, true)]
  140. [InlineData (KeyCode.B, true)]
  141. [InlineData (KeyCode.F1 | KeyCode.ShiftMask, true)]
  142. [InlineData (KeyCode.Null, false)]
  143. [InlineData (KeyCode.ShiftMask, false)]
  144. [InlineData (KeyCode.CtrlMask, false)]
  145. [InlineData (KeyCode.AltMask, false)]
  146. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask, false)]
  147. public void IsValid (Key key, bool expected) => Assert.Equal (expected, key.IsValid);
  148. [Fact]
  149. public void HandledProperty_ShouldBeFalseByDefault ()
  150. {
  151. var eventArgs = new Key ();
  152. Assert.False (eventArgs.Handled);
  153. }
  154. [Theory]
  155. [InlineData (KeyCode.Enter, KeyCode.Enter)]
  156. [InlineData (KeyCode.Esc, KeyCode.Esc)]
  157. [InlineData (KeyCode.A, (KeyCode)'a')]
  158. [InlineData (KeyCode.A | KeyCode.ShiftMask, KeyCode.A | KeyCode.ShiftMask)]
  159. [InlineData (KeyCode.Z, (KeyCode)'z')]
  160. [InlineData (KeyCode.Space, KeyCode.Space)]
  161. public void Cast_KeyCode_To_Key (KeyCode cdk, Key expected)
  162. {
  163. // explicit
  164. var key = (Key)cdk;
  165. Assert.Equal (expected.ToString (), key.ToString ());
  166. // implicit
  167. key = cdk;
  168. Assert.Equal (expected.ToString (), key.ToString ());
  169. }
  170. [Fact]
  171. public void Standard_Keys_Always_New ()
  172. {
  173. // Make two local keys, and grab Key.A, which is a reference to a singleton.
  174. Key aKey1 = Key.A;
  175. Key aKey2 = Key.A;
  176. // Assert the starting state that is expected
  177. Assert.False (aKey1.Handled);
  178. Assert.False (aKey2.Handled);
  179. Assert.False (Key.A.Handled);
  180. // Now set Handled true on one of our local keys
  181. aKey1.Handled = true;
  182. // Assert the newly-expected case
  183. // The last two assertions will fail, because we have actually modified a singleton
  184. Assert.True (aKey1.Handled);
  185. Assert.False (aKey2.Handled);
  186. Assert.False (Key.A.Handled);
  187. }
  188. [Theory]
  189. [InlineData ((KeyCode)'a', true)]
  190. [InlineData ((KeyCode)'a' | KeyCode.ShiftMask, true)]
  191. [InlineData (KeyCode.A, true)]
  192. [InlineData (KeyCode.A | KeyCode.ShiftMask, true)]
  193. [InlineData (KeyCode.F, true)]
  194. [InlineData (KeyCode.F | KeyCode.ShiftMask, true)]
  195. // these have alt or ctrl modifiers or are not a..z
  196. [InlineData (KeyCode.A | KeyCode.CtrlMask, false)]
  197. [InlineData (KeyCode.A | KeyCode.AltMask, false)]
  198. [InlineData (KeyCode.D0, false)]
  199. [InlineData (KeyCode.Esc, false)]
  200. [InlineData (KeyCode.Tab, false)]
  201. public void IsKeyCodeAtoZ (KeyCode key, bool expected)
  202. {
  203. var eventArgs = new Key (key);
  204. Assert.Equal (expected, eventArgs.IsKeyCodeAtoZ);
  205. }
  206. [Theory]
  207. [InlineData ((KeyCode)'❿', '❿')]
  208. [InlineData ((KeyCode)'☑', '☑')]
  209. [InlineData ((KeyCode)'英', '英')]
  210. [InlineData ((KeyCode)'{', '{')]
  211. [InlineData ((KeyCode)'\'', '\'')]
  212. [InlineData ((KeyCode)'\r', '\r')]
  213. [InlineData ((KeyCode)'ó', 'ó')]
  214. [InlineData ((KeyCode)'ó' | KeyCode.ShiftMask, 'ó')]
  215. [InlineData ((KeyCode)'Ó', 'Ó')]
  216. [InlineData ((KeyCode)'ç' | KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.CtrlMask, '\0')]
  217. [InlineData ((KeyCode)'a', 97)] // 97 or Key.Space | Key.A
  218. [InlineData ((KeyCode)'A', 97)] // 65 or equivalent to Key.A, but A-Z are mapped to lower case by drivers
  219. //[InlineData (Key.A, 97)] // 65 equivalent to (Key)'A', but A-Z are mapped to lower case by drivers
  220. [InlineData (KeyCode.ShiftMask | KeyCode.A, 65)]
  221. [InlineData (KeyCode.CtrlMask | KeyCode.A, '\0')]
  222. [InlineData (KeyCode.AltMask | KeyCode.A, '\0')]
  223. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.A, '\0')]
  224. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.A, '\0')]
  225. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.A, '\0')]
  226. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.A, '\0')]
  227. [InlineData ((KeyCode)'z', 'z')]
  228. [InlineData ((KeyCode)'Z', 'z')]
  229. [InlineData (KeyCode.ShiftMask | KeyCode.Z, 'Z')]
  230. [InlineData ((KeyCode)'1', '1')]
  231. [InlineData (KeyCode.ShiftMask | KeyCode.D1, '1')]
  232. [InlineData (KeyCode.CtrlMask | KeyCode.D1, '\0')]
  233. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.D1, '\0')]
  234. [InlineData (KeyCode.F1, '\0')]
  235. [InlineData (KeyCode.ShiftMask | KeyCode.F1, '\0')]
  236. [InlineData (KeyCode.CtrlMask | KeyCode.F1, '\0')]
  237. [InlineData (KeyCode.Enter, '\n')]
  238. [InlineData (KeyCode.Tab, '\t')]
  239. [InlineData (KeyCode.Esc, 0x1b)]
  240. [InlineData (KeyCode.Space, ' ')]
  241. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Enter, '\0')]
  242. [InlineData (KeyCode.Null, '\0')]
  243. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Null, '\0')]
  244. [InlineData (KeyCode.CharMask, '\0')]
  245. [InlineData (KeyCode.SpecialMask, '\0')]
  246. public void AsRune_ShouldReturnCorrectIntValue (KeyCode key, Rune expected)
  247. {
  248. var eventArgs = new Key (key);
  249. Assert.Equal (expected, eventArgs.AsRune);
  250. }
  251. [Theory]
  252. [InlineData (KeyCode.AltMask, true)]
  253. [InlineData (KeyCode.A, false)]
  254. public void IsAlt_ShouldReturnCorrectValue (KeyCode key, bool expected)
  255. {
  256. var eventArgs = new Key (key);
  257. Assert.Equal (expected, eventArgs.IsAlt);
  258. }
  259. [Fact]
  260. public void WithShift_ShouldReturnCorrectValue ()
  261. {
  262. var a = new Key (KeyCode.A);
  263. Assert.Equal (KeyCode.A | KeyCode.ShiftMask, a.WithShift);
  264. var CAD = Key.Delete.WithCtrl.WithAlt;
  265. Assert.Equal (KeyCode.Delete | KeyCode.CtrlMask | KeyCode.AltMask, CAD);
  266. }
  267. [Fact]
  268. public void NoShift_ShouldReturnCorrectValue ()
  269. {
  270. var CAD = Key.Delete.WithCtrl.WithAlt;
  271. Assert.Equal (KeyCode.Delete | KeyCode.CtrlMask | KeyCode.AltMask, CAD);
  272. Assert.Equal (KeyCode.Delete | KeyCode.AltMask, CAD.NoCtrl);
  273. var a = new Key (KeyCode.A).WithCtrl.WithAlt.WithShift;
  274. Assert.Equal (KeyCode.A, a.NoCtrl.NoShift.NoAlt);
  275. Assert.Equal (KeyCode.A, a.NoAlt.NoShift.NoCtrl);
  276. Assert.Equal (KeyCode.A, a.NoAlt.NoShift.NoCtrl.NoCtrl.NoAlt.NoShift);
  277. Assert.Equal (Key.Delete, Key.Delete.WithCtrl.NoCtrl);
  278. Assert.Equal ((KeyCode)Key.Delete | KeyCode.CtrlMask, Key.Delete.NoCtrl.WithCtrl);
  279. }
  280. [Fact]
  281. public void Standard_Keys_Should_Equal_KeyCode ()
  282. {
  283. Assert.Equal (KeyCode.A, Key.A);
  284. Assert.Equal (KeyCode.Delete, Key.Delete);
  285. }
  286. // TODO: Create equality operator for KeyCode
  287. //Assert.Equal (KeyCode.Delete, Key.Delete);
  288. // Similar tests for IsShift and IsCtrl
  289. [Fact]
  290. public void ToString_ShouldReturnReadableString ()
  291. {
  292. var eventArgs = new Key (KeyCode.CtrlMask | KeyCode.A);
  293. Assert.Equal ("Ctrl+A", eventArgs.ToString ());
  294. }
  295. [Theory]
  296. [InlineData (KeyCode.CtrlMask | KeyCode.A, '+', "Ctrl+A")]
  297. [InlineData (KeyCode.AltMask | KeyCode.B, '-', "Alt-B")]
  298. public void ToStringWithSeparator_ShouldReturnFormattedString (KeyCode key, char separator, string expected) => Assert.Equal (expected, Key.ToString (key, (Rune)separator));
  299. [Theory]
  300. [InlineData ((KeyCode)'☑', "☑")]
  301. //[InlineData ((ConsoleDriverKey)'英', "英")]
  302. //[InlineData ((ConsoleDriverKey)'{', "{")]
  303. [InlineData ((KeyCode)'\'', "\'")]
  304. [InlineData ((KeyCode)'ó', "ó")]
  305. [InlineData ((KeyCode)'ó' | KeyCode.ShiftMask, "Shift+ó")] // is this right???
  306. [InlineData ((KeyCode)'Ó', "Ó")]
  307. [InlineData ((KeyCode)'ç' | KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt+Shift+ç")]
  308. [InlineData ((KeyCode)'a', "a")] // 97 or Key.Space | Key.A
  309. [InlineData ((KeyCode)'A', "a")] // 65 or equivalent to Key.A, but A-Z are mapped to lower case by drivers
  310. [InlineData (KeyCode.ShiftMask | KeyCode.A, "A")]
  311. [InlineData ((KeyCode)'a' | KeyCode.ShiftMask, "A")]
  312. [InlineData (KeyCode.CtrlMask | KeyCode.A, "Ctrl+A")]
  313. [InlineData (KeyCode.AltMask | KeyCode.A, "Alt+A")]
  314. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.A, "Ctrl+Shift+A")]
  315. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.A, "Alt+Shift+A")]
  316. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.A, "Ctrl+Alt+A")]
  317. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.A, "Ctrl+Alt+Shift+A")]
  318. [InlineData (KeyCode.ShiftMask | KeyCode.Z, "Z")]
  319. [InlineData (KeyCode.CtrlMask | KeyCode.Z, "Ctrl+Z")]
  320. [InlineData (KeyCode.AltMask | KeyCode.Z, "Alt+Z")]
  321. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.Z, "Ctrl+Shift+Z")]
  322. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.Z, "Alt+Shift+Z")]
  323. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.Z, "Ctrl+Alt+Z")]
  324. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Z, "Ctrl+Alt+Shift+Z")]
  325. [InlineData ((KeyCode)'1', "1")]
  326. [InlineData (KeyCode.ShiftMask | KeyCode.D1, "Shift+1")]
  327. [InlineData (KeyCode.CtrlMask | KeyCode.D1, "Ctrl+1")]
  328. [InlineData (KeyCode.AltMask | KeyCode.D1, "Alt+1")]
  329. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.D1, "Ctrl+Shift+1")]
  330. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.D1, "Alt+Shift+1")]
  331. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.D1, "Ctrl+Alt+1")]
  332. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.D1, "Ctrl+Alt+Shift+1")]
  333. [InlineData (KeyCode.F1, "F1")]
  334. [InlineData (KeyCode.ShiftMask | KeyCode.F1, "Shift+F1")]
  335. [InlineData (KeyCode.CtrlMask | KeyCode.F1, "Ctrl+F1")]
  336. [InlineData (KeyCode.AltMask | KeyCode.F1, "Alt+F1")]
  337. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.F1, "Ctrl+Shift+F1")]
  338. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.F1, "Alt+Shift+F1")]
  339. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.F1, "Ctrl+Alt+F1")]
  340. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.F1, "Ctrl+Alt+Shift+F1")]
  341. [InlineData (KeyCode.Enter, "Enter")]
  342. [InlineData (KeyCode.ShiftMask | KeyCode.Enter, "Shift+Enter")]
  343. [InlineData (KeyCode.CtrlMask | KeyCode.Enter, "Ctrl+Enter")]
  344. [InlineData (KeyCode.AltMask | KeyCode.Enter, "Alt+Enter")]
  345. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.Enter, "Ctrl+Shift+Enter")]
  346. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.Enter, "Alt+Shift+Enter")]
  347. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.Enter, "Ctrl+Alt+Enter")]
  348. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Enter, "Ctrl+Alt+Shift+Enter")]
  349. [InlineData (KeyCode.Delete, "Delete")]
  350. [InlineData (KeyCode.ShiftMask | KeyCode.Delete, "Shift+Delete")]
  351. [InlineData (KeyCode.CtrlMask | KeyCode.Delete, "Ctrl+Delete")]
  352. [InlineData (KeyCode.AltMask | KeyCode.Delete, "Alt+Delete")]
  353. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.Delete, "Ctrl+Shift+Delete")]
  354. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.Delete, "Alt+Shift+Delete")]
  355. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.Delete, "Ctrl+Alt+Delete")]
  356. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Delete, "Ctrl+Alt+Shift+Delete")]
  357. [InlineData (KeyCode.CursorUp, "CursorUp")]
  358. [InlineData (KeyCode.ShiftMask | KeyCode.CursorUp, "Shift+CursorUp")]
  359. [InlineData (KeyCode.CtrlMask | KeyCode.CursorUp, "Ctrl+CursorUp")]
  360. [InlineData (KeyCode.AltMask | KeyCode.CursorUp, "Alt+CursorUp")]
  361. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.CursorUp, "Ctrl+Shift+CursorUp")]
  362. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.CursorUp, "Alt+Shift+CursorUp")]
  363. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.CursorUp, "Ctrl+Alt+CursorUp")]
  364. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.CursorUp, "Ctrl+Alt+Shift+CursorUp")]
  365. [InlineData (KeyCode.Null, "Null")]
  366. [InlineData (KeyCode.ShiftMask | KeyCode.Null, "Null")]
  367. [InlineData (KeyCode.CtrlMask | KeyCode.Null, "Null")]
  368. [InlineData (KeyCode.AltMask | KeyCode.Null, "Null")]
  369. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.Null, "Null")]
  370. [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.Null, "Null")]
  371. [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.Null, "Null")]
  372. [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Null, "Null")]
  373. [InlineData (KeyCode.AltKey, "AltKey")]
  374. [InlineData (KeyCode.CtrlKey, "CtrlKey")]
  375. [InlineData (KeyCode.ShiftKey, "ShiftKey")]
  376. [InlineData (KeyCode.CharMask, "CharMask")]
  377. [InlineData (KeyCode.SpecialMask, "Ctrl+Alt+Shift")]
  378. public void ToString_ShouldReturnFormattedString (KeyCode key, string expected) => Assert.Equal (expected, Key.ToString (key));
  379. // TryParse
  380. [Theory]
  381. [InlineData ("a", KeyCode.A)]
  382. [InlineData ("Ctrl+A", KeyCode.A | KeyCode.CtrlMask)]
  383. [InlineData ("Alt+A", KeyCode.A | KeyCode.AltMask)]
  384. [InlineData ("Shift+A", KeyCode.A | KeyCode.ShiftMask)]
  385. [InlineData ("A", KeyCode.A | KeyCode.ShiftMask)]
  386. [InlineData ("â", (KeyCode)'â')]
  387. [InlineData ("Shift+â", (KeyCode)'â' | KeyCode.ShiftMask)]
  388. [InlineData ("Shift+Â", (KeyCode)'Â' | KeyCode.ShiftMask)]
  389. [InlineData ("Ctrl+Shift+CursorUp", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.CursorUp)]
  390. [InlineData ("Ctrl+Alt+Shift+CursorUp", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.CursorUp)]
  391. [InlineData ("ctrl+alt+shift+cursorup", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.CursorUp)]
  392. [InlineData ("CTRL+ALT+SHIFT+CURSORUP", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.CursorUp)]
  393. [InlineData ("Ctrl+Alt+Shift+Delete", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Delete)]
  394. [InlineData ("Ctrl+Alt+Shift+Enter", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Enter)]
  395. [InlineData ("Tab", KeyCode.Tab)]
  396. [InlineData ("Shift+Tab", KeyCode.Tab | KeyCode.ShiftMask)]
  397. [InlineData ("Ctrl+Tab", KeyCode.Tab | KeyCode.CtrlMask)]
  398. [InlineData ("Alt+Tab", KeyCode.Tab | KeyCode.AltMask)]
  399. [InlineData ("Ctrl+Shift+Tab", KeyCode.Tab | KeyCode.ShiftMask | KeyCode.CtrlMask)]
  400. [InlineData ("Ctrl+Alt+Tab", KeyCode.Tab | KeyCode.AltMask | KeyCode.CtrlMask)]
  401. [InlineData ("", KeyCode.Null)]
  402. [InlineData (" ", KeyCode.Space)]
  403. [InlineData ("Shift+ ", KeyCode.Space | KeyCode.ShiftMask)]
  404. [InlineData ("Ctrl+ ", KeyCode.Space | KeyCode.CtrlMask)]
  405. [InlineData ("Alt+ ", KeyCode.Space | KeyCode.AltMask)]
  406. [InlineData ("F1", KeyCode.F1)]
  407. [InlineData ("0", KeyCode.D0)]
  408. [InlineData ("9", KeyCode.D9)]
  409. [InlineData ("D0", KeyCode.D0)]
  410. [InlineData ("65", KeyCode.A | KeyCode.ShiftMask)]
  411. [InlineData ("97", KeyCode.A)]
  412. [InlineData ("Shift", KeyCode.ShiftKey)]
  413. [InlineData ("Ctrl", KeyCode.CtrlKey)]
  414. [InlineData ("Ctrl-A", KeyCode.A | KeyCode.CtrlMask)]
  415. [InlineData ("Alt-A", KeyCode.A | KeyCode.AltMask)]
  416. [InlineData ("A-Ctrl", KeyCode.A | KeyCode.CtrlMask)]
  417. [InlineData ("Alt-A-Ctrl", KeyCode.A | KeyCode.CtrlMask | KeyCode.AltMask)]
  418. public void TryParse_ShouldReturnTrue_WhenValidKey (string keyString, Key expected)
  419. {
  420. Key key;
  421. Assert.True (Key.TryParse (keyString, out key));
  422. Assert.Equal (((Key)expected).ToString (), key.ToString ());
  423. }
  424. [Theory]
  425. [InlineData ("aa")]
  426. [InlineData ("-1")]
  427. [InlineData ("Crtl-A")]
  428. [InlineData ("Ctrl=A")]
  429. [InlineData ("Crtl")]
  430. [InlineData ("99a")]
  431. [InlineData ("a99")]
  432. [InlineData ("#99")]
  433. [InlineData ("x99")]
  434. [InlineData ("0x99")]
  435. [InlineData ("Ctrl-Ctrl")]
  436. public void TryParse_ShouldReturnFalse_On_InvalidKey (string keyString) => Assert.False (Key.TryParse (keyString, out var _));
  437. }