summaryrefslogtreecommitdiffstats
path: root/tests/tool_i.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tool_i.tcl')
-rw-r--r--tests/tool_i.tcl156
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.*$"
+}