| 1 | # This file contains a collection of tests for the Tcl built-in 'chan' | 
|---|
| 2 | # command. Sourcing this file into Tcl runs the tests and generates | 
|---|
| 3 | # output for errors. No output means no errors were found. | 
|---|
| 4 | # | 
|---|
| 5 | # Copyright (c) 2005 Donal K. Fellows | 
|---|
| 6 | # | 
|---|
| 7 | # See the file "license.terms" for information on usage and redistribution | 
|---|
| 8 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. | 
|---|
| 9 | # | 
|---|
| 10 | # RCS: @(#) $Id: chan.test,v 1.11 2007/12/13 15:26:04 dgp Exp $ | 
|---|
| 11 |  | 
|---|
| 12 | if {[lsearch [namespace children] ::tcltest] == -1} { | 
|---|
| 13 |     package require tcltest 2 | 
|---|
| 14 |     namespace import -force ::tcltest::* | 
|---|
| 15 | } | 
|---|
| 16 |  | 
|---|
| 17 | # | 
|---|
| 18 | # Note: The tests for the chan methods "create" and "postevent" | 
|---|
| 19 | # currently reside in the file "ioCmd.test". | 
|---|
| 20 | # | 
|---|
| 21 |  | 
|---|
| 22 | test chan-1.1 {chan command general syntax} -body { | 
|---|
| 23 |     chan | 
|---|
| 24 | } -returnCodes error -result "wrong # args: should be \"chan subcommand ?argument ...?\"" | 
|---|
| 25 | test chan-1.2 {chan command general syntax} -body { | 
|---|
| 26 |     chan FOOBAR | 
|---|
| 27 | } -returnCodes error -result "unknown or ambiguous subcommand \"FOOBAR\": must be blocked, close, configure, copy, create, eof, event, flush, gets, names, pending, postevent, puts, read, seek, tell, or truncate" | 
|---|
| 28 |  | 
|---|
| 29 | test chan-2.1 {chan command: blocked subcommand} -body { | 
|---|
| 30 |     chan blocked foo bar | 
|---|
| 31 | } -returnCodes error -result "wrong # args: should be \"chan blocked channelId\"" | 
|---|
| 32 |  | 
|---|
| 33 | test chan-3.1 {chan command: close subcommand} -body { | 
|---|
| 34 |     chan close foo bar | 
|---|
| 35 | } -returnCodes error -result "wrong # args: should be \"chan close channelId\"" | 
|---|
| 36 |  | 
|---|
| 37 | test chan-4.1 {chan command: configure subcommand} -body { | 
|---|
| 38 |     chan configure | 
|---|
| 39 | } -returnCodes error -result "wrong # args: should be \"chan configure channelId ?optionName? ?value? ?optionName value?...\"" | 
|---|
| 40 | test chan-4.2 {chan command: [Bug 800753]} -body { | 
|---|
| 41 |     chan configure stdout -eofchar \u0100 | 
|---|
| 42 | } -returnCodes error -match glob -result {bad value*} | 
|---|
| 43 | test chan-4.3 {chan command: [Bug 800753]} -body { | 
|---|
| 44 |     chan configure stdout -eofchar \u0000 | 
|---|
| 45 | } -returnCodes error -match glob -result {bad value*} | 
|---|
| 46 | test chan-4.4 {chan command: check valid inValue, no outValue} -body { | 
|---|
| 47 |     chan configure stdout -eofchar [list \x27 {}] | 
|---|
| 48 | } -returnCodes ok -result {} | 
|---|
| 49 | test chan-4.5 {chan command: check valid inValue, invalid outValue} -body { | 
|---|
| 50 |     chan configure stdout -eofchar [list \x27 \x80] | 
|---|
| 51 | } -returnCodes error -match glob -result {bad value for -eofchar:*} | 
|---|
| 52 | test chan-4.6 {chan command: check no inValue, valid outValue} -body { | 
|---|
| 53 |     chan configure stdout -eofchar [list {} \x27] | 
|---|
| 54 | } -returnCodes ok -result {} | 
|---|
| 55 |  | 
|---|
| 56 | test chan-5.1 {chan command: copy subcommand} -body { | 
|---|
| 57 |     chan copy foo | 
|---|
| 58 | } -returnCodes error -result "wrong # args: should be \"chan copy input output ?-size size? ?-command callback?\"" | 
|---|
| 59 |  | 
|---|
| 60 | test chan-6.1 {chan command: eof subcommand} -body { | 
|---|
| 61 |     chan eof foo bar | 
|---|
| 62 | } -returnCodes error -result "wrong # args: should be \"chan eof channelId\"" | 
|---|
| 63 |  | 
|---|
| 64 | test chan-7.1 {chan command: event subcommand} -body { | 
|---|
| 65 |     chan event foo | 
|---|
| 66 | } -returnCodes error -result "wrong # args: should be \"chan event channelId event ?script?\"" | 
|---|
| 67 |  | 
|---|
| 68 | test chan-8.1 {chan command: flush subcommand} -body { | 
|---|
| 69 |     chan flush foo bar | 
|---|
| 70 | } -returnCodes error -result "wrong # args: should be \"chan flush channelId\"" | 
|---|
| 71 |  | 
|---|
| 72 | test chan-9.1 {chan command: gets subcommand} -body { | 
|---|
| 73 |     chan gets | 
|---|
| 74 | } -returnCodes error -result "wrong # args: should be \"chan gets channelId ?varName?\"" | 
|---|
| 75 |  | 
|---|
| 76 | test chan-10.1 {chan command: names subcommand} -body { | 
|---|
| 77 |     chan names foo bar | 
|---|
| 78 | } -returnCodes error -result "wrong # args: should be \"chan names ?pattern?\"" | 
|---|
| 79 |  | 
|---|
| 80 | test chan-11.1 {chan command: puts subcommand} -body { | 
|---|
| 81 |     chan puts foo bar foo bar | 
|---|
| 82 | } -returnCodes error -result "wrong # args: should be \"chan puts ?-nonewline? ?channelId? string\"" | 
|---|
| 83 |  | 
|---|
| 84 | test chan-12.1 {chan command: read subcommand} -body { | 
|---|
| 85 |     chan read | 
|---|
| 86 | } -returnCodes error -result "wrong # args: should be \"chan read channelId ?numChars?\" or \"chan read ?-nonewline? channelId\"" | 
|---|
| 87 |  | 
|---|
| 88 | test chan-13.1 {chan command: seek subcommand} -body { | 
|---|
| 89 |     chan seek foo bar foo bar | 
|---|
| 90 | } -returnCodes error -result "wrong # args: should be \"chan seek channelId offset ?origin?\"" | 
|---|
| 91 |  | 
|---|
| 92 | test chan-14.1 {chan command: tell subcommand} -body { | 
|---|
| 93 |     chan tell foo bar | 
|---|
| 94 | } -returnCodes error -result "wrong # args: should be \"chan tell channelId\"" | 
|---|
| 95 |  | 
|---|
| 96 | test chan-15.1 {chan command: truncate subcommand} -body { | 
|---|
| 97 |     chan truncate foo bar foo bar | 
|---|
| 98 | } -returnCodes error -result "wrong \# args: should be \"chan truncate channelId ?length?\"" | 
|---|
| 99 | test chan-15.2 {chan command: truncate subcommand} -setup { | 
|---|
| 100 |     set file [makeFile {} testTruncate] | 
|---|
| 101 |     set f [open $file w+] | 
|---|
| 102 |     fconfigure $f -translation binary | 
|---|
| 103 | } -body { | 
|---|
| 104 |     seek $f 0 | 
|---|
| 105 |     puts -nonewline $f 12345 | 
|---|
| 106 |     seek $f 0 | 
|---|
| 107 |     chan truncate $f 2 | 
|---|
| 108 |     read $f | 
|---|
| 109 | } -result 12 -cleanup { | 
|---|
| 110 |     catch {close $f} | 
|---|
| 111 |     catch {removeFile $file} | 
|---|
| 112 | } | 
|---|
| 113 |  | 
|---|
| 114 | # TIP 287: chan pending | 
|---|
| 115 | test chan-16.1 {chan command: pending subcommand} -body { | 
|---|
| 116 |     chan pending | 
|---|
| 117 | } -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\"" | 
|---|
| 118 | test chan-16.2 {chan command: pending subcommand} -body { | 
|---|
| 119 |     chan pending stdin | 
|---|
| 120 | } -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\"" | 
|---|
| 121 | test chan-16.3 {chan command: pending subcommand} -body { | 
|---|
| 122 |     chan pending stdin stdout stderr | 
|---|
| 123 | } -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\"" | 
|---|
| 124 | test chan-16.4 {chan command: pending subcommand} -body { | 
|---|
| 125 |     chan pending {input output} stdout | 
|---|
| 126 | } -returnCodes error -result "bad mode \"input output\": must be input or output" | 
|---|
| 127 | test chan-16.5 {chan command: pending input subcommand} -body { | 
|---|
| 128 |     chan pending input stdout  | 
|---|
| 129 | } -result -1 | 
|---|
| 130 | test chan-16.6 {chan command: pending input subcommand} -body { | 
|---|
| 131 |     chan pending input stdin | 
|---|
| 132 | } -result 0 | 
|---|
| 133 | test chan-16.7 {chan command: pending input subcommand} -body { | 
|---|
| 134 |     chan pending input FOOBAR | 
|---|
| 135 | } -returnCodes error -result "can not find channel named \"FOOBAR\"" | 
|---|
| 136 | test chan-16.8 {chan command: pending input subcommand} -setup { | 
|---|
| 137 |     set file [makeFile {} testAvailable] | 
|---|
| 138 |     set f [open $file w+] | 
|---|
| 139 |     chan configure $f -translation lf -buffering line | 
|---|
| 140 | } -body { | 
|---|
| 141 |     chan puts $f foo | 
|---|
| 142 |     chan puts $f bar | 
|---|
| 143 |     chan puts $f baz | 
|---|
| 144 |     chan seek $f 0 | 
|---|
| 145 |     chan gets $f | 
|---|
| 146 |     chan pending input $f | 
|---|
| 147 | } -result 8 -cleanup { | 
|---|
| 148 |     catch {chan close $f} | 
|---|
| 149 |     catch {removeFile $file} | 
|---|
| 150 | } | 
|---|
| 151 | test chan-16.9 {chan command: pending input subcommand} -setup { | 
|---|
| 152 |     proc chan-16.9-accept {sock addr port} { | 
|---|
| 153 |         chan configure $sock -blocking 0 -buffering line -buffersize 32 | 
|---|
| 154 |         chan event $sock readable [list chan-16.9-readable $sock] | 
|---|
| 155 |     } | 
|---|
| 156 |  | 
|---|
| 157 |     proc chan-16.9-readable {sock} { | 
|---|
| 158 |         set r [chan gets $sock line] | 
|---|
| 159 |         set l [string length $line] | 
|---|
| 160 |         set e [chan eof $sock] | 
|---|
| 161 |         set b [chan blocked $sock] | 
|---|
| 162 |         set i [chan pending input $sock] | 
|---|
| 163 |  | 
|---|
| 164 |         lappend ::chan-16.9-data $r $l $e $b $i | 
|---|
| 165 |  | 
|---|
| 166 |         if {$r != -1 || $e || $l || !$b || $i > 128} { | 
|---|
| 167 |             set data [read $sock $i] | 
|---|
| 168 |             lappend ::chan-16.9-data [string range $data 0 2] | 
|---|
| 169 |             lappend ::chan-16.9-data [string range $data end-2 end] | 
|---|
| 170 |             set ::chan-16.9-done 1 | 
|---|
| 171 |             chan event $sock readable {} | 
|---|
| 172 |         } else { | 
|---|
| 173 |             after idle chan-16.9-client | 
|---|
| 174 |         } | 
|---|
| 175 |     } | 
|---|
| 176 |  | 
|---|
| 177 |     proc chan-16.9-client {} { | 
|---|
| 178 |         chan puts -nonewline $::client ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 | 
|---|
| 179 |         chan flush $::client | 
|---|
| 180 |     } | 
|---|
| 181 |  | 
|---|
| 182 |     set ::server [socket -server chan-16.9-accept -myaddr 127.0.0.1 0] | 
|---|
| 183 |     set ::client [socket 127.0.0.1 [lindex [fconfigure $::server -sockname] 2]] | 
|---|
| 184 |     set ::chan-16.9-data [list] | 
|---|
| 185 |     set ::chan-16.9-done 0 | 
|---|
| 186 | } -body { | 
|---|
| 187 |     after idle chan-16.9-client  | 
|---|
| 188 |     vwait ::chan-16.9-done | 
|---|
| 189 |     set ::chan-16.9-data | 
|---|
| 190 | } -result {-1 0 0 1 36 -1 0 0 1 72 -1 0 0 1 108 -1 0 0 1 144 ABC 890} -cleanup { | 
|---|
| 191 |     catch {chan close $client} | 
|---|
| 192 |     catch {chan close $server} | 
|---|
| 193 |     rename chan-16.9-accept {} | 
|---|
| 194 |     rename chan-16.9-readable {} | 
|---|
| 195 |     rename chan-16.9-client {} | 
|---|
| 196 |     unset -nocomplain ::chan-16.9-data | 
|---|
| 197 |     unset -nocomplain ::chan-16.9-done | 
|---|
| 198 |     unset -nocomplain ::server | 
|---|
| 199 |     unset -nocomplain ::client | 
|---|
| 200 | } | 
|---|
| 201 | test chan-16.10 {chan command: pending output subcommand} -body { | 
|---|
| 202 |     chan pending output stdin | 
|---|
| 203 | } -result -1 | 
|---|
| 204 | test chan-16.11 {chan command: pending output subcommand} -body { | 
|---|
| 205 |     chan pending output stdout | 
|---|
| 206 | } -result 0 | 
|---|
| 207 | test chan-16.12 {chan command: pending output subcommand} -body { | 
|---|
| 208 |     chan pending output FOOBAR | 
|---|
| 209 | } -returnCodes error -result "can not find channel named \"FOOBAR\"" | 
|---|
| 210 | test chan-16.13 {chan command: pending output subcommand} -setup { | 
|---|
| 211 |     set file [makeFile {} testPendingOutput] | 
|---|
| 212 |     set f [open $file w+] | 
|---|
| 213 |     chan configure $f -translation lf -buffering full -buffersize 1024 | 
|---|
| 214 | } -body { | 
|---|
| 215 |     set result [list] | 
|---|
| 216 |     chan puts $f [string repeat x 512] | 
|---|
| 217 |     lappend result [chan pending output $f] | 
|---|
| 218 |     chan flush $f | 
|---|
| 219 |     lappend result [chan pending output $f] | 
|---|
| 220 | } -result [list 513 0] -cleanup { | 
|---|
| 221 |     unset -nocomplain result | 
|---|
| 222 |     catch {chan close $f} | 
|---|
| 223 |     catch {removeFile $file} | 
|---|
| 224 | } | 
|---|
| 225 |  | 
|---|
| 226 | cleanupTests | 
|---|
| 227 | return | 
|---|
| 228 |  | 
|---|
| 229 | # Local Variables: | 
|---|
| 230 | # mode: tcl | 
|---|
| 231 | # End: | 
|---|