test.helper.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. var assert = chai.assert;
  2. var expect = chai.expect;
  3. describe('Helpers', function() {
  4. "use strict";
  5. describe('keysymFromKeyCode', function() {
  6. it('should map known keycodes to keysyms', function() {
  7. expect(kbdUtil.keysymFromKeyCode(0x41, false), 'a').to.be.equal(0x61);
  8. expect(kbdUtil.keysymFromKeyCode(0x41, true), 'A').to.be.equal(0x41);
  9. expect(kbdUtil.keysymFromKeyCode(0xd, false), 'enter').to.be.equal(0xFF0D);
  10. expect(kbdUtil.keysymFromKeyCode(0x11, false), 'ctrl').to.be.equal(0xFFE3);
  11. expect(kbdUtil.keysymFromKeyCode(0x12, false), 'alt').to.be.equal(0xFFE9);
  12. expect(kbdUtil.keysymFromKeyCode(0xe1, false), 'altgr').to.be.equal(0xFE03);
  13. expect(kbdUtil.keysymFromKeyCode(0x1b, false), 'esc').to.be.equal(0xFF1B);
  14. expect(kbdUtil.keysymFromKeyCode(0x26, false), 'up').to.be.equal(0xFF52);
  15. });
  16. it('should return null for unknown keycodes', function() {
  17. expect(kbdUtil.keysymFromKeyCode(0xc0, false), 'DK æ').to.be.null;
  18. expect(kbdUtil.keysymFromKeyCode(0xde, false), 'DK ø').to.be.null;
  19. });
  20. });
  21. describe('keysyms.fromUnicode', function() {
  22. it('should map ASCII characters to keysyms', function() {
  23. expect(keysyms.fromUnicode('a'.charCodeAt())).to.have.property('keysym', 0x61);
  24. expect(keysyms.fromUnicode('A'.charCodeAt())).to.have.property('keysym', 0x41);
  25. });
  26. it('should map Latin-1 characters to keysyms', function() {
  27. expect(keysyms.fromUnicode('ø'.charCodeAt())).to.have.property('keysym', 0xf8);
  28. expect(keysyms.fromUnicode('é'.charCodeAt())).to.have.property('keysym', 0xe9);
  29. });
  30. it('should map characters that are in Windows-1252 but not in Latin-1 to keysyms', function() {
  31. expect(keysyms.fromUnicode('Š'.charCodeAt())).to.have.property('keysym', 0x01a9);
  32. });
  33. it('should map characters which aren\'t in Latin1 *or* Windows-1252 to keysyms', function() {
  34. expect(keysyms.fromUnicode('ŵ'.charCodeAt())).to.have.property('keysym', 0x1000175);
  35. });
  36. it('should return undefined for unknown codepoints', function() {
  37. expect(keysyms.fromUnicode('\n'.charCodeAt())).to.be.undefined;
  38. expect(keysyms.fromUnicode('\u1F686'.charCodeAt())).to.be.undefined;
  39. });
  40. });
  41. describe('substituteCodepoint', function() {
  42. it('should replace characters which don\'t have a keysym', function() {
  43. expect(kbdUtil.substituteCodepoint('Ș'.charCodeAt())).to.equal('Ş'.charCodeAt());
  44. expect(kbdUtil.substituteCodepoint('ș'.charCodeAt())).to.equal('ş'.charCodeAt());
  45. expect(kbdUtil.substituteCodepoint('Ț'.charCodeAt())).to.equal('Ţ'.charCodeAt());
  46. expect(kbdUtil.substituteCodepoint('ț'.charCodeAt())).to.equal('ţ'.charCodeAt());
  47. });
  48. it('should pass other characters through unchanged', function() {
  49. expect(kbdUtil.substituteCodepoint('T'.charCodeAt())).to.equal('T'.charCodeAt());
  50. });
  51. });
  52. describe('nonCharacterKey', function() {
  53. it('should recognize the right keys', function() {
  54. expect(kbdUtil.nonCharacterKey({keyCode: 0xd}), 'enter').to.be.defined;
  55. expect(kbdUtil.nonCharacterKey({keyCode: 0x08}), 'backspace').to.be.defined;
  56. expect(kbdUtil.nonCharacterKey({keyCode: 0x09}), 'tab').to.be.defined;
  57. expect(kbdUtil.nonCharacterKey({keyCode: 0x10}), 'shift').to.be.defined;
  58. expect(kbdUtil.nonCharacterKey({keyCode: 0x11}), 'ctrl').to.be.defined;
  59. expect(kbdUtil.nonCharacterKey({keyCode: 0x12}), 'alt').to.be.defined;
  60. expect(kbdUtil.nonCharacterKey({keyCode: 0xe0}), 'meta').to.be.defined;
  61. });
  62. it('should not recognize character keys', function() {
  63. expect(kbdUtil.nonCharacterKey({keyCode: 'A'}), 'A').to.be.null;
  64. expect(kbdUtil.nonCharacterKey({keyCode: '1'}), '1').to.be.null;
  65. expect(kbdUtil.nonCharacterKey({keyCode: '.'}), '.').to.be.null;
  66. expect(kbdUtil.nonCharacterKey({keyCode: ' '}), 'space').to.be.null;
  67. });
  68. });
  69. describe('getKeysym', function() {
  70. it('should prefer char', function() {
  71. expect(kbdUtil.getKeysym({char : 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x61);
  72. });
  73. it('should use charCode if no char', function() {
  74. expect(kbdUtil.getKeysym({char : '', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
  75. expect(kbdUtil.getKeysym({charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
  76. expect(kbdUtil.getKeysym({char : 'hello', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
  77. });
  78. it('should use keyCode if no charCode', function() {
  79. expect(kbdUtil.getKeysym({keyCode: 0x42, which: 0x43, shiftKey: false})).to.have.property('keysym', 0x62);
  80. expect(kbdUtil.getKeysym({keyCode: 0x42, which: 0x43, shiftKey: true})).to.have.property('keysym', 0x42);
  81. });
  82. it('should use which if no keyCode', function() {
  83. expect(kbdUtil.getKeysym({which: 0x43, shiftKey: false})).to.have.property('keysym', 0x63);
  84. expect(kbdUtil.getKeysym({which: 0x43, shiftKey: true})).to.have.property('keysym', 0x43);
  85. });
  86. it('should substitute where applicable', function() {
  87. expect(kbdUtil.getKeysym({char : 'Ș'})).to.have.property('keysym', 0x1aa);
  88. });
  89. });
  90. describe('Modifier Sync', function() { // return a list of fake events necessary to fix modifier state
  91. describe('Toggle all modifiers', function() {
  92. var sync = kbdUtil.ModifierSync();
  93. it ('should do nothing if all modifiers are up as expected', function() {
  94. expect(sync.keydown({
  95. keyCode: 0x41,
  96. ctrlKey: false,
  97. altKey: false,
  98. altGraphKey: false,
  99. shiftKey: false,
  100. metaKey: false})
  101. ).to.have.lengthOf(0);
  102. });
  103. it ('should synthesize events if all keys are unexpectedly down', function() {
  104. var result = sync.keydown({
  105. keyCode: 0x41,
  106. ctrlKey: true,
  107. altKey: true,
  108. altGraphKey: true,
  109. shiftKey: true,
  110. metaKey: true
  111. });
  112. expect(result).to.have.lengthOf(5);
  113. var keysyms = {};
  114. for (var i = 0; i < result.length; ++i) {
  115. keysyms[result[i].keysym] = (result[i].type == 'keydown');
  116. }
  117. expect(keysyms[0xffe3]);
  118. expect(keysyms[0xffe9]);
  119. expect(keysyms[0xfe03]);
  120. expect(keysyms[0xffe1]);
  121. expect(keysyms[0xffe7]);
  122. });
  123. it ('should do nothing if all modifiers are down as expected', function() {
  124. expect(sync.keydown({
  125. keyCode: 0x41,
  126. ctrlKey: true,
  127. altKey: true,
  128. altGraphKey: true,
  129. shiftKey: true,
  130. metaKey: true
  131. })).to.have.lengthOf(0);
  132. });
  133. });
  134. describe('Toggle Ctrl', function() {
  135. var sync = kbdUtil.ModifierSync();
  136. it('should sync if modifier is suddenly down', function() {
  137. expect(sync.keydown({
  138. keyCode: 0x41,
  139. ctrlKey: true,
  140. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe3), type: 'keydown'}]);
  141. });
  142. it('should sync if modifier is suddenly up', function() {
  143. expect(sync.keydown({
  144. keyCode: 0x41,
  145. ctrlKey: false
  146. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe3), type: 'keyup'}]);
  147. });
  148. });
  149. describe('Toggle Alt', function() {
  150. var sync = kbdUtil.ModifierSync();
  151. it('should sync if modifier is suddenly down', function() {
  152. expect(sync.keydown({
  153. keyCode: 0x41,
  154. altKey: true,
  155. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe9), type: 'keydown'}]);
  156. });
  157. it('should sync if modifier is suddenly up', function() {
  158. expect(sync.keydown({
  159. keyCode: 0x41,
  160. altKey: false
  161. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe9), type: 'keyup'}]);
  162. });
  163. });
  164. describe('Toggle AltGr', function() {
  165. var sync = kbdUtil.ModifierSync();
  166. it('should sync if modifier is suddenly down', function() {
  167. expect(sync.keydown({
  168. keyCode: 0x41,
  169. altGraphKey: true,
  170. })).to.be.deep.equal([{keysym: keysyms.lookup(0xfe03), type: 'keydown'}]);
  171. });
  172. it('should sync if modifier is suddenly up', function() {
  173. expect(sync.keydown({
  174. keyCode: 0x41,
  175. altGraphKey: false
  176. })).to.be.deep.equal([{keysym: keysyms.lookup(0xfe03), type: 'keyup'}]);
  177. });
  178. });
  179. describe('Toggle Shift', function() {
  180. var sync = kbdUtil.ModifierSync();
  181. it('should sync if modifier is suddenly down', function() {
  182. expect(sync.keydown({
  183. keyCode: 0x41,
  184. shiftKey: true,
  185. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe1), type: 'keydown'}]);
  186. });
  187. it('should sync if modifier is suddenly up', function() {
  188. expect(sync.keydown({
  189. keyCode: 0x41,
  190. shiftKey: false
  191. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe1), type: 'keyup'}]);
  192. });
  193. });
  194. describe('Toggle Meta', function() {
  195. var sync = kbdUtil.ModifierSync();
  196. it('should sync if modifier is suddenly down', function() {
  197. expect(sync.keydown({
  198. keyCode: 0x41,
  199. metaKey: true,
  200. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe7), type: 'keydown'}]);
  201. });
  202. it('should sync if modifier is suddenly up', function() {
  203. expect(sync.keydown({
  204. keyCode: 0x41,
  205. metaKey: false
  206. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe7), type: 'keyup'}]);
  207. });
  208. });
  209. describe('Modifier keyevents', function() {
  210. it('should not sync a modifier on its own events', function() {
  211. expect(kbdUtil.ModifierSync().keydown({
  212. keyCode: 0x11,
  213. ctrlKey: false
  214. })).to.be.deep.equal([]);
  215. expect(kbdUtil.ModifierSync().keydown({
  216. keyCode: 0x11,
  217. ctrlKey: true
  218. }), 'B').to.be.deep.equal([]);
  219. })
  220. it('should update state on modifier keyevents', function() {
  221. var sync = kbdUtil.ModifierSync();
  222. sync.keydown({
  223. keyCode: 0x11,
  224. });
  225. expect(sync.keydown({
  226. keyCode: 0x41,
  227. ctrlKey: true,
  228. })).to.be.deep.equal([]);
  229. });
  230. it('should sync other modifiers on ctrl events', function() {
  231. expect(kbdUtil.ModifierSync().keydown({
  232. keyCode: 0x11,
  233. altKey: true
  234. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe9), type: 'keydown'}]);
  235. })
  236. });
  237. describe('sync modifiers on non-key events', function() {
  238. it('should generate sync events when receiving non-keyboard events', function() {
  239. expect(kbdUtil.ModifierSync().syncAny({
  240. altKey: true
  241. })).to.be.deep.equal([{keysym: keysyms.lookup(0xffe9), type: 'keydown'}]);
  242. });
  243. });
  244. });
  245. });