import assert from 'node:assert/strict'; import { resolve } from 'node:path'; import { once } from 'node:events'; import { Terminal } from './terminal.mjs'; const terminal = new Terminal(resolve(process.argv[2] || 'rc2')); try { await terminal.expect('% '); await terminal.command("fn replacement { bind_result='echo selected' }; bind ctrl-r replace replacement"); terminal.send('echo draft\x12'); await terminal.expect('% echo selected'); terminal.send('\r'); assert.match(await terminal.expect('\r\n% '), /\r\nselected\r\n/); await terminal.command("fn insertion { bind_result=('a b' 'it''s;*') }; bind ctrl-t insert insertion"); terminal.send('echo tail\x01\x1b[C\x1b[C\x1b[C\x1b[C\x1b[C\x14'); await terminal.expect("% echo 'a b' 'it''s;*'"); terminal.send(' \r'); assert.match(await terminal.expect('\r\n% '), /\r\na b it's;\* tail\r\n/); terminal.send("echo 'tail'\x1b[D\x14"); await terminal.expect("% echo 'tail"); terminal.send('\r'); assert.match(await terminal.expect('\r\n% '), /\r\ntaila b it's;\*\r\n/); await terminal.command('fn cancel { bind_result=wrong; return 1 }; bind ctrl-r replace cancel'); terminal.send('echo ac\x1b[D\x12'); await terminal.expect('% echo ac'); terminal.send('b\r'); assert.match(await terminal.expect('\r\n% '), /\r\nabc\r\n/); await terminal.command('fn empty { bind_result=() }; bind ctrl-r replace empty'); terminal.send('echo ac\x1b[D\x12'); await terminal.expect('\r\n\r\x1b[J% echo ac'); terminal.send('b\r'); assert.match(await terminal.expect('\r\n% '), /\r\nabc\r\n/); await terminal.command("fn wait_hook { sh -c 'echo HOOK_WAIT; exec sleep 30' }; bind ctrl-r run wait_hook"); terminal.send('echo ac\x1b[D\x12'); await terminal.expect('HOOK_WAIT\r\n'); terminal.send('\x03'); await terminal.expect('\r\x1b[J% echo ac'); terminal.send('b\r'); assert.match(await terminal.expect('\r\n% '), /\r\nabc\r\n/); await terminal.command('fn wait_hook { echo HOOK_START; sleep 30 }; bind ctrl-r run wait_hook'); terminal.send('echo ac\x1b[D\x12'); await terminal.expect('HOOK_START\r\n'); terminal.send('\x03'); await terminal.expect('\r\x1b[J% echo ac'); terminal.send('b\r'); assert.match(await terminal.expect('\r\n% '), /\r\nabc\r\n/); await terminal.command("fn context { echo CONTEXT:$1:$2; bind_result=ignored }; bind ctrl-r run context; bind_result=original; ~ no yes"); terminal.send('echo ac\x1b[D\x12'); await terminal.expect('CONTEXT:echo ac:6\r\n'); await terminal.expect('\r\x1b[J% echo ac'); terminal.send('\x15echo $status $bind_result\r'); assert.match(await terminal.expect('\r\n% '), /\r\n1 original\r\n/); await terminal.command("fn replacement { bind_result='echo survived' }; bind ctrl-r replace replacement"); await terminal.command('for (i in `{seq 1 5000}) { scratch=$i }; scratch=()'); terminal.send('\x12'); await terminal.expect('% echo survived'); terminal.send('\r'); assert.match(await terminal.expect('\r\n% '), /\r\nsurvived\r\n/); await terminal.command('fn clear { bind_result=\'\' }; bind ctrl-r replace clear'); terminal.send('echo discard\x12'); await terminal.expect('\r\n\r\x1b[J% '); terminal.send('echo cleared\r'); assert.match(await terminal.expect('\r\n% '), /\r\ncleared\r\n/); await terminal.command('fn directory { cd / }; bind alt-c run directory'); terminal.send('echo kept\x1bc'); await terminal.expect('% echo kept'); terminal.send('\r'); assert.match(await terminal.expect('\r\n% '), /\r\nkept\r\n/); assert.match(await terminal.command('pwd'), /\r\n\/\r\n/); assert.match(await terminal.command('bind'), /bind 'ctrl-r' replace 'clear'/); await terminal.command('bind -e ctrl-r'); assert.doesNotMatch(await terminal.command('bind'), /bind 'ctrl-r' replace/); await terminal.command("bind 'alt-;' run directory"); assert.match(await terminal.command('bind'), /bind 'alt-;' run 'directory'/); await terminal.command('fn leave { exit 17 }; bind ctrl-d run leave'); terminal.process.stdin.write('V\n'); await terminal.expect('[restore-check]\n'); const exit = once(terminal.process, 'exit'); terminal.send('\x04'); assert.equal((await exit)[0], 17); } finally { await terminal.close(); } console.log('Bind tests passed');