]> git.proxmox.com Git - mirror_xterm.js.git/blob - test/test.js
Remove typings (not needed in TS 2+)
[mirror_xterm.js.git] / test / test.js
1 var assert = require('chai').assert;
2 var expect = require('chai').expect;
3 var Terminal = require('../build/xterm');
4
5 describe('xterm.js', function() {
6 var xterm;
7
8 beforeEach(function () {
9 xterm = new Terminal();
10 xterm.refresh = function(){};
11 xterm.viewport = {
12 syncScrollArea: function(){}
13 };
14 });
15
16 describe('getOption', function() {
17 it('should retrieve the option correctly', function() {
18 // In the `options` namespace.
19 xterm.options.cursorBlink = true;
20 assert.equal(xterm.getOption('cursorBlink'), true);
21
22 // On the Terminal instance
23 delete xterm.options.cursorBlink;
24 xterm.cursorBlink = false;
25 assert.equal(xterm.getOption('cursorBlink'), false);
26 });
27 it('should throw when retrieving a non-existant option', function() {
28 assert.throws(xterm.getOption.bind(xterm, 'fake', true));
29 });
30 });
31
32 describe('setOption', function() {
33 it('should set the option correctly', function() {
34 xterm.setOption('cursorBlink', true);
35 assert.equal(xterm.cursorBlink, true);
36 assert.equal(xterm.options.cursorBlink, true);
37 xterm.setOption('cursorBlink', false);
38 assert.equal(xterm.cursorBlink, false);
39 assert.equal(xterm.options.cursorBlink, false);
40 });
41 it('should throw when setting a non-existant option', function() {
42 assert.throws(xterm.setOption.bind(xterm, 'fake', true));
43 });
44 });
45
46 describe('clear', function() {
47 it('should clear a buffer equal to rows', function() {
48 var promptLine = xterm.lines[xterm.ybase + xterm.y];
49 xterm.clear();
50 assert.equal(xterm.y, 0);
51 assert.equal(xterm.ybase, 0);
52 assert.equal(xterm.ydisp, 0);
53 assert.equal(xterm.lines.length, xterm.rows);
54 assert.deepEqual(xterm.lines[0], promptLine);
55 for (var i = 1; i < xterm.rows; i++) {
56 assert.deepEqual(xterm.lines[0], xterm.blankLine());
57 }
58 });
59 it('should clear a buffer larger than rows', function() {
60 // Fill the buffer with dummy rows
61 for (var i = 0; i < xterm.rows * 2; i++) {
62 xterm.write('test\n');
63 }
64
65 var promptLine = xterm.lines[xterm.ybase + xterm.y];
66 xterm.clear();
67 assert.equal(xterm.y, 0);
68 assert.equal(xterm.ybase, 0);
69 assert.equal(xterm.ydisp, 0);
70 assert.equal(xterm.lines.length, xterm.rows);
71 assert.deepEqual(xterm.lines[0], promptLine);
72 for (var i = 1; i < xterm.rows; i++) {
73 assert.deepEqual(xterm.lines[i], xterm.blankLine());
74 }
75 });
76 it('should not break the prompt when cleared twice', function() {
77 var promptLine = xterm.lines[xterm.ybase + xterm.y];
78 xterm.clear();
79 xterm.clear();
80 assert.equal(xterm.y, 0);
81 assert.equal(xterm.ybase, 0);
82 assert.equal(xterm.ydisp, 0);
83 assert.equal(xterm.lines.length, xterm.rows);
84 assert.deepEqual(xterm.lines[0], promptLine);
85 for (var i = 1; i < xterm.rows; i++) {
86 assert.deepEqual(xterm.lines[i], xterm.blankLine());
87 }
88 });
89 });
90
91 describe('scroll', function() {
92 describe('scrollDisp', function() {
93 var startYDisp;
94 beforeEach(function() {
95 for (var i = 0; i < xterm.rows * 2; i++) {
96 xterm.writeln('test');
97 }
98 startYDisp = xterm.rows + 1;
99 });
100 it('should scroll a single line', function() {
101 assert.equal(xterm.ydisp, startYDisp);
102 xterm.scrollDisp(-1);
103 assert.equal(xterm.ydisp, startYDisp - 1);
104 xterm.scrollDisp(1);
105 assert.equal(xterm.ydisp, startYDisp);
106 });
107 it('should scroll multiple lines', function() {
108 assert.equal(xterm.ydisp, startYDisp);
109 xterm.scrollDisp(-5);
110 assert.equal(xterm.ydisp, startYDisp - 5);
111 xterm.scrollDisp(5);
112 assert.equal(xterm.ydisp, startYDisp);
113 });
114 it('should not scroll beyond the bounds of the buffer', function() {
115 assert.equal(xterm.ydisp, startYDisp);
116 xterm.scrollDisp(1);
117 assert.equal(xterm.ydisp, startYDisp);
118 for (var i = 0; i < startYDisp; i++) {
119 xterm.scrollDisp(-1);
120 }
121 assert.equal(xterm.ydisp, 0);
122 xterm.scrollDisp(-1);
123 assert.equal(xterm.ydisp, 0);
124 });
125 });
126
127 describe('scrollPages', function() {
128 var startYDisp;
129 beforeEach(function() {
130 for (var i = 0; i < xterm.rows * 3; i++) {
131 xterm.writeln('test');
132 }
133 startYDisp = (xterm.rows * 2) + 1;
134 });
135 it('should scroll a single page', function() {
136 assert.equal(xterm.ydisp, startYDisp);
137 xterm.scrollPages(-1);
138 assert.equal(xterm.ydisp, startYDisp - (xterm.rows - 1));
139 xterm.scrollPages(1);
140 assert.equal(xterm.ydisp, startYDisp);
141 });
142 it('should scroll a multiple pages', function() {
143 assert.equal(xterm.ydisp, startYDisp);
144 xterm.scrollPages(-2);
145 assert.equal(xterm.ydisp, startYDisp - (xterm.rows - 1) * 2);
146 xterm.scrollPages(2);
147 assert.equal(xterm.ydisp, startYDisp);
148 });
149 });
150
151 describe('scrollToTop', function() {
152 beforeEach(function() {
153 for (var i = 0; i < xterm.rows * 3; i++) {
154 xterm.writeln('test');
155 }
156 });
157 it('should scroll to the top', function() {
158 assert.notEqual(xterm.ydisp, 0);
159 xterm.scrollToTop();
160 assert.equal(xterm.ydisp, 0);
161 });
162 });
163
164 describe('scrollToBottom', function() {
165 var startYDisp;
166 beforeEach(function() {
167 for (var i = 0; i < xterm.rows * 3; i++) {
168 xterm.writeln('test');
169 }
170 startYDisp = (xterm.rows * 2) + 1;
171 });
172 it('should scroll to the bottom', function() {
173 xterm.scrollDisp(-1);
174 xterm.scrollToBottom();
175 assert.equal(xterm.ydisp, startYDisp);
176 xterm.scrollPages(-1);
177 xterm.scrollToBottom();
178 assert.equal(xterm.ydisp, startYDisp);
179 xterm.scrollToTop();
180 xterm.scrollToBottom();
181 assert.equal(xterm.ydisp, startYDisp);
182 });
183 });
184 });
185
186 describe('evaluateKeyEscapeSequence', function() {
187 it('should return the correct escape sequence for unmodified keys', function() {
188 // Backspace
189 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 8 }).key, '\x7f'); // ^?
190 // Tab
191 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 9 }).key, '\t');
192 // Return/enter
193 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 13 }).key, '\r'); // CR
194 // Escape
195 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 27 }).key, '\x1b');
196 // Page up, page down
197 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 33 }).key, '\x1b[5~'); // CSI 5 ~
198 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 34 }).key, '\x1b[6~'); // CSI 6 ~
199 // End, Home
200 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 35 }).key, '\x1b[F'); // SS3 F
201 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 36 }).key, '\x1b[H'); // SS3 H
202 // Left, up, right, down arrows
203 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 37 }).key, '\x1b[D'); // CSI D
204 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 38 }).key, '\x1b[A'); // CSI A
205 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 39 }).key, '\x1b[C'); // CSI C
206 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 40 }).key, '\x1b[B'); // CSI B
207 // Insert
208 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 45 }).key, '\x1b[2~'); // CSI 2 ~
209 // Delete
210 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 46 }).key, '\x1b[3~'); // CSI 3 ~
211 // F1-F12
212 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 112 }).key, '\x1bOP'); // SS3 P
213 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 113 }).key, '\x1bOQ'); // SS3 Q
214 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 114 }).key, '\x1bOR'); // SS3 R
215 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 115 }).key, '\x1bOS'); // SS3 S
216 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 116 }).key, '\x1b[15~'); // CSI 1 5 ~
217 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 117 }).key, '\x1b[17~'); // CSI 1 7 ~
218 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 118 }).key, '\x1b[18~'); // CSI 1 8 ~
219 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 119 }).key, '\x1b[19~'); // CSI 1 9 ~
220 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 120 }).key, '\x1b[20~'); // CSI 2 0 ~
221 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 121 }).key, '\x1b[21~'); // CSI 2 1 ~
222 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 122 }).key, '\x1b[23~'); // CSI 2 3 ~
223 assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 123 }).key, '\x1b[24~'); // CSI 2 4 ~
224 });
225 it('should return \\x1b[3;5~ for ctrl+delete', function() {
226 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 46 }).key, '\x1b[3;5~');
227 });
228 it('should return \\x1b[3;2~ for shift+delete', function() {
229 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 46 }).key, '\x1b[3;2~');
230 });
231 it('should return \\x1b[3;3~ for alt+delete', function() {
232 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~');
233 });
234 it('should return \\x1b[5D for ctrl+left', function() {
235 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D
236 });
237 it('should return \\x1b[5C for ctrl+right', function() {
238 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C
239 });
240 it('should return \\x1b[5A for ctrl+up', function() {
241 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A
242 });
243 it('should return \\x1b[5B for ctrl+down', function() {
244 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B
245 });
246 // Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100
247 // http://unix.stackexchange.com/a/108106
248 it('should return \\x1b[5D for alt+left', function() {
249 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D
250 });
251 it('should return \\x1b[5C for alt+right', function() {
252 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C
253 });
254 it('should return \\x1b[5A for alt+up', function() {
255 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A
256 });
257 it('should return \\x1b[5B for alt+down', function() {
258 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B
259 });
260 it('should return the correct escape sequence for modified F1-F12 keys', function() {
261 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 112 }).key, '\x1b[1;2P');
262 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 113 }).key, '\x1b[1;2Q');
263 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 114 }).key, '\x1b[1;2R');
264 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 115 }).key, '\x1b[1;2S');
265 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 116 }).key, '\x1b[15;2~');
266 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 117 }).key, '\x1b[17;2~');
267 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 118 }).key, '\x1b[18;2~');
268 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 119 }).key, '\x1b[19;2~');
269 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 120 }).key, '\x1b[20;2~');
270 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 121 }).key, '\x1b[21;2~');
271 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 122 }).key, '\x1b[23;2~');
272 assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 123 }).key, '\x1b[24;2~');
273 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 112 }).key, '\x1b[1;3P');
274 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 113 }).key, '\x1b[1;3Q');
275 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 114 }).key, '\x1b[1;3R');
276 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 115 }).key, '\x1b[1;3S');
277 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 116 }).key, '\x1b[15;3~');
278 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 117 }).key, '\x1b[17;3~');
279 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 118 }).key, '\x1b[18;3~');
280 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 119 }).key, '\x1b[19;3~');
281 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 120 }).key, '\x1b[20;3~');
282 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 121 }).key, '\x1b[21;3~');
283 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 122 }).key, '\x1b[23;3~');
284 assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 123 }).key, '\x1b[24;3~');
285
286 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 112 }).key, '\x1b[1;5P');
287 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 113 }).key, '\x1b[1;5Q');
288 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 114 }).key, '\x1b[1;5R');
289 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 115 }).key, '\x1b[1;5S');
290 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 116 }).key, '\x1b[15;5~');
291 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 117 }).key, '\x1b[17;5~');
292 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 118 }).key, '\x1b[18;5~');
293 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 119 }).key, '\x1b[19;5~');
294 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 120 }).key, '\x1b[20;5~');
295 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 121 }).key, '\x1b[21;5~');
296 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 122 }).key, '\x1b[23;5~');
297 assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 123 }).key, '\x1b[24;5~');
298 });
299 });
300
301 describe('attachCustomEventHandler', function () {
302 var evKeyDown = {
303 preventDefault: function() {},
304 stopPropagation: function() {},
305 type: 'keydown'
306 }
307
308 beforeEach(function() {
309 xterm.handler = function() {};
310 xterm.showCursor = function() {};
311 xterm.clearSelection = function() {};
312 xterm.compositionHelper = {
313 keydown: {
314 bind: function() {
315 return function () { return true; }
316 }
317 }
318 }
319 });
320
321 it('should process the keydown event based on what the handler returns', function () {
322 assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), true);
323 xterm.attachCustomKeydownHandler(function (ev) {
324 return ev.keyCode === 77;
325 });
326 assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), true);
327 xterm.attachCustomKeydownHandler(function (ev) {
328 return ev.keyCode !== 77;
329 });
330 assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), false);
331 });
332
333 it('should alive after reset(ESC c Full Reset (RIS))', function () {
334 xterm.attachCustomKeydownHandler(function (ev) {
335 return ev.keyCode !== 77;
336 });
337 assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), false);
338 xterm.reset();
339 assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), false);
340 });
341 });
342
343 describe('Third level shift', function() {
344 var evKeyDown = {
345 preventDefault: function() {},
346 stopPropagation: function() {},
347 type: 'keydown'
348 },
349 evKeyPress = {
350 preventDefault: function() {},
351 stopPropagation: function() {},
352 type: 'keypress'
353 };
354
355 beforeEach(function() {
356 xterm.handler = function() {};
357 xterm.showCursor = function() {};
358 xterm.clearSelection = function() {};
359 xterm.compositionHelper = {
360 isComposing: false,
361 keydown: {
362 bind: function() {
363 return function() { return true; };
364 }
365 }
366 };
367 });
368
369 describe('On Mac OS', function() {
370 beforeEach(function() {
371 xterm.isMac = true;
372 });
373
374 it('should not interfere with the alt key on keyDown', function() {
375 assert.equal(
376 xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, keyCode: 81 })),
377 true
378 );
379 assert.equal(
380 xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, keyCode: 192 })),
381 true
382 );
383 });
384
385 it('should interefere with the alt + arrow keys', function() {
386 assert.equal(
387 xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, keyCode: 37 })),
388 false
389 );
390 assert.equal(
391 xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, keyCode: 39 })),
392 false
393 );
394 });
395
396 it('should emit key with alt + key on keyPress', function(done) {
397 var keys = ['@', '@', '\\', '\\', '|', '|'];
398
399 xterm.on('keypress', function(key) {
400 if (key) {
401 var index = keys.indexOf(key);
402 assert(index !== -1, "Emitted wrong key: " + key);
403 keys.splice(index, 1);
404 }
405 if (keys.length === 0) done();
406 });
407
408 xterm.keyPress(Object.assign({}, evKeyPress, { altKey: true, keyCode: 64 })); // @
409 // Firefox
410 xterm.keyPress(Object.assign({}, evKeyPress, { altKey: true, charCode: 64, keyCode: 0 }));
411 xterm.keyPress(Object.assign({}, evKeyPress, { altKey: true, keyCode: 92 })); // \
412 xterm.keyPress(Object.assign({}, evKeyPress, { altKey: true, charCode: 92, keyCode: 0 }));
413 xterm.keyPress(Object.assign({}, evKeyPress, { altKey: true, keyCode: 124 })); // |
414 xterm.keyPress(Object.assign({}, evKeyPress, { altKey: true, charCode: 124, keyCode: 0 }));
415 });
416 });
417
418 describe('On MS Windows', function() {
419 beforeEach(function() {
420 xterm.isMSWindows = true;
421 });
422
423 it('should not interfere with the alt + ctrl key on keyDown', function() {
424 assert.equal(
425 xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, ctrlKey: true, keyCode: 81 })),
426 true
427 );
428 assert.equal(
429 xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, ctrlKey: true, keyCode: 192 })),
430 true
431 );
432 });
433
434 it('should interefere with the alt + ctrl + arrow keys', function() {
435 assert.equal(
436 xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, ctrlKey: true, keyCode: 37 })),
437 false
438 );
439 assert.equal(
440 xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, ctrlKey: true, keyCode: 39 })),
441 false
442 );
443 });
444
445 it('should emit key with alt + ctrl + key on keyPress', function(done) {
446 var keys = ['@', '@', '\\', '\\', '|', '|'];
447
448 xterm.on('keypress', function(key) {
449 if (key) {
450 var index = keys.indexOf(key);
451 assert(index !== -1, "Emitted wrong key: " + key);
452 keys.splice(index, 1);
453 }
454 if (keys.length === 0) done();
455 });
456
457 xterm.keyPress(
458 Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, keyCode: 64 })
459 ); // @
460 xterm.keyPress(
461 Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, charCode: 64, keyCode: 0 })
462 );
463 xterm.keyPress(
464 Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, keyCode: 92 })
465 ); // \
466 xterm.keyPress(
467 Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, charCode: 92, keyCode: 0 })
468 );
469 xterm.keyPress(
470 Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, keyCode: 124 })
471 ); // |
472 xterm.keyPress(
473 Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, charCode: 124, keyCode: 0 })
474 );
475 });
476 });
477 });
478
479 describe('unicode - surrogates', function() {
480 it('2 characters per cell', function () {
481 var high = String.fromCharCode(0xD800);
482 for (var i=0xDC00; i<=0xDCFF; ++i) {
483 xterm.write(high + String.fromCharCode(i));
484 var tchar = xterm.lines[0][0];
485 expect(tchar[1]).eql(high + String.fromCharCode(i));
486 expect(tchar[1].length).eql(2);
487 expect(tchar[2]).eql(1);
488 expect(xterm.lines[0][1][1]).eql(' ');
489 xterm.reset();
490 }
491 });
492 it('2 characters at last cell', function() {
493 var high = String.fromCharCode(0xD800);
494 for (var i=0xDC00; i<=0xDCFF; ++i) {
495 xterm.x = xterm.cols - 1;
496 xterm.write(high + String.fromCharCode(i));
497 expect(xterm.lines[0][xterm.x-1][1]).eql(high + String.fromCharCode(i));
498 expect(xterm.lines[0][xterm.x-1][1].length).eql(2);
499 expect(xterm.lines[1][0][1]).eql(' ');
500 xterm.reset();
501 }
502 });
503 it('2 characters per cell over line end with autowrap', function() {
504 var high = String.fromCharCode(0xD800);
505 for (var i=0xDC00; i<=0xDCFF; ++i) {
506 xterm.x = xterm.cols - 1;
507 xterm.wraparoundMode = true;
508 xterm.write('a' + high + String.fromCharCode(i));
509 expect(xterm.lines[0][xterm.cols-1][1]).eql('a');
510 expect(xterm.lines[1][0][1]).eql(high + String.fromCharCode(i));
511 expect(xterm.lines[1][0][1].length).eql(2);
512 expect(xterm.lines[1][1][1]).eql(' ');
513 xterm.reset();
514 }
515 });
516 it('2 characters per cell over line end without autowrap', function() {
517 var high = String.fromCharCode(0xD800);
518 for (var i=0xDC00; i<=0xDCFF; ++i) {
519 xterm.x = xterm.cols - 1;
520 xterm.wraparoundMode = false;
521 xterm.write('a' + high + String.fromCharCode(i));
522 expect(xterm.lines[0][xterm.cols-1][1]).eql(high + String.fromCharCode(i));
523 expect(xterm.lines[0][xterm.cols-1][1].length).eql(2);
524 expect(xterm.lines[1][1][1]).eql(' ');
525 xterm.reset();
526 }
527 });
528 it('splitted surrogates', function() {
529 var high = String.fromCharCode(0xD800);
530 for (var i=0xDC00; i<=0xDCFF; ++i) {
531 xterm.write(high);
532 xterm.write(String.fromCharCode(i));
533 var tchar = xterm.lines[0][0];
534 expect(tchar[1]).eql(high + String.fromCharCode(i));
535 expect(tchar[1].length).eql(2);
536 expect(tchar[2]).eql(1);
537 expect(xterm.lines[0][1][1]).eql(' ');
538 xterm.reset();
539 }
540 });
541 });
542
543 describe('unicode - combining characters', function() {
544 it('café', function () {
545 xterm.write('cafe\u0301');
546 expect(xterm.lines[0][3][1]).eql('e\u0301');
547 expect(xterm.lines[0][3][1].length).eql(2);
548 expect(xterm.lines[0][3][2]).eql(1);
549 });
550 it('café - end of line', function() {
551 xterm.x = xterm.cols - 1 - 3;
552 xterm.write('cafe\u0301');
553 expect(xterm.lines[0][xterm.cols-1][1]).eql('e\u0301');
554 expect(xterm.lines[0][xterm.cols-1][1].length).eql(2);
555 expect(xterm.lines[0][xterm.cols-1][2]).eql(1);
556 expect(xterm.lines[0][1][1]).eql(' ');
557 expect(xterm.lines[0][1][1].length).eql(1);
558 expect(xterm.lines[0][1][2]).eql(1);
559 });
560 it('multiple combined é', function() {
561 xterm.wraparoundMode = true;
562 xterm.write(Array(100).join('e\u0301'));
563 for (var i=0; i<xterm.cols; ++i) {
564 var tchar = xterm.lines[0][i];
565 expect(tchar[1]).eql('e\u0301');
566 expect(tchar[1].length).eql(2);
567 expect(tchar[2]).eql(1);
568 }
569 tchar = xterm.lines[1][0];
570 expect(tchar[1]).eql('e\u0301');
571 expect(tchar[1].length).eql(2);
572 expect(tchar[2]).eql(1);
573 });
574 it('multiple surrogate with combined', function() {
575 xterm.wraparoundMode = true;
576 xterm.write(Array(100).join('\uD800\uDC00\u0301'));
577 for (var i=0; i<xterm.cols; ++i) {
578 var tchar = xterm.lines[0][i];
579 expect(tchar[1]).eql('\uD800\uDC00\u0301');
580 expect(tchar[1].length).eql(3);
581 expect(tchar[2]).eql(1);
582 }
583 tchar = xterm.lines[1][0];
584 expect(tchar[1]).eql('\uD800\uDC00\u0301');
585 expect(tchar[1].length).eql(3);
586 expect(tchar[2]).eql(1);
587 });
588 });
589
590 describe('unicode - fullwidth characters', function() {
591 it('cursor movement even', function() {
592 expect(xterm.x).eql(0);
593 xterm.write('¥');
594 expect(xterm.x).eql(2);
595 });
596 it('cursor movement odd', function() {
597 xterm.x = 1;
598 expect(xterm.x).eql(1);
599 xterm.write('¥');
600 expect(xterm.x).eql(3);
601 });
602 it('line of ¥ even', function() {
603 xterm.wraparoundMode = true;
604 xterm.write(Array(50).join('¥'));
605 for (var i=0; i<xterm.cols; ++i) {
606 var tchar = xterm.lines[0][i];
607 if (i % 2) {
608 expect(tchar[1]).eql('');
609 expect(tchar[1].length).eql(0);
610 expect(tchar[2]).eql(0);
611 } else {
612 expect(tchar[1]).eql('¥');
613 expect(tchar[1].length).eql(1);
614 expect(tchar[2]).eql(2);
615 }
616 }
617 tchar = xterm.lines[1][0];
618 expect(tchar[1]).eql('¥');
619 expect(tchar[1].length).eql(1);
620 expect(tchar[2]).eql(2);
621 });
622 it('line of ¥ odd', function() {
623 xterm.wraparoundMode = true;
624 xterm.x = 1;
625 xterm.write(Array(50).join('¥'));
626 for (var i=1; i<xterm.cols-1; ++i) {
627 var tchar = xterm.lines[0][i];
628 if (!(i % 2)) {
629 expect(tchar[1]).eql('');
630 expect(tchar[1].length).eql(0);
631 expect(tchar[2]).eql(0);
632 } else {
633 expect(tchar[1]).eql('¥');
634 expect(tchar[1].length).eql(1);
635 expect(tchar[2]).eql(2);
636 }
637 }
638 tchar = xterm.lines[0][xterm.cols-1];
639 expect(tchar[1]).eql(' ');
640 expect(tchar[1].length).eql(1);
641 expect(tchar[2]).eql(1);
642 tchar = xterm.lines[1][0];
643 expect(tchar[1]).eql('¥');
644 expect(tchar[1].length).eql(1);
645 expect(tchar[2]).eql(2);
646 });
647 it('line of ¥ with combining odd', function() {
648 xterm.wraparoundMode = true;
649 xterm.x = 1;
650 xterm.write(Array(50).join('¥\u0301'));
651 for (var i=1; i<xterm.cols-1; ++i) {
652 var tchar = xterm.lines[0][i];
653 if (!(i % 2)) {
654 expect(tchar[1]).eql('');
655 expect(tchar[1].length).eql(0);
656 expect(tchar[2]).eql(0);
657 } else {
658 expect(tchar[1]).eql('¥\u0301');
659 expect(tchar[1].length).eql(2);
660 expect(tchar[2]).eql(2);
661 }
662 }
663 tchar = xterm.lines[0][xterm.cols-1];
664 expect(tchar[1]).eql(' ');
665 expect(tchar[1].length).eql(1);
666 expect(tchar[2]).eql(1);
667 tchar = xterm.lines[1][0];
668 expect(tchar[1]).eql('¥\u0301');
669 expect(tchar[1].length).eql(2);
670 expect(tchar[2]).eql(2);
671 });
672 it('line of ¥ with combining even', function() {
673 xterm.wraparoundMode = true;
674 xterm.write(Array(50).join('¥\u0301'));
675 for (var i=0; i<xterm.cols; ++i) {
676 var tchar = xterm.lines[0][i];
677 if (i % 2) {
678 expect(tchar[1]).eql('');
679 expect(tchar[1].length).eql(0);
680 expect(tchar[2]).eql(0);
681 } else {
682 expect(tchar[1]).eql('¥\u0301');
683 expect(tchar[1].length).eql(2);
684 expect(tchar[2]).eql(2);
685 }
686 }
687 tchar = xterm.lines[1][0];
688 expect(tchar[1]).eql('¥\u0301');
689 expect(tchar[1].length).eql(2);
690 expect(tchar[2]).eql(2);
691 });
692 it('line of surrogate fullwidth with combining odd', function() {
693 xterm.wraparoundMode = true;
694 xterm.x = 1;
695 xterm.write(Array(50).join('\ud843\ude6d\u0301'));
696 for (var i=1; i<xterm.cols-1; ++i) {
697 var tchar = xterm.lines[0][i];
698 if (!(i % 2)) {
699 expect(tchar[1]).eql('');
700 expect(tchar[1].length).eql(0);
701 expect(tchar[2]).eql(0);
702 } else {
703 expect(tchar[1]).eql('\ud843\ude6d\u0301');
704 expect(tchar[1].length).eql(3);
705 expect(tchar[2]).eql(2);
706 }
707 }
708 tchar = xterm.lines[0][xterm.cols-1];
709 expect(tchar[1]).eql(' ');
710 expect(tchar[1].length).eql(1);
711 expect(tchar[2]).eql(1);
712 tchar = xterm.lines[1][0];
713 expect(tchar[1]).eql('\ud843\ude6d\u0301');
714 expect(tchar[1].length).eql(3);
715 expect(tchar[2]).eql(2);
716 });
717 it('line of surrogate fullwidth with combining even', function() {
718 xterm.wraparoundMode = true;
719 xterm.write(Array(50).join('\ud843\ude6d\u0301'));
720 for (var i=0; i<xterm.cols; ++i) {
721 var tchar = xterm.lines[0][i];
722 if (i % 2) {
723 expect(tchar[1]).eql('');
724 expect(tchar[1].length).eql(0);
725 expect(tchar[2]).eql(0);
726 } else {
727 expect(tchar[1]).eql('\ud843\ude6d\u0301');
728 expect(tchar[1].length).eql(3);
729 expect(tchar[2]).eql(2);
730 }
731 }
732 tchar = xterm.lines[1][0];
733 expect(tchar[1]).eql('\ud843\ude6d\u0301');
734 expect(tchar[1].length).eql(3);
735 expect(tchar[2]).eql(2);
736 });
737 });
738
739 describe('insert mode', function() {
740 it('halfwidth - all', function () {
741 xterm.write(Array(9).join('0123456789').slice(-80));
742 xterm.x = 10;
743 xterm.y = 0;
744 xterm.insertMode = true;
745 xterm.write('abcde');
746 expect(xterm.lines[0].length).eql(xterm.cols);
747 expect(xterm.lines[0][10][1]).eql('a');
748 expect(xterm.lines[0][14][1]).eql('e');
749 expect(xterm.lines[0][15][1]).eql('0');
750 expect(xterm.lines[0][79][1]).eql('4');
751 });
752 it('fullwidth - insert', function() {
753 xterm.write(Array(9).join('0123456789').slice(-80));
754 xterm.x = 10;
755 xterm.y = 0;
756 xterm.insertMode = true;
757 xterm.write('¥¥¥');
758 expect(xterm.lines[0].length).eql(xterm.cols);
759 expect(xterm.lines[0][10][1]).eql('¥');
760 expect(xterm.lines[0][11][1]).eql('');
761 expect(xterm.lines[0][14][1]).eql('¥');
762 expect(xterm.lines[0][15][1]).eql('');
763 expect(xterm.lines[0][79][1]).eql('3');
764 });
765 it('fullwidth - right border', function() {
766 xterm.write(Array(41).join('¥'));
767 xterm.x = 10;
768 xterm.y = 0;
769 xterm.insertMode = true;
770 xterm.write('a');
771 expect(xterm.lines[0].length).eql(xterm.cols);
772 expect(xterm.lines[0][10][1]).eql('a');
773 expect(xterm.lines[0][11][1]).eql('¥');
774 expect(xterm.lines[0][79][1]).eql(' '); // fullwidth char got replaced
775 xterm.write('b');
776 expect(xterm.lines[0].length).eql(xterm.cols);
777 expect(xterm.lines[0][11][1]).eql('b');
778 expect(xterm.lines[0][12][1]).eql('¥');
779 expect(xterm.lines[0][79][1]).eql(''); // empty cell after fullwidth
780 });
781 });
782 });