11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst assert = require('assert'); 51cb0ef41Sopenharmony_ciconst repl = require('repl'); 61cb0ef41Sopenharmony_ciconst ArrayStream = require('../common/arraystream'); 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_cicommon.skipIfDumbTerminal(); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci// \u001b[nG - Moves the cursor to n st column 111cb0ef41Sopenharmony_ci// \u001b[0J - Clear screen 121cb0ef41Sopenharmony_ci// \u001b[0K - Clear to line end 131cb0ef41Sopenharmony_ciconst terminalCode = '\u001b[1G\u001b[0J> \u001b[3G'; 141cb0ef41Sopenharmony_ciconst terminalCodeRegex = new RegExp(terminalCode.replace(/\[/g, '\\['), 'g'); 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cifunction run({ input, output, event, checkTerminalCodes = true }) { 171cb0ef41Sopenharmony_ci const stream = new ArrayStream(); 181cb0ef41Sopenharmony_ci let found = ''; 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci stream.write = (msg) => found += msg.replace('\r', ''); 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci let expected = 231cb0ef41Sopenharmony_ci `${terminalCode}.editor\n` + 241cb0ef41Sopenharmony_ci '// Entering editor mode (Ctrl+D to finish, Ctrl+C to cancel)\n' + 251cb0ef41Sopenharmony_ci `${input}${output}\n${terminalCode}`; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci const replServer = repl.start({ 281cb0ef41Sopenharmony_ci prompt: '> ', 291cb0ef41Sopenharmony_ci terminal: true, 301cb0ef41Sopenharmony_ci input: stream, 311cb0ef41Sopenharmony_ci output: stream, 321cb0ef41Sopenharmony_ci useColors: false 331cb0ef41Sopenharmony_ci }); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci stream.emit('data', '.editor\n'); 361cb0ef41Sopenharmony_ci stream.emit('data', input); 371cb0ef41Sopenharmony_ci replServer.write('', event); 381cb0ef41Sopenharmony_ci replServer.close(); 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci if (!checkTerminalCodes) { 411cb0ef41Sopenharmony_ci found = found.replace(terminalCodeRegex, '').replace(/\n/g, ''); 421cb0ef41Sopenharmony_ci expected = expected.replace(terminalCodeRegex, '').replace(/\n/g, ''); 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci assert.strictEqual(found, expected); 461cb0ef41Sopenharmony_ci} 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciconst tests = [ 491cb0ef41Sopenharmony_ci { 501cb0ef41Sopenharmony_ci input: '', 511cb0ef41Sopenharmony_ci output: '\n(To exit, press Ctrl+C again or Ctrl+D or type .exit)', 521cb0ef41Sopenharmony_ci event: { ctrl: true, name: 'c' } 531cb0ef41Sopenharmony_ci }, 541cb0ef41Sopenharmony_ci { 551cb0ef41Sopenharmony_ci input: 'let i = 1;', 561cb0ef41Sopenharmony_ci output: '', 571cb0ef41Sopenharmony_ci event: { ctrl: true, name: 'c' } 581cb0ef41Sopenharmony_ci }, 591cb0ef41Sopenharmony_ci { 601cb0ef41Sopenharmony_ci input: 'let i = 1;\ni + 3', 611cb0ef41Sopenharmony_ci output: '\n4', 621cb0ef41Sopenharmony_ci event: { ctrl: true, name: 'd' } 631cb0ef41Sopenharmony_ci }, 641cb0ef41Sopenharmony_ci { 651cb0ef41Sopenharmony_ci input: ' let i = 1;\ni + 3', 661cb0ef41Sopenharmony_ci output: '\n4', 671cb0ef41Sopenharmony_ci event: { ctrl: true, name: 'd' } 681cb0ef41Sopenharmony_ci }, 691cb0ef41Sopenharmony_ci { 701cb0ef41Sopenharmony_ci input: '', 711cb0ef41Sopenharmony_ci output: '', 721cb0ef41Sopenharmony_ci checkTerminalCodes: false, 731cb0ef41Sopenharmony_ci event: null, 741cb0ef41Sopenharmony_ci }, 751cb0ef41Sopenharmony_ci]; 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_citests.forEach(run); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci// Auto code alignment for .editor mode 801cb0ef41Sopenharmony_cifunction testCodeAlignment({ input, cursor = 0, line = '' }) { 811cb0ef41Sopenharmony_ci const stream = new ArrayStream(); 821cb0ef41Sopenharmony_ci const outputStream = new ArrayStream(); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci stream.write = () => { throw new Error('Writing not allowed!'); }; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci const replServer = repl.start({ 871cb0ef41Sopenharmony_ci prompt: '> ', 881cb0ef41Sopenharmony_ci terminal: true, 891cb0ef41Sopenharmony_ci input: stream, 901cb0ef41Sopenharmony_ci output: outputStream, 911cb0ef41Sopenharmony_ci useColors: false 921cb0ef41Sopenharmony_ci }); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci stream.emit('data', '.editor\n'); 951cb0ef41Sopenharmony_ci input.split('').forEach((ch) => stream.emit('data', ch)); 961cb0ef41Sopenharmony_ci // Test the content of current line and the cursor position 971cb0ef41Sopenharmony_ci assert.strictEqual(line, replServer.line); 981cb0ef41Sopenharmony_ci assert.strictEqual(cursor, replServer.cursor); 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci replServer.write('', { ctrl: true, name: 'd' }); 1011cb0ef41Sopenharmony_ci replServer.close(); 1021cb0ef41Sopenharmony_ci // Ensure that empty lines are not saved in history 1031cb0ef41Sopenharmony_ci assert.notStrictEqual(replServer.history[0].trim(), ''); 1041cb0ef41Sopenharmony_ci} 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ciconst codeAlignmentTests = [ 1071cb0ef41Sopenharmony_ci { 1081cb0ef41Sopenharmony_ci input: 'let i = 1;\n' 1091cb0ef41Sopenharmony_ci }, 1101cb0ef41Sopenharmony_ci { 1111cb0ef41Sopenharmony_ci input: ' let i = 1;\n', 1121cb0ef41Sopenharmony_ci cursor: 2, 1131cb0ef41Sopenharmony_ci line: ' ' 1141cb0ef41Sopenharmony_ci }, 1151cb0ef41Sopenharmony_ci { 1161cb0ef41Sopenharmony_ci input: ' let i = 1;\n', 1171cb0ef41Sopenharmony_ci cursor: 5, 1181cb0ef41Sopenharmony_ci line: ' ' 1191cb0ef41Sopenharmony_ci }, 1201cb0ef41Sopenharmony_ci { 1211cb0ef41Sopenharmony_ci input: ' let i = 1;\n let j = 2\n', 1221cb0ef41Sopenharmony_ci cursor: 2, 1231cb0ef41Sopenharmony_ci line: ' ' 1241cb0ef41Sopenharmony_ci }, 1251cb0ef41Sopenharmony_ci]; 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_cicodeAlignmentTests.forEach(testCodeAlignment); 128