+ expect(kbd.onkeyevent).to.not.have.been.called;
+ kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
+ expect(kbd.onkeyevent).to.have.been.calledTwice;
+ expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
+ expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0x61, "KeyA", true);
+
+ // Check that the timer is properly dead
+ kbd.onkeyevent.reset();
+ this.clock.tick(100);
+ expect(kbd.onkeyevent).to.not.have.been.called;
+ });
+
+ it('should release ControlLeft on other key release', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
+ expect(kbd.onkeyevent).to.have.been.calledOnce;
+ expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0x61, "KeyA", true);
+ kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'}));
+ expect(kbd.onkeyevent).to.have.been.calledThrice;
+ expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
+ expect(kbd.onkeyevent.thirdCall).to.have.been.calledWith(0x61, "KeyA", false);
+
+ // Check that the timer is properly dead
+ kbd.onkeyevent.reset();
+ this.clock.tick(100);
+ expect(kbd.onkeyevent).to.not.have.been.called;
+ });
+
+ it('should generate AltGraph for quick Ctrl+Alt sequence', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1, timeStamp: Date.now()}));
+ this.clock.tick(20);
+ kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2, timeStamp: Date.now()}));
+ expect(kbd.onkeyevent).to.have.been.calledOnce;
+ expect(kbd.onkeyevent).to.have.been.calledWith(0xfe03, 'AltRight', true);
+
+ // Check that the timer is properly dead
+ kbd.onkeyevent.reset();
+ this.clock.tick(100);
+ expect(kbd.onkeyevent).to.not.have.been.called;
+ });
+
+ it('should generate Ctrl, Alt for slow Ctrl+Alt sequence', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1, timeStamp: Date.now()}));
+ this.clock.tick(60);
+ kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2, timeStamp: Date.now()}));
+ expect(kbd.onkeyevent).to.have.been.calledTwice;
+ expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
+ expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xffea, "AltRight", true);
+
+ // Check that the timer is properly dead
+ kbd.onkeyevent.reset();
+ this.clock.tick(100);
+ expect(kbd.onkeyevent).to.not.have.been.called;
+ });
+
+ it('should pass through single Alt', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2}));
+ expect(kbd.onkeyevent).to.have.been.calledOnce;
+ expect(kbd.onkeyevent).to.have.been.calledWith(0xffea, 'AltRight', true);
+ });
+
+ it('should pass through single AltGr', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'AltGraph', location: 2}));
+ expect(kbd.onkeyevent).to.have.been.calledOnce;
+ expect(kbd.onkeyevent).to.have.been.calledWith(0xfe03, 'AltRight', true);