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