# selftest_vim.exp -- drives vim.tiny over a REAL pty, the curses half of # 58-vim-tiny.test. # # Everything in the .test file's Ex leg runs with `-e -s`, which never calls # termcap_active / starttermcap() at all: silent Ex mode reads commands from a # pipe and writes nothing to a terminal, so none of it touches tgetent(), the # /etc/terminfo lookup, raw mode, or the key decoder. Those are exactly what this # payload is for, and they are the half of the port that the --with-tlib=tinfo # change in vim-tiny_%.bbappend exists to make work -- so an all-green Ex leg with # this payload red would mean the editor ships and cannot be used. # # WHY THE VERDICTS ARE ON DISK, NOT ON THE SCREEN -- the same finding # selftest_nano.exp records, and it reproduces here. The first burst (terminal # setup + the intro screen) arrives reliably; matching anything vim repaints # afterwards is not dependable on this target even though vim is demonstrably # still running and still obeying keystrokes. A screen scrape is also the WEAKER # assertion -- an editor can repaint a convincing lie -- so this payload types # blind against settle delays and lets 58-vim-tiny.test assert THE BYTES THAT # REACHED THE DISK. The one screen assertion kept (V1intro) is the one measured to # be reliable, and it is the strongest single statement available: vim only paints # that banner after tgetent() has answered and the terminfo entry for $TERM has # been found, which is the whole subject of the recipe change. # # EVERY SESSION IS -u NONE -n. -u NONE so no vimrc anywhere can change the # keystroke meanings these verdicts depend on, and -n so no swap file is created: # a leftover swap from a killed run would put a "swap file already exists" prompt # in front of the next session and hang it, turning one failure into all of them. # # Keystrokes are plain bytes -- i, ESC, d, :, w, q -- EXCEPT the deliberate one: # S4 sends the Down arrow, ESC [ B. That is the runtime risk worth naming, because # the same ESC byte that starts the sequence is also vim's own "leave insert mode" # key, so vim must distinguish them by the inter-byte gap that this runtime's # timers are known to distort. It is measured through the disk: after Down, dd # must delete line 2. # # argv: -- created and pre-seeded by 58-vim-tiny.test, which asserts the # resulting files. # Emits V- OK/FAIL lines, then ALL-VIM-OK iff every case passed. log_user 0 set stty_init "rows 24 columns 80" set env(TERM) "xterm" # GENEROUS RATHER THAN TIGHT -- HEADROOM, NOT A FIX. Read this with the V1elapsed # line below, which exists so the number here can never drift back into folklore: # the intro is MEASURED at 1-2 s across runs, so ten seconds was never the # constraint and raising it to sixty did not make anything work. It is kept only # because a bound is worth having slack on a loaded host, and because on a green # run it costs nothing -- a timeout is only ever paid by a case that was going to # fail anyway. # # What it is NOT is an explanation of the one intro miss seen during development. # That miss happened in the single run whose .test still carried a broken case # spawning an EXTRA vim that died on an Ex error just before this payload, and it # has not reproduced in the three runs since. A guest does not return memory on # process exit (see the brintos-selftests README), so that extra 20 MB # instantiation is the obvious suspect -- but it was never A/B'd, so it stays a # suspect. Do not promote it to a cause here, and do not "fix" a future intro miss # by raising this number again: measure V1elapsed first. set timeout 60 set work [lindex $argv 0] set pass 0 set total 0 proc verdict {tag ok} { global pass total incr total if {$ok} { incr pass; puts "V-$tag OK" } else { puts "V-$tag FAIL" } } # --- S1: the intro screen, on a terminal, with no file argument. # Reaching this banner means tgetent() resolved out of libtinfo.a, the xterm entry # was found in /etc/terminfo, raw mode was entered and the first repaint reached # the pty. A build that linked but could not find a terminal library dies here # instead, with "E558: Terminal entry not found in terminfo". set ok 0 set t0 [clock seconds] spawn -noecho vim.tiny -u NONE -n expect { "VIM - Vi IMproved" { set ok 1 } timeout {} eof {} } verdict V1intro $ok puts "V-V1elapsed [expr {[clock seconds] - $t0}]s" sleep 1 send ":q!\r" expect { eof {} timeout {} } lassign [wait] _p _s _oserr rc0 verdict V2introexit [expr {$_oserr == 0 && $rc0 == 0}] # --- S2: insert mode. `i`, two lines of text, ESC, :wq -- the plainest possible # proof that a keystroke reached the editor and a buffer change reached the disk. spawn -noecho vim.tiny -u NONE -n $work/typed.txt sleep 2 send "i" sleep 1 send "hello from vim\rsecond line" sleep 1 send "\033" sleep 1 send ":wq\r" expect { eof {} timeout {} } lassign [wait] _p _s _oserr rc1 verdict V3typedexit [expr {$_oserr == 0 && $rc1 == 0}] # --- S3: normal-mode `dd` on line 1 -- two identical plain bytes, no escape and # no mode change, so a failure here is the command dispatcher rather than timing. spawn -noecho vim.tiny -u NONE -n $work/cut.txt sleep 2 send "dd" sleep 1 send ":wq\r" expect { eof {} timeout {} } lassign [wait] _p _s _oserr rc2 verdict V4cutexit [expr {$_oserr == 0 && $rc2 == 0}] # --- S4: the escape-sequence probe. Down arrow (ESC [ B) then dd, so WHICH line # disappears is the answer: line 2 (bravo) means the three bytes were decoded as # one key rather than as ESC followed by two typed characters. spawn -noecho vim.tiny -u NONE -n $work/arrow.txt sleep 2 send "\033\[B" sleep 1 send "dd" sleep 1 send ":wq\r" expect { eof {} timeout {} } lassign [wait] _p _s _oserr rc3 verdict V5arrowexit [expr {$_oserr == 0 && $rc3 == 0}] puts "V-SUMMARY pass=$pass/$total" if {$pass == $total} { puts "ALL-VIM-OK" }