]>
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 refreshes
18 xterm
.queueRefresh = function(start
, end
) {
19 xterm
.refresh(start
, end
);
21 // Force synchronous writes
22 xterm
.write = function(data
) {
23 xterm
.writeBuffer
.push(data
);
28 describe('getOption', function() {
29 it('should retrieve the option correctly', function() {
30 // In the `options` namespace.
31 xterm
.options
.cursorBlink
= true;
32 assert
.equal(xterm
.getOption('cursorBlink'), true);
34 // On the Terminal instance
35 delete xterm
.options
.cursorBlink
;
36 xterm
.cursorBlink
= false;
37 assert
.equal(xterm
.getOption('cursorBlink'), false);
39 it('should throw when retrieving a non-existant option', function() {
40 assert
.throws(xterm
.getOption
.bind(xterm
, 'fake', true));
44 describe('setOption', function() {
45 it('should set the option correctly', function() {
46 xterm
.setOption('cursorBlink', true);
47 assert
.equal(xterm
.cursorBlink
, true);
48 assert
.equal(xterm
.options
.cursorBlink
, true);
49 xterm
.setOption('cursorBlink', false);
50 assert
.equal(xterm
.cursorBlink
, false);
51 assert
.equal(xterm
.options
.cursorBlink
, false);
53 it('should throw when setting a non-existant option', function() {
54 assert
.throws(xterm
.setOption
.bind(xterm
, 'fake', true));
58 describe('clear', function() {
59 it('should clear a buffer equal to rows', function() {
60 var promptLine
= xterm
.lines
.get(xterm
.ybase
+ xterm
.y
);
62 assert
.equal(xterm
.y
, 0);
63 assert
.equal(xterm
.ybase
, 0);
64 assert
.equal(xterm
.ydisp
, 0);
65 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
66 assert
.deepEqual(xterm
.lines
.get(0), promptLine
);
67 for (var i
= 1; i
< xterm
.rows
; i
++) {
68 assert
.deepEqual(xterm
.lines
.get(i
), xterm
.blankLine());
71 it('should clear a buffer larger than rows', function() {
72 // Fill the buffer with dummy rows
73 for (var i
= 0; i
< xterm
.rows
* 2; i
++) {
74 xterm
.write('test\n');
77 var promptLine
= xterm
.lines
.get(xterm
.ybase
+ xterm
.y
);
79 assert
.equal(xterm
.y
, 0);
80 assert
.equal(xterm
.ybase
, 0);
81 assert
.equal(xterm
.ydisp
, 0);
82 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
83 assert
.deepEqual(xterm
.lines
.get(0), promptLine
);
84 for (var i
= 1; i
< xterm
.rows
; i
++) {
85 assert
.deepEqual(xterm
.lines
.get(i
), xterm
.blankLine());
88 it('should not break the prompt when cleared twice', function() {
89 var promptLine
= xterm
.lines
.get(xterm
.ybase
+ xterm
.y
);
92 assert
.equal(xterm
.y
, 0);
93 assert
.equal(xterm
.ybase
, 0);
94 assert
.equal(xterm
.ydisp
, 0);
95 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
96 assert
.deepEqual(xterm
.lines
.get(0), promptLine
);
97 for (var i
= 1; i
< xterm
.rows
; i
++) {
98 assert
.deepEqual(xterm
.lines
.get(i
), xterm
.blankLine());
103 describe('scroll', function() {
104 describe('scrollDisp', function() {
106 beforeEach(function() {
107 for (var i
= 0; i
< xterm
.rows
* 2; i
++) {
108 xterm
.writeln('test');
110 startYDisp
= xterm
.rows
+ 1;
112 it('should scroll a single line', function() {
113 assert
.equal(xterm
.ydisp
, startYDisp
);
114 xterm
.scrollDisp(-1);
115 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
117 assert
.equal(xterm
.ydisp
, startYDisp
);
119 it('should scroll multiple lines', function() {
120 assert
.equal(xterm
.ydisp
, startYDisp
);
121 xterm
.scrollDisp(-5);
122 assert
.equal(xterm
.ydisp
, startYDisp
- 5);
124 assert
.equal(xterm
.ydisp
, startYDisp
);
126 it('should not scroll beyond the bounds of the buffer', function() {
127 assert
.equal(xterm
.ydisp
, startYDisp
);
129 assert
.equal(xterm
.ydisp
, startYDisp
);
130 for (var i
= 0; i
< startYDisp
; i
++) {
131 xterm
.scrollDisp(-1);
133 assert
.equal(xterm
.ydisp
, 0);
134 xterm
.scrollDisp(-1);
135 assert
.equal(xterm
.ydisp
, 0);
139 describe('scrollPages', function() {
141 beforeEach(function() {
142 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
143 xterm
.writeln('test');
145 startYDisp
= (xterm
.rows
* 2) + 1;
147 it('should scroll a single page', function() {
148 assert
.equal(xterm
.ydisp
, startYDisp
);
149 xterm
.scrollPages(-1);
150 assert
.equal(xterm
.ydisp
, startYDisp
- (xterm
.rows
- 1));
151 xterm
.scrollPages(1);
152 assert
.equal(xterm
.ydisp
, startYDisp
);
154 it('should scroll a multiple pages', function() {
155 assert
.equal(xterm
.ydisp
, startYDisp
);
156 xterm
.scrollPages(-2);
157 assert
.equal(xterm
.ydisp
, startYDisp
- (xterm
.rows
- 1) * 2);
158 xterm
.scrollPages(2);
159 assert
.equal(xterm
.ydisp
, startYDisp
);
163 describe('scrollToTop', function() {
164 beforeEach(function() {
165 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
166 xterm
.writeln('test');
169 it('should scroll to the top', function() {
170 assert
.notEqual(xterm
.ydisp
, 0);
172 assert
.equal(xterm
.ydisp
, 0);
176 describe('scrollToBottom', function() {
178 beforeEach(function() {
179 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
180 xterm
.writeln('test');
182 startYDisp
= (xterm
.rows
* 2) + 1;
184 it('should scroll to the bottom', function() {
185 xterm
.scrollDisp(-1);
186 xterm
.scrollToBottom();
187 assert
.equal(xterm
.ydisp
, startYDisp
);
188 xterm
.scrollPages(-1);
189 xterm
.scrollToBottom();
190 assert
.equal(xterm
.ydisp
, startYDisp
);
192 xterm
.scrollToBottom();
193 assert
.equal(xterm
.ydisp
, startYDisp
);
197 describe('keyDown', function () {
198 it('should scroll down, when a key is pressed and terminal is scrolled up', function () {
199 // Override evaluateKeyEscapeSequence to return cancel code
200 xterm
.evaluateKeyEscapeSequence = function() {
206 preventDefault: function(){},
207 stopPropagation: function(){}
212 assert
.notEqual(xterm
.ydisp
, xterm
.ybase
);
213 xterm
.keyDown(event
);
215 // Ensure that now the terminal is scrolled to bottom
216 assert
.equal(xterm
.ydisp
, xterm
.ybase
);
219 it('should not scroll down, when a custom keydown handler prevents the event', function () {
220 // Add some output to the terminal
221 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
222 xterm
.writeln('test');
224 var startYDisp
= (xterm
.rows
* 2) + 1;
225 xterm
.attachCustomKeydownHandler(function () {
229 assert
.equal(xterm
.ydisp
, startYDisp
);
230 xterm
.scrollDisp(-1);
231 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
232 xterm
.keyDown({ keyCode
: 0 });
233 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
238 describe('evaluateKeyEscapeSequence', function() {
239 it('should return the correct escape sequence for unmodified keys', function() {
241 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 8 }).key
, '\x7f'); // ^?
243 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 9 }).key
, '\t');
245 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 13 }).key
, '\r'); // CR
247 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 27 }).key
, '\x1b');
248 // Page up, page down
249 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 33 }).key
, '\x1b[5~'); // CSI 5 ~
250 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 34 }).key
, '\x1b[6~'); // CSI 6 ~
252 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 35 }).key
, '\x1b[F'); // SS3 F
253 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 36 }).key
, '\x1b[H'); // SS3 H
254 // Left, up, right, down arrows
255 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 37 }).key
, '\x1b[D'); // CSI D
256 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 38 }).key
, '\x1b[A'); // CSI A
257 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 39 }).key
, '\x1b[C'); // CSI C
258 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 40 }).key
, '\x1b[B'); // CSI B
260 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 45 }).key
, '\x1b[2~'); // CSI 2 ~
262 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 46 }).key
, '\x1b[3~'); // CSI 3 ~
264 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 112 }).key
, '\x1bOP'); // SS3 P
265 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 113 }).key
, '\x1bOQ'); // SS3 Q
266 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 114 }).key
, '\x1bOR'); // SS3 R
267 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 115 }).key
, '\x1bOS'); // SS3 S
268 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 116 }).key
, '\x1b[15~'); // CSI 1 5 ~
269 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 117 }).key
, '\x1b[17~'); // CSI 1 7 ~
270 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 118 }).key
, '\x1b[18~'); // CSI 1 8 ~
271 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 119 }).key
, '\x1b[19~'); // CSI 1 9 ~
272 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 120 }).key
, '\x1b[20~'); // CSI 2 0 ~
273 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 121 }).key
, '\x1b[21~'); // CSI 2 1 ~
274 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 122 }).key
, '\x1b[23~'); // CSI 2 3 ~
275 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 123 }).key
, '\x1b[24~'); // CSI 2 4 ~
277 it('should return \\x1b[3;5~ for ctrl+delete', function() {
278 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 46 }).key
, '\x1b[3;5~');
280 it('should return \\x1b[3;2~ for shift+delete', function() {
281 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 46 }).key
, '\x1b[3;2~');
283 it('should return \\x1b[3;3~ for alt+delete', function() {
284 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 46 }).key
, '\x1b[3;3~');
286 it('should return \\x1b[5D for ctrl+left', function() {
287 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 37 }).key
, '\x1b[1;5D'); // CSI 5 D
289 it('should return \\x1b[5C for ctrl+right', function() {
290 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 39 }).key
, '\x1b[1;5C'); // CSI 5 C
292 it('should return \\x1b[5A for ctrl+up', function() {
293 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 38 }).key
, '\x1b[1;5A'); // CSI 5 A
295 it('should return \\x1b[5B for ctrl+down', function() {
296 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 40 }).key
, '\x1b[1;5B'); // CSI 5 B
299 describe('On non-macOS platforms', function() {
300 beforeEach(function() {
301 xterm
.browser
.isMac
= false;
303 // Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100
304 // http://unix.stackexchange.com/a/108106
305 it('should return \\x1b[5D for alt+left', function() {
306 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 37 }).key
, '\x1b[1;5D'); // CSI 5 D
308 it('should return \\x1b[5C for alt+right', function() {
309 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 39 }).key
, '\x1b[1;5C'); // CSI 5 C
313 describe('On macOS platforms', function() {
314 beforeEach(function() {
315 xterm
.browser
.isMac
= true;
317 it('should return \\x1bb for alt+left', function() {
318 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 37 }).key
, '\x1bb'); // CSI 5 D
320 it('should return \\x1bf for alt+right', function() {
321 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 39 }).key
, '\x1bf'); // CSI 5 C
325 it('should return \\x1b[5A for alt+up', function() {
326 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 38 }).key
, '\x1b[1;5A'); // CSI 5 A
328 it('should return \\x1b[5B for alt+down', function() {
329 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 40 }).key
, '\x1b[1;5B'); // CSI 5 B
331 it('should return the correct escape sequence for modified F1-F12 keys', function() {
332 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 112 }).key
, '\x1b[1;2P');
333 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 113 }).key
, '\x1b[1;2Q');
334 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 114 }).key
, '\x1b[1;2R');
335 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 115 }).key
, '\x1b[1;2S');
336 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 116 }).key
, '\x1b[15;2~');
337 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 117 }).key
, '\x1b[17;2~');
338 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 118 }).key
, '\x1b[18;2~');
339 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 119 }).key
, '\x1b[19;2~');
340 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 120 }).key
, '\x1b[20;2~');
341 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 121 }).key
, '\x1b[21;2~');
342 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 122 }).key
, '\x1b[23;2~');
343 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 123 }).key
, '\x1b[24;2~');
344 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 112 }).key
, '\x1b[1;3P');
345 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 113 }).key
, '\x1b[1;3Q');
346 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 114 }).key
, '\x1b[1;3R');
347 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 115 }).key
, '\x1b[1;3S');
348 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 116 }).key
, '\x1b[15;3~');
349 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 117 }).key
, '\x1b[17;3~');
350 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 118 }).key
, '\x1b[18;3~');
351 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 119 }).key
, '\x1b[19;3~');
352 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 120 }).key
, '\x1b[20;3~');
353 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 121 }).key
, '\x1b[21;3~');
354 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 122 }).key
, '\x1b[23;3~');
355 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 123 }).key
, '\x1b[24;3~');
357 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 112 }).key
, '\x1b[1;5P');
358 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 113 }).key
, '\x1b[1;5Q');
359 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 114 }).key
, '\x1b[1;5R');
360 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 115 }).key
, '\x1b[1;5S');
361 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 116 }).key
, '\x1b[15;5~');
362 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 117 }).key
, '\x1b[17;5~');
363 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 118 }).key
, '\x1b[18;5~');
364 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 119 }).key
, '\x1b[19;5~');
365 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 120 }).key
, '\x1b[20;5~');
366 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 121 }).key
, '\x1b[21;5~');
367 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 122 }).key
, '\x1b[23;5~');
368 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 123 }).key
, '\x1b[24;5~');
372 describe('attachCustomEventHandler', function () {
374 preventDefault: function() {},
375 stopPropagation: function() {},
379 beforeEach(function() {
380 xterm
.handler = function() {};
381 xterm
.showCursor = function() {};
382 xterm
.clearSelection = function() {};
383 xterm
.compositionHelper
= {
386 return function () { return true; }
392 it('should process the keydown event based on what the handler returns', function () {
393 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), true);
394 xterm
.attachCustomKeydownHandler(function (ev
) {
395 return ev
.keyCode
=== 77;
397 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), true);
398 xterm
.attachCustomKeydownHandler(function (ev
) {
399 return ev
.keyCode
!== 77;
401 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
404 it('should alive after reset(ESC c Full Reset (RIS))', function () {
405 xterm
.attachCustomKeydownHandler(function (ev
) {
406 return ev
.keyCode
!== 77;
408 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
410 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
414 describe('Third level shift', function() {
416 preventDefault: function() {},
417 stopPropagation: function() {},
421 preventDefault: function() {},
422 stopPropagation: function() {},
426 beforeEach(function() {
427 xterm
.handler = function() {};
428 xterm
.showCursor = function() {};
429 xterm
.clearSelection = function() {};
430 xterm
.compositionHelper
= {
434 return function() { return true; };
440 describe('On Mac OS', function() {
441 beforeEach(function() {
442 xterm
.browser
.isMac
= true;
445 it('should not interfere with the alt key on keyDown', function() {
447 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 81 })),
451 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 192 })),
456 it('should interefere with the alt + arrow keys', function() {
458 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 37 })),
462 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 39 })),
467 it('should emit key with alt + key on keyPress', function(done
) {
468 var keys
= ['@', '@', '\\', '\\', '|', '|'];
470 xterm
.on('keypress', function(key
) {
472 var index
= keys
.indexOf(key
);
473 assert(index
!== -1, "Emitted wrong key: " + key
);
474 keys
.splice(index
, 1);
476 if (keys
.length
=== 0) done();
479 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 64 })); // @
481 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 64, keyCode
: 0 }));
482 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 92 })); // \
483 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 92, keyCode
: 0 }));
484 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 124 })); // |
485 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 124, keyCode
: 0 }));
489 describe('On MS Windows', function() {
490 beforeEach(function() {
491 xterm
.browser
.isMSWindows
= true;
494 it('should not interfere with the alt + ctrl key on keyDown', function() {
496 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 81 })),
500 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 192 })),
505 it('should interefere with the alt + ctrl + arrow keys', function() {
507 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 37 })),
511 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 39 })),
516 it('should emit key with alt + ctrl + key on keyPress', function(done
) {
517 var keys
= ['@', '@', '\\', '\\', '|', '|'];
519 xterm
.on('keypress', function(key
) {
521 var index
= keys
.indexOf(key
);
522 assert(index
!== -1, "Emitted wrong key: " + key
);
523 keys
.splice(index
, 1);
525 if (keys
.length
=== 0) done();
529 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 64 })
532 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 64, keyCode
: 0 })
535 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 92 })
538 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 92, keyCode
: 0 })
541 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 124 })
544 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 124, keyCode
: 0 })
550 describe('unicode - surrogates', function() {
551 it('2 characters per cell', function () {
552 var high
= String
.fromCharCode(0xD800);
553 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
554 xterm
.write(high
+ String
.fromCharCode(i
));
555 var tchar
= xterm
.lines
.get(0)[0];
556 expect(tchar
[1]).eql(high
+ String
.fromCharCode(i
));
557 expect(tchar
[1].length
).eql(2);
558 expect(tchar
[2]).eql(1);
559 expect(xterm
.lines
.get(0)[1][1]).eql(' ');
563 it('2 characters at last cell', function() {
564 var high
= String
.fromCharCode(0xD800);
565 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
566 xterm
.x
= xterm
.cols
- 1;
567 xterm
.write(high
+ String
.fromCharCode(i
));
568 expect(xterm
.lines
.get(0)[xterm
.x
-1][1]).eql(high
+ String
.fromCharCode(i
));
569 expect(xterm
.lines
.get(0)[xterm
.x
-1][1].length
).eql(2);
570 expect(xterm
.lines
.get(1)[0][1]).eql(' ');
574 it('2 characters per cell over line end with autowrap', function() {
575 var high
= String
.fromCharCode(0xD800);
576 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
577 xterm
.x
= xterm
.cols
- 1;
578 xterm
.wraparoundMode
= true;
579 xterm
.write('a' + high
+ String
.fromCharCode(i
));
580 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1]).eql('a');
581 expect(xterm
.lines
.get(1)[0][1]).eql(high
+ String
.fromCharCode(i
));
582 expect(xterm
.lines
.get(1)[0][1].length
).eql(2);
583 expect(xterm
.lines
.get(1)[1][1]).eql(' ');
587 it('2 characters per cell over line end without autowrap', function() {
588 var high
= String
.fromCharCode(0xD800);
589 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
590 xterm
.x
= xterm
.cols
- 1;
591 xterm
.wraparoundMode
= false;
592 xterm
.write('a' + high
+ String
.fromCharCode(i
));
593 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1]).eql(high
+ String
.fromCharCode(i
));
594 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1].length
).eql(2);
595 expect(xterm
.lines
.get(1)[1][1]).eql(' ');
599 it('splitted surrogates', function() {
600 var high
= String
.fromCharCode(0xD800);
601 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
603 xterm
.write(String
.fromCharCode(i
));
604 var tchar
= xterm
.lines
.get(0)[0];
605 expect(tchar
[1]).eql(high
+ String
.fromCharCode(i
));
606 expect(tchar
[1].length
).eql(2);
607 expect(tchar
[2]).eql(1);
608 expect(xterm
.lines
.get(0)[1][1]).eql(' ');
614 describe('unicode - combining characters', function() {
615 it('café', function () {
616 xterm
.write('cafe\u0301');
617 expect(xterm
.lines
.get(0)[3][1]).eql('e\u0301');
618 expect(xterm
.lines
.get(0)[3][1].length
).eql(2);
619 expect(xterm
.lines
.get(0)[3][2]).eql(1);
621 it('café - end of line', function() {
622 xterm
.x
= xterm
.cols
- 1 - 3;
623 xterm
.write('cafe\u0301');
624 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1]).eql('e\u0301');
625 expect(xterm
.lines
.get(0)[xterm
.cols
-1][1].length
).eql(2);
626 expect(xterm
.lines
.get(0)[xterm
.cols
-1][2]).eql(1);
627 expect(xterm
.lines
.get(0)[1][1]).eql(' ');
628 expect(xterm
.lines
.get(0)[1][1].length
).eql(1);
629 expect(xterm
.lines
.get(0)[1][2]).eql(1);
631 it('multiple combined é', function() {
632 xterm
.wraparoundMode
= true;
633 xterm
.write(Array(100).join('e\u0301'));
634 for (var i
=0; i
<xterm
.cols
; ++i
) {
635 var tchar
= xterm
.lines
.get(0)[i
];
636 expect(tchar
[1]).eql('e\u0301');
637 expect(tchar
[1].length
).eql(2);
638 expect(tchar
[2]).eql(1);
640 tchar
= xterm
.lines
.get(1)[0];
641 expect(tchar
[1]).eql('e\u0301');
642 expect(tchar
[1].length
).eql(2);
643 expect(tchar
[2]).eql(1);
645 it('multiple surrogate with combined', function() {
646 xterm
.wraparoundMode
= true;
647 xterm
.write(Array(100).join('\uD800\uDC00\u0301'));
648 for (var i
=0; i
<xterm
.cols
; ++i
) {
649 var tchar
= xterm
.lines
.get(0)[i
];
650 expect(tchar
[1]).eql('\uD800\uDC00\u0301');
651 expect(tchar
[1].length
).eql(3);
652 expect(tchar
[2]).eql(1);
654 tchar
= xterm
.lines
.get(1)[0];
655 expect(tchar
[1]).eql('\uD800\uDC00\u0301');
656 expect(tchar
[1].length
).eql(3);
657 expect(tchar
[2]).eql(1);
661 describe('unicode - fullwidth characters', function() {
662 it('cursor movement even', function() {
663 expect(xterm
.x
).eql(0);
665 expect(xterm
.x
).eql(2);
667 it('cursor movement odd', function() {
669 expect(xterm
.x
).eql(1);
671 expect(xterm
.x
).eql(3);
673 it('line of ¥ even', function() {
674 xterm
.wraparoundMode
= true;
675 xterm
.write(Array(50).join('¥'));
676 for (var i
=0; i
<xterm
.cols
; ++i
) {
677 var tchar
= xterm
.lines
.get(0)[i
];
679 expect(tchar
[1]).eql('');
680 expect(tchar
[1].length
).eql(0);
681 expect(tchar
[2]).eql(0);
683 expect(tchar
[1]).eql('¥');
684 expect(tchar
[1].length
).eql(1);
685 expect(tchar
[2]).eql(2);
688 tchar
= xterm
.lines
.get(1)[0];
689 expect(tchar
[1]).eql('¥');
690 expect(tchar
[1].length
).eql(1);
691 expect(tchar
[2]).eql(2);
693 it('line of ¥ odd', function() {
694 xterm
.wraparoundMode
= true;
696 xterm
.write(Array(50).join('¥'));
697 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
698 var tchar
= xterm
.lines
.get(0)[i
];
700 expect(tchar
[1]).eql('');
701 expect(tchar
[1].length
).eql(0);
702 expect(tchar
[2]).eql(0);
704 expect(tchar
[1]).eql('¥');
705 expect(tchar
[1].length
).eql(1);
706 expect(tchar
[2]).eql(2);
709 tchar
= xterm
.lines
.get(0)[xterm
.cols
-1];
710 expect(tchar
[1]).eql(' ');
711 expect(tchar
[1].length
).eql(1);
712 expect(tchar
[2]).eql(1);
713 tchar
= xterm
.lines
.get(1)[0];
714 expect(tchar
[1]).eql('¥');
715 expect(tchar
[1].length
).eql(1);
716 expect(tchar
[2]).eql(2);
718 it('line of ¥ with combining odd', function() {
719 xterm
.wraparoundMode
= true;
721 xterm
.write(Array(50).join('¥\u0301'));
722 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
723 var tchar
= xterm
.lines
.get(0)[i
];
725 expect(tchar
[1]).eql('');
726 expect(tchar
[1].length
).eql(0);
727 expect(tchar
[2]).eql(0);
729 expect(tchar
[1]).eql('¥\u0301');
730 expect(tchar
[1].length
).eql(2);
731 expect(tchar
[2]).eql(2);
734 tchar
= xterm
.lines
.get(0)[xterm
.cols
-1];
735 expect(tchar
[1]).eql(' ');
736 expect(tchar
[1].length
).eql(1);
737 expect(tchar
[2]).eql(1);
738 tchar
= xterm
.lines
.get(1)[0];
739 expect(tchar
[1]).eql('¥\u0301');
740 expect(tchar
[1].length
).eql(2);
741 expect(tchar
[2]).eql(2);
743 it('line of ¥ with combining even', function() {
744 xterm
.wraparoundMode
= true;
745 xterm
.write(Array(50).join('¥\u0301'));
746 for (var i
=0; i
<xterm
.cols
; ++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(1)[0];
759 expect(tchar
[1]).eql('¥\u0301');
760 expect(tchar
[1].length
).eql(2);
761 expect(tchar
[2]).eql(2);
763 it('line of surrogate fullwidth with combining odd', function() {
764 xterm
.wraparoundMode
= true;
766 xterm
.write(Array(50).join('\ud843\ude6d\u0301'));
767 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
768 var tchar
= xterm
.lines
.get(0)[i
];
770 expect(tchar
[1]).eql('');
771 expect(tchar
[1].length
).eql(0);
772 expect(tchar
[2]).eql(0);
774 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
775 expect(tchar
[1].length
).eql(3);
776 expect(tchar
[2]).eql(2);
779 tchar
= xterm
.lines
.get(0)[xterm
.cols
-1];
780 expect(tchar
[1]).eql(' ');
781 expect(tchar
[1].length
).eql(1);
782 expect(tchar
[2]).eql(1);
783 tchar
= xterm
.lines
.get(1)[0];
784 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
785 expect(tchar
[1].length
).eql(3);
786 expect(tchar
[2]).eql(2);
788 it('line of surrogate fullwidth with combining even', function() {
789 xterm
.wraparoundMode
= true;
790 xterm
.write(Array(50).join('\ud843\ude6d\u0301'));
791 for (var i
=0; i
<xterm
.cols
; ++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(1)[0];
804 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
805 expect(tchar
[1].length
).eql(3);
806 expect(tchar
[2]).eql(2);
810 describe('insert mode', function() {
811 it('halfwidth - all', function () {
812 xterm
.write(Array(9).join('0123456789').slice(-80));
815 xterm
.insertMode
= true;
816 xterm
.write('abcde');
817 expect(xterm
.lines
.get(0).length
).eql(xterm
.cols
);
818 expect(xterm
.lines
.get(0)[10][1]).eql('a');
819 expect(xterm
.lines
.get(0)[14][1]).eql('e');
820 expect(xterm
.lines
.get(0)[15][1]).eql('0');
821 expect(xterm
.lines
.get(0)[79][1]).eql('4');
823 it('fullwidth - insert', function() {
824 xterm
.write(Array(9).join('0123456789').slice(-80));
827 xterm
.insertMode
= true;
829 expect(xterm
.lines
.get(0).length
).eql(xterm
.cols
);
830 expect(xterm
.lines
.get(0)[10][1]).eql('¥');
831 expect(xterm
.lines
.get(0)[11][1]).eql('');
832 expect(xterm
.lines
.get(0)[14][1]).eql('¥');
833 expect(xterm
.lines
.get(0)[15][1]).eql('');
834 expect(xterm
.lines
.get(0)[79][1]).eql('3');
836 it('fullwidth - right border', function() {
837 xterm
.write(Array(41).join('¥'));
840 xterm
.insertMode
= true;
842 expect(xterm
.lines
.get(0).length
).eql(xterm
.cols
);
843 expect(xterm
.lines
.get(0)[10][1]).eql('a');
844 expect(xterm
.lines
.get(0)[11][1]).eql('¥');
845 expect(xterm
.lines
.get(0)[79][1]).eql(' '); // fullwidth char got replaced
847 expect(xterm
.lines
.get(0).length
).eql(xterm
.cols
);
848 expect(xterm
.lines
.get(0)[11][1]).eql('b');
849 expect(xterm
.lines
.get(0)[12][1]).eql('¥');
850 expect(xterm
.lines
.get(0)[79][1]).eql(''); // empty cell after fullwidth