]>
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; }
19 describe('getOption', function() {
20 it('should retrieve the option correctly', function() {
21 // In the `options` namespace.
22 xterm
.options
.cursorBlink
= true;
23 assert
.equal(xterm
.getOption('cursorBlink'), true);
25 // On the Terminal instance
26 delete xterm
.options
.cursorBlink
;
27 xterm
.cursorBlink
= false;
28 assert
.equal(xterm
.getOption('cursorBlink'), false);
30 it('should throw when retrieving a non-existant option', function() {
31 assert
.throws(xterm
.getOption
.bind(xterm
, 'fake', true));
35 describe('setOption', function() {
36 it('should set the option correctly', function() {
37 xterm
.setOption('cursorBlink', true);
38 assert
.equal(xterm
.cursorBlink
, true);
39 assert
.equal(xterm
.options
.cursorBlink
, true);
40 xterm
.setOption('cursorBlink', false);
41 assert
.equal(xterm
.cursorBlink
, false);
42 assert
.equal(xterm
.options
.cursorBlink
, false);
44 it('should throw when setting a non-existant option', function() {
45 assert
.throws(xterm
.setOption
.bind(xterm
, 'fake', true));
49 describe('clear', function() {
50 it('should clear a buffer equal to rows', function() {
51 var promptLine
= xterm
.lines
[xterm
.ybase
+ xterm
.y
];
53 assert
.equal(xterm
.y
, 0);
54 assert
.equal(xterm
.ybase
, 0);
55 assert
.equal(xterm
.ydisp
, 0);
56 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
57 assert
.deepEqual(xterm
.lines
[0], promptLine
);
58 for (var i
= 1; i
< xterm
.rows
; i
++) {
59 assert
.deepEqual(xterm
.lines
[0], xterm
.blankLine());
62 it('should clear a buffer larger than rows', function() {
63 // Fill the buffer with dummy rows
64 for (var i
= 0; i
< xterm
.rows
* 2; i
++) {
65 xterm
.write('test\n');
68 var promptLine
= xterm
.lines
[xterm
.ybase
+ xterm
.y
];
70 assert
.equal(xterm
.y
, 0);
71 assert
.equal(xterm
.ybase
, 0);
72 assert
.equal(xterm
.ydisp
, 0);
73 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
74 assert
.deepEqual(xterm
.lines
[0], promptLine
);
75 for (var i
= 1; i
< xterm
.rows
; i
++) {
76 assert
.deepEqual(xterm
.lines
[i
], xterm
.blankLine());
79 it('should not break the prompt when cleared twice', function() {
80 var promptLine
= xterm
.lines
[xterm
.ybase
+ xterm
.y
];
83 assert
.equal(xterm
.y
, 0);
84 assert
.equal(xterm
.ybase
, 0);
85 assert
.equal(xterm
.ydisp
, 0);
86 assert
.equal(xterm
.lines
.length
, xterm
.rows
);
87 assert
.deepEqual(xterm
.lines
[0], promptLine
);
88 for (var i
= 1; i
< xterm
.rows
; i
++) {
89 assert
.deepEqual(xterm
.lines
[i
], xterm
.blankLine());
94 describe('scroll', function() {
95 describe('scrollDisp', function() {
97 beforeEach(function() {
98 for (var i
= 0; i
< xterm
.rows
* 2; i
++) {
99 xterm
.writeln('test');
101 startYDisp
= xterm
.rows
+ 1;
103 it('should scroll a single line', function() {
104 assert
.equal(xterm
.ydisp
, startYDisp
);
105 xterm
.scrollDisp(-1);
106 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
108 assert
.equal(xterm
.ydisp
, startYDisp
);
110 it('should scroll multiple lines', function() {
111 assert
.equal(xterm
.ydisp
, startYDisp
);
112 xterm
.scrollDisp(-5);
113 assert
.equal(xterm
.ydisp
, startYDisp
- 5);
115 assert
.equal(xterm
.ydisp
, startYDisp
);
117 it('should not scroll beyond the bounds of the buffer', function() {
118 assert
.equal(xterm
.ydisp
, startYDisp
);
120 assert
.equal(xterm
.ydisp
, startYDisp
);
121 for (var i
= 0; i
< startYDisp
; i
++) {
122 xterm
.scrollDisp(-1);
124 assert
.equal(xterm
.ydisp
, 0);
125 xterm
.scrollDisp(-1);
126 assert
.equal(xterm
.ydisp
, 0);
130 describe('scrollPages', function() {
132 beforeEach(function() {
133 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
134 xterm
.writeln('test');
136 startYDisp
= (xterm
.rows
* 2) + 1;
138 it('should scroll a single page', function() {
139 assert
.equal(xterm
.ydisp
, startYDisp
);
140 xterm
.scrollPages(-1);
141 assert
.equal(xterm
.ydisp
, startYDisp
- (xterm
.rows
- 1));
142 xterm
.scrollPages(1);
143 assert
.equal(xterm
.ydisp
, startYDisp
);
145 it('should scroll a multiple pages', function() {
146 assert
.equal(xterm
.ydisp
, startYDisp
);
147 xterm
.scrollPages(-2);
148 assert
.equal(xterm
.ydisp
, startYDisp
- (xterm
.rows
- 1) * 2);
149 xterm
.scrollPages(2);
150 assert
.equal(xterm
.ydisp
, startYDisp
);
154 describe('scrollToTop', function() {
155 beforeEach(function() {
156 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
157 xterm
.writeln('test');
160 it('should scroll to the top', function() {
161 assert
.notEqual(xterm
.ydisp
, 0);
163 assert
.equal(xterm
.ydisp
, 0);
167 describe('scrollToBottom', function() {
169 beforeEach(function() {
170 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
171 xterm
.writeln('test');
173 startYDisp
= (xterm
.rows
* 2) + 1;
175 it('should scroll to the bottom', function() {
176 xterm
.scrollDisp(-1);
177 xterm
.scrollToBottom();
178 assert
.equal(xterm
.ydisp
, startYDisp
);
179 xterm
.scrollPages(-1);
180 xterm
.scrollToBottom();
181 assert
.equal(xterm
.ydisp
, startYDisp
);
183 xterm
.scrollToBottom();
184 assert
.equal(xterm
.ydisp
, startYDisp
);
188 describe('keyDown', function () {
189 it('should scroll down, when a key is pressed and terminal is scrolled up', function () {
190 // Override evaluateKeyEscapeSequence to return cancel code
191 xterm
.evaluateKeyEscapeSequence = function() {
192 return { cancel
: true };
197 preventDefault: function(){},
198 stopPropagation: function(){}
203 xterm
.keyDown(event
);
205 // Ensure that now the terminal is scrolled to bottom
206 assert
.equal(xterm
.ydisp
, xterm
.ybase
);
209 it('should not scroll down, when a custom keydown handler prevents the event', function () {
210 // Add some output to the terminal
211 for (var i
= 0; i
< xterm
.rows
* 3; i
++) {
212 xterm
.writeln('test');
214 var startYDisp
= (xterm
.rows
* 2) + 1;
215 xterm
.attachCustomKeydownHandler(function () {
219 assert
.equal(xterm
.ydisp
, startYDisp
);
220 xterm
.scrollDisp(-1);
221 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
222 xterm
.keyDown({ keyCode
: 0 });
223 assert
.equal(xterm
.ydisp
, startYDisp
- 1);
228 describe('evaluateKeyEscapeSequence', function() {
229 it('should return the correct escape sequence for unmodified keys', function() {
231 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 8 }).key
, '\x7f'); // ^?
233 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 9 }).key
, '\t');
235 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 13 }).key
, '\r'); // CR
237 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 27 }).key
, '\x1b');
238 // Page up, page down
239 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 33 }).key
, '\x1b[5~'); // CSI 5 ~
240 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 34 }).key
, '\x1b[6~'); // CSI 6 ~
242 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 35 }).key
, '\x1b[F'); // SS3 F
243 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 36 }).key
, '\x1b[H'); // SS3 H
244 // Left, up, right, down arrows
245 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 37 }).key
, '\x1b[D'); // CSI D
246 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 38 }).key
, '\x1b[A'); // CSI A
247 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 39 }).key
, '\x1b[C'); // CSI C
248 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 40 }).key
, '\x1b[B'); // CSI B
250 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 45 }).key
, '\x1b[2~'); // CSI 2 ~
252 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 46 }).key
, '\x1b[3~'); // CSI 3 ~
254 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 112 }).key
, '\x1bOP'); // SS3 P
255 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 113 }).key
, '\x1bOQ'); // SS3 Q
256 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 114 }).key
, '\x1bOR'); // SS3 R
257 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 115 }).key
, '\x1bOS'); // SS3 S
258 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 116 }).key
, '\x1b[15~'); // CSI 1 5 ~
259 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 117 }).key
, '\x1b[17~'); // CSI 1 7 ~
260 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 118 }).key
, '\x1b[18~'); // CSI 1 8 ~
261 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 119 }).key
, '\x1b[19~'); // CSI 1 9 ~
262 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 120 }).key
, '\x1b[20~'); // CSI 2 0 ~
263 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 121 }).key
, '\x1b[21~'); // CSI 2 1 ~
264 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 122 }).key
, '\x1b[23~'); // CSI 2 3 ~
265 assert
.equal(xterm
.evaluateKeyEscapeSequence({ keyCode
: 123 }).key
, '\x1b[24~'); // CSI 2 4 ~
267 it('should return \\x1b[3;5~ for ctrl+delete', function() {
268 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 46 }).key
, '\x1b[3;5~');
270 it('should return \\x1b[3;2~ for shift+delete', function() {
271 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 46 }).key
, '\x1b[3;2~');
273 it('should return \\x1b[3;3~ for alt+delete', function() {
274 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 46 }).key
, '\x1b[3;3~');
276 it('should return \\x1b[5D for ctrl+left', function() {
277 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 37 }).key
, '\x1b[1;5D'); // CSI 5 D
279 it('should return \\x1b[5C for ctrl+right', function() {
280 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 39 }).key
, '\x1b[1;5C'); // CSI 5 C
282 it('should return \\x1b[5A for ctrl+up', function() {
283 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 38 }).key
, '\x1b[1;5A'); // CSI 5 A
285 it('should return \\x1b[5B for ctrl+down', function() {
286 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 40 }).key
, '\x1b[1;5B'); // CSI 5 B
288 // Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100
289 // http://unix.stackexchange.com/a/108106
290 it('should return \\x1b[5D for alt+left', function() {
291 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 37 }).key
, '\x1b[1;5D'); // CSI 5 D
293 it('should return \\x1b[5C for alt+right', function() {
294 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 39 }).key
, '\x1b[1;5C'); // CSI 5 C
296 it('should return \\x1b[5A for alt+up', function() {
297 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 38 }).key
, '\x1b[1;5A'); // CSI 5 A
299 it('should return \\x1b[5B for alt+down', function() {
300 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 40 }).key
, '\x1b[1;5B'); // CSI 5 B
302 it('should return the correct escape sequence for modified F1-F12 keys', function() {
303 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 112 }).key
, '\x1b[1;2P');
304 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 113 }).key
, '\x1b[1;2Q');
305 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 114 }).key
, '\x1b[1;2R');
306 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 115 }).key
, '\x1b[1;2S');
307 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 116 }).key
, '\x1b[15;2~');
308 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 117 }).key
, '\x1b[17;2~');
309 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 118 }).key
, '\x1b[18;2~');
310 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 119 }).key
, '\x1b[19;2~');
311 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 120 }).key
, '\x1b[20;2~');
312 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 121 }).key
, '\x1b[21;2~');
313 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 122 }).key
, '\x1b[23;2~');
314 assert
.equal(xterm
.evaluateKeyEscapeSequence({ shiftKey
: true, keyCode
: 123 }).key
, '\x1b[24;2~');
315 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 112 }).key
, '\x1b[1;3P');
316 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 113 }).key
, '\x1b[1;3Q');
317 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 114 }).key
, '\x1b[1;3R');
318 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 115 }).key
, '\x1b[1;3S');
319 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 116 }).key
, '\x1b[15;3~');
320 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 117 }).key
, '\x1b[17;3~');
321 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 118 }).key
, '\x1b[18;3~');
322 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 119 }).key
, '\x1b[19;3~');
323 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 120 }).key
, '\x1b[20;3~');
324 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 121 }).key
, '\x1b[21;3~');
325 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 122 }).key
, '\x1b[23;3~');
326 assert
.equal(xterm
.evaluateKeyEscapeSequence({ altKey
: true, keyCode
: 123 }).key
, '\x1b[24;3~');
328 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 112 }).key
, '\x1b[1;5P');
329 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 113 }).key
, '\x1b[1;5Q');
330 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 114 }).key
, '\x1b[1;5R');
331 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 115 }).key
, '\x1b[1;5S');
332 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 116 }).key
, '\x1b[15;5~');
333 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 117 }).key
, '\x1b[17;5~');
334 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 118 }).key
, '\x1b[18;5~');
335 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 119 }).key
, '\x1b[19;5~');
336 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 120 }).key
, '\x1b[20;5~');
337 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 121 }).key
, '\x1b[21;5~');
338 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 122 }).key
, '\x1b[23;5~');
339 assert
.equal(xterm
.evaluateKeyEscapeSequence({ ctrlKey
: true, keyCode
: 123 }).key
, '\x1b[24;5~');
343 describe('attachCustomEventHandler', function () {
345 preventDefault: function() {},
346 stopPropagation: function() {},
350 beforeEach(function() {
351 xterm
.handler = function() {};
352 xterm
.showCursor = function() {};
353 xterm
.clearSelection = function() {};
354 xterm
.compositionHelper
= {
357 return function () { return true; }
363 it('should process the keydown event based on what the handler returns', function () {
364 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), true);
365 xterm
.attachCustomKeydownHandler(function (ev
) {
366 return ev
.keyCode
=== 77;
368 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), true);
369 xterm
.attachCustomKeydownHandler(function (ev
) {
370 return ev
.keyCode
!== 77;
372 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
375 it('should alive after reset(ESC c Full Reset (RIS))', function () {
376 xterm
.attachCustomKeydownHandler(function (ev
) {
377 return ev
.keyCode
!== 77;
379 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
381 assert
.equal(xterm
.keyDown(Object
.assign({}, evKeyDown
, { keyCode
: 77 })), false);
385 describe('Third level shift', function() {
387 preventDefault: function() {},
388 stopPropagation: function() {},
392 preventDefault: function() {},
393 stopPropagation: function() {},
397 beforeEach(function() {
398 xterm
.handler = function() {};
399 xterm
.showCursor = function() {};
400 xterm
.clearSelection = function() {};
401 xterm
.compositionHelper
= {
405 return function() { return true; };
411 describe('On Mac OS', function() {
412 beforeEach(function() {
413 xterm
.browser
.isMac
= true;
416 it('should not interfere with the alt key on keyDown', function() {
418 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 81 })),
422 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 192 })),
427 it('should interefere with the alt + arrow keys', function() {
429 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 37 })),
433 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, keyCode
: 39 })),
438 it('should emit key with alt + key on keyPress', function(done
) {
439 var keys
= ['@', '@', '\\', '\\', '|', '|'];
441 xterm
.on('keypress', function(key
) {
443 var index
= keys
.indexOf(key
);
444 assert(index
!== -1, "Emitted wrong key: " + key
);
445 keys
.splice(index
, 1);
447 if (keys
.length
=== 0) done();
450 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 64 })); // @
452 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 64, keyCode
: 0 }));
453 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 92 })); // \
454 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 92, keyCode
: 0 }));
455 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, keyCode
: 124 })); // |
456 xterm
.keyPress(Object
.assign({}, evKeyPress
, { altKey
: true, charCode
: 124, keyCode
: 0 }));
460 describe('On MS Windows', function() {
461 beforeEach(function() {
462 xterm
.browser
.isMSWindows
= true;
465 it('should not interfere with the alt + ctrl key on keyDown', function() {
467 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 81 })),
471 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 192 })),
476 it('should interefere with the alt + ctrl + arrow keys', function() {
478 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 37 })),
482 xterm
.keyDown(Object
.assign({}, evKeyDown
, { altKey
: true, ctrlKey
: true, keyCode
: 39 })),
487 it('should emit key with alt + ctrl + key on keyPress', function(done
) {
488 var keys
= ['@', '@', '\\', '\\', '|', '|'];
490 xterm
.on('keypress', function(key
) {
492 var index
= keys
.indexOf(key
);
493 assert(index
!== -1, "Emitted wrong key: " + key
);
494 keys
.splice(index
, 1);
496 if (keys
.length
=== 0) done();
500 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 64 })
503 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 64, keyCode
: 0 })
506 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 92 })
509 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 92, keyCode
: 0 })
512 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, keyCode
: 124 })
515 Object
.assign({}, evKeyPress
, { altKey
: true, ctrlKey
: true, charCode
: 124, keyCode
: 0 })
521 describe('unicode - surrogates', function() {
522 it('2 characters per cell', function () {
523 var high
= String
.fromCharCode(0xD800);
524 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
525 xterm
.write(high
+ String
.fromCharCode(i
));
526 var tchar
= xterm
.lines
[0][0];
527 expect(tchar
[1]).eql(high
+ String
.fromCharCode(i
));
528 expect(tchar
[1].length
).eql(2);
529 expect(tchar
[2]).eql(1);
530 expect(xterm
.lines
[0][1][1]).eql(' ');
534 it('2 characters at last cell', function() {
535 var high
= String
.fromCharCode(0xD800);
536 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
537 xterm
.x
= xterm
.cols
- 1;
538 xterm
.write(high
+ String
.fromCharCode(i
));
539 expect(xterm
.lines
[0][xterm
.x
-1][1]).eql(high
+ String
.fromCharCode(i
));
540 expect(xterm
.lines
[0][xterm
.x
-1][1].length
).eql(2);
541 expect(xterm
.lines
[1][0][1]).eql(' ');
545 it('2 characters per cell over line end with autowrap', function() {
546 var high
= String
.fromCharCode(0xD800);
547 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
548 xterm
.x
= xterm
.cols
- 1;
549 xterm
.wraparoundMode
= true;
550 xterm
.write('a' + high
+ String
.fromCharCode(i
));
551 expect(xterm
.lines
[0][xterm
.cols
-1][1]).eql('a');
552 expect(xterm
.lines
[1][0][1]).eql(high
+ String
.fromCharCode(i
));
553 expect(xterm
.lines
[1][0][1].length
).eql(2);
554 expect(xterm
.lines
[1][1][1]).eql(' ');
558 it('2 characters per cell over line end without autowrap', function() {
559 var high
= String
.fromCharCode(0xD800);
560 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
561 xterm
.x
= xterm
.cols
- 1;
562 xterm
.wraparoundMode
= false;
563 xterm
.write('a' + high
+ String
.fromCharCode(i
));
564 expect(xterm
.lines
[0][xterm
.cols
-1][1]).eql(high
+ String
.fromCharCode(i
));
565 expect(xterm
.lines
[0][xterm
.cols
-1][1].length
).eql(2);
566 expect(xterm
.lines
[1][1][1]).eql(' ');
570 it('splitted surrogates', function() {
571 var high
= String
.fromCharCode(0xD800);
572 for (var i
=0xDC00; i
<=0xDCFF; ++i
) {
574 xterm
.write(String
.fromCharCode(i
));
575 var tchar
= xterm
.lines
[0][0];
576 expect(tchar
[1]).eql(high
+ String
.fromCharCode(i
));
577 expect(tchar
[1].length
).eql(2);
578 expect(tchar
[2]).eql(1);
579 expect(xterm
.lines
[0][1][1]).eql(' ');
585 describe('unicode - combining characters', function() {
586 it('café', function () {
587 xterm
.write('cafe\u0301');
588 expect(xterm
.lines
[0][3][1]).eql('e\u0301');
589 expect(xterm
.lines
[0][3][1].length
).eql(2);
590 expect(xterm
.lines
[0][3][2]).eql(1);
592 it('café - end of line', function() {
593 xterm
.x
= xterm
.cols
- 1 - 3;
594 xterm
.write('cafe\u0301');
595 expect(xterm
.lines
[0][xterm
.cols
-1][1]).eql('e\u0301');
596 expect(xterm
.lines
[0][xterm
.cols
-1][1].length
).eql(2);
597 expect(xterm
.lines
[0][xterm
.cols
-1][2]).eql(1);
598 expect(xterm
.lines
[0][1][1]).eql(' ');
599 expect(xterm
.lines
[0][1][1].length
).eql(1);
600 expect(xterm
.lines
[0][1][2]).eql(1);
602 it('multiple combined é', function() {
603 xterm
.wraparoundMode
= true;
604 xterm
.write(Array(100).join('e\u0301'));
605 for (var i
=0; i
<xterm
.cols
; ++i
) {
606 var tchar
= xterm
.lines
[0][i
];
607 expect(tchar
[1]).eql('e\u0301');
608 expect(tchar
[1].length
).eql(2);
609 expect(tchar
[2]).eql(1);
611 tchar
= xterm
.lines
[1][0];
612 expect(tchar
[1]).eql('e\u0301');
613 expect(tchar
[1].length
).eql(2);
614 expect(tchar
[2]).eql(1);
616 it('multiple surrogate with combined', function() {
617 xterm
.wraparoundMode
= true;
618 xterm
.write(Array(100).join('\uD800\uDC00\u0301'));
619 for (var i
=0; i
<xterm
.cols
; ++i
) {
620 var tchar
= xterm
.lines
[0][i
];
621 expect(tchar
[1]).eql('\uD800\uDC00\u0301');
622 expect(tchar
[1].length
).eql(3);
623 expect(tchar
[2]).eql(1);
625 tchar
= xterm
.lines
[1][0];
626 expect(tchar
[1]).eql('\uD800\uDC00\u0301');
627 expect(tchar
[1].length
).eql(3);
628 expect(tchar
[2]).eql(1);
632 describe('unicode - fullwidth characters', function() {
633 it('cursor movement even', function() {
634 expect(xterm
.x
).eql(0);
636 expect(xterm
.x
).eql(2);
638 it('cursor movement odd', function() {
640 expect(xterm
.x
).eql(1);
642 expect(xterm
.x
).eql(3);
644 it('line of ¥ even', function() {
645 xterm
.wraparoundMode
= true;
646 xterm
.write(Array(50).join('¥'));
647 for (var i
=0; i
<xterm
.cols
; ++i
) {
648 var tchar
= xterm
.lines
[0][i
];
650 expect(tchar
[1]).eql('');
651 expect(tchar
[1].length
).eql(0);
652 expect(tchar
[2]).eql(0);
654 expect(tchar
[1]).eql('¥');
655 expect(tchar
[1].length
).eql(1);
656 expect(tchar
[2]).eql(2);
659 tchar
= xterm
.lines
[1][0];
660 expect(tchar
[1]).eql('¥');
661 expect(tchar
[1].length
).eql(1);
662 expect(tchar
[2]).eql(2);
664 it('line of ¥ odd', function() {
665 xterm
.wraparoundMode
= true;
667 xterm
.write(Array(50).join('¥'));
668 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
669 var tchar
= xterm
.lines
[0][i
];
671 expect(tchar
[1]).eql('');
672 expect(tchar
[1].length
).eql(0);
673 expect(tchar
[2]).eql(0);
675 expect(tchar
[1]).eql('¥');
676 expect(tchar
[1].length
).eql(1);
677 expect(tchar
[2]).eql(2);
680 tchar
= xterm
.lines
[0][xterm
.cols
-1];
681 expect(tchar
[1]).eql(' ');
682 expect(tchar
[1].length
).eql(1);
683 expect(tchar
[2]).eql(1);
684 tchar
= xterm
.lines
[1][0];
685 expect(tchar
[1]).eql('¥');
686 expect(tchar
[1].length
).eql(1);
687 expect(tchar
[2]).eql(2);
689 it('line of ¥ with combining odd', function() {
690 xterm
.wraparoundMode
= true;
692 xterm
.write(Array(50).join('¥\u0301'));
693 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
694 var tchar
= xterm
.lines
[0][i
];
696 expect(tchar
[1]).eql('');
697 expect(tchar
[1].length
).eql(0);
698 expect(tchar
[2]).eql(0);
700 expect(tchar
[1]).eql('¥\u0301');
701 expect(tchar
[1].length
).eql(2);
702 expect(tchar
[2]).eql(2);
705 tchar
= xterm
.lines
[0][xterm
.cols
-1];
706 expect(tchar
[1]).eql(' ');
707 expect(tchar
[1].length
).eql(1);
708 expect(tchar
[2]).eql(1);
709 tchar
= xterm
.lines
[1][0];
710 expect(tchar
[1]).eql('¥\u0301');
711 expect(tchar
[1].length
).eql(2);
712 expect(tchar
[2]).eql(2);
714 it('line of ¥ with combining even', function() {
715 xterm
.wraparoundMode
= true;
716 xterm
.write(Array(50).join('¥\u0301'));
717 for (var i
=0; i
<xterm
.cols
; ++i
) {
718 var tchar
= xterm
.lines
[0][i
];
720 expect(tchar
[1]).eql('');
721 expect(tchar
[1].length
).eql(0);
722 expect(tchar
[2]).eql(0);
724 expect(tchar
[1]).eql('¥\u0301');
725 expect(tchar
[1].length
).eql(2);
726 expect(tchar
[2]).eql(2);
729 tchar
= xterm
.lines
[1][0];
730 expect(tchar
[1]).eql('¥\u0301');
731 expect(tchar
[1].length
).eql(2);
732 expect(tchar
[2]).eql(2);
734 it('line of surrogate fullwidth with combining odd', function() {
735 xterm
.wraparoundMode
= true;
737 xterm
.write(Array(50).join('\ud843\ude6d\u0301'));
738 for (var i
=1; i
<xterm
.cols
-1; ++i
) {
739 var tchar
= xterm
.lines
[0][i
];
741 expect(tchar
[1]).eql('');
742 expect(tchar
[1].length
).eql(0);
743 expect(tchar
[2]).eql(0);
745 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
746 expect(tchar
[1].length
).eql(3);
747 expect(tchar
[2]).eql(2);
750 tchar
= xterm
.lines
[0][xterm
.cols
-1];
751 expect(tchar
[1]).eql(' ');
752 expect(tchar
[1].length
).eql(1);
753 expect(tchar
[2]).eql(1);
754 tchar
= xterm
.lines
[1][0];
755 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
756 expect(tchar
[1].length
).eql(3);
757 expect(tchar
[2]).eql(2);
759 it('line of surrogate fullwidth with combining even', function() {
760 xterm
.wraparoundMode
= true;
761 xterm
.write(Array(50).join('\ud843\ude6d\u0301'));
762 for (var i
=0; i
<xterm
.cols
; ++i
) {
763 var tchar
= xterm
.lines
[0][i
];
765 expect(tchar
[1]).eql('');
766 expect(tchar
[1].length
).eql(0);
767 expect(tchar
[2]).eql(0);
769 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
770 expect(tchar
[1].length
).eql(3);
771 expect(tchar
[2]).eql(2);
774 tchar
= xterm
.lines
[1][0];
775 expect(tchar
[1]).eql('\ud843\ude6d\u0301');
776 expect(tchar
[1].length
).eql(3);
777 expect(tchar
[2]).eql(2);
781 describe('insert mode', function() {
782 it('halfwidth - all', function () {
783 xterm
.write(Array(9).join('0123456789').slice(-80));
786 xterm
.insertMode
= true;
787 xterm
.write('abcde');
788 expect(xterm
.lines
[0].length
).eql(xterm
.cols
);
789 expect(xterm
.lines
[0][10][1]).eql('a');
790 expect(xterm
.lines
[0][14][1]).eql('e');
791 expect(xterm
.lines
[0][15][1]).eql('0');
792 expect(xterm
.lines
[0][79][1]).eql('4');
794 it('fullwidth - insert', function() {
795 xterm
.write(Array(9).join('0123456789').slice(-80));
798 xterm
.insertMode
= true;
800 expect(xterm
.lines
[0].length
).eql(xterm
.cols
);
801 expect(xterm
.lines
[0][10][1]).eql('¥');
802 expect(xterm
.lines
[0][11][1]).eql('');
803 expect(xterm
.lines
[0][14][1]).eql('¥');
804 expect(xterm
.lines
[0][15][1]).eql('');
805 expect(xterm
.lines
[0][79][1]).eql('3');
807 it('fullwidth - right border', function() {
808 xterm
.write(Array(41).join('¥'));
811 xterm
.insertMode
= true;
813 expect(xterm
.lines
[0].length
).eql(xterm
.cols
);
814 expect(xterm
.lines
[0][10][1]).eql('a');
815 expect(xterm
.lines
[0][11][1]).eql('¥');
816 expect(xterm
.lines
[0][79][1]).eql(' '); // fullwidth char got replaced
818 expect(xterm
.lines
[0].length
).eql(xterm
.cols
);
819 expect(xterm
.lines
[0][11][1]).eql('b');
820 expect(xterm
.lines
[0][12][1]).eql('¥');
821 expect(xterm
.lines
[0][79][1]).eql(''); // empty cell after fullwidth