blob: 623398fa638cdf5553698dcf10d07ff2fd835494 [file] [log] [blame]
aPiecek266ca762023-03-22 15:04:59 +01001package require Expect
2
3source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/common.tcl" : "../common.tcl"}]
4
5# set the timeout to 1 second
6set timeout 1
7# prompt of yanglint
8set prompt "> "
9# turn off dialog between expect and yanglint
10log_user 0
11
12variable ly_setup {
13 spawn $::env(YANGLINT)
14 ly_skip_warnings
15}
16
17variable ly_cleanup {
18 ly_exit
19}
20
21# detection on eof and timeout will be on every expect command
22expect_after {
23 eof {
24 global error_head
25 error "$error_head unexpected termination"
26 } timeout {
27 global error_head
28 error "$error_head timeout"
29 }
30}
31
32# Run commands from command line
33tcltest::loadTestedCommands
34
35# namespace of internal functions
36namespace eval ly::private {}
37
38# Skip no dir and/or no history warnings and prompt.
39proc ly_skip_warnings {} {
40 global prompt
41 expect -re "(YANGLINT.*)*$prompt" {}
42}
43
44# Send command 'cmd' to the process, then check output string by 'pattern'.
45# Parameter cmd is a string of arguments.
46# Parameter pattern is a regex or an exact string to match. If is not specified, only prompt assumed afterwards.
47# It must not contain a prompt. There can be an '$' character at the end of the pattern, in which case the regex
48# matches the characters before the prompt.
49# Parameter 'opt' can contain:
50# -ex has a similar meaning to the expect command. The 'pattern' parameter is used as a simple string
51# for exact matching of the output. So 'pattern' is not a regular expression but some characters
52# must still be escaped, eg ][.
53proc ly_cmd {cmd {pattern ""} {opt ""}} {
54 global prompt
55
56 send -- "${cmd}\r"
57 expect -- "${cmd}\r\n"
58
59 if { $pattern eq "" } {
60 # command without output
61 expect ^$prompt
62 return
63 }
64
65 # definition of an expression that matches failure
66 set failure_pattern "\r\n${prompt}$"
67
68 if { $opt eq "" && [string index $pattern end] eq "$"} {
69 # check output by regular expression
70 # It was explicitly specified how the expression should end.
71 set pattern [string replace $pattern end end]
72 expect {
73 -re "${pattern}\r\n${prompt}$" {}
74 -re $failure_pattern {
75 error "unexpected output:\n$expect_out(buffer)"
76 }
77 }
78 } elseif { $opt eq "" } {
79 # check output by regular expression
80 expect {
81 -re "${pattern}.*\r\n${prompt}$" {}
82 -re $failure_pattern {
83 error "unexpected output:\n$expect_out(buffer)"
84 }
85 }
86 } elseif { $opt eq "-ex" } {
87 # check output by exact matching
88 expect {
89 -ex "${pattern}\r\n${prompt}" {}
90 -re $failure_pattern {
91 error "unexpected output:\n$expect_out(buffer)"
92 }
93 }
94 } else {
95 global error_head
96 error "$error_head unrecognized value of parameter 'opt'"
97 }
98}
99
100# Send command 'cmd' to the process, expect error header and then check output string by 'pattern'.
101# Parameter cmd is a string of arguments.
102# Parameter pattern is a regex. It must not contain a prompt.
103proc ly_cmd_err {cmd pattern} {
104 global prompt
105
106 send -- "${cmd}\r"
107 expect -- "${cmd}\r\n"
108
109 expect {
110 -re "YANGLINT\\\[E\\\]: .*${pattern}.*\r\n${prompt}$" {}
111 -re "libyang\\\[\[0-9]+\\\]: .*${pattern}.*\r\n${prompt}$" {}
112 -re "\r\n${prompt}$" {
113 error "unexpected output:\n$expect_out(buffer)"
114 }
115 }
116}
117
118# Send command 'cmd' to the process, expect warning header and then check output string by 'pattern'.
119# Parameter cmd is a string of arguments.
120# Parameter pattern is a regex. It must not contain a prompt.
121proc ly_cmd_wrn {cmd pattern} {
122 global prompt
123
124 send -- "${cmd}\r"
125 expect -- "${cmd}\r\n"
126
127 expect {
128 -re "YANGLINT\\\[W\\\]: .*${pattern}.*\r\n${prompt}$" {}
129 -re "\r\n${prompt}$" {
130 error "unexpected output:\n$expect_out(buffer)"
131 }
132 }
133}
134
135# Whatever is written is sent, output is ignored and then another prompt is expected.
136# Parameter cmd is optional and any output is ignored.
137proc ly_ignore {{cmd ""}} {
138 global prompt
139
140 send "${cmd}\r"
141 expect -re "$prompt$"
142}
143
144# Send a completion request and check if the anchored regex output matches.
145proc ly_completion {input output} {
146 global prompt
147
148 send -- "${input}\t"
149 # expecting echoing input, output and 10 terminal control characters
150 expect -re "^${input}\r> ${output}.*\r.*$"
151}
152
153# Send a completion request and check if the anchored regex hint options match.
154proc ly_hint {input prev_input hints} {
155 set output {}
156 foreach i $hints {
157 # each element might have some number of spaces and CRLF around it
158 append output "${i} *(?:\\r\\n)?"
159 }
160
161 send -- "${input}\t"
162 # expecting the hints, previous input from which the hints were generated
163 # and some number of terminal control characters
164 expect -re "^\r\n${output}\r> ${prev_input}.*\r.*$"
165}
166
167# Send 'exit' and wait for eof.
168proc ly_exit {} {
169 send "exit\r"
170 expect eof
171}