From 79430a18ebe128bf961baea73dffb8bb59d18ab6 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Wed, 11 Nov 2020 16:03:52 -0800 Subject: [PATCH] ;ui: commit old WIP hledger-ui tests --- tests/ui/README | 7 ++ tests/ui/_hledger-ui.test | 28 +++++++ tests/ui/hledgerui2txt | 4 + tests/ui/uitest.empty | 156 ++++++++++++++++++++++++++++++++++++++ tests/ui/uitest.expect | 46 +++++++++++ tests/ui/uitest2.expect | 15 ++++ 6 files changed, 256 insertions(+) create mode 100644 tests/ui/README create mode 100644 tests/ui/_hledger-ui.test create mode 100755 tests/ui/hledgerui2txt create mode 100755 tests/ui/uitest.empty create mode 100755 tests/ui/uitest.expect create mode 100755 tests/ui/uitest2.expect diff --git a/tests/ui/README b/tests/ui/README new file mode 100644 index 000000000..12dfb7b01 --- /dev/null +++ b/tests/ui/README @@ -0,0 +1,7 @@ +Some old attempts at making automated tests for hledger-ui, +using either of + +- empty: http://empty.sourceforge.net or (perhaps not tried) https://github.com/ierton/empty +- expect: https://en.wikipedia.org/wiki/Expect + +Needed, but not working yet. \ No newline at end of file diff --git a/tests/ui/_hledger-ui.test b/tests/ui/_hledger-ui.test new file mode 100644 index 000000000..d6708a63b --- /dev/null +++ b/tests/ui/_hledger-ui.test @@ -0,0 +1,28 @@ +# 1. The accounts screen is shown on startup, with the top item selected. +$ ./uitest -f ../../examples/sample.journal +--- sample.journal account balances (1/8) + assets:bank:checking 0 + assets:bank:saving $1 + assets:cash $-2 + expenses:food $1 + expenses:supplies $1 + income:gifts $-1 + income:salary $-1 + liabilities:debts $1 + +# 2. It can be depth-limited at startup. +$ ./uitest -f ../../examples/sample.journal -1 +--- sample.journal account balances to depth 1 (1/4) + assets $-1 + expenses $2 + income $-2 + liabilities $1 + +# 3. When an account is depth clipped, register should show the transactions of it and its subs (#1208) +$ ./uitest -f ../../examples/sample.journal -1 --register assets:bank:checking +--- assets:bank:checking transactions (4/4) + 2008/01/01 income in:salary $1 $1 + 2008/06/01 gift in:gifts $1 $2 + 2008/06/02 save as:ba:saving $-1 $1 + 2008/12/31 * pay off li:debts $-1 0 +>= diff --git a/tests/ui/hledgerui2txt b/tests/ui/hledgerui2txt new file mode 100755 index 000000000..44fd5e3d6 --- /dev/null +++ b/tests/ui/hledgerui2txt @@ -0,0 +1,4 @@ +#!/bin/sh +# Convert hledger-ui's output to plain text. Extracted from uitest.sh, see comments there. +exec perl -pe 's/\e\[\d+;1H/\n/g; s/\e\[?.*?[\@-~]//g; s/$/\n/;' | \ + perl -ne 's/(─)+/---/; s/(─)+//; s/ +$//; print unless /^$/' # or /\?:help/' diff --git a/tests/ui/uitest.empty b/tests/ui/uitest.empty new file mode 100755 index 000000000..7b33f79dc --- /dev/null +++ b/tests/ui/uitest.empty @@ -0,0 +1,156 @@ +#!/bin/sh + +# Run hledger-ui in the background without needing an interactive +# terminal, passing through any arguments, and dump its first screen* +# as cleaned up plain text. This allows scripts to run hledger-ui and +# capture its output. +# * Or, all output from inputs hard-coded below. +# +# Here's some sample output for "tests/hledgeruicapture -f examples/sample.journal" +# showing the initial output (accounts screen) then the outputs from four inputs: +# RIGHT (draws register screen) +# UP (moves selection up one row; only the heading and old/new rows are redrawn) +# LEFT (draws accounts screen again) +# 1 (redraws accounts screen with depth limit 1). +# Note, +# - only lines which have been redrawn are shown (and perhaps redrawing parts of lines is also possible) +# - all inputs above cause the top line to be redrawn, which helps distinguish the outputs +# - the top line's border chars are converted to --- +# - empty lines and the bottom line (help & border) are omitted +# +# --- sample.journal account balances (1/8) +# assets:bank:checking 0 +# assets:bank:saving $1 +# assets:cash $-2 +# expenses:food $1 +# expenses:supplies $1 +# income:gifts $-1 +# income:salary $-1 +# liabilities:debts $1 +# --- assets:bank:checking transactions (4/4) +# 2008-01-01 income in:salary $1 $1 +# 2008-06-01 gift in:gifts $1 $2 +# 2008-06-02 save as:ba:saving $-1 $1 +# 2008-12-31 * pay off li:debts $-1 0 +# --- assets:bank:checking transactions (3/4) +# 2008-06-02 save as:ba:saving $-1 $1 +# 2008-12-31 * pay off li:debts $-1 0 +# --- sample.journal account balances (1/8) +# assets:bank:checking 0 +# assets:bank:saving $1 +# assets:cash $-2 +# expenses:food $1 +# expenses:supplies $1 +# income:gifts $-1 +# income:salary $-1 +# liabilities:debts $1 +# --- sample.journal account balances to depth 1 (1/4) +# assets $-1 +# expenses $2 +# income $-2 +# liabilities $1 +# +# +# Todo: +# - allow a sequence of inputs to be provided. Eg, first line of stdin +# is hledger-ui arguments, and each following line is an input. +# +# +# Requirements: +# - empty (http://empty.sourceforge.net) is used as a (complicated, +# delicate) way of running hledger-ui from a non-interactive script. +# It is included in tools/empty/ and should be installed in PATH. It +# seemed simpler than using expect (but maybe isn't). + +# For debugging: +# watch -n0.2 "pgrep -fl '(empty|hledger-ui)' | grep -v watch" +# https://www.linuxjournal.com/article/2156 + +# Convert a stream of hledger-ui ANSI output captured by empty +# to a plain text sequence of outputs, suitable for tests. +# Based on https://unix.stackexchange.com/a/4529/286158, Term::ANSIColor +# First regex: +# 1. convert "move to first column" escape sequences to newlines +# 2. strip remaining escape sequences +# 3. (replace empty's <<< delimiters with newlines - not any more, where have they gone ?) +# 4. add a final newline +# Second regex (because I couldn't fix newline matching in the first): +# 1. replace screen-width dash borders with short hyphen delimiters +# 2. strip trailing spaces on each line +# 3. hide empty lines +# 4. hide each screen's bottom help line +hledgerui2txt() +{ + perl -pe 's/\e\[\d+;1H/\n/g; s/\e\[?.*?[\@-~]//g; s/$/\n/;' | \ + perl -ne 's/(─)+/---/; s/(─)+//; s/ +$//; print unless /^$/ or /q:quit/' +} + +# Be sure not to leave empty and/or hledger-ui running if this script is killed. +# (Doesn't prevent occasional "Fatal open FIFO ... No such file or directory" errors.) +cleanup() { + (echo; echo "hledgeruicapture: interrupted, cleaning up") >&2 + if [[ -e p$$ ]]; then PID=$(cat p$$); kill $PID; rm -f c$$; fi +} +trap cleanup INT QUIT TERM + +# Start hledger-ui (and empty's monitor process) in the background, +# specifying input/output FIFOs (with process-specific names in case +# of concurrent testing). We don't use empty's default FIFOs because +# finding their paths in a script is a hassle. +empty -f -i i$$ -o o$$ -p p$$ hledger-ui "$@" + +# Wait for the first screen's final line (containing "q:quit"), then +# send 'q' causing hledger-ui to exit. +# Doesn't work if the line has already been displayed when this runs. +#empty -w -t 1 -i o$$ -o i$$ q:quit q + +# Wait long enough to ensure the first screen has rendered +# (assuming no crazy large data is being displayed). +sleep 0.1 + +# # Testing: send some other stuff +# U=$'\e[A' +# D=$'\e[B' +# R=$'\e[C' +# L=$'\e[D' +# empty -s -o i$$ $R; sleep 0.1 +# empty -s -o i$$ $U; sleep 0.1 +# empty -s -o i$$ $L; sleep 0.1 +# empty -s -o i$$ 1; sleep 0.1 +# empty -s -o i$$ 2; sleep 0.1 +# empty -s -o i$$ 3; sleep 0.1 +# empty -s -o i$$ 1; sleep 0.1 + +# capture the output FIFO's content in a file, before hledger-ui quits ? +# hangs until ctrl-c, why ? +#cat o$$ #> c$$ + +# Send 'q' on the input FIFO, causing hledger-ui to exit. +empty -s -o i$$ q +# But wait until after the pipe has been read, below ? Doesn't help. +# (sleep 1; empty -s -o i$$ q) & + +# drain the output FIFO one last time, allowing empty monitor to exit ? no +#cat o$$ + +# kill empty's monitor process deliberately ? no +#empty -k `cat p$$` + + +# Read all from the output FIFO, causing empty's monitor to exit and +# clean up the FIFOs. And convert it to plain text. + +# can never get empty -r to work right +##empty -r -b 10000 -t 10 -i o$$ | hledgerui2txt + +# cat works.. +# but only when running interactively. When non-interactive +# (eg echo | ./uitest), the FIFO returns nothing. Could be "If all +# file descriptors referring to the write end of a pipe have been +# closed, then an attempt to read(2) from the pipe will see +# end-of-file (read(2) will return 0)" +cat o$$ | hledgerui2txt + +# convert the captured output, and clean up +# cat c$$ | hledgerui2txt +# rm c$$ diff --git a/tests/ui/uitest.expect b/tests/ui/uitest.expect new file mode 100755 index 000000000..33071e76a --- /dev/null +++ b/tests/ui/uitest.expect @@ -0,0 +1,46 @@ +#!/usr/bin/env expect + +# Run hledger-ui in the background without needing an interactive +# shell, passing through any arguments, and dump its first screen* as +# cleaned up plain text. This allows hledger-ui's output to be tested. +# +# * Or multiple screens, from processing the inputs below. + + +set timeout 1 +log_user 0 +# we'll pipe what we capture through hledgerui2txt +set filter [open |./hledgerui2txt w] + +spawn hledger-ui $argv + +# warning: expect-ing output of a brick app is tricky. +# It draws parts of the screen, in layers, with embedded +# escape codes. + +# wait for the first screen to draw (to the bottom line) +# expect "account balances" +# expect timeout +# expect -re ":quit ─+" +#expect ":quit" +puts $filter $expect_out(buffer) + +# send 1 +# expect -re ":quit ─+" +# puts $expect_out(buffer) + +# send 2 +# expect -re ":quit ─+" +# # the last output must be handled differently +# set out $expect_out(buffer) + +# send q +# expect eof + +# # send 2 +# # expect -re ":quit" + +# puts $filter $out +close $filter + +# interact diff --git a/tests/ui/uitest2.expect b/tests/ui/uitest2.expect new file mode 100755 index 000000000..06e6ce99c --- /dev/null +++ b/tests/ui/uitest2.expect @@ -0,0 +1,15 @@ +#!/usr/bin/env expect + +# Run uitest.empty-ui in the background without needing an interactive +# shell, passing through any arguments. It's pretty stupid to be using +# both expect AND empty, but so far this is the only way I've got it +# to work. The empty script is reasonably reliable at producing the +# output, but can't itself run in a non-interactive script; expect is +# able to make it do that. + + +# TODO: kill (our) empty process if this script is interrupted +trap {puts {open "|ls"}} {INT TERM} + +spawn ./uitest.empty $argv +expect eof