[AngularJS Unit tesint] Testing keyboard event
HTML:
<div ng-focus="vm.onFocus(month)", aria-focus="{{vm.focus == month}}", ng-keydown="vm.onKeydown($event, month)">
Component Controller:
onKeydown(e, num) { switch(e.which) { case 13: // enter case 32: { // Space e.preventDefault(); this.select(+num); break; } case 38: { // up e.preventDefault(); this.onUp(this.focus); break; } case 39: { // right e.preventDefault(); this.onRight(this.focus); break; } case 37: { // left e.preventDefault(); this.onLeft(this.focus); break; } case 40: { //down e.preventDefault(); this.onDown(this.focus); break; } default: { angular.noop(); } } } onFocus(num) { this.focus = +num; } onUp(crtFocus) { if (crtFocus === null) { return; } const newFocus = crtFocus - 4 <= this._MIN_MONTH ? this._MIN_MONTH : crtFocus - 4; this.onFocus(newFocus); } onDown(crtFocus) { if (crtFocus === null) { return; } const newFocus = crtFocus + 4 >= this._MAX_MONTH ? this._MAX_MONTH : crtFocus + 4; this.onFocus(newFocus); } onRight(crtFocus) { if (crtFocus === null) { return; } const newFocus = crtFocus + 1 >= this._MAX_MONTH ? this._MAX_MONTH : crtFocus + 1; this.onFocus(newFocus); } onLeft(crtFocus) { if (crtFocus === null) { return; } const newFocus = crtFocus - 1 <= this._MIN_MONTH ? this._MIN_MONTH : crtFocus - 1; this.onFocus(newFocus); } onBlur() { this.focus = null; }
Testing:
describe('keyboard control', () => { const UNKNOWN = 10, ENTER = 13, SPACE = 32, UP = 38, RIGHT = 39, LEFT = 37, DOWN = 40; it('onKeydown should be called when recevice on keydown event', () => { spyOn(ctrl, 'onKeydown'); angular.element(firstTile).triggerHandler({type: 'keydown', which: ENTER}); $scope.$digest(); expect(ctrl.onKeydown).toHaveBeenCalled(); }); it('select function should be called when receive "Enter" keydown events', () => { spyOn(ctrl, 'select').and.callThrough(); angular.element(firstTile).triggerHandler({type: 'keydown', which: ENTER}); $scope.$digest(); expect(ctrl.select).toHaveBeenCalledWith(1); }); it('select function should be called when receive "Space" keydown events', () => { spyOn(ctrl, 'select').and.callThrough(); angular.element(firstTile).triggerHandler({type: 'keydown', which: SPACE}); $scope.$digest(); expect(ctrl.select).toHaveBeenCalledWith(1); }); it('onUp function should be called when UP keydown triggered', () => { spyOn(ctrl, 'onUp').and.callThrough(); ctrl.focus = 12; const expected = ctrl.focus - 4; angular.element(lastTile).triggerHandler({type: 'keydown', which: UP}); $scope.$digest(); expect(ctrl.onUp).toHaveBeenCalledWith(12); expect(ctrl.focus).toEqual(expected); }); it('if current focus is null, onFocus should not be called', () => { spyOn(ctrl, 'onFocus'); expect(ctrl.focus).toBe(null); angular.element(lastTile).triggerHandler({type: 'keydown', which: UP}); $scope.$digest(); expect(ctrl.onFocus).not.toHaveBeenCalled(); }); it('onLeft function should be called when UP keydown triggered', () => { spyOn(ctrl, 'onLeft').and.callThrough(); ctrl.focus = 12; const expected = ctrl.focus - 1; angular.element(lastTile).triggerHandler({type: 'keydown', which: LEFT}); $scope.$digest(); expect(ctrl.onLeft).toHaveBeenCalledWith(12); expect(ctrl.focus).toEqual(expected); }); it('onRight function should be called when UP keydown triggered', () => { spyOn(ctrl, 'onRight').and.callThrough(); ctrl.focus = 1; const expected = ctrl.focus + 1; angular.element(firstTile).triggerHandler({type: 'keydown', which: RIGHT}); $scope.$digest(); expect(ctrl.onRight).toHaveBeenCalledWith(1); expect(ctrl.focus).toEqual(expected); }); it('onDown function should be called when UP keydown triggered', () => { spyOn(ctrl, 'onDown').and.callThrough(); ctrl.focus = 1; const expected = ctrl.focus + 4; angular.element(firstTile).triggerHandler({type: 'keydown', which: DOWN}); $scope.$digest(); expect(ctrl.onDown).toHaveBeenCalledWith(1); expect(ctrl.focus).toEqual(expected); }); it('should only trigger angular.noop() function when other keycode keydown event trigger', () => { spyOn(angular, 'noop'); angular.element(firstTile).triggerHandler({type: 'keydown', which: UNKNOWN}); $scope.$digest(); expect(angular.noop).toHaveBeenCalled(); }); });
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2016-11-22 [HTML] Creating visual skip links in HTML and CSS
2016-11-22 [AngularFire2] Signup and logout
2016-11-22 [AngularFire2] Building an Authentication Observable Data Service
2015-11-22 [ES6] Converting an array-like object into an Array with Array.from()
2014-11-22 [ES6] 11. String Templates
2014-11-22 [AngularJS] $interval
2014-11-22 [ES6] 10. Array Comprehensions