1'use strict'; 2const common = require('../common'); 3const { PassThrough } = require('stream'); 4const readline = require('readline'); 5const assert = require('assert'); 6 7common.skipIfDumbTerminal(); 8 9{ 10 const input = new PassThrough(); 11 const rl = readline.createInterface({ 12 terminal: true, 13 input: input 14 }); 15 16 rl.on('line', common.mustCall((data) => { 17 assert.strictEqual(data, 'abc'); 18 })); 19 20 input.end('abc'); 21} 22 23{ 24 const input = new PassThrough(); 25 const rl = readline.createInterface({ 26 terminal: true, 27 input: input 28 }); 29 30 rl.on('line', common.mustNotCall('must not be called before newline')); 31 32 input.write('abc'); 33} 34 35{ 36 const input = new PassThrough(); 37 const rl = readline.createInterface({ 38 terminal: true, 39 input: input 40 }); 41 42 rl.on('line', common.mustCall((data) => { 43 assert.strictEqual(data, 'abc'); 44 })); 45 46 input.write('abc\n'); 47} 48 49{ 50 const input = new PassThrough(); 51 const rl = readline.createInterface({ 52 terminal: true, 53 input: input 54 }); 55 56 rl.write('foo'); 57 assert.strictEqual(rl.cursor, 3); 58 59 const key = { 60 xterm: { 61 home: ['\x1b[H', { ctrl: true, name: 'a' }], 62 end: ['\x1b[F', { ctrl: true, name: 'e' }], 63 }, 64 gnome: { 65 home: ['\x1bOH', { ctrl: true, name: 'a' }], 66 end: ['\x1bOF', { ctrl: true, name: 'e' }] 67 }, 68 rxvt: { 69 home: ['\x1b[7', { ctrl: true, name: 'a' }], 70 end: ['\x1b[8', { ctrl: true, name: 'e' }] 71 }, 72 putty: { 73 home: ['\x1b[1~', { ctrl: true, name: 'a' }], 74 end: ['\x1b[>~', { ctrl: true, name: 'e' }] 75 } 76 }; 77 78 [key.xterm, key.gnome, key.rxvt, key.putty].forEach(function(key) { 79 rl.write.apply(rl, key.home); 80 assert.strictEqual(rl.cursor, 0); 81 rl.write.apply(rl, key.end); 82 assert.strictEqual(rl.cursor, 3); 83 }); 84 85} 86 87{ 88 const input = new PassThrough(); 89 const rl = readline.createInterface({ 90 terminal: true, 91 input: input 92 }); 93 94 const key = { 95 xterm: { 96 home: ['\x1b[H', { ctrl: true, name: 'a' }], 97 metab: ['\x1bb', { meta: true, name: 'b' }], 98 metaf: ['\x1bf', { meta: true, name: 'f' }], 99 } 100 }; 101 102 rl.write('foo bar.hop/zoo'); 103 rl.write.apply(rl, key.xterm.home); 104 [ 105 { cursor: 4, key: key.xterm.metaf }, 106 { cursor: 7, key: key.xterm.metaf }, 107 { cursor: 8, key: key.xterm.metaf }, 108 { cursor: 11, key: key.xterm.metaf }, 109 { cursor: 12, key: key.xterm.metaf }, 110 { cursor: 15, key: key.xterm.metaf }, 111 { cursor: 12, key: key.xterm.metab }, 112 { cursor: 11, key: key.xterm.metab }, 113 { cursor: 8, key: key.xterm.metab }, 114 { cursor: 7, key: key.xterm.metab }, 115 { cursor: 4, key: key.xterm.metab }, 116 { cursor: 0, key: key.xterm.metab }, 117 ].forEach(function(action) { 118 rl.write.apply(rl, action.key); 119 assert.strictEqual(rl.cursor, action.cursor); 120 }); 121} 122 123{ 124 const input = new PassThrough(); 125 const rl = readline.createInterface({ 126 terminal: true, 127 input: input 128 }); 129 130 const key = { 131 xterm: { 132 home: ['\x1b[H', { ctrl: true, name: 'a' }], 133 metad: ['\x1bd', { meta: true, name: 'd' }] 134 } 135 }; 136 137 rl.write('foo bar.hop/zoo'); 138 rl.write.apply(rl, key.xterm.home); 139 [ 140 'bar.hop/zoo', 141 '.hop/zoo', 142 'hop/zoo', 143 '/zoo', 144 'zoo', 145 '', 146 ].forEach(function(expectedLine) { 147 rl.write.apply(rl, key.xterm.metad); 148 assert.strictEqual(rl.cursor, 0); 149 assert.strictEqual(rl.line, expectedLine); 150 }); 151} 152