yanglint UPDATE new completion test

Yanglint interactive completion test added and other expect tests united
to use common procedures.
diff --git a/tools/lint/tests/expect/common.exp b/tools/lint/tests/expect/common.exp
new file mode 100644
index 0000000..e85f34e
--- /dev/null
+++ b/tools/lint/tests/expect/common.exp
@@ -0,0 +1,61 @@
+# set the timeout to 1 second
+set timeout 1
+
+# expect a single line of anchored regex output
+proc expect_output {output} {
+    expect {
+        -re "^${output}$" {}
+        timeout {exit 1}
+    }
+}
+
+# send a command and either expect some anchored regex output if specified or just an empty line
+proc expect_command {command has_output output} {
+    send -- "${command}\r"
+
+    if ($has_output==1) {
+        expect {
+            -re "^${command}\r\n${output}$" {}
+            timeout {exit 1}
+        }
+    } else {
+        # input echoes
+        expect {
+            -re "^${command}\r\n$" {}
+            timeout {exit 1}
+        }
+        expect {
+            -re "^> $" {}
+            timeout {exit 1}
+        }
+    }
+}
+
+# send a completion request and check if the anchored regex output matches
+proc expect_completion {input output} {
+    send -- "${input}\t"
+
+    expect {
+        # expecting echoing input, output and 10 terminal control characters
+        -re "^${input}\r> ${output}.*\r.*$" {}
+        timeout {exit 1}
+    }
+}
+
+# send a completion request and check if the anchored regex hint options match
+proc expect_hint {input prev_input hints} {
+    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"
+
+    expect {
+        # expecting the hints, previous input from which the hints were generated
+        # and some number of terminal control characters
+        -re "^\r\n${output}\r> ${prev_input}.*\r.*$" {}
+        timeout {exit 1}
+    }
+}
diff --git a/tools/lint/tests/expect/completion.exp b/tools/lint/tests/expect/completion.exp
new file mode 100755
index 0000000..cf17bec
--- /dev/null
+++ b/tools/lint/tests/expect/completion.exp
@@ -0,0 +1,57 @@
+#!/usr/bin/expect -f
+
+if { [info exists ::env(CURRENT_SOURCE_DIR)] } {
+    source "$env(CURRENT_SOURCE_DIR)/tests/expect/common.exp"
+} else {
+    source "common.exp"
+}
+
+spawn $env(YANGLINT)
+
+expect_output "> "
+
+expect_command "clear -ii" 0 ""
+
+expect_command "add /home/roman/ribyang/tools/lint/examples/ietf-ip.yang" 0 ""
+
+expect_completion "print -f info -P " "print -f info -P /ietf-"
+
+set hints {"/ietf-yang-schema-mount:schema-mounts" "/ietf-interfaces:interfaces" "/ietf-interfaces:interfaces-state"}
+
+expect_hint "" "print -f info -P /ietf-" $hints
+
+expect_completion "i" "print -f info -P /ietf-interfaces:interfaces"
+
+expect_completion "/" "print -f info -P /ietf-interfaces:interfaces/interface"
+
+set hints {"/ietf-interfaces:interfaces/interface"
+"/ietf-interfaces:interfaces/interface/name" "/ietf-interfaces:interfaces/interface/description"
+"/ietf-interfaces:interfaces/interface/type" "/ietf-interfaces:interfaces/interface/enabled"
+"/ietf-interfaces:interfaces/interface/link-up-down-trap-enable"
+"/ietf-interfaces:interfaces/interface/ietf-ip:ipv4" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6"}
+
+expect_hint "" "print -f info -P /ietf-interfaces:interfaces/interface" $hints
+
+expect_completion "/i" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv"
+
+expect_completion "4" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4"
+
+set hints { "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled"
+"/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/forwarding" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/mtu"
+"/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/neighbor"
+}
+
+expect_hint "\t" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv" $hints
+
+expect_completion "/e" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled "
+
+send -- "\r"
+
+expect {
+    -re ".*\r\n> " {}
+    timeout {exit 1}
+}
+
+send -- "exit\r"
+
+expect eof
diff --git a/tools/lint/tests/expect/feature.exp b/tools/lint/tests/expect/feature.exp
index 80822e3..c2999b3 100755
--- a/tools/lint/tests/expect/feature.exp
+++ b/tools/lint/tests/expect/feature.exp
@@ -1,20 +1,17 @@
 #!/usr/bin/expect -f
 
-set timeout 1
+if { [info exists ::env(CURRENT_SOURCE_DIR)] } {
+    source "$env(CURRENT_SOURCE_DIR)/tests/expect/common.exp"
+} else {
+    source "common.exp"
+}
 
 spawn $env(YANGLINT)
-expect -exact "> "
-send -- "feature -a\r"
-expect {
-    "feature -a\r
-yang:\r
-\t(none)\r
-\r
-ietf-yang-schema-mount:\r
-\t(none)\r
-\r
-> " { }
-    timeout { exit 1 }
-}
+
+expect_output "> "
+
+expect_command "feature -a" 1 "yang:\r\n\t\\(none\\)\r\n\r\nietf-yang-schema-mount:\r\n\t\\(none\\)\r\n\r\n> "
+
 send -- "exit\r"
+
 expect eof
diff --git a/tools/lint/tests/expect/list.exp b/tools/lint/tests/expect/list.exp
index aef0585..796b901 100755
--- a/tools/lint/tests/expect/list.exp
+++ b/tools/lint/tests/expect/list.exp
@@ -1,20 +1,17 @@
 #!/usr/bin/expect -f
 
-set timeout 1
+if { [info exists ::env(CURRENT_SOURCE_DIR)] } {
+    source "$env(CURRENT_SOURCE_DIR)/tests/expect/common.exp"
+} else {
+    source "common.exp"
+}
 
 spawn $env(YANGLINT)
-expect "> "
-send -- "list\r"
-expect {
-	"list\r
-List of the loaded models:\r
-    i ietf-yang-metadata@2016-08-05\r
-    I yang@2022-06-16\r
-    i ietf-inet-types@2013-07-15\r
-    i ietf-yang-types@2013-07-15\r
-    I ietf-yang-schema-mount@2019-01-14\r
-> " { }
-	timeout { exit 1 }
-}
+
+expect_output "> "
+
+expect_command "list" 1 "List of the loaded models:\r\n *i ietf-yang-metadata@2016-08-05\r\n *I yang@2022-06-16\r\n *i ietf-inet-types@2013-07-15\r\n *i ietf-yang-types@2013-07-15\r\n *I ietf-yang-schema-mount@2019-01-14\r\n> "
+
 send -- "exit\r"
+
 expect eof