Skip to content

Commit 16b5da5

Browse files
committed
Fix assertion, bring back triggerMouseEvent tests
1 parent 4812abb commit 16b5da5

File tree

2 files changed

+214
-1
lines changed

2 files changed

+214
-1
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/**
2+
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
3+
* @license MIT
4+
*/
5+
import { assert } from 'chai';
6+
import { MouseService } from 'browser/services/MouseService';
7+
import { MouseStateService } from 'common/services/MouseStateService';
8+
import { CoreMouseAction, CoreMouseButton } from 'common/Types';
9+
import { IBufferService, ICoreService, ILogService, IOptionsService } from 'common/services/Services';
10+
import { MockCoreBrowserService, MockRenderService, MockSelectionService } from 'browser/TestUtils.test';
11+
12+
function toBytes(s: string | undefined): number[] {
13+
if (!s) {
14+
return [];
15+
}
16+
const res: number[] = [];
17+
for (let i = 0; i < s.length; ++i) {
18+
res.push(s.charCodeAt(i));
19+
}
20+
return res;
21+
}
22+
23+
// Minimal mocks for deps that MouseService touches in these tests
24+
const bufferService: IBufferService = {
25+
buffer: { hasScrollback: true } as any,
26+
cols: 500,
27+
rows: 500
28+
} as any;
29+
30+
const optionsService: IOptionsService = {
31+
rawOptions: {
32+
logLevel: 'info',
33+
fastScrollSensitivity: 1,
34+
scrollSensitivity: 1
35+
}
36+
} as any;
37+
38+
const logService: ILogService = {
39+
debug: () => {},
40+
info: () => {},
41+
warn: () => {},
42+
error: () => {}
43+
} as any;
44+
45+
describe('MouseService _triggerMouseEvent', () => {
46+
let mouseService: MouseService;
47+
let mouseStateService: MouseStateService;
48+
let coreService: ICoreService;
49+
let reports: string[];
50+
51+
beforeEach(() => {
52+
reports = [];
53+
mouseStateService = new MouseStateService();
54+
coreService = {
55+
triggerDataEvent: (data: string) => reports.push(data),
56+
triggerBinaryEvent: (data: string) => reports.push(data),
57+
decPrivateModes: { applicationCursorKeys: false }
58+
} as any;
59+
60+
mouseService = new MouseService(
61+
new MockRenderService(),
62+
{
63+
getMouseReportCoords: (_ev: MouseEvent, _el: HTMLElement) => ({ col: 0, row: 0, x: 0, y: 0 })
64+
} as any,
65+
mouseStateService,
66+
coreService,
67+
bufferService,
68+
optionsService,
69+
new MockSelectionService(),
70+
logService,
71+
new MockCoreBrowserService()
72+
);
73+
});
74+
75+
function trigger(e: Parameters<any>[0]): boolean {
76+
return (mouseService as any)._triggerMouseEvent(e);
77+
}
78+
79+
it('NONE', () => {
80+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
81+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), false);
82+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), false);
83+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), false);
84+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), false);
85+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), false);
86+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE }), false);
87+
});
88+
89+
it('X10', () => {
90+
mouseStateService.activeProtocol = 'X10';
91+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
92+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), false);
93+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), false);
94+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), true);
95+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), true);
96+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), false);
97+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE }), false);
98+
});
99+
100+
it('VT200', () => {
101+
mouseStateService.activeProtocol = 'VT200';
102+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
103+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), true);
104+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), false);
105+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), true);
106+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), true);
107+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), true);
108+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE }), false);
109+
});
110+
111+
it('DRAG', () => {
112+
mouseStateService.activeProtocol = 'DRAG';
113+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
114+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), true);
115+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), true);
116+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), true);
117+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), true);
118+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), true);
119+
});
120+
121+
it('ANY', () => {
122+
mouseStateService.activeProtocol = 'ANY';
123+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
124+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), true);
125+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), true);
126+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), true);
127+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), true);
128+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), true);
129+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE }), true);
130+
// should not report in any case
131+
// invalid button + action combinations
132+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.MOVE }), false);
133+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.DOWN }), false);
134+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.UP }), false);
135+
// invalid coords
136+
assert.equal(trigger({ col: -1, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
137+
assert.equal(trigger({ col: 500, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
138+
assert.equal(trigger({ col: 0, row: -1, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
139+
assert.equal(trigger({ col: 0, row: 500, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
140+
});
141+
142+
describe('coords', () => {
143+
it('DEFAULT encoding', () => {
144+
mouseStateService.activeProtocol = 'ANY';
145+
for (let i = 0; i < bufferService.cols; ++i) {
146+
assert.equal(trigger({ col: i, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
147+
if (i > 222) {
148+
// supress mouse reports if we are out of addressible range (max. 222)
149+
assert.deepEqual(toBytes(reports.pop()), []);
150+
} else {
151+
assert.deepEqual(toBytes(reports.pop()), [0x1b, 0x5b, 0x4d, 0x20, i + 33, 0x21]);
152+
}
153+
}
154+
});
155+
156+
it('SGR encoding', () => {
157+
mouseStateService.activeProtocol = 'ANY';
158+
mouseStateService.activeEncoding = 'SGR';
159+
for (let i = 0; i < bufferService.cols; ++i) {
160+
assert.equal(trigger({ col: i, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
161+
assert.deepEqual(reports.pop(), `\x1b[<0;${i + 1};1M`);
162+
}
163+
});
164+
165+
it('SGR_PIXELS encoding', () => {
166+
mouseStateService.activeProtocol = 'ANY';
167+
mouseStateService.activeEncoding = 'SGR_PIXELS';
168+
for (let i = 0; i < 500; ++i) {
169+
assert.equal(trigger({ col: 0, row: 0, x: i, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
170+
assert.deepEqual(reports.pop(), `\x1b[<0;${i};0M`);
171+
}
172+
});
173+
});
174+
175+
it('eventCodes with modifiers (DEFAULT encoding)', () => {
176+
// TODO: implement AUX button tests
177+
mouseStateService.activeProtocol = 'ANY';
178+
mouseStateService.activeEncoding = 'DEFAULT';
179+
// all buttons + down + no modifer
180+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN, ctrl: false, alt: false, shift: false }), true);
181+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN, ctrl: false, alt: false, shift: false }), true);
182+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN, ctrl: false, alt: false, shift: false }), true);
183+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.DOWN, ctrl: false, alt: false, shift: false }), true);
184+
assert.deepEqual(reports, ['\x1b[M !!', '\x1b[M!!!', '\x1b[M"!!', '\x1b[Ma!!']);
185+
reports = [];
186+
187+
// all buttons + up + no modifier
188+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP, ctrl: false, alt: false, shift: false }), true);
189+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.UP, ctrl: false, alt: false, shift: false }), true);
190+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.UP, ctrl: false, alt: false, shift: false }), true);
191+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP, ctrl: false, alt: false, shift: false }), true);
192+
assert.deepEqual(reports, ['\x1b[M#!!', '\x1b[M#!!', '\x1b[M#!!', '\x1b[M`!!']);
193+
reports = [];
194+
195+
// all buttons + move + no modifier
196+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: false }), true);
197+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: false }), true);
198+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: false }), true);
199+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: false }), true);
200+
assert.deepEqual(reports, ['\x1b[M@!!', '\x1b[MA!!', '\x1b[MB!!', '\x1b[MC!!']);
201+
reports = [];
202+
203+
// button none + move + modifiers
204+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: true, alt: false, shift: false }), true);
205+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: false, alt: true, shift: false }), true);
206+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: true }), true);
207+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: true, alt: true, shift: false }), true);
208+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: false, alt: true, shift: true }), true);
209+
assert.equal(trigger({ col: 0, row: 0, x: 0, y: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: true, alt: true, shift: true }), true);
210+
assert.deepEqual(reports, ['\x1b[MS!!', '\x1b[MK!!', '\x1b[MG!!', '\x1b[M[!!', '\x1b[MO!!', '\x1b[M_!!']);
211+
reports = [];
212+
});
213+
});

src/common/services/MouseStateService.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,6 @@ describe('MouseStateService', () => {
8383
cms.activeProtocol = 'ANY';
8484
cms.activeEncoding = 'DEFAULT';
8585
assert.equal(cms.restrictMouseEvent(event), true);
86-
assert.deepEqual(toBytes(cms.encodeMouseEvent(event)), [0x1b, 0x5b, 0x4d, 0x21, 0x21, 0x21]);
86+
assert.deepEqual(toBytes(cms.encodeMouseEvent(event)), [0x1b, 0x5b, 0x4d, 0x20, 0x21, 0x21]);
8787
});
8888
});

0 commit comments

Comments
 (0)