1'use strict'; 2 3const common = require('../common'); 4const assert = require('assert'); 5const repl = require('repl'); 6const ArrayStream = require('../common/arraystream'); 7 8common.skipIfDumbTerminal(); 9 10// \u001b[nG - Moves the cursor to n st column 11// \u001b[0J - Clear screen 12// \u001b[0K - Clear to line end 13const terminalCode = '\u001b[1G\u001b[0J> \u001b[3G'; 14const terminalCodeRegex = new RegExp(terminalCode.replace(/\[/g, '\\['), 'g'); 15 16function run({ input, output, event, checkTerminalCodes = true }) { 17 const stream = new ArrayStream(); 18 let found = ''; 19 20 stream.write = (msg) => found += msg.replace('\r', ''); 21 22 let expected = 23 `${terminalCode}.editor\n` + 24 '// Entering editor mode (Ctrl+D to finish, Ctrl+C to cancel)\n' + 25 `${input}${output}\n${terminalCode}`; 26 27 const replServer = repl.start({ 28 prompt: '> ', 29 terminal: true, 30 input: stream, 31 output: stream, 32 useColors: false 33 }); 34 35 stream.emit('data', '.editor\n'); 36 stream.emit('data', input); 37 replServer.write('', event); 38 replServer.close(); 39 40 if (!checkTerminalCodes) { 41 found = found.replace(terminalCodeRegex, '').replace(/\n/g, ''); 42 expected = expected.replace(terminalCodeRegex, '').replace(/\n/g, ''); 43 } 44 45 assert.strictEqual(found, expected); 46} 47 48const tests = [ 49 { 50 input: '', 51 output: '\n(To exit, press Ctrl+C again or Ctrl+D or type .exit)', 52 event: { ctrl: true, name: 'c' } 53 }, 54 { 55 input: 'let i = 1;', 56 output: '', 57 event: { ctrl: true, name: 'c' } 58 }, 59 { 60 input: 'let i = 1;\ni + 3', 61 output: '\n4', 62 event: { ctrl: true, name: 'd' } 63 }, 64 { 65 input: ' let i = 1;\ni + 3', 66 output: '\n4', 67 event: { ctrl: true, name: 'd' } 68 }, 69 { 70 input: '', 71 output: '', 72 checkTerminalCodes: false, 73 event: null, 74 }, 75]; 76 77tests.forEach(run); 78 79// Auto code alignment for .editor mode 80function testCodeAlignment({ input, cursor = 0, line = '' }) { 81 const stream = new ArrayStream(); 82 const outputStream = new ArrayStream(); 83 84 stream.write = () => { throw new Error('Writing not allowed!'); }; 85 86 const replServer = repl.start({ 87 prompt: '> ', 88 terminal: true, 89 input: stream, 90 output: outputStream, 91 useColors: false 92 }); 93 94 stream.emit('data', '.editor\n'); 95 input.split('').forEach((ch) => stream.emit('data', ch)); 96 // Test the content of current line and the cursor position 97 assert.strictEqual(line, replServer.line); 98 assert.strictEqual(cursor, replServer.cursor); 99 100 replServer.write('', { ctrl: true, name: 'd' }); 101 replServer.close(); 102 // Ensure that empty lines are not saved in history 103 assert.notStrictEqual(replServer.history[0].trim(), ''); 104} 105 106const codeAlignmentTests = [ 107 { 108 input: 'let i = 1;\n' 109 }, 110 { 111 input: ' let i = 1;\n', 112 cursor: 2, 113 line: ' ' 114 }, 115 { 116 input: ' let i = 1;\n', 117 cursor: 5, 118 line: ' ' 119 }, 120 { 121 input: ' let i = 1;\n let j = 2\n', 122 cursor: 2, 123 line: ' ' 124 }, 125]; 126 127codeAlignmentTests.forEach(testCodeAlignment); 128