describe 'Angular Hotkeys', -> hotkeys = scope = $rootScope = $rootElement = $window = null beforeEach -> module 'cfp.hotkeys', (hotkeysProvider) -> hotkeysProvider.useNgRoute = true return result = null inject (_$rootElement_, _$rootScope_, _hotkeys_) -> hotkeys = _hotkeys_ $rootElement = _$rootElement_ $rootScope = _$rootScope_ scope = $rootScope.$new() afterEach -> hotkeys.del('w') t = document.getElementById('cfp-test') if t t.parentNode.removeChild(t) it 'should insert the help menu into the dom', -> children = angular.element($rootElement).children() expect(children.hasClass('cfp-hotkeys-container')).toBe true it 'add(args)', -> hotkeys.add 'w', 'description here', -> expect(hotkeys.get('w').description).toBe 'description here' expect(hotkeys.get('x')).toBe false it 'add(object)', -> callback = false hotkeys.add combo: 'w' description: 'description' callback: () -> callback = true expect(hotkeys.get('w').description).toBe 'description' # Test callback: expect(callback).toBe false KeyEvent.simulate('w'.charCodeAt(0), 90) expect(callback).toBe true it 'description should be optional', -> # func argument style: hotkeys.add 'w', -> expect(hotkeys.get('w').description).toBe '$$undefined$$' # object style: hotkeys.add combo: 'e' callback: -> expect(hotkeys.get('e').description).toBe '$$undefined$$' it 'del()', -> hotkeys.add 'w', -> expect(hotkeys.get('w').description).toBe '$$undefined$$' hotkeys.del 'w' expect(hotkeys.get('w')).toBe false it 'should toggle help when ? is pressed', -> expect(angular.element($rootElement).children().hasClass('in')).toBe false KeyEvent.simulate('?'.charCodeAt(0), 90) expect(angular.element($rootElement).children().hasClass('in')).toBe true it 'should bind esc when the cheatsheet is shown', -> expect(hotkeys.get('esc')).toBe false expect(angular.element($rootElement).children().hasClass('in')).toBe false KeyEvent.simulate('?'.charCodeAt(0), 90) expect(angular.element($rootElement).children().hasClass('in')).toBe true expect(hotkeys.get('esc').combo).toEqual ['esc'] KeyEvent.simulate('?'.charCodeAt(0), 90) expect(hotkeys.get('esc')).toBe false it 'should remember previously bound ESC when cheatsheet is shown', -> expect(hotkeys.get('esc')).toBe false # bind something to escape: hotkeys.add 'esc', 'temp', () -> expect(hotkeys.get('esc').description).toBe 'temp' originalCallback = hotkeys.get('esc').callback # show the cheat-sheet which will overwrite the esc key. however, we want to # show the original combo description in the callback, yet have the new # callback bound to remove the cheatsheet from view. KeyEvent.simulate('?'.charCodeAt(0), 90) expect(hotkeys.get('esc').description).toBe 'temp' expect(hotkeys.get('esc').callback).not.toBe originalCallback # hide the cheat sheet to verify the previous esc binding is back KeyEvent.simulate('?'.charCodeAt(0), 90) expect(hotkeys.get('esc').description).toBe 'temp' it 'should (un)bind based on route changes', -> # fake a route change: expect(hotkeys.get('w e s')).toBe false $rootScope.$broadcast('$routeChangeSuccess', { hotkeys: [['w e s', 'Do something Amazing!', 'callme("ishmael")']] }); expect(hotkeys.get('w e s').combo).toEqual ['w e s'] # ensure hotkey is unbound when the route changes $rootScope.$broadcast('$routeChangeSuccess', {}); expect(hotkeys.get('w e s')).toBe false it 'should callback when the hotkey is pressed', -> executed = false hotkeys.add 'w', -> executed = true KeyEvent.simulate('w'.charCodeAt(0), 90) expect(executed).toBe true it 'should callback according to action', -> keypressA = false; keypressB = false; hotkeys.add 'a', -> keypressA = true , 'keyup' hotkeys.add 'b', -> keypressB = true KeyEvent.simulate('a'.charCodeAt(0), 90) KeyEvent.simulate('b'.charCodeAt(0), 90) expect(keypressA).toBe false expect(keypressB).toBe true expect(hotkeys.get('a').action).toBe 'keyup' it 'should allow to invoke hotkey.callback programmatically without event object', -> called = false; hotkeys.add 'a', -> called = true , 'keyup' hotkeys.get('a').callback() expect(called).toBe true it 'should run routes-defined hotkey callbacks when scope is available', -> executed = false passedArg = null $rootScope.callme = (arg) -> executed = true passedArg = arg $rootScope.$broadcast '$routeChangeSuccess', hotkeys: [['w', 'Do something Amazing!', 'callme("ishmael")']] scope: $rootScope expect(executed).toBe false KeyEvent.simulate('w'.charCodeAt(0), 90) expect(executed).toBe true expect(passedArg).toBe 'ishmael' it 'should callback when hotkey is pressed in input field and allowIn INPUT is configured', -> executed = no $body = angular.element document.body $input = angular.element '' $body.prepend $input hotkeys.add combo: 'w' allowIn: ['INPUT'] callback: -> executed = yes KeyEvent.simulate('w'.charCodeAt(0), 90, undefined, $input[0]) expect(executed).toBe yes it 'should callback when hotkey is pressed in select field and allowIn SELECT is configured', -> executed = no $body = angular.element document.body $select = angular.element '