]>
git.proxmox.com Git - mirror_xterm.js.git/blob - src/test/test.js
1 var assert
= require('chai').assert
;
2 var expect
= require('chai').expect
;
3 var Terminal
= require('../xterm');
5 describe('xterm.js', function() {
8 beforeEach(function () {
9 xterm
= new Terminal();
10 xterm
.refresh = function(){};
12 syncScrollArea: function(){}
14 xterm
.compositionHelper
= {
15 keydown: function(){ return true; }
17 // Force synchronous writes
18 xterm
.write = function(data
) {
19 xterm
.writeBuffer
.push(data
);
30 describe('getOption', function() {
31 it('should retrieve the option correctly', function() {
32 // In the `options` namespace.
33 xterm
.options
.cursorBlink
= true;
34 assert
.equal(xterm
.getOption('cursorBlink'), true);
36 // On the Terminal instance
37 delete xterm
.options
.cursorBlink
;
38 xterm
.cursorBlink
= false;
39 assert
.equal(xterm
.getOption('cursorBlink'), false);
41 it('should throw when retrieving a non-existant option', function() {
42 assert
.throws(xterm
.getOption
.bind(xterm
, 'fake', true));
46 describe('setOption', function() {
47 it('should set the option correctly', function() {
48 xterm
.setOption('cursorBlink', true);
49 assert
.equal(xterm
.cursorBlink
, true);
50 assert
.equal(xterm
.options
.cursorBlink
, true);
51 xterm
.setOption('cursorBlink', false);
52 assert
.equal(xterm
.cursorBlink
, false);
53 assert
.equal(xterm
.options
.cursorBlink
, false);
55 it('should throw when setting a non-existant option', function() {
56 assert
.throws(xterm
.setOption
.bind(xterm
, 'fake', true));
58 it('should not allow scrollback less than number of rows', function() {
59 let setOptionCall
= xterm
.setOption
.bind(xterm
, 'scrollback', xterm
.rows
- 1);
61 assert
.equal(setOptionCall(), false);
65 describe('clear', function() {
66 it('should clear a buffer equal to rows', function() {
67 var promptLine
= xterm
.lines
.get(xterm
.ybase
+ xterm
.y
);
69 assert
.equal(xterm
.y
, 0);
70 assert
.equal(xterm
.ybase
, 0);
71 assert
.equal(xterm
.ydisp
, 0);
72 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
73 assert
.deepEqual(xterm
.lines
.get(0), promptLine
);
74 for (var i
= 1; i
< xterm
.rows
; i
++) {
75 assert
.deepEqual(xterm
.lines
.get(i
), xterm
.blankLine());
78 it('should clear a buffer larger than rows', function() {
79 // Fill the buffer with dummy rows
80 for (var i
= 0; i
< xterm
.rows
* 2; i
++) {
81 xterm
.write('test\n');
84 var promptLine
= xterm
.lines
.get(xterm
.ybase
+ xterm
.y
);
86 assert
.equal(xterm
.y
, 0);
87 assert
.equal(xterm
.ybase
, 0);
88 assert
.equal(xterm
.ydisp
, 0);
89 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
90 assert
.deepEqual(xterm
.lines
.get(0), promptLine
);
91 for (var i
= 1; i
< xterm
.rows
; i
++) {
92 assert
.deepEqual(xterm
.lines
.get(i
), xterm
.blankLine());
95 it('should not break the prompt when cleared twice', function() {
96 var promptLine
= xterm
.lines
.get(xterm
.ybase
+ xterm
.y
);
99 assert
.equal(xterm
.y
, 0);
100 assert
.equal(xterm
.ybase
, 0);
101 assert
.equal(xterm
.ydisp
, 0);
102 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
103 assert
.deepEqual(xterm
.lines
.get(0), promptLine
);
104 for (var i
= 1; i
< xterm
.rows
; i
++) {
105 assert
.deepEqual(xterm
.lines
.get(i
), xterm
.blankLine());
110 describe('scroll', function() {
111 describe('scrollDisp', function() {
113 beforeEach(function() {
114 for (var i
= 0; i
< xterm
.rows
* 2; i
++) {
115 xterm
.writeln('test');
117 startYDisp
= xterm
.rows
+ 1;
119 it('should scroll a single line', function() {
120 assert
.equal(xterm
.ydisp
, startYDisp
);
121 xterm
.scrollDisp(-1);
122 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
124 assert
.equal(xterm
.ydisp
, startYDisp
);
126 it('should scroll multiple lines', function() {
127 assert
.equal(xterm
.ydisp
, startYDisp
);
128 xterm
.scrollDisp(-5);
129 assert
.equal(xterm
.ydisp
, startYDisp
- 5);
131 assert
.equal(xterm
.ydisp
, startYDisp
);
133 it('should not scroll beyond the bounds of the buffer', function() {
134 assert
.equal(xterm
.ydisp
, startYDisp
);
136 assert
.equal(xterm
.ydisp
, startYDisp
);
137 for (var i
= 0; i
< startYDisp
; i
++) {
138 xterm
.scrollDisp(-1);
140 assert
.equal(xterm
.ydisp
, 0);
141 xterm
.scrollDisp(-1);
142 assert
.equal(xterm
.ydisp
, 0);
146 describe('scrollPages', function() {
148 beforeEach(function() {
149 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
150 xterm
.writeln('test');
152 startYDisp
= (xterm
.rows
* 2) + 1;
154 it('should scroll a single page', function() {
155 assert
.equal(xterm
.ydisp
, startYDisp
);
156 xterm
.scrollPages(-1);
157 assert
.equal(xterm
.ydisp
, startYDisp
- (xterm
.rows
- 1));
158 xterm
.scrollPages(1);
159 assert
.equal(xterm
.ydisp
, startYDisp
);
161 it('should scroll a multiple pages', function() {
162 assert
.equal(xterm
.ydisp
, startYDisp
);
163 xterm
.scrollPages(-2);
164 assert
.equal(xterm
.ydisp
, startYDisp
- (xterm
.rows
- 1) * 2);
165 xterm
.scrollPages(2);
166 assert
.equal(xterm
.ydisp
, startYDisp
);
170 describe('scrollToTop', function() {
171 beforeEach(function() {
172 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
173 xterm
.writeln('test');
176 it('should scroll to the top', function() {
177 assert
.notEqual(xterm
.ydisp
, 0);
179 assert
.equal(xterm
.ydisp
, 0);
183 describe('scrollToBottom', function() {
185 beforeEach(function() {
186 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
187 xterm
.writeln('test');
189 startYDisp
= (xterm
.rows
* 2) + 1;
191 it('should scroll to the bottom', function() {
192 xterm
.scrollDisp(-1);
193 xterm
.scrollToBottom();
194 assert
.equal(xterm
.ydisp
, startYDisp
);
195 xterm
.scrollPages(-1);
196 xterm
.scrollToBottom();
197 assert
.equal(xterm
.ydisp
, startYDisp
);
199 xterm
.scrollToBottom();
200 assert
.equal(xterm
.ydisp
, startYDisp
);
204 describe('keyDown', function () {
205 it('should scroll down, when a key is pressed and terminal is scrolled up', function () {
206 // Override evaluateKeyEscapeSequence to return cancel code
207 xterm
.evaluateKeyEscapeSequence = function() {
213 preventDefault: function(){},
214 stopPropagation: function(){}
219 assert
.notEqual(xterm
.ydisp
, xterm
.ybase
);
220 xterm
.keyDown(event
);
222 // Ensure that now the terminal is scrolled to bottom
223 assert
.equal(xterm
.ydisp
, xterm
.ybase
);
226 it('should not scroll down, when a custom keydown handler prevents the event', function () {
227 // Add some output to the terminal
228 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
229 xterm
.writeln('test');
231 var startYDisp
= (xterm
.rows
* 2) + 1;
232 xterm
.attachCustomKeydownHandler(function () {
236 assert
.equal(xterm
.ydisp
, startYDisp
);
237 xterm
.scrollDisp(-1);
238 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
239 xterm
.keyDown({ keyCode
: 0 });
240 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
245 describe('evaluateKeyEscapeSequence', function() {
246 it('should return the correct escape sequence for unmodified keys', function() {
248 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 8 }).key
, '\x7f'); // ^?
250 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 9 }).key
, '\t');
252 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 13 }).key
, '\r'); // CR
254 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 27 }).key
, '\x1b');
255 // Page up, page down
256 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 33 }).key
, '\x1b[5~'); // CSI 5 ~
257 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 34 }).key
, '\x1b[6~'); // CSI 6 ~
259 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 35 }).key
, '\x1b[F'); // SS3 F
260 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 36 }).key
, '\x1b[H'); // SS3 H
261 // Left, up, right, down arrows
262 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 37 }).key
, '\x1b[D'); // CSI D
263 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 38 }).key
, '\x1b[A'); // CSI A
264 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 39 }).key
, '\x1b[C'); // CSI C
265 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 40 }).key
, '\x1b[B'); // CSI B
267 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 45 }).key
, '\x1b[2~'); // CSI 2 ~
269 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 46 }).key
, '\x1b[3~'); // CSI 3 ~
271 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 112 }).key
, '\x1bOP'); // SS3 P
272 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 113 }).key
, '\x1bOQ'); // SS3 Q
273 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 114 }).key
, '\x1bOR'); // SS3 R
274 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 115 }).key
, '\x1bOS'); // SS3 S
275 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 116 }).key
, '\x1b[15~'); // CSI 1 5 ~
276 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 117 }).key
, '\x1b[17~'); // CSI 1 7 ~
277 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 118 }).key
, '\x1b[18~'); // CSI 1 8 ~
278 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 119 }).key
, '\x1b[19~'); // CSI 1 9 ~
279 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 120 }).key
, '\x1b[20~'); // CSI 2 0 ~
280 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 121 }).key
, '\x1b[21~'); // CSI 2 1 ~
281 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 122 }).key
, '\x1b[23~'); // CSI 2 3 ~
282 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 123 }).key
, '\x1b[24~'); // CSI 2 4 ~
284 it('should return \\x1b[3;5~ for ctrl+delete', function() {
285 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 46 }).key
, '\x1b[3;5~');
287 it('should return \\x1b[3;2~ for shift+delete', function() {
288 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 46 }).key
, '\x1b[3;2~');
290 it('should return \\x1b[3;3~ for alt+delete', function() {
291 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 46 }).key
, '\x1b[3;3~');
293 it('should return \\x1b[5D for ctrl+left', function() {
294 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 37 }).key
, '\x1b[1;5D'); // CSI 5 D
296 it('should return \\x1b[5C for ctrl+right', function() {
297 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 39 }).key
, '\x1b[1;5C'); // CSI 5 C
299 it('should return \\x1b[5A for ctrl+up', function() {
300 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 38 }).key
, '\x1b[1;5A'); // CSI 5 A
302 it('should return \\x1b[5B for ctrl+down', function() {
303 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 40 }).key
, '\x1b[1;5B'); // CSI 5 B
306 describe('On non-macOS platforms', function() {
307 beforeEach(function() {
308 xterm
.browser
.isMac
= false;
310 // Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100
311 // http://unix.stackexchange.com/a/108106
312 it('should return \\x1b[5D for alt+left', function() {
313 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 37 }).key
, '\x1b[1;5D'); // CSI 5 D
315 it('should return \\x1b[5C for alt+right', function() {
316 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 39 }).key
, '\x1b[1;5C'); // CSI 5 C
320 describe('On macOS platforms', function() {
321 beforeEach(function() {
322 xterm
.browser
.isMac
= true;
324 it('should return \\x1bb for alt+left', function() {
325 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 37 }).key
, '\x1bb'); // CSI 5 D
327 it('should return \\x1bf for alt+right', function() {
328 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 39 }).key
, '\x1bf'); // CSI 5 C
332 it('should return \\x1b[5A for alt+up', function() {
333 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 38 }).key
, '\x1b[1;5A'); // CSI 5 A
335 it('should return \\x1b[5B for alt+down', function() {
336 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 40 }).key
, '\x1b[1;5B'); // CSI 5 B
338 it('should return the correct escape sequence for modified F1-F12 keys', function() {
339 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 112 }).key
, '\x1b[1;2P');
340 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 113 }).key
, '\x1b[1;2Q');
341 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 114 }).key
, '\x1b[1;2R');
342 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 115 }).key
, '\x1b[1;2S');
343 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 116 }).key
, '\x1b[15;2~');
344 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 117 }).key
, '\x1b[17;2~');
345 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 118 }).key
, '\x1b[18;2~');
346 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 119 }).key
, '\x1b[19;2~');
347 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 120 }).key
, '\x1b[20;2~');
348 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 121 }).key
, '\x1b[21;2~');
349 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 122 }).key
, '\x1b[23;2~');
350 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 123 }).key
, '\x1b[24;2~');
351 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 112 }).key
, '\x1b[1;3P');
352 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 113 }).key
, '\x1b[1;3Q');
353 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 114 }).key
, '\x1b[1;3R');
354 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 115 }).key
, '\x1b[1;3S');
355 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 116 }).key
, '\x1b[15;3~');
356 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 117 }).key
, '\x1b[17;3~');
357 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 118 }).key
, '\x1b[18;3~');
358 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 119 }).key
, '\x1b[19;3~');
359 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 120 }).key
, '\x1b[20;3~');
360 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 121 }).key
, '\x1b[21;3~');
361 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 122 }).key
, '\x1b[23;3~');
362 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 123 }).key
, '\x1b[24;3~');
364 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 112 }).key
, '\x1b[1;5P');
365 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 113 }).key
, '\x1b[1;5Q');
366 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 114 }).key
, '\x1b[1;5R');
367 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 115 }).key
, '\x1b[1;5S');
368 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 116 }).key
, '\x1b[15;5~');
369 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 117 }).key
, '\x1b[17;5~');
370 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 118 }).key
, '\x1b[18;5~');
371 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 119 }).key
, '\x1b[19;5~');
372 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 120 }).key
, '\x1b[20;5~');
373 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 121 }).key
, '\x1b[21;5~');
374 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 122 }).key
, '\x1b[23;5~');
375 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 123 }).key
, '\x1b[24;5~');
379 describe('attachCustomKeyEventHandler', function () {
381 preventDefault: function() {},
382 stopPropagation: function() {},
386 preventDefault: function() {},
387 stopPropagation: function() {},
391 beforeEach(function() {
392 xterm
.handler = function() {};
393 xterm
.showCursor = function() {};
394 xterm
.clearSelection = function() {};
395 xterm
.compositionHelper
= {
398 return function () { return true; }
403 return function () { return true; }
409 it('should process the keydown/keypress event based on what the handler returns', function () {
410 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), true);
411 assert
.equal(xterm
.keyPress(Object
.assign({}, evKeyPress
, { keyCode
: 77 })), true);
412 xterm
.attachCustomKeyEventHandler(function (ev
) {
413 return ev
.keyCode
=== 77;
415 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), true);
416 assert
.equal(xterm
.keyPress(Object
.assign({}, evKeyPress
, { keyCode
: 77 })), true);
417 xterm
.attachCustomKeyEventHandler(function (ev
) {
418 return ev
.keyCode
!== 77;
420 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
421 assert
.equal(xterm
.keyPress(Object
.assign({}, evKeyPress
, { keyCode
: 77 })), false);
424 it('should alive after reset(ESC c Full Reset (RIS))', function () {
425 xterm
.attachCustomKeyEventHandler(function (ev
) {
426 return ev
.keyCode
!== 77;
428 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
429 assert
.equal(xterm
.keyPress(Object
.assign({}, evKeyPress
, { keyCode
: 77 })), false);
431 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
432 assert
.equal(xterm
.keyPress(Object
.assign({}, evKeyPress
, { keyCode
: 77 })), false);
436 describe('Third level shift', function() {
438 preventDefault: function() {},
439 stopPropagation: function() {},
443 preventDefault: function() {},
444 stopPropagation: function() {},
448 beforeEach(function() {
449 xterm
.handler = function() {};
450 xterm
.showCursor = function() {};
451 xterm
.clearSelection = function() {};
452 xterm
.compositionHelper
= {
456 return function() { return true; };
462 describe('On Mac OS', function() {
463 beforeEach(function() {
464 xterm
.browser
.isMac
= true;
467 it('should not interfere with the alt key on keyDown', function() {
469 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 81 })),
473 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 192 })),
478 it('should interefere with the alt + arrow keys', function() {
480 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 37 })),
484 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 39 })),
489 it('should emit key with alt + key on keyPress', function(done
) {
490 var keys
= ['@', '@', '\\', '\\', '|', '|'];
492 xterm
.on('keypress', function(key
) {
494 var index
= keys
.indexOf(key
);
495 assert(index
!== -1, "Emitted wrong key: " + key
);
496 keys
.splice(index
, 1);
498 if (keys
.length
=== 0) done();
501 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 64 })); // @
503 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 64, keyCode
: 0 }));
504 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 92 })); // \
505 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 92, keyCode
: 0 }));
506 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 124 })); // |
507 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 124, keyCode
: 0 }));
511 describe('On MS Windows', function() {
512 beforeEach(function() {
513 xterm
.browser
.isMSWindows
= true;
516 it('should not interfere with the alt + ctrl key on keyDown', function() {
518 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 81 })),
522 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 192 })),
527 it('should interefere with the alt + ctrl + arrow keys', function() {
529 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 37 })),
533 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 39 })),
538 it('should emit key with alt + ctrl + key on keyPress', function(done
) {
539 var keys
= ['@', '@', '\\', '\\', '|', '|'];
541 xterm
.on('keypress', function(key
) {
543 var index
= keys
.indexOf(key
);
544 assert(index
!== -1, "Emitted wrong key: " + key
);
545 keys
.splice(index
, 1);
547 if (keys
.length
=== 0) done();
551 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 64 })
554 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 64, keyCode
: 0 })
557 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 92 })
560 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 92, keyCode
: 0 })
563 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 124 })
566 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 124, keyCode
: 0 })
572 describe('unicode - surrogates', function() {
573 it('2 characters per cell', function () {
574 this.timeout(10000); // This is needed because istanbul patches code and slows it down
575 var high
= String
.fromCharCode(0xD800);
576 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
577 xterm
.write(high
+ String
.fromCharCode(i
));
578 var tchar
= xterm
.lines
.get(0)[0];
579 expect(tchar
[1]).eql(high
+ String
.fromCharCode(i
));
580 expect(tchar
[1].length
).eql(2);
581 expect(tchar
[2]).eql(1);
582 expect(xterm
.lines
.get(0)[1][1]).eql(' ');
586 it('2 characters at last cell', function() {
587 var high
= String
.fromCharCode(0xD800);
588 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
589 xterm
.x
= xterm
.cols
- 1;
590 xterm
.write(high
+ String
.fromCharCode(i
));
591 expect(xterm
.lines
.get(0)[xterm
.x
-1][1]).eql(high
+ String
.fromCharCode(i
));
592 expect(xterm
.lines
.get(0)[xterm
.x
-1][1].length
).eql(2);
593 expect(xterm
.lines
.get(1)[0][1]).eql(' ');
597 it('2 characters per cell over line end with autowrap', function() {
598 var high
= String
.fromCharCode(0xD800);
599 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
600 xterm
.x
= xterm
.cols
- 1;
601 xterm
.wraparoundMode
= true;
602 xterm
.write('a' + high
+ String
.fromCharCode(i
));
603 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1]).eql('a');
604 expect(xterm
.lines
.get(1)[0][1]).eql(high
+ String
.fromCharCode(i
));
605 expect(xterm
.lines
.get(1)[0][1].length
).eql(2);
606 expect(xterm
.lines
.get(1)[1][1]).eql(' ');
610 it('2 characters per cell over line end without autowrap', function() {
611 var high
= String
.fromCharCode(0xD800);
612 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
613 xterm
.x
= xterm
.cols
- 1;
614 xterm
.wraparoundMode
= false;
615 xterm
.write('a' + high
+ String
.fromCharCode(i
));
616 // auto wraparound mode should cut off the rest of the line
617 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1]).eql('a');
618 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1].length
).eql(1);
619 expect(xterm
.lines
.get(1)[1][1]).eql(' ');
623 it('splitted surrogates', function() {
624 var high
= String
.fromCharCode(0xD800);
625 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
627 xterm
.write(String
.fromCharCode(i
));
628 var tchar
= xterm
.lines
.get(0)[0];
629 expect(tchar
[1]).eql(high
+ String
.fromCharCode(i
));
630 expect(tchar
[1].length
).eql(2);
631 expect(tchar
[2]).eql(1);
632 expect(xterm
.lines
.get(0)[1][1]).eql(' ');
638 describe('unicode - combining characters', function() {
639 it('café', function () {
640 xterm
.write('cafe\u0301');
641 expect(xterm
.lines
.get(0)[3][1]).eql('e\u0301');
642 expect(xterm
.lines
.get(0)[3][1].length
).eql(2);
643 expect(xterm
.lines
.get(0)[3][2]).eql(1);
645 it('café - end of line', function() {
646 xterm
.x
= xterm
.cols
- 1 - 3;
647 xterm
.write('cafe\u0301');
648 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1]).eql('e\u0301');
649 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1].length
).eql(2);
650 expect(xterm
.lines
.get(0)[xterm
.cols
-1][2]).eql(1);
651 expect(xterm
.lines
.get(0)[1][1]).eql(' ');
652 expect(xterm
.lines
.get(0)[1][1].length
).eql(1);
653 expect(xterm
.lines
.get(0)[1][2]).eql(1);
655 it('multiple combined é', function() {
656 xterm
.wraparoundMode
= true;
657 xterm
.write(Array(100).join('e\u0301'));
658 for (var i
=0; i
<xterm
.cols
; ++i
) {
659 var tchar
= xterm
.lines
.get(0)[i
];
660 expect(tchar
[1]).eql('e\u0301');
661 expect(tchar
[1].length
).eql(2);
662 expect(tchar
[2]).eql(1);
664 tchar
= xterm
.lines
.get(1)[0];
665 expect(tchar
[1]).eql('e\u0301');
666 expect(tchar
[1].length
).eql(2);
667 expect(tchar
[2]).eql(1);
669 it('multiple surrogate with combined', function() {
670 xterm
.wraparoundMode
= true;
671 xterm
.write(Array(100).join('\uD800\uDC00\u0301'));
672 for (var i
=0; i
<xterm
.cols
; ++i
) {
673 var tchar
= xterm
.lines
.get(0)[i
];
674 expect(tchar
[1]).eql('\uD800\uDC00\u0301');
675 expect(tchar
[1].length
).eql(3);
676 expect(tchar
[2]).eql(1);
678 tchar
= xterm
.lines
.get(1)[0];
679 expect(tchar
[1]).eql('\uD800\uDC00\u0301');
680 expect(tchar
[1].length
).eql(3);
681 expect(tchar
[2]).eql(1);
685 describe('unicode - fullwidth characters', function() {
686 it('cursor movement even', function() {
687 expect(xterm
.x
).eql(0);
689 expect(xterm
.x
).eql(2);
691 it('cursor movement odd', function() {
693 expect(xterm
.x
).eql(1);
695 expect(xterm
.x
).eql(3);
697 it('line of ¥ even', function() {
698 xterm
.wraparoundMode
= true;
699 xterm
.write(Array(50).join('¥'));
700 for (var i
=0; i
<xterm
.cols
; ++i
) {
701 var tchar
= xterm
.lines
.get(0)[i
];
703 expect(tchar
[1]).eql('');
704 expect(tchar
[1].length
).eql(0);
705 expect(tchar
[2]).eql(0);
707 expect(tchar
[1]).eql('¥');
708 expect(tchar
[1].length
).eql(1);
709 expect(tchar
[2]).eql(2);
712 tchar
= xterm
.lines
.get(1)[0];
713 expect(tchar
[1]).eql('¥');
714 expect(tchar
[1].length
).eql(1);
715 expect(tchar
[2]).eql(2);
717 it('line of ¥ odd', function() {
718 xterm
.wraparoundMode
= true;
720 xterm
.write(Array(50).join('¥'));
721 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
722 var tchar
= xterm
.lines
.get(0)[i
];
724 expect(tchar
[1]).eql('');
725 expect(tchar
[1].length
).eql(0);
726 expect(tchar
[2]).eql(0);
728 expect(tchar
[1]).eql('¥');
729 expect(tchar
[1].length
).eql(1);
730 expect(tchar
[2]).eql(2);
733 tchar
= xterm
.lines
.get(0)[xterm
.cols
-1];
734 expect(tchar
[1]).eql(' ');
735 expect(tchar
[1].length
).eql(1);
736 expect(tchar
[2]).eql(1);
737 tchar
= xterm
.lines
.get(1)[0];
738 expect(tchar
[1]).eql('¥');
739 expect(tchar
[1].length
).eql(1);
740 expect(tchar
[2]).eql(2);
742 it('line of ¥ with combining odd', function() {
743 xterm
.wraparoundMode
= true;
745 xterm
.write(Array(50).join('¥\u0301'));
746 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
747 var tchar
= xterm
.lines
.get(0)[i
];
749 expect(tchar
[1]).eql('');
750 expect(tchar
[1].length
).eql(0);
751 expect(tchar
[2]).eql(0);
753 expect(tchar
[1]).eql('¥\u0301');
754 expect(tchar
[1].length
).eql(2);
755 expect(tchar
[2]).eql(2);
758 tchar
= xterm
.lines
.get(0)[xterm
.cols
-1];
759 expect(tchar
[1]).eql(' ');
760 expect(tchar
[1].length
).eql(1);
761 expect(tchar
[2]).eql(1);
762 tchar
= xterm
.lines
.get(1)[0];
763 expect(tchar
[1]).eql('¥\u0301');
764 expect(tchar
[1].length
).eql(2);
765 expect(tchar
[2]).eql(2);
767 it('line of ¥ with combining even', function() {
768 xterm
.wraparoundMode
= true;
769 xterm
.write(Array(50).join('¥\u0301'));
770 for (var i
=0; i
<xterm
.cols
; ++i
) {
771 var tchar
= xterm
.lines
.get(0)[i
];
773 expect(tchar
[1]).eql('');
774 expect(tchar
[1].length
).eql(0);
775 expect(tchar
[2]).eql(0);
777 expect(tchar
[1]).eql('¥\u0301');
778 expect(tchar
[1].length
).eql(2);
779 expect(tchar
[2]).eql(2);
782 tchar
= xterm
.lines
.get(1)[0];
783 expect(tchar
[1]).eql('¥\u0301');
784 expect(tchar
[1].length
).eql(2);
785 expect(tchar
[2]).eql(2);
787 it('line of surrogate fullwidth with combining odd', function() {
788 xterm
.wraparoundMode
= true;
790 xterm
.write(Array(50).join('\ud843\ude6d\u0301'));
791 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
792 var tchar
= xterm
.lines
.get(0)[i
];
794 expect(tchar
[1]).eql('');
795 expect(tchar
[1].length
).eql(0);
796 expect(tchar
[2]).eql(0);
798 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
799 expect(tchar
[1].length
).eql(3);
800 expect(tchar
[2]).eql(2);
803 tchar
= xterm
.lines
.get(0)[xterm
.cols
-1];
804 expect(tchar
[1]).eql(' ');
805 expect(tchar
[1].length
).eql(1);
806 expect(tchar
[2]).eql(1);
807 tchar
= xterm
.lines
.get(1)[0];
808 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
809 expect(tchar
[1].length
).eql(3);
810 expect(tchar
[2]).eql(2);
812 it('line of surrogate fullwidth with combining even', function() {
813 xterm
.wraparoundMode
= true;
814 xterm
.write(Array(50).join('\ud843\ude6d\u0301'));
815 for (var i
=0; i
<xterm
.cols
; ++i
) {
816 var tchar
= xterm
.lines
.get(0)[i
];
818 expect(tchar
[1]).eql('');
819 expect(tchar
[1].length
).eql(0);
820 expect(tchar
[2]).eql(0);
822 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
823 expect(tchar
[1].length
).eql(3);
824 expect(tchar
[2]).eql(2);
827 tchar
= xterm
.lines
.get(1)[0];
828 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
829 expect(tchar
[1].length
).eql(3);
830 expect(tchar
[2]).eql(2);
834 describe('insert mode', function() {
835 it('halfwidth - all', function () {
836 xterm
.write(Array(9).join('0123456789').slice(-80));
839 xterm
.insertMode
= true;
840 xterm
.write('abcde');
841 expect(xterm
.lines
.get(0).length
).eql(xterm
.cols
);
842 expect(xterm
.lines
.get(0)[10][1]).eql('a');
843 expect(xterm
.lines
.get(0)[14][1]).eql('e');
844 expect(xterm
.lines
.get(0)[15][1]).eql('0');
845 expect(xterm
.lines
.get(0)[79][1]).eql('4');
847 it('fullwidth - insert', function() {
848 xterm
.write(Array(9).join('0123456789').slice(-80));
851 xterm
.insertMode
= true;
853 expect(xterm
.lines
.get(0).length
).eql(xterm
.cols
);
854 expect(xterm
.lines
.get(0)[10][1]).eql('¥');
855 expect(xterm
.lines
.get(0)[11][1]).eql('');
856 expect(xterm
.lines
.get(0)[14][1]).eql('¥');
857 expect(xterm
.lines
.get(0)[15][1]).eql('');
858 expect(xterm
.lines
.get(0)[79][1]).eql('3');
860 it('fullwidth - right border', function() {
861 xterm
.write(Array(41).join('¥'));
864 xterm
.insertMode
= true;
866 expect(xterm
.lines
.get(0).length
).eql(xterm
.cols
);
867 expect(xterm
.lines
.get(0)[10][1]).eql('a');
868 expect(xterm
.lines
.get(0)[11][1]).eql('¥');
869 expect(xterm
.lines
.get(0)[79][1]).eql(' '); // fullwidth char got replaced
871 expect(xterm
.lines
.get(0).length
).eql(xterm
.cols
);
872 expect(xterm
.lines
.get(0)[11][1]).eql('b');
873 expect(xterm
.lines
.get(0)[12][1]).eql('¥');
874 expect(xterm
.lines
.get(0)[79][1]).eql(''); // empty cell after fullwidth