]>
Commit | Line | Data |
---|---|---|
fa093e2b | 1 | var assert = require('chai').assert; |
4afa08da | 2 | var expect = require('chai').expect; |
56ecc77d | 3 | var Terminal = require('../xterm'); |
fa093e2b | 4 | |
3a866cf2 DI |
5 | describe('xterm.js', function() { |
6 | var xterm; | |
fa093e2b | 7 | |
3a866cf2 DI |
8 | beforeEach(function () { |
9 | xterm = new Terminal(); | |
246b0eda | 10 | xterm.refresh = function(){}; |
71e20801 DI |
11 | xterm.viewport = { |
12 | syncScrollArea: function(){} | |
13 | }; | |
a507e4f0 DI |
14 | xterm.compositionHelper = { |
15 | keydown: function(){ return true; } | |
16 | }; | |
94c01ec3 DI |
17 | // Force synchronous writes |
18 | xterm.write = function(data) { | |
19 | xterm.writeBuffer.push(data); | |
20 | xterm.innerWrite(); | |
21 | }; | |
12160a50 DI |
22 | xterm.element = { |
23 | classList: { | |
64663bf4 DI |
24 | toggle: function(){}, |
25 | remove: function(){} | |
12160a50 DI |
26 | } |
27 | }; | |
3a866cf2 DI |
28 | }); |
29 | ||
4b459fe0 PK |
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); | |
35 | ||
36 | // On the Terminal instance | |
37 | delete xterm.options.cursorBlink; | |
38 | xterm.cursorBlink = false; | |
39 | assert.equal(xterm.getOption('cursorBlink'), false); | |
40 | }); | |
41 | it('should throw when retrieving a non-existant option', function() { | |
42 | assert.throws(xterm.getOption.bind(xterm, 'fake', true)); | |
43 | }); | |
44 | }); | |
45 | ||
ab5cc0ad DI |
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); | |
54 | }); | |
55 | it('should throw when setting a non-existant option', function() { | |
56 | assert.throws(xterm.setOption.bind(xterm, 'fake', true)); | |
57 | }); | |
3180a6f6 | 58 | it('should not allow scrollback less than number of rows', function() { |
59 | let setOptionCall = xterm.setOption.bind(xterm, 'scrollback', xterm.rows - 1); | |
60 | ||
61 | assert.equal(setOptionCall(), false); | |
62 | }); | |
ab5cc0ad DI |
63 | }); |
64 | ||
76719413 DI |
65 | describe('clear', function() { |
66 | it('should clear a buffer equal to rows', function() { | |
607c8191 | 67 | var promptLine = xterm.lines.get(xterm.ybase + xterm.y); |
76719413 DI |
68 | xterm.clear(); |
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); | |
607c8191 | 73 | assert.deepEqual(xterm.lines.get(0), promptLine); |
76719413 | 74 | for (var i = 1; i < xterm.rows; i++) { |
607c8191 | 75 | assert.deepEqual(xterm.lines.get(i), xterm.blankLine()); |
76719413 DI |
76 | } |
77 | }); | |
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'); | |
82 | } | |
83 | ||
607c8191 | 84 | var promptLine = xterm.lines.get(xterm.ybase + xterm.y); |
76719413 DI |
85 | xterm.clear(); |
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); | |
607c8191 | 90 | assert.deepEqual(xterm.lines.get(0), promptLine); |
76719413 | 91 | for (var i = 1; i < xterm.rows; i++) { |
607c8191 | 92 | assert.deepEqual(xterm.lines.get(i), xterm.blankLine()); |
26fc5399 DI |
93 | } |
94 | }); | |
95 | it('should not break the prompt when cleared twice', function() { | |
607c8191 | 96 | var promptLine = xterm.lines.get(xterm.ybase + xterm.y); |
26fc5399 DI |
97 | xterm.clear(); |
98 | xterm.clear(); | |
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); | |
607c8191 | 103 | assert.deepEqual(xterm.lines.get(0), promptLine); |
26fc5399 | 104 | for (var i = 1; i < xterm.rows; i++) { |
607c8191 | 105 | assert.deepEqual(xterm.lines.get(i), xterm.blankLine()); |
76719413 DI |
106 | } |
107 | }); | |
108 | }); | |
109 | ||
c02eea6a DI |
110 | describe('scroll', function() { |
111 | describe('scrollDisp', function() { | |
112 | var startYDisp; | |
113 | beforeEach(function() { | |
114 | for (var i = 0; i < xterm.rows * 2; i++) { | |
115 | xterm.writeln('test'); | |
116 | } | |
117 | startYDisp = xterm.rows + 1; | |
118 | }); | |
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); | |
123 | xterm.scrollDisp(1); | |
124 | assert.equal(xterm.ydisp, startYDisp); | |
125 | }); | |
126 | it('should scroll multiple lines', function() { | |
127 | assert.equal(xterm.ydisp, startYDisp); | |
128 | xterm.scrollDisp(-5); | |
129 | assert.equal(xterm.ydisp, startYDisp - 5); | |
130 | xterm.scrollDisp(5); | |
131 | assert.equal(xterm.ydisp, startYDisp); | |
132 | }); | |
133 | it('should not scroll beyond the bounds of the buffer', function() { | |
134 | assert.equal(xterm.ydisp, startYDisp); | |
135 | xterm.scrollDisp(1); | |
136 | assert.equal(xterm.ydisp, startYDisp); | |
137 | for (var i = 0; i < startYDisp; i++) { | |
138 | xterm.scrollDisp(-1); | |
139 | } | |
140 | assert.equal(xterm.ydisp, 0); | |
141 | xterm.scrollDisp(-1); | |
142 | assert.equal(xterm.ydisp, 0); | |
143 | }); | |
fe0d878b | 144 | }); |
941e57a2 DI |
145 | |
146 | describe('scrollPages', function() { | |
147 | var startYDisp; | |
148 | beforeEach(function() { | |
149 | for (var i = 0; i < xterm.rows * 3; i++) { | |
150 | xterm.writeln('test'); | |
151 | } | |
152 | startYDisp = (xterm.rows * 2) + 1; | |
153 | }); | |
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); | |
160 | }); | |
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); | |
167 | }); | |
168 | }); | |
e5d130b6 DI |
169 | |
170 | describe('scrollToTop', function() { | |
171 | beforeEach(function() { | |
172 | for (var i = 0; i < xterm.rows * 3; i++) { | |
173 | xterm.writeln('test'); | |
174 | } | |
175 | }); | |
176 | it('should scroll to the top', function() { | |
177 | assert.notEqual(xterm.ydisp, 0); | |
178 | xterm.scrollToTop(); | |
179 | assert.equal(xterm.ydisp, 0); | |
180 | }); | |
181 | }); | |
182 | ||
183 | describe('scrollToBottom', function() { | |
184 | var startYDisp; | |
185 | beforeEach(function() { | |
186 | for (var i = 0; i < xterm.rows * 3; i++) { | |
187 | xterm.writeln('test'); | |
188 | } | |
189 | startYDisp = (xterm.rows * 2) + 1; | |
190 | }); | |
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); | |
198 | xterm.scrollToTop(); | |
199 | xterm.scrollToBottom(); | |
200 | assert.equal(xterm.ydisp, startYDisp); | |
201 | }); | |
202 | }); | |
0de3d839 PK |
203 | |
204 | describe('keyDown', function () { | |
205 | it('should scroll down, when a key is pressed and terminal is scrolled up', function () { | |
a507e4f0 DI |
206 | // Override evaluateKeyEscapeSequence to return cancel code |
207 | xterm.evaluateKeyEscapeSequence = function() { | |
3b2e89d8 | 208 | return { key: 'a' }; |
a507e4f0 DI |
209 | }; |
210 | var event = { | |
211 | type: 'keydown', | |
1ee316ca | 212 | keyCode: 0, |
a507e4f0 DI |
213 | preventDefault: function(){}, |
214 | stopPropagation: function(){} | |
215 | }; | |
216 | ||
217 | xterm.ydisp = 0; | |
218 | xterm.ybase = 40; | |
3b2e89d8 | 219 | assert.notEqual(xterm.ydisp, xterm.ybase); |
a507e4f0 DI |
220 | xterm.keyDown(event); |
221 | ||
222 | // Ensure that now the terminal is scrolled to bottom | |
223 | assert.equal(xterm.ydisp, xterm.ybase); | |
224 | }); | |
0de3d839 | 225 | |
a507e4f0 DI |
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'); | |
230 | } | |
231 | var startYDisp = (xterm.rows * 2) + 1; | |
232 | xterm.attachCustomKeydownHandler(function () { | |
0de3d839 PK |
233 | return false; |
234 | }); | |
235 | ||
a507e4f0 DI |
236 | assert.equal(xterm.ydisp, startYDisp); |
237 | xterm.scrollDisp(-1); | |
238 | assert.equal(xterm.ydisp, startYDisp - 1); | |
1ee316ca | 239 | xterm.keyDown({ keyCode: 0 }); |
a507e4f0 | 240 | assert.equal(xterm.ydisp, startYDisp - 1); |
0de3d839 PK |
241 | }); |
242 | }); | |
fe0d878b DI |
243 | }); |
244 | ||
3a866cf2 | 245 | describe('evaluateKeyEscapeSequence', function() { |
0535f942 DI |
246 | it('should return the correct escape sequence for unmodified keys', function() { |
247 | // Backspace | |
248 | assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 8 }).key, '\x7f'); // ^? | |
249 | // Tab | |
250 | assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 9 }).key, '\t'); | |
251 | // Return/enter | |
252 | assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 13 }).key, '\r'); // CR | |
253 | // Escape | |
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 ~ | |
258 | // End, Home | |
8e7eeff4 JB |
259 | assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 35 }).key, '\x1b[F'); // SS3 F |
260 | assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 36 }).key, '\x1b[H'); // SS3 H | |
0535f942 DI |
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 | |
266 | // Insert | |
267 | assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 45 }).key, '\x1b[2~'); // CSI 2 ~ | |
268 | // Delete | |
269 | assert.equal(xterm.evaluateKeyEscapeSequence({ keyCode: 46 }).key, '\x1b[3~'); // CSI 3 ~ | |
270 | // F1-F12 | |
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 ~ | |
3a866cf2 | 283 | }); |
62ce64f9 | 284 | it('should return \\x1b[3;5~ for ctrl+delete', function() { |
285 | assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 46 }).key, '\x1b[3;5~'); | |
286 | }); | |
287 | it('should return \\x1b[3;2~ for shift+delete', function() { | |
288 | assert.equal(xterm.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 46 }).key, '\x1b[3;2~'); | |
289 | }); | |
290 | it('should return \\x1b[3;3~ for alt+delete', function() { | |
291 | assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~'); | |
292 | }); | |
0535f942 | 293 | it('should return \\x1b[5D for ctrl+left', function() { |
8e7eeff4 | 294 | assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D |
c86fd878 | 295 | }); |
0535f942 | 296 | it('should return \\x1b[5C for ctrl+right', function() { |
8e7eeff4 | 297 | assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C |
3a866cf2 | 298 | }); |
5d6e0356 PK |
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 | |
301 | }); | |
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 | |
304 | }); | |
2824da37 BR |
305 | |
306 | describe('On non-macOS platforms', function() { | |
307 | beforeEach(function() { | |
308 | xterm.browser.isMac = false; | |
309 | }); | |
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 | |
314 | }); | |
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 | |
317 | }); | |
5d6e0356 | 318 | }); |
2824da37 BR |
319 | |
320 | describe('On macOS platforms', function() { | |
321 | beforeEach(function() { | |
322 | xterm.browser.isMac = true; | |
323 | }); | |
324 | it('should return \\x1bb for alt+left', function() { | |
325 | assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1bb'); // CSI 5 D | |
326 | }); | |
327 | it('should return \\x1bf for alt+right', function() { | |
328 | assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1bf'); // CSI 5 C | |
329 | }); | |
5d6e0356 | 330 | }); |
2824da37 | 331 | |
5d6e0356 PK |
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 | |
334 | }); | |
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 | |
337 | }); | |
7f7156ba | 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~'); | |
ab5cc0ad | 363 | |
7f7156ba | 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~'); | |
376 | }); | |
3a866cf2 | 377 | }); |
fed92ac5 | 378 | |
8e79d53d | 379 | describe('attachCustomKeyEventHandler', function () { |
9cb5b005 DI |
380 | var evKeyDown = { |
381 | preventDefault: function() {}, | |
382 | stopPropagation: function() {}, | |
383 | type: 'keydown' | |
384 | } | |
95aed8fc C |
385 | var evKeyPress = { |
386 | preventDefault: function() {}, | |
387 | stopPropagation: function() {}, | |
388 | type: 'keypress' | |
389 | } | |
9cb5b005 DI |
390 | |
391 | beforeEach(function() { | |
392 | xterm.handler = function() {}; | |
393 | xterm.showCursor = function() {}; | |
394 | xterm.clearSelection = function() {}; | |
e2d0de26 DI |
395 | xterm.compositionHelper = { |
396 | keydown: { | |
397 | bind: function() { | |
398 | return function () { return true; } | |
399 | } | |
95aed8fc C |
400 | }, |
401 | keypress: { | |
402 | bind: function() { | |
403 | return function () { return true; } | |
404 | } | |
e2d0de26 DI |
405 | } |
406 | } | |
9cb5b005 DI |
407 | }); |
408 | ||
8e79d53d | 409 | it('should process the keydown/keypress event based on what the handler returns', function () { |
9cb5b005 | 410 | assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), true); |
95aed8fc | 411 | assert.equal(xterm.keyPress(Object.assign({}, evKeyPress, { keyCode: 77 })), true); |
8e79d53d | 412 | xterm.attachCustomKeyEventHandler(function (ev) { |
95aed8fc C |
413 | return ev.keyCode === 77; |
414 | }); | |
8e79d53d | 415 | assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), true); |
95aed8fc | 416 | assert.equal(xterm.keyPress(Object.assign({}, evKeyPress, { keyCode: 77 })), true); |
8e79d53d | 417 | xterm.attachCustomKeyEventHandler(function (ev) { |
95aed8fc C |
418 | return ev.keyCode !== 77; |
419 | }); | |
8e79d53d | 420 | assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), false); |
95aed8fc C |
421 | assert.equal(xterm.keyPress(Object.assign({}, evKeyPress, { keyCode: 77 })), false); |
422 | }); | |
423 | ||
c2aa0d75 | 424 | it('should alive after reset(ESC c Full Reset (RIS))', function () { |
8e79d53d | 425 | xterm.attachCustomKeyEventHandler(function (ev) { |
95aed8fc C |
426 | return ev.keyCode !== 77; |
427 | }); | |
c2aa0d75 | 428 | assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), false); |
95aed8fc | 429 | assert.equal(xterm.keyPress(Object.assign({}, evKeyPress, { keyCode: 77 })), false); |
c2aa0d75 | 430 | xterm.reset(); |
431 | assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), false); | |
95aed8fc | 432 | assert.equal(xterm.keyPress(Object.assign({}, evKeyPress, { keyCode: 77 })), false); |
c2aa0d75 | 433 | }); |
9cb5b005 DI |
434 | }); |
435 | ||
b01165c1 | 436 | describe('Third level shift', function() { |
6663a947 PK |
437 | var evKeyDown = { |
438 | preventDefault: function() {}, | |
439 | stopPropagation: function() {}, | |
440 | type: 'keydown' | |
441 | }, | |
442 | evKeyPress = { | |
443 | preventDefault: function() {}, | |
444 | stopPropagation: function() {}, | |
445 | type: 'keypress' | |
446 | }; | |
b01165c1 | 447 | |
448 | beforeEach(function() { | |
449 | xterm.handler = function() {}; | |
450 | xterm.showCursor = function() {}; | |
451 | xterm.clearSelection = function() {}; | |
237e6819 | 452 | xterm.compositionHelper = { |
a3a7017f DI |
453 | isComposing: false, |
454 | keydown: { | |
455 | bind: function() { | |
456 | return function() { return true; }; | |
457 | } | |
458 | } | |
237e6819 | 459 | }; |
00f380a7 | 460 | }); |
b01165c1 | 461 | |
462 | describe('On Mac OS', function() { | |
463 | beforeEach(function() { | |
bc70b3b3 | 464 | xterm.browser.isMac = true; |
b01165c1 | 465 | }); |
466 | ||
467 | it('should not interfere with the alt key on keyDown', function() { | |
468 | assert.equal( | |
6663a947 | 469 | xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, keyCode: 81 })), |
b01165c1 | 470 | true |
471 | ); | |
472 | assert.equal( | |
6663a947 | 473 | xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, keyCode: 192 })), |
b01165c1 | 474 | true |
475 | ); | |
476 | }); | |
477 | ||
478 | it('should interefere with the alt + arrow keys', function() { | |
479 | assert.equal( | |
6663a947 | 480 | xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, keyCode: 37 })), |
b01165c1 | 481 | false |
482 | ); | |
483 | assert.equal( | |
6663a947 | 484 | xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, keyCode: 39 })), |
b01165c1 | 485 | false |
486 | ); | |
487 | }); | |
488 | ||
489 | it('should emit key with alt + key on keyPress', function(done) { | |
490 | var keys = ['@', '@', '\\', '\\', '|', '|']; | |
491 | ||
492 | xterm.on('keypress', function(key) { | |
493 | if (key) { | |
494 | var index = keys.indexOf(key); | |
495 | assert(index !== -1, "Emitted wrong key: " + key); | |
496 | keys.splice(index, 1); | |
497 | } | |
498 | if (keys.length === 0) done(); | |
499 | }); | |
500 | ||
6663a947 | 501 | xterm.keyPress(Object.assign({}, evKeyPress, { altKey: true, keyCode: 64 })); // @ |
b01165c1 | 502 | // Firefox |
6663a947 PK |
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 })); | |
b01165c1 | 508 | }); |
509 | }); | |
510 | ||
511 | describe('On MS Windows', function() { | |
512 | beforeEach(function() { | |
b1ad564b | 513 | xterm.browser.isMSWindows = true; |
b01165c1 | 514 | }); |
515 | ||
516 | it('should not interfere with the alt + ctrl key on keyDown', function() { | |
517 | assert.equal( | |
6663a947 | 518 | xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, ctrlKey: true, keyCode: 81 })), |
b01165c1 | 519 | true |
520 | ); | |
521 | assert.equal( | |
6663a947 | 522 | xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, ctrlKey: true, keyCode: 192 })), |
b01165c1 | 523 | true |
524 | ); | |
525 | }); | |
526 | ||
527 | it('should interefere with the alt + ctrl + arrow keys', function() { | |
528 | assert.equal( | |
6663a947 | 529 | xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, ctrlKey: true, keyCode: 37 })), |
b01165c1 | 530 | false |
531 | ); | |
532 | assert.equal( | |
6663a947 | 533 | xterm.keyDown(Object.assign({}, evKeyDown, { altKey: true, ctrlKey: true, keyCode: 39 })), |
b01165c1 | 534 | false |
535 | ); | |
536 | }); | |
537 | ||
538 | it('should emit key with alt + ctrl + key on keyPress', function(done) { | |
539 | var keys = ['@', '@', '\\', '\\', '|', '|']; | |
540 | ||
541 | xterm.on('keypress', function(key) { | |
542 | if (key) { | |
543 | var index = keys.indexOf(key); | |
544 | assert(index !== -1, "Emitted wrong key: " + key); | |
545 | keys.splice(index, 1); | |
546 | } | |
547 | if (keys.length === 0) done(); | |
548 | }); | |
549 | ||
550 | xterm.keyPress( | |
6663a947 | 551 | Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, keyCode: 64 }) |
b01165c1 | 552 | ); // @ |
553 | xterm.keyPress( | |
6663a947 | 554 | Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, charCode: 64, keyCode: 0 }) |
b01165c1 | 555 | ); |
556 | xterm.keyPress( | |
6663a947 | 557 | Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, keyCode: 92 }) |
b01165c1 | 558 | ); // \ |
559 | xterm.keyPress( | |
6663a947 | 560 | Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, charCode: 92, keyCode: 0 }) |
b01165c1 | 561 | ); |
562 | xterm.keyPress( | |
6663a947 | 563 | Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, keyCode: 124 }) |
b01165c1 | 564 | ); // | |
565 | xterm.keyPress( | |
6663a947 | 566 | Object.assign({}, evKeyPress, { altKey: true, ctrlKey: true, charCode: 124, keyCode: 0 }) |
b01165c1 | 567 | ); |
568 | }); | |
569 | }); | |
570 | }); | |
c3bc59b5 | 571 | |
4afa08da | 572 | describe('unicode - surrogates', function() { |
c3bc59b5 | 573 | it('2 characters per cell', function () { |
695a9523 | 574 | this.timeout(10000); // This is needed because istanbul patches code and slows it down |
33abd69e | 575 | var high = String.fromCharCode(0xD800); |
4afa08da JB |
576 | for (var i=0xDC00; i<=0xDCFF; ++i) { |
577 | xterm.write(high + String.fromCharCode(i)); | |
607c8191 | 578 | var tchar = xterm.lines.get(0)[0]; |
4afa08da JB |
579 | expect(tchar[1]).eql(high + String.fromCharCode(i)); |
580 | expect(tchar[1].length).eql(2); | |
581 | expect(tchar[2]).eql(1); | |
607c8191 | 582 | expect(xterm.lines.get(0)[1][1]).eql(' '); |
4afa08da JB |
583 | xterm.reset(); |
584 | } | |
c3bc59b5 | 585 | }); |
4afa08da | 586 | it('2 characters at last cell', function() { |
33abd69e | 587 | var high = String.fromCharCode(0xD800); |
4afa08da JB |
588 | for (var i=0xDC00; i<=0xDCFF; ++i) { |
589 | xterm.x = xterm.cols - 1; | |
590 | xterm.write(high + String.fromCharCode(i)); | |
607c8191 DI |
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(' '); | |
4afa08da JB |
594 | xterm.reset(); |
595 | } | |
c3bc59b5 | 596 | }); |
4afa08da | 597 | it('2 characters per cell over line end with autowrap', function() { |
33abd69e | 598 | var high = String.fromCharCode(0xD800); |
4afa08da JB |
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)); | |
607c8191 DI |
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(' '); | |
4afa08da JB |
607 | xterm.reset(); |
608 | } | |
c3bc59b5 | 609 | }); |
4afa08da | 610 | it('2 characters per cell over line end without autowrap', function() { |
33abd69e | 611 | var high = String.fromCharCode(0xD800); |
4afa08da JB |
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)); | |
b789a7e8 DI |
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); | |
607c8191 | 619 | expect(xterm.lines.get(1)[1][1]).eql(' '); |
4afa08da JB |
620 | xterm.reset(); |
621 | } | |
c3bc59b5 | 622 | }); |
4afa08da | 623 | it('splitted surrogates', function() { |
33abd69e | 624 | var high = String.fromCharCode(0xD800); |
4afa08da JB |
625 | for (var i=0xDC00; i<=0xDCFF; ++i) { |
626 | xterm.write(high); | |
627 | xterm.write(String.fromCharCode(i)); | |
607c8191 | 628 | var tchar = xterm.lines.get(0)[0]; |
4afa08da JB |
629 | expect(tchar[1]).eql(high + String.fromCharCode(i)); |
630 | expect(tchar[1].length).eql(2); | |
631 | expect(tchar[2]).eql(1); | |
607c8191 | 632 | expect(xterm.lines.get(0)[1][1]).eql(' '); |
4afa08da JB |
633 | xterm.reset(); |
634 | } | |
c3bc59b5 | 635 | }); |
4afa08da JB |
636 | }); |
637 | ||
638 | describe('unicode - combining characters', function() { | |
c3bc59b5 | 639 | it('café', function () { |
4afa08da | 640 | xterm.write('cafe\u0301'); |
607c8191 DI |
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); | |
c3bc59b5 | 644 | }); |
4afa08da JB |
645 | it('café - end of line', function() { |
646 | xterm.x = xterm.cols - 1 - 3; | |
647 | xterm.write('cafe\u0301'); | |
607c8191 DI |
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); | |
c3bc59b5 | 654 | }); |
4afa08da JB |
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) { | |
607c8191 | 659 | var tchar = xterm.lines.get(0)[i]; |
4afa08da JB |
660 | expect(tchar[1]).eql('e\u0301'); |
661 | expect(tchar[1].length).eql(2); | |
662 | expect(tchar[2]).eql(1); | |
663 | } | |
607c8191 | 664 | tchar = xterm.lines.get(1)[0]; |
4afa08da JB |
665 | expect(tchar[1]).eql('e\u0301'); |
666 | expect(tchar[1].length).eql(2); | |
667 | expect(tchar[2]).eql(1); | |
c3bc59b5 | 668 | }); |
4afa08da JB |
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) { | |
607c8191 | 673 | var tchar = xterm.lines.get(0)[i]; |
4afa08da JB |
674 | expect(tchar[1]).eql('\uD800\uDC00\u0301'); |
675 | expect(tchar[1].length).eql(3); | |
676 | expect(tchar[2]).eql(1); | |
677 | } | |
607c8191 | 678 | tchar = xterm.lines.get(1)[0]; |
4afa08da JB |
679 | expect(tchar[1]).eql('\uD800\uDC00\u0301'); |
680 | expect(tchar[1].length).eql(3); | |
681 | expect(tchar[2]).eql(1); | |
c3bc59b5 | 682 | }); |
4afa08da | 683 | }); |
c3bc59b5 | 684 | |
4afa08da JB |
685 | describe('unicode - fullwidth characters', function() { |
686 | it('cursor movement even', function() { | |
687 | expect(xterm.x).eql(0); | |
688 | xterm.write('¥'); | |
689 | expect(xterm.x).eql(2); | |
c3bc59b5 | 690 | }); |
4afa08da JB |
691 | it('cursor movement odd', function() { |
692 | xterm.x = 1; | |
693 | expect(xterm.x).eql(1); | |
694 | xterm.write('¥'); | |
695 | expect(xterm.x).eql(3); | |
c3bc59b5 | 696 | }); |
4afa08da JB |
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) { | |
607c8191 | 701 | var tchar = xterm.lines.get(0)[i]; |
4afa08da JB |
702 | if (i % 2) { |
703 | expect(tchar[1]).eql(''); | |
704 | expect(tchar[1].length).eql(0); | |
705 | expect(tchar[2]).eql(0); | |
706 | } else { | |
707 | expect(tchar[1]).eql('¥'); | |
708 | expect(tchar[1].length).eql(1); | |
709 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 710 | } |
4afa08da | 711 | } |
607c8191 | 712 | tchar = xterm.lines.get(1)[0]; |
4afa08da JB |
713 | expect(tchar[1]).eql('¥'); |
714 | expect(tchar[1].length).eql(1); | |
715 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 716 | }); |
4afa08da JB |
717 | it('line of ¥ odd', function() { |
718 | xterm.wraparoundMode = true; | |
719 | xterm.x = 1; | |
720 | xterm.write(Array(50).join('¥')); | |
721 | for (var i=1; i<xterm.cols-1; ++i) { | |
607c8191 | 722 | var tchar = xterm.lines.get(0)[i]; |
4afa08da JB |
723 | if (!(i % 2)) { |
724 | expect(tchar[1]).eql(''); | |
725 | expect(tchar[1].length).eql(0); | |
726 | expect(tchar[2]).eql(0); | |
727 | } else { | |
728 | expect(tchar[1]).eql('¥'); | |
729 | expect(tchar[1].length).eql(1); | |
730 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 731 | } |
4afa08da | 732 | } |
607c8191 | 733 | tchar = xterm.lines.get(0)[xterm.cols-1]; |
4afa08da JB |
734 | expect(tchar[1]).eql(' '); |
735 | expect(tchar[1].length).eql(1); | |
736 | expect(tchar[2]).eql(1); | |
607c8191 | 737 | tchar = xterm.lines.get(1)[0]; |
4afa08da JB |
738 | expect(tchar[1]).eql('¥'); |
739 | expect(tchar[1].length).eql(1); | |
740 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 741 | }); |
4afa08da JB |
742 | it('line of ¥ with combining odd', function() { |
743 | xterm.wraparoundMode = true; | |
744 | xterm.x = 1; | |
745 | xterm.write(Array(50).join('¥\u0301')); | |
746 | for (var i=1; i<xterm.cols-1; ++i) { | |
607c8191 | 747 | var tchar = xterm.lines.get(0)[i]; |
4afa08da JB |
748 | if (!(i % 2)) { |
749 | expect(tchar[1]).eql(''); | |
750 | expect(tchar[1].length).eql(0); | |
751 | expect(tchar[2]).eql(0); | |
752 | } else { | |
753 | expect(tchar[1]).eql('¥\u0301'); | |
754 | expect(tchar[1].length).eql(2); | |
755 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 756 | } |
4afa08da | 757 | } |
607c8191 | 758 | tchar = xterm.lines.get(0)[xterm.cols-1]; |
4afa08da JB |
759 | expect(tchar[1]).eql(' '); |
760 | expect(tchar[1].length).eql(1); | |
761 | expect(tchar[2]).eql(1); | |
607c8191 | 762 | tchar = xterm.lines.get(1)[0]; |
4afa08da JB |
763 | expect(tchar[1]).eql('¥\u0301'); |
764 | expect(tchar[1].length).eql(2); | |
765 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 766 | }); |
4afa08da JB |
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) { | |
607c8191 | 771 | var tchar = xterm.lines.get(0)[i]; |
4afa08da JB |
772 | if (i % 2) { |
773 | expect(tchar[1]).eql(''); | |
774 | expect(tchar[1].length).eql(0); | |
775 | expect(tchar[2]).eql(0); | |
776 | } else { | |
777 | expect(tchar[1]).eql('¥\u0301'); | |
778 | expect(tchar[1].length).eql(2); | |
779 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 780 | } |
4afa08da | 781 | } |
607c8191 | 782 | tchar = xterm.lines.get(1)[0]; |
4afa08da JB |
783 | expect(tchar[1]).eql('¥\u0301'); |
784 | expect(tchar[1].length).eql(2); | |
785 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 786 | }); |
4afa08da JB |
787 | it('line of surrogate fullwidth with combining odd', function() { |
788 | xterm.wraparoundMode = true; | |
789 | xterm.x = 1; | |
790 | xterm.write(Array(50).join('\ud843\ude6d\u0301')); | |
791 | for (var i=1; i<xterm.cols-1; ++i) { | |
607c8191 | 792 | var tchar = xterm.lines.get(0)[i]; |
4afa08da JB |
793 | if (!(i % 2)) { |
794 | expect(tchar[1]).eql(''); | |
795 | expect(tchar[1].length).eql(0); | |
796 | expect(tchar[2]).eql(0); | |
797 | } else { | |
798 | expect(tchar[1]).eql('\ud843\ude6d\u0301'); | |
799 | expect(tchar[1].length).eql(3); | |
800 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 801 | } |
4afa08da | 802 | } |
607c8191 | 803 | tchar = xterm.lines.get(0)[xterm.cols-1]; |
4afa08da JB |
804 | expect(tchar[1]).eql(' '); |
805 | expect(tchar[1].length).eql(1); | |
806 | expect(tchar[2]).eql(1); | |
607c8191 | 807 | tchar = xterm.lines.get(1)[0]; |
4afa08da JB |
808 | expect(tchar[1]).eql('\ud843\ude6d\u0301'); |
809 | expect(tchar[1].length).eql(3); | |
810 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 811 | }); |
4afa08da JB |
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) { | |
607c8191 | 816 | var tchar = xterm.lines.get(0)[i]; |
4afa08da JB |
817 | if (i % 2) { |
818 | expect(tchar[1]).eql(''); | |
819 | expect(tchar[1].length).eql(0); | |
820 | expect(tchar[2]).eql(0); | |
821 | } else { | |
822 | expect(tchar[1]).eql('\ud843\ude6d\u0301'); | |
823 | expect(tchar[1].length).eql(3); | |
824 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 825 | } |
4afa08da | 826 | } |
607c8191 | 827 | tchar = xterm.lines.get(1)[0]; |
4afa08da JB |
828 | expect(tchar[1]).eql('\ud843\ude6d\u0301'); |
829 | expect(tchar[1].length).eql(3); | |
830 | expect(tchar[2]).eql(2); | |
c3bc59b5 | 831 | }); |
4afa08da | 832 | }); |
c3bc59b5 | 833 | |
4afa08da JB |
834 | describe('insert mode', function() { |
835 | it('halfwidth - all', function () { | |
836 | xterm.write(Array(9).join('0123456789').slice(-80)); | |
837 | xterm.x = 10; | |
838 | xterm.y = 0; | |
839 | xterm.insertMode = true; | |
840 | xterm.write('abcde'); | |
607c8191 DI |
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'); | |
4afa08da JB |
846 | }); |
847 | it('fullwidth - insert', function() { | |
848 | xterm.write(Array(9).join('0123456789').slice(-80)); | |
849 | xterm.x = 10; | |
850 | xterm.y = 0; | |
851 | xterm.insertMode = true; | |
852 | xterm.write('¥¥¥'); | |
607c8191 DI |
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'); | |
4afa08da JB |
859 | }); |
860 | it('fullwidth - right border', function() { | |
861 | xterm.write(Array(41).join('¥')); | |
862 | xterm.x = 10; | |
863 | xterm.y = 0; | |
864 | xterm.insertMode = true; | |
865 | xterm.write('a'); | |
607c8191 DI |
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 | |
4afa08da | 870 | xterm.write('b'); |
607c8191 DI |
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 | |
4afa08da JB |
875 | }); |
876 | }); | |
fa093e2b | 877 | }); |