From 6fd0153b91e4bf525ac1cb8368faff3af759f495 Mon Sep 17 00:00:00 2001 From: Adem Gaygusuz Date: Sat, 2 Jun 2018 13:14:56 +0100 Subject: [PATCH] Fix cli cleanup exit command after auto completing --- src/js/tabs/cli.js | 80 ++++++++++++++++++++-------------------------- test/tabs/cli.js | 37 +++++++++++++++------ 2 files changed, 63 insertions(+), 54 deletions(-) diff --git a/src/js/tabs/cli.js b/src/js/tabs/cli.js index 2b8a803b..2a724953 100644 --- a/src/js/tabs/cli.js +++ b/src/js/tabs/cli.js @@ -11,6 +11,36 @@ function removePromptHash(promptText) { return promptText.replace(/^# /, ''); } +function cliBufferCharsToDelete(command, buffer) { + var commonChars = 0; + for (var i = 0;i < buffer.length;i++) { + if (command[i] === buffer[i]) { + commonChars++; + } else { + break; + } + } + + return buffer.length - commonChars; +} + +function commandWithBackSpaces(command, buffer, noOfCharsToDelete) { + const backspace = String.fromCharCode(127); + return backspace.repeat(noOfCharsToDelete) + command.substring(buffer.length - noOfCharsToDelete, command.length); +} + +function getCliCommand(command, cliBuffer) { + const buffer = removePromptHash(cliBuffer); + const bufferRegex = new RegExp('^' + buffer, 'g'); + if (command.match(bufferRegex)) { + return command.replace(bufferRegex, ''); + } + + const noOfCharsToDelete = cliBufferCharsToDelete(command, buffer); + + return commandWithBackSpaces(command, buffer, noOfCharsToDelete); +} + TABS.cli.initialize = function (callback) { var self = this; @@ -61,7 +91,7 @@ TABS.cli.initialize = function (callback) { writer.write(new Blob([self.outputHistory], {type: 'text/plain'})); } else { console.log('write complete'); - }; + } }; writer.truncate(0); @@ -71,36 +101,6 @@ TABS.cli.initialize = function (callback) { }); }); - function cliBufferCharsToDelete(command, buffer) { - var commonChars = 0; - for (var i = 0;i < buffer.length;i++) { - if (command[i] === buffer[i]) { - commonChars++; - } else { - break; - } - } - - return buffer.length - commonChars; - } - - function commandWithBackSpaces(command, buffer, noOfCharsToDelete) { - const backspace = String.fromCharCode(127); - return backspace.repeat(noOfCharsToDelete) + command.substring(buffer.length - noOfCharsToDelete, command.length); - } - - function getCliCommand(command, cliBuffer) { - const buffer = removePromptHash(cliBuffer); - const bufferRegex = new RegExp('^' + buffer, 'g'); - if (command.match(bufferRegex)) { - return command.replace(bufferRegex, ''); - } - - const noOfCharsToDelete = cliBufferCharsToDelete(command, buffer); - - return commandWithBackSpaces(command, buffer, noOfCharsToDelete); - } - // Tab key detection must be on keydown, // `keypress`/`keyup` happens too late, as `textarea` will have already lost focus. textarea.keydown(function (event) { @@ -134,7 +134,7 @@ TABS.cli.initialize = function (callback) { if (line.toLowerCase().startsWith('profile')) { processingDelay = self.profileSwitchDelayMs; } - const isLastCommand = index + 1 === outputArray.length; + const isLastCommand = outputArray.length === index + 1; if (isLastCommand && self.cliBuffer) { line = getCliCommand(line, self.cliBuffer); } @@ -317,11 +317,11 @@ TABS.cli.read = function (readInfo) { }; TABS.cli.sendLine = function (line, callback) { - TABS.cli.send(line + '\n', callback); + this.send(line + '\n', callback); }; TABS.cli.sendAutoComplete = function (line, callback) { - TABS.cli.send(line + '\t', callback); + this.send(line + '\t', callback); }; TABS.cli.send = function (line, callback) { @@ -340,17 +340,7 @@ TABS.cli.cleanup = function (callback) { if (callback) callback(); return; } - - var bufferOut = new ArrayBuffer(5); - var bufView = new Uint8Array(bufferOut); - - bufView[0] = 0x65; // e - bufView[1] = 0x78; // x - bufView[2] = 0x69; // i - bufView[3] = 0x74; // t - bufView[4] = 0x0D; // enter - - serial.send(bufferOut, function (writeInfo) { + this.send(getCliCommand('exit\r', this.cliBuffer), function (writeInfo) { // we could handle this "nicely", but this will do for now // (another approach is however much more complicated): // we can setup an interval asking for data lets say every 200ms, when data arrives, callback will be triggered and tab switched diff --git a/test/tabs/cli.js b/test/tabs/cli.js index 8810de6b..a0944187 100644 --- a/test/tabs/cli.js +++ b/test/tabs/cli.js @@ -35,14 +35,17 @@ describe('TABS.cli', () => { }); it('ambiguous auto-complete results', () => { + TABS.cli.cliBuffer = 'se'; + TABS.cli.read({ data: toArrayBuffer('\r\033[Kserialpassthrough\tservo\r\n# ser') }); // Ambigous auto-complete from firmware is preceded with an \r carriage return + // which only renders a line break on Mac const expectedValue = GUI.operating_system === "MacOS" ? - '
serialpassthrough\tservo
' : - 'serialpassthrough\tservo
'; + 'se
serialpassthrough\tservo
' : + 'seserialpassthrough\tservo
'; expect(cliOutput.html()).to.equal(expectedValue); expect(cliPrompt.val()).to.equal('ser'); }); @@ -91,6 +94,8 @@ describe('TABS.cli', () => { input.trigger(event); } + const backspaceCode = String.fromCharCode(127); + describe('input', () => { const content = $('
').attr('id', 'content'); const cliTab = $('
').addClass('tab-cli'); @@ -181,10 +186,8 @@ describe('TABS.cli', () => { triggerTabKey(cliPrompt); - const backspace = String.fromCharCode(127); - expect(TABS.cli.send).to.have.been.calledOnce; - expect(TABS.cli.send).to.have.been.calledWith(backspace.repeat(3) + '\t'); + expect(TABS.cli.send).to.have.been.calledWith(backspaceCode.repeat(3) + '\t'); done(); }); }); @@ -225,15 +228,13 @@ describe('TABS.cli', () => { triggerEnterKey(cliPrompt); - const backspace = String.fromCharCode(127); - expect(TABS.cli.send).to.have.been.calledOnce; - expect(TABS.cli.send).to.have.been.calledWith(backspace.repeat(3) + '\n'); + expect(TABS.cli.send).to.have.been.calledWith(backspaceCode.repeat(3) + '\n'); done(); }); }); - it('cliBufer is cleared on startup', done => { + it('cliBuffer is cleared on startup', done => { TABS.cli.cliBuffer = '# serial'; TABS.cli.initialize(() => { @@ -241,5 +242,23 @@ describe('TABS.cli', () => { done(); }); }); + + it('exit upon cleanup clears cliBuffer first', done => { + CONFIGURATOR.connectionValid = true; + TABS.cli.cliValid = true; + + + TABS.cli.initialize(() => { + const commandInBuffer = 'resource'; + + TABS.cli.cliBuffer = `# ${commandInBuffer}`; + + TABS.cli.cleanup(); + + expect(TABS.cli.send).to.have.been.calledOnce; + expect(TABS.cli.send).to.have.been.calledWith(backspaceCode.repeat(commandInBuffer.length) + 'exit\r'); + done(); + }); + }); }); });