diff options
Diffstat (limited to 'tests/tool_i.tcl')
-rw-r--r-- | tests/tool_i.tcl | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/tests/tool_i.tcl b/tests/tool_i.tcl new file mode 100644 index 0000000..d0f3d4b --- /dev/null +++ b/tests/tool_i.tcl @@ -0,0 +1,156 @@ +# @brief Common functions and variables for Tool Under Test (TUT). +# +# The script requires variables: +# TUT_PATH - Assumed absolute path to the directory in which the TUT is located. +# TUT_NAME - TUT name (without path). +# +# The script sets the variables: +# TUT - The path (including the name) of the executable TUT. +# error_prompt - Delimiter on error. +# error_head - Header on error. + +package require Expect + +# Complete the path for Tool Under Test (TUT). For example, on Windows, TUT can be located in the Debug or Release +# subdirectory. Note that Release build takes precedence over Debug. +set conftypes {{} Release Debug} +foreach i $conftypes { + if { [file executable "$TUT_PATH/$i/$TUT_NAME"] || [file executable "$TUT_PATH/$i/$TUT_NAME.exe"] } { + set TUT "$TUT_PATH/$i/$TUT_NAME" + break + } +} +if {![info exists TUT]} { + error "$TUT_NAME executable not found" +} + +# prompt of error message +set error_prompt ">>>" +# the beginning of error message +set error_head "$error_prompt Check-failed" + +# detection on eof and timeout will be on every expect command +expect_after { + eof { + global error_head + error "$error_head unexpected termination" + } timeout { + global error_head + error "$error_head timeout" + } +} + +# Run commands from command line +tcltest::loadTestedCommands + +# namespace of internal functions +namespace eval ly::private {} + +# Send command 'cmd' to the process, then check output string by 'pattern'. +# Parameter cmd is a string of arguments. +# Parameter pattern is a regex or an exact string to match. If is not specified, only prompt assumed afterwards. +# It must not contain a prompt. There can be an '$' character at the end of the pattern, in which case the regex +# matches the characters before the prompt. +# Parameter 'opt' can contain: +# -ex has a similar meaning to the expect command. The 'pattern' parameter is used as a simple string +# for exact matching of the output. So 'pattern' is not a regular expression but some characters +# must still be escaped, eg ][. +proc ly_cmd {cmd {pattern ""} {opt ""}} { + global prompt + + send -- "${cmd}\r" + expect -- "${cmd}\r\n" + + if { $pattern eq "" } { + # command without output + expect ^$prompt + return + } + + # definition of an expression that matches failure + set failure_pattern "\r\n${prompt}$" + + if { $opt eq "" && [string index $pattern end] eq "$"} { + # check output by regular expression + # It was explicitly specified how the expression should end. + set pattern [string replace $pattern end end] + expect { + -re "${pattern}\r\n${prompt}$" {} + -re $failure_pattern { + error "unexpected output:\n$expect_out(buffer)" + } + } + } elseif { $opt eq "" } { + # check output by regular expression + expect { + -re "${pattern}.*\r\n${prompt}$" {} + -re $failure_pattern { + error "unexpected output:\n$expect_out(buffer)" + } + } + } elseif { $opt eq "-ex" } { + # check output by exact matching + expect { + -ex "${pattern}\r\n${prompt}" {} + -re $failure_pattern { + error "unexpected output:\n$expect_out(buffer)" + } + } + } else { + global error_head + error "$error_head unrecognized value of parameter 'opt'" + } +} + +# Send command 'cmd' to the process, expect some header and then check output string by 'pattern'. +# This function is useful for checking an error that appears in the form of a header. +# Parameter header is the expected header on the output. +# Parameter cmd is a string of arguments. +# Parameter pattern is a regex. It must not contain a prompt. +proc ly_cmd_header {cmd header pattern} { + global prompt + + send -- "${cmd}\r" + expect -- "${cmd}\r\n" + + expect { + -re "$header .*${pattern}.*\r\n${prompt}$" {} + -re "\r\n${prompt}$" { + error "unexpected output:\n$expect_out(buffer)" + } + } +} + +# Whatever is written is sent, output is ignored and then another prompt is expected. +# Parameter cmd is optional and any output is ignored. +proc ly_ignore {{cmd ""}} { + global prompt + + send "${cmd}\r" + expect -re "$prompt$" +} + +# Send a completion request and check if the anchored regex output matches. +proc ly_completion {input output} { + global prompt + + send -- "${input}\t" + # expecting echoing input, output and 10 terminal control characters + expect -re "^${input}\r${prompt}${output}.*\r.*$" +} + +# Send a completion request and check if the anchored regex hint options match. +proc ly_hint {input prev_input hints} { + global prompt + + set output {} + foreach i $hints { + # each element might have some number of spaces and CRLF around it + append output "${i} *(?:\\r\\n)?" + } + + send -- "${input}\t" + # expecting the hints, previous input from which the hints were generated + # and some number of terminal control characters + expect -re "${output}\r${prompt}${prev_input}.*\r.*$" +} |