KeyboardSpec.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /* global sinon */
  2. import TestContainer from 'mocha-test-container-support';
  3. import {
  4. assign
  5. } from 'min-dash';
  6. import modelingModule from 'lib/features/modeling';
  7. import keyboardModule from 'lib/features/keyboard';
  8. import {
  9. bootstrapDiagram,
  10. inject
  11. } from 'test/TestHelper';
  12. import { createKeyEvent } from 'test/util/KeyEvents';
  13. var spy = sinon.spy,
  14. stub = sinon.stub;
  15. describe('features/keyboard', function() {
  16. var TEST_KEY = 99;
  17. var defaultDiagramConfig = {
  18. modules: [
  19. modelingModule,
  20. keyboardModule
  21. ],
  22. canvas: {
  23. deferUpdate: false
  24. }
  25. };
  26. beforeEach(bootstrapDiagram(defaultDiagramConfig));
  27. it('should bootstrap diagram with keyboard', inject(function(keyboard) {
  28. expect(keyboard).to.exist;
  29. }));
  30. describe('keyboard binding', function() {
  31. var keyboardConfig = {
  32. keyboard: {
  33. bindTo: document
  34. }
  35. };
  36. beforeEach(bootstrapDiagram(assign(defaultDiagramConfig, keyboardConfig)));
  37. it('should integrate with <attach> + <detach> events', inject(
  38. function(keyboard, eventBus) {
  39. // assume
  40. expect(keyboard._node).not.to.exist;
  41. // when
  42. eventBus.fire('attach');
  43. expect(keyboard._node).to.eql(document);
  44. // but when
  45. eventBus.fire('detach');
  46. expect(keyboard._node).not.to.exist;
  47. }
  48. ));
  49. });
  50. describe('keydown event listener handling', function() {
  51. var testDiv;
  52. beforeEach(function() {
  53. var testContainer = TestContainer.get(this);
  54. testDiv = document.createElement('div');
  55. testDiv.setAttribute('class', 'testClass');
  56. testContainer.appendChild(testDiv);
  57. });
  58. it('should bind keyboard events to node', inject(function(keyboard) {
  59. // given
  60. var keyHandlerSpy = spy(keyboard, '_keyHandler');
  61. // when
  62. keyboard.bind(testDiv);
  63. // then
  64. dispatchKeyboardEvent(testDiv, 'keydown');
  65. expect(keyHandlerSpy).to.have.been.called;
  66. }));
  67. it('should unbind keyboard events to node', inject(function(keyboard) {
  68. // given
  69. var keyHandlerSpy = spy(keyboard, '_keyHandler');
  70. keyboard.bind(testDiv);
  71. // when
  72. keyboard.unbind();
  73. // then
  74. dispatchKeyboardEvent(testDiv, 'keydown');
  75. expect(keyHandlerSpy).not.to.have.been.called;
  76. }));
  77. it('should unbind regardless of not being bound', inject(function(keyboard) {
  78. // when
  79. keyboard.unbind();
  80. }));
  81. it('should return node', inject(function(keyboard) {
  82. // given
  83. keyboard.bind(testDiv);
  84. // when
  85. var binding = keyboard.getBinding();
  86. // then
  87. expect(binding).to.equal(testDiv);
  88. }));
  89. it('should not fire event if target is input field', inject(
  90. function(keyboard, eventBus) {
  91. // given
  92. var eventBusSpy = spy(eventBus, 'fire');
  93. var inputField = document.createElement('input');
  94. testDiv.appendChild(inputField);
  95. // when
  96. keyboard._keyHandler({ key: TEST_KEY, target: inputField });
  97. // then
  98. expect(eventBusSpy).to.not.be.called;
  99. })
  100. );
  101. });
  102. describe('add listener', function() {
  103. it('should handle listeners by priority', inject(function(keyboard) {
  104. // given
  105. var lowerPrioritySpy = spy();
  106. var higherPrioritySpy = stub().returns(true);
  107. keyboard.addListener(500, lowerPrioritySpy);
  108. keyboard.addListener(1000, higherPrioritySpy);
  109. var event = createKeyEvent(TEST_KEY);
  110. // when
  111. keyboard._keyHandler(event);
  112. // then
  113. expect(higherPrioritySpy).to.be.called;
  114. expect(lowerPrioritySpy).to.not.be.called;
  115. }));
  116. it('should invoke listener of lower priority if key was not handled', inject(
  117. function(keyboard) {
  118. // given
  119. var lowerPrioritySpy = spy();
  120. var higherPrioritySpy = spy();
  121. keyboard.addListener(500, lowerPrioritySpy);
  122. keyboard.addListener(1000, higherPrioritySpy);
  123. var event = createKeyEvent(TEST_KEY);
  124. // when
  125. keyboard._keyHandler(event);
  126. // then
  127. expect(higherPrioritySpy).to.be.called;
  128. expect(lowerPrioritySpy).to.be.called;
  129. }
  130. ));
  131. it('should allow to add event listener by passing bare function', inject(
  132. function(keyboard) {
  133. // given
  134. var keyboardEventSpy = spy();
  135. keyboard.addListener(keyboardEventSpy);
  136. var event = createKeyEvent(TEST_KEY);
  137. // when
  138. keyboard._keyHandler(event);
  139. // then
  140. expect(keyboardEventSpy).to.be.called;
  141. }
  142. ));
  143. it('should prevent default if listener returned true', inject(
  144. function(keyboard) {
  145. // given
  146. var keyboardEventStub = sinon.stub().returns(true);
  147. keyboard.addListener(keyboardEventStub);
  148. var event = createKeyEvent(TEST_KEY);
  149. // when
  150. keyboard._keyHandler(event);
  151. // then
  152. expect(keyboardEventStub).to.be.called;
  153. expect(event.defaultPrevented).to.be.true;
  154. }
  155. ));
  156. });
  157. });
  158. // helpers //////////
  159. function dispatchKeyboardEvent(target, type) {
  160. var event;
  161. try {
  162. event = new KeyboardEvent(type);
  163. } catch (e) {
  164. event = document.createEvent('KeyboardEvent');
  165. event.initEvent(type, true, false);
  166. }
  167. target.dispatchEvent(event);
  168. }