AccessKeyHandlerTests.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. using System.Collections.Generic;
  2. using Avalonia.Controls;
  3. using Avalonia.Input;
  4. using Avalonia.UnitTests;
  5. using Moq;
  6. using Xunit;
  7. namespace Avalonia.Base.UnitTests.Input
  8. {
  9. public class AccessKeyHandlerTests : ScopedTestBase
  10. {
  11. [Fact]
  12. public void Should_Raise_Key_Events_For_Unregistered_Access_Key()
  13. {
  14. var root = new TestRoot();
  15. var target = new AccessKeyHandler();
  16. var events = new List<string>();
  17. target.SetOwner(root);
  18. root.KeyDown += (s, e) => events.Add($"KeyDown {e.Key}");
  19. root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
  20. KeyDown(root, Key.LeftAlt);
  21. KeyDown(root, Key.A, KeyModifiers.Alt);
  22. KeyUp(root, Key.A, KeyModifiers.Alt);
  23. KeyUp(root, Key.LeftAlt);
  24. Assert.Equal(new[]
  25. {
  26. "KeyDown LeftAlt",
  27. "KeyDown A",
  28. "KeyUp A",
  29. "KeyUp LeftAlt",
  30. }, events);
  31. }
  32. [Fact]
  33. public void Should_Raise_Key_Events_For_Unregistered_Access_Key_With_MainMenu()
  34. {
  35. var root = new TestRoot();
  36. var target = new AccessKeyHandler();
  37. var menu = Mock.Of<IMainMenu>();
  38. var events = new List<string>();
  39. target.SetOwner(root);
  40. target.MainMenu = menu;
  41. root.KeyDown += (s, e) => events.Add($"KeyDown {e.Key}");
  42. root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
  43. KeyDown(root, Key.LeftAlt);
  44. KeyDown(root, Key.A, KeyModifiers.Alt);
  45. KeyUp(root, Key.A, KeyModifiers.Alt);
  46. KeyUp(root, Key.LeftAlt);
  47. Assert.Equal(new[]
  48. {
  49. "KeyDown LeftAlt",
  50. "KeyDown A",
  51. "KeyUp A",
  52. "KeyUp LeftAlt",
  53. }, events);
  54. }
  55. [Fact]
  56. public void Should_Raise_Key_Events_For_Alt_Key()
  57. {
  58. var root = new TestRoot();
  59. var target = new AccessKeyHandler();
  60. var events = new List<string>();
  61. target.SetOwner(root);
  62. root.KeyDown += (s, e) => events.Add($"KeyDown {e.Key}");
  63. root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
  64. KeyDown(root, Key.LeftAlt);
  65. KeyUp(root, Key.LeftAlt);
  66. Assert.Equal(new[]
  67. {
  68. "KeyDown LeftAlt",
  69. "KeyUp LeftAlt",
  70. }, events);
  71. }
  72. [Fact]
  73. public void Should_Raise_Key_Events_For_Alt_Key_With_MainMenu()
  74. {
  75. var root = new TestRoot();
  76. var target = new AccessKeyHandler();
  77. var menu = new Mock<IMainMenu>();
  78. var events = new List<string>();
  79. menu.SetupAllProperties();
  80. menu.Setup(x => x.Open()).Callback(() => menu.Setup(x => x.IsOpen).Returns(true));
  81. target.SetOwner(root);
  82. target.MainMenu = menu.Object;
  83. root.KeyDown += (s, e) => events.Add($"KeyDown {e.Key}");
  84. root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
  85. KeyDown(root, Key.LeftAlt);
  86. KeyUp(root, Key.LeftAlt);
  87. KeyDown(root, Key.LeftAlt);
  88. KeyUp(root, Key.LeftAlt);
  89. Assert.Equal(new[]
  90. {
  91. "KeyDown LeftAlt",
  92. "KeyUp LeftAlt",
  93. "KeyDown LeftAlt",
  94. "KeyUp LeftAlt",
  95. }, events);
  96. }
  97. [Fact]
  98. public void Should_Raise_Key_Events_For_Registered_Access_Key()
  99. {
  100. var button = new Button();
  101. var root = new TestRoot(button);
  102. var target = new AccessKeyHandler();
  103. var events = new List<string>();
  104. target.SetOwner(root);
  105. target.Register('A', button);
  106. root.KeyDown += (s, e) => events.Add($"KeyDown {e.Key}");
  107. root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
  108. KeyDown(root, Key.LeftAlt);
  109. KeyDown(root, Key.A, KeyModifiers.Alt);
  110. KeyUp(root, Key.A, KeyModifiers.Alt);
  111. KeyUp(root, Key.LeftAlt);
  112. // This differs from WPF which doesn't raise the `A` key event, but matches UWP.
  113. Assert.Equal(new[]
  114. {
  115. "KeyDown LeftAlt",
  116. "KeyDown A",
  117. "KeyUp A",
  118. "KeyUp LeftAlt",
  119. }, events);
  120. }
  121. [Fact]
  122. public void Should_Raise_AccessKey_For_Registered_Access_Key()
  123. {
  124. using (UnitTestApplication.Start(TestServices.RealFocus))
  125. {
  126. var button = new Button();
  127. var root = new TestRoot(button);
  128. var target = new AccessKeyHandler();
  129. var raised = 0;
  130. KeyboardDevice.Instance?.SetFocusedElement(button, NavigationMethod.Unspecified, KeyModifiers.None);
  131. target.SetOwner(root);
  132. target.Register('A', button);
  133. button.AddHandler(AccessKeyHandler.AccessKeyEvent, (s, e) => ++raised);
  134. KeyDown(root, Key.LeftAlt);
  135. Assert.Equal(0, raised);
  136. KeyDown(root, Key.A, KeyModifiers.Alt);
  137. Assert.Equal(1, raised);
  138. KeyUp(root, Key.A, KeyModifiers.Alt);
  139. KeyUp(root, Key.LeftAlt);
  140. Assert.Equal(1, raised);
  141. }
  142. }
  143. [Theory]
  144. [InlineData(false, 0)]
  145. [InlineData(true, 1)]
  146. public void Should_Raise_AccessKey_For_Registered_Access_Key_When_Effectively_Enabled(bool enabled, int expected)
  147. {
  148. using (UnitTestApplication.Start(TestServices.RealFocus))
  149. {
  150. var button = new Button();
  151. var root = new TestRoot(button) { IsEnabled = enabled };
  152. var target = new AccessKeyHandler();
  153. var raised = 0;
  154. KeyboardDevice.Instance?.SetFocusedElement(button, NavigationMethod.Unspecified, KeyModifiers.None);
  155. target.SetOwner(root);
  156. target.Register('A', button);
  157. button.AddHandler(AccessKeyHandler.AccessKeyEvent, (s, e) => ++raised);
  158. KeyDown(root, Key.LeftAlt);
  159. Assert.Equal(0, raised);
  160. KeyDown(root, Key.A, KeyModifiers.Alt);
  161. Assert.Equal(expected, raised);
  162. KeyUp(root, Key.A, KeyModifiers.Alt);
  163. KeyUp(root, Key.LeftAlt);
  164. Assert.Equal(expected, raised);
  165. }
  166. }
  167. [Fact]
  168. public void Should_Open_MainMenu_On_Alt_KeyUp()
  169. {
  170. using (UnitTestApplication.Start(TestServices.RealFocus))
  171. {
  172. var target = new AccessKeyHandler();
  173. var menu = new FakeMenu();
  174. var root = new TestRoot(menu);
  175. KeyboardDevice.Instance?.SetFocusedElement(menu, NavigationMethod.Unspecified,
  176. KeyModifiers.None);
  177. target.SetOwner(root);
  178. target.MainMenu = menu;
  179. KeyDown(root, Key.LeftAlt);
  180. Assert.Equal(0, menu.TimesOpenCalled);
  181. KeyUp(root, Key.LeftAlt);
  182. Assert.Equal(1, menu.TimesOpenCalled);
  183. }
  184. }
  185. private static void KeyDown(IInputElement target, Key key, KeyModifiers modifiers = KeyModifiers.None)
  186. {
  187. target.RaiseEvent(new KeyEventArgs
  188. {
  189. RoutedEvent = InputElement.KeyDownEvent,
  190. Key = key,
  191. KeyModifiers = modifiers,
  192. });
  193. }
  194. private static void KeyUp(IInputElement target, Key key, KeyModifiers modifiers = KeyModifiers.None)
  195. {
  196. target.RaiseEvent(new KeyEventArgs
  197. {
  198. RoutedEvent = InputElement.KeyUpEvent,
  199. Key = key,
  200. KeyModifiers = modifiers,
  201. });
  202. }
  203. class FakeMenu : Menu
  204. {
  205. public int TimesOpenCalled { get; set; }
  206. public override void Open()
  207. {
  208. TimesOpenCalled++;
  209. }
  210. }
  211. }
  212. }