From f08ad87e7a243086b1db96b57fd2faaed1ed2298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sat, 3 Sep 2022 13:25:20 +0200 Subject: [PATCH] unit tests --- src/common/InputHandler.test.ts | 73 +++++++++++++++++++++++++++++++++ src/common/InputHandler.ts | 5 ++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index 2fa4ac2f..143686a1 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -2146,6 +2146,79 @@ describe('InputHandler', () => { }); }); }); + describe('DECRQM', () => { + const reportStack: string[] = []; + beforeEach(() => { + reportStack.length = 0; + coreService.onData(data => reportStack.push(data)); + }); + it('ANSI 2 (keyboard action mode)', async () => { + await inputHandler.parseP('\x1b[2$p'); + assert.deepEqual(reportStack.pop(), '\x1b[2;3$y'); // always set + }); + it('ANSI 4 (insert mode)', async () => { + await inputHandler.parseP('\x1b[4$p'); + assert.deepEqual(reportStack.pop(), '\x1b[4;2$y'); // reset by default + await inputHandler.parseP('\x1b[4h'); + await inputHandler.parseP('\x1b[4$p'); + assert.deepEqual(reportStack.pop(), '\x1b[4;1$y'); // now active + await inputHandler.parseP('\x1b[4l'); + await inputHandler.parseP('\x1b[4$p'); + assert.deepEqual(reportStack.pop(), '\x1b[4;2$y'); // again reset + }); + it('ANSI 12 (send/receive)', async () => { + await inputHandler.parseP('\x1b[12$p'); + assert.deepEqual(reportStack.pop(), '\x1b[12;4$y'); // always reset + }); + it('ANSI 20 (newline mode)', async () => { + await inputHandler.parseP('\x1b[20$p'); + assert.deepEqual(reportStack.pop(), '\x1b[20;2$y'); // reset by default + await inputHandler.parseP('\x1b[20h'); + await inputHandler.parseP('\x1b[20$p'); + assert.deepEqual(reportStack.pop(), '\x1b[20;1$y'); // now active + await inputHandler.parseP('\x1b[20l'); + await inputHandler.parseP('\x1b[20$p'); + assert.deepEqual(reportStack.pop(), '\x1b[20;2$y'); // again reset + }); + it('ANSI unknown', async () => { + await inputHandler.parseP('\x1b[1234$p'); + assert.deepEqual(reportStack.pop(), '\x1b[1234;0$y'); // not recognized + }); + it('DEC privates with set/reset semantic', async () => { + // initially reset + const reset = [1, 6, 9, 12, 45, 66, 1000, 1002, 1003, 1004, 1006, 1016, 47, 1047, 1049, 2004]; + for (const mode of reset) { + await inputHandler.parseP(`\x1b[?${mode}$p`); + assert.deepEqual(reportStack.pop(), `\x1b[?${mode};2$y`); // initial reset + await inputHandler.parseP(`\x1b[?${mode}h`); + await inputHandler.parseP(`\x1b[?${mode}$p`); + assert.deepEqual(reportStack.pop(), `\x1b[?${mode};1$y`); // now active + await inputHandler.parseP(`\x1b[?${mode}l`); + await inputHandler.parseP(`\x1b[?${mode}$p`); + assert.deepEqual(reportStack.pop(), `\x1b[?${mode};2$y`); // again reset + } + // initially set + const set = [7, 25]; + for (const mode of set) { + await inputHandler.parseP(`\x1b[?${mode}$p`); + assert.deepEqual(reportStack.pop(), `\x1b[?${mode};1$y`); // initial set + await inputHandler.parseP(`\x1b[?${mode}l`); + await inputHandler.parseP(`\x1b[?${mode}$p`); + assert.deepEqual(reportStack.pop(), `\x1b[?${mode};2$y`); // now inactive + await inputHandler.parseP(`\x1b[?${mode}h`); + await inputHandler.parseP(`\x1b[?${mode}$p`); + assert.deepEqual(reportStack.pop(), `\x1b[?${mode};1$y`); // again set + } + }); + it('DEC privates perma modes', async () => { + // [mode number, state value] + const perma = [[3, 0], [8, 3], [1005, 4], [1015, 4], [1048, 1]]; + for (const [mode, value] of perma) { + await inputHandler.parseP(`\x1b[?${mode}$p`); + assert.deepEqual(reportStack.pop(), `\x1b[?${mode};${value}$y`); + } + }); + }); }); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 18db078f..6b3801a8 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -2270,7 +2270,7 @@ export class InputHandler extends Disposable implements IInputHandler { * For modes not understood xterm.js always returns `notRecognized`. In general this means, * that a certain operation mode is not implemented and cannot be used. * - * Modes changing the active terminal buffer (47, 1047, 1048, 1049) are not subqueried + * Modes changing the active terminal buffer (47, 1047, 1049) are not subqueried * and only report, whether the alternate buffer is set. * * Mouse encodings and mouse protocols are handled mutual exclusive, @@ -2332,7 +2332,8 @@ export class InputHandler extends Disposable implements IInputHandler { if (p === 1006) return f(p, b2v(mouseEncoding === 'SGR')); if (p === 1015) return f(p, V.PERMANENTLY_RESET); if (p === 1016) return f(p, b2v(mouseEncoding === 'SGR_PIXELS')); - if (p === 47 || p === 1047 || p === 1048 || p === 1049) return f(p, b2v(active === alt)); + if (p === 1048) return f(p, V.SET); // xterm always returns SET here + if (p === 47 || p === 1047 || p === 1049) return f(p, b2v(active === alt)); if (p === 2004) return f(p, b2v(dm.bracketedPasteMode)); return f(p, V.NOT_RECOGNIZED); }