| [25] | 1 | # This file contains tests for the tclBasic.c source file. Tests appear in | 
|---|
 | 2 | # the same order as the C code that they test. The set of tests is | 
|---|
 | 3 | # currently incomplete since it currently includes only new tests for | 
|---|
 | 4 | # code changed for the addition of Tcl namespaces. Other variable- | 
|---|
 | 5 | # related tests appear in several other test files including | 
|---|
 | 6 | # assocd.test, cmdInfo.test, eval.test, expr.test, interp.test, | 
|---|
 | 7 | # and trace.test. | 
|---|
 | 8 | # | 
|---|
 | 9 | # Sourcing this file into Tcl runs the tests and generates output for | 
|---|
 | 10 | # errors. No output means no errors were found. | 
|---|
 | 11 | # | 
|---|
 | 12 | # Copyright (c) 1997 Sun Microsystems, Inc. | 
|---|
 | 13 | # Copyright (c) 1998-1999 by Scriptics Corporation. | 
|---|
 | 14 | # | 
|---|
 | 15 | # See the file "license.terms" for information on usage and redistribution | 
|---|
 | 16 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. | 
|---|
 | 17 | # | 
|---|
 | 18 | # RCS: @(#) $Id: basic.test,v 1.44 2007/04/20 05:51:11 kennykb Exp $ | 
|---|
 | 19 | # | 
|---|
 | 20 |  | 
|---|
 | 21 | package require tcltest 2 | 
|---|
 | 22 | namespace import -force ::tcltest::* | 
|---|
 | 23 |  | 
|---|
 | 24 | testConstraint testevalex [llength [info commands testevalex]] | 
|---|
 | 25 | testConstraint testcmdtoken [llength [info commands testcmdtoken]] | 
|---|
 | 26 | testConstraint testcreatecommand [llength [info commands testcreatecommand]] | 
|---|
 | 27 | testConstraint exec [llength [info commands exec]] | 
|---|
 | 28 |  | 
|---|
 | 29 | catch {namespace delete test_ns_basic} | 
|---|
 | 30 | catch {interp delete test_interp} | 
|---|
 | 31 | catch {rename p ""} | 
|---|
 | 32 | catch {rename q ""} | 
|---|
 | 33 | catch {rename cmd ""} | 
|---|
 | 34 | catch {unset x} | 
|---|
 | 35 |  | 
|---|
 | 36 | test basic-1.1 {Tcl_CreateInterp, creates interp's global namespace} { | 
|---|
 | 37 |     catch {interp delete test_interp} | 
|---|
 | 38 |     interp create test_interp | 
|---|
 | 39 |     interp eval test_interp { | 
|---|
 | 40 |         namespace eval test_ns_basic { | 
|---|
 | 41 |             proc p {} { | 
|---|
 | 42 |                 return [namespace current] | 
|---|
 | 43 |             } | 
|---|
 | 44 |         } | 
|---|
 | 45 |     } | 
|---|
 | 46 |     list [interp eval test_interp {test_ns_basic::p}] \ | 
|---|
 | 47 |          [interp delete test_interp] | 
|---|
 | 48 | } {::test_ns_basic {}} | 
|---|
 | 49 |  | 
|---|
 | 50 | test basic-2.1 {TclHideUnsafeCommands} {emptyTest} { | 
|---|
 | 51 | } {} | 
|---|
 | 52 |  | 
|---|
 | 53 | test basic-3.1 {Tcl_CallWhenDeleted: see dcall.test} {emptyTest} { | 
|---|
 | 54 | } {} | 
|---|
 | 55 |  | 
|---|
 | 56 | test basic-4.1 {Tcl_DontCallWhenDeleted: see dcall.test} {emptyTest} { | 
|---|
 | 57 | } {} | 
|---|
 | 58 |  | 
|---|
 | 59 | test basic-5.1 {Tcl_SetAssocData: see assoc.test} {emptyTest} { | 
|---|
 | 60 | } {} | 
|---|
 | 61 |  | 
|---|
 | 62 | test basic-6.1 {Tcl_DeleteAssocData: see assoc.test} {emptyTest} { | 
|---|
 | 63 | } {} | 
|---|
 | 64 |  | 
|---|
 | 65 | test basic-7.1 {Tcl_GetAssocData: see assoc.test} {emptyTest} { | 
|---|
 | 66 | } {} | 
|---|
 | 67 |  | 
|---|
 | 68 | test basic-8.1 {Tcl_InterpDeleted} {emptyTest} { | 
|---|
 | 69 | } {} | 
|---|
 | 70 |  | 
|---|
 | 71 | test basic-9.1 {Tcl_DeleteInterp: see interp.test} {emptyTest} { | 
|---|
 | 72 | } {} | 
|---|
 | 73 |  | 
|---|
 | 74 | test basic-10.1 {DeleteInterpProc, destroys interp's global namespace} { | 
|---|
 | 75 |     catch {interp delete test_interp} | 
|---|
 | 76 |     interp create test_interp | 
|---|
 | 77 |     interp eval test_interp { | 
|---|
 | 78 |         namespace eval test_ns_basic { | 
|---|
 | 79 |             namespace export p | 
|---|
 | 80 |             proc p {} { | 
|---|
 | 81 |                 return [namespace current] | 
|---|
 | 82 |             } | 
|---|
 | 83 |         } | 
|---|
 | 84 |         namespace eval test_ns_2 { | 
|---|
 | 85 |             namespace import ::test_ns_basic::p | 
|---|
 | 86 |             variable v 27 | 
|---|
 | 87 |             proc q {} { | 
|---|
 | 88 |                 variable v | 
|---|
 | 89 |                 return "[p] $v" | 
|---|
 | 90 |             } | 
|---|
 | 91 |         } | 
|---|
 | 92 |     } | 
|---|
 | 93 |     list [interp eval test_interp {test_ns_2::q}] \ | 
|---|
 | 94 |          [interp eval test_interp {namespace delete ::}] \ | 
|---|
 | 95 |          [catch {interp eval test_interp {set a 123}} msg] $msg \ | 
|---|
 | 96 |          [interp delete test_interp] | 
|---|
 | 97 | } {{::test_ns_basic 27} {} 1 {invalid command name "set"} {}} | 
|---|
 | 98 |  | 
|---|
 | 99 | test basic-11.1 {HiddenCmdsDeleteProc, invalidate cached refs to deleted hidden cmd} { | 
|---|
 | 100 |     catch {interp delete test_interp} | 
|---|
 | 101 |     interp create test_interp | 
|---|
 | 102 |     interp eval test_interp { | 
|---|
 | 103 |         proc p {} { | 
|---|
 | 104 |             return 27 | 
|---|
 | 105 |         } | 
|---|
 | 106 |     } | 
|---|
 | 107 |     interp alias {} localP test_interp p | 
|---|
 | 108 |     list [interp eval test_interp {p}] \ | 
|---|
 | 109 |          [localP] \ | 
|---|
 | 110 |          [test_interp hide p] \ | 
|---|
 | 111 |          [catch {localP} msg] $msg \ | 
|---|
 | 112 |          [interp delete test_interp] \ | 
|---|
 | 113 |          [catch {localP} msg] $msg | 
|---|
 | 114 | } {27 27 {} 1 {invalid command name "p"} {} 1 {invalid command name "localP"}} | 
|---|
 | 115 |  | 
|---|
 | 116 | # NB: More tests about hide/expose are found in interp.test | 
|---|
 | 117 |  | 
|---|
 | 118 | test basic-12.1 {Tcl_HideCommand, names of hidden cmds can't have namespace qualifiers} { | 
|---|
 | 119 |     catch {interp delete test_interp} | 
|---|
 | 120 |     interp create test_interp | 
|---|
 | 121 |     interp eval test_interp { | 
|---|
 | 122 |         namespace eval test_ns_basic { | 
|---|
 | 123 |             proc p {} { | 
|---|
 | 124 |                 return [namespace current] | 
|---|
 | 125 |             } | 
|---|
 | 126 |         } | 
|---|
 | 127 |     } | 
|---|
 | 128 |     list [catch {test_interp hide test_ns_basic::p x} msg] $msg \ | 
|---|
 | 129 |          [catch {test_interp hide x test_ns_basic::p} msg1] $msg1 \ | 
|---|
 | 130 |          [interp delete test_interp] | 
|---|
 | 131 | } {1 {can only hide global namespace commands (use rename then hide)} 1 {cannot use namespace qualifiers in hidden command token (rename)} {}} | 
|---|
 | 132 |  | 
|---|
 | 133 | test basic-12.2 {Tcl_HideCommand, a hidden cmd remembers its containing namespace} { | 
|---|
 | 134 |     catch {namespace delete test_ns_basic} | 
|---|
 | 135 |     catch {rename cmd ""} | 
|---|
 | 136 |     proc cmd {} {   ;# note that this is global | 
|---|
 | 137 |         return [namespace current] | 
|---|
 | 138 |     } | 
|---|
 | 139 |     namespace eval test_ns_basic { | 
|---|
 | 140 |         proc hideCmd {} { | 
|---|
 | 141 |             interp hide {} cmd | 
|---|
 | 142 |         } | 
|---|
 | 143 |         proc exposeCmd {} { | 
|---|
 | 144 |             interp expose {} cmd | 
|---|
 | 145 |         } | 
|---|
 | 146 |         proc callCmd {} { | 
|---|
 | 147 |             cmd | 
|---|
 | 148 |         } | 
|---|
 | 149 |     } | 
|---|
 | 150 |     list [test_ns_basic::callCmd] \ | 
|---|
 | 151 |          [test_ns_basic::hideCmd] \ | 
|---|
 | 152 |          [catch {cmd} msg] $msg \ | 
|---|
 | 153 |          [test_ns_basic::exposeCmd] \ | 
|---|
 | 154 |          [test_ns_basic::callCmd] \ | 
|---|
 | 155 |          [namespace delete test_ns_basic] | 
|---|
 | 156 | } {:: {} 1 {invalid command name "cmd"} {} :: {}} | 
|---|
 | 157 |  | 
|---|
 | 158 | test basic-13.1 {Tcl_ExposeCommand, a command stays in the global namespace and cannot go to another namespace} { | 
|---|
 | 159 |     catch {namespace delete test_ns_basic} | 
|---|
 | 160 |     catch {rename cmd ""} | 
|---|
 | 161 |     proc cmd {} {   ;# note that this is global | 
|---|
 | 162 |         return [namespace current] | 
|---|
 | 163 |     } | 
|---|
 | 164 |     namespace eval test_ns_basic { | 
|---|
 | 165 |         proc hideCmd {} { | 
|---|
 | 166 |             interp hide {} cmd | 
|---|
 | 167 |         } | 
|---|
 | 168 |         proc exposeCmdFailing {} { | 
|---|
 | 169 |             interp expose {} cmd ::test_ns_basic::newCmd | 
|---|
 | 170 |         } | 
|---|
 | 171 |         proc exposeCmdWorkAround {} { | 
|---|
 | 172 |             interp expose {} cmd; | 
|---|
 | 173 |             rename cmd ::test_ns_basic::newCmd; | 
|---|
 | 174 |         } | 
|---|
 | 175 |         proc callCmd {} { | 
|---|
 | 176 |             cmd | 
|---|
 | 177 |         } | 
|---|
 | 178 |     } | 
|---|
 | 179 |     list [test_ns_basic::callCmd] \ | 
|---|
 | 180 |          [test_ns_basic::hideCmd] \ | 
|---|
 | 181 |          [catch {test_ns_basic::exposeCmdFailing} msg] $msg \ | 
|---|
 | 182 |          [test_ns_basic::exposeCmdWorkAround] \ | 
|---|
 | 183 |          [test_ns_basic::newCmd] \ | 
|---|
 | 184 |          [namespace delete test_ns_basic] | 
|---|
 | 185 | } {:: {} 1 {cannot expose to a namespace (use expose to toplevel, then rename)} {} ::test_ns_basic {}} | 
|---|
 | 186 | test basic-13.2 {Tcl_ExposeCommand, invalidate cached refs to cmd now being exposed} { | 
|---|
 | 187 |     catch {rename p ""} | 
|---|
 | 188 |     catch {rename cmd ""} | 
|---|
 | 189 |     proc p {} { | 
|---|
 | 190 |         cmd | 
|---|
 | 191 |     } | 
|---|
 | 192 |     proc cmd {} { | 
|---|
 | 193 |         return 42 | 
|---|
 | 194 |     } | 
|---|
 | 195 |     list [p] \ | 
|---|
 | 196 |          [interp hide {} cmd] \ | 
|---|
 | 197 |          [proc cmd {} {return Hello}] \ | 
|---|
 | 198 |          [cmd] \ | 
|---|
 | 199 |          [rename cmd ""] \ | 
|---|
 | 200 |          [interp expose {} cmd] \ | 
|---|
 | 201 |          [p] | 
|---|
 | 202 | } {42 {} {} Hello {} {} 42} | 
|---|
 | 203 |  | 
|---|
 | 204 | test basic-14.1 {Tcl_CreateCommand, new cmd goes into a namespace specified in its name, if any} {testcreatecommand} { | 
|---|
 | 205 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 206 |     list [testcreatecommand create] \ | 
|---|
 | 207 |          [test_ns_basic::createdcommand] \ | 
|---|
 | 208 |          [testcreatecommand delete] | 
|---|
 | 209 | } {{} {CreatedCommandProc in ::test_ns_basic} {}} | 
|---|
 | 210 | test basic-14.2 {Tcl_CreateCommand, namespace code ignore single ":"s in middle or end of names} {testcreatecommand} { | 
|---|
 | 211 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 212 |     catch {rename value:at: ""} | 
|---|
 | 213 |     list [testcreatecommand create2] \ | 
|---|
 | 214 |          [value:at:] \ | 
|---|
 | 215 |          [testcreatecommand delete2] | 
|---|
 | 216 | } {{} {CreatedCommandProc2 in ::} {}} | 
|---|
 | 217 |  | 
|---|
 | 218 | test basic-15.1 {Tcl_CreateObjCommand, new cmd goes into a namespace specified in its name, if any} { | 
|---|
 | 219 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 220 |     namespace eval test_ns_basic {} | 
|---|
 | 221 |     proc test_ns_basic::cmd {} {  ;# proc requires that ns already exist | 
|---|
 | 222 |         return [namespace current] | 
|---|
 | 223 |     } | 
|---|
 | 224 |     list [test_ns_basic::cmd] \ | 
|---|
 | 225 |          [namespace delete test_ns_basic] | 
|---|
 | 226 | } {::test_ns_basic {}} | 
|---|
 | 227 |  | 
|---|
 | 228 | test basic-16.1 {TclInvokeStringCommand} {emptyTest} { | 
|---|
 | 229 | } {} | 
|---|
 | 230 |  | 
|---|
 | 231 | test basic-17.1 {TclInvokeObjCommand} {emptyTest} { | 
|---|
 | 232 | } {} | 
|---|
 | 233 |  | 
|---|
 | 234 | test basic-18.1 {TclRenameCommand, name of existing cmd can have namespace qualifiers} { | 
|---|
 | 235 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 236 |     catch {rename cmd ""} | 
|---|
 | 237 |     namespace eval test_ns_basic { | 
|---|
 | 238 |         proc p {} { | 
|---|
 | 239 |             return "p in [namespace current]" | 
|---|
 | 240 |         } | 
|---|
 | 241 |     } | 
|---|
 | 242 |     list [test_ns_basic::p] \ | 
|---|
 | 243 |          [rename test_ns_basic::p test_ns_basic::q] \ | 
|---|
 | 244 |          [test_ns_basic::q]  | 
|---|
 | 245 | } {{p in ::test_ns_basic} {} {p in ::test_ns_basic}} | 
|---|
 | 246 | test basic-18.2 {TclRenameCommand, existing cmd must be found} { | 
|---|
 | 247 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 248 |     list [catch {rename test_ns_basic::p test_ns_basic::q} msg] $msg | 
|---|
 | 249 | } {1 {can't rename "test_ns_basic::p": command doesn't exist}} | 
|---|
 | 250 | test basic-18.3 {TclRenameCommand, delete cmd if new name is empty} { | 
|---|
 | 251 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 252 |     namespace eval test_ns_basic { | 
|---|
 | 253 |         proc p {} { | 
|---|
 | 254 |             return "p in [namespace current]" | 
|---|
 | 255 |         } | 
|---|
 | 256 |     } | 
|---|
 | 257 |     list [info commands test_ns_basic::*] \ | 
|---|
 | 258 |          [rename test_ns_basic::p ""] \ | 
|---|
 | 259 |          [info commands test_ns_basic::*] | 
|---|
 | 260 | } {::test_ns_basic::p {} {}} | 
|---|
 | 261 | test basic-18.4 {TclRenameCommand, bad new name} { | 
|---|
 | 262 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 263 |     namespace eval test_ns_basic { | 
|---|
 | 264 |         proc p {} { | 
|---|
 | 265 |             return "p in [namespace current]" | 
|---|
 | 266 |         } | 
|---|
 | 267 |     } | 
|---|
 | 268 |     rename test_ns_basic::p :::george::martha | 
|---|
 | 269 | } {} | 
|---|
 | 270 | test basic-18.5 {TclRenameCommand, new name must not already exist} { | 
|---|
 | 271 |     namespace eval test_ns_basic { | 
|---|
 | 272 |         proc q {} { | 
|---|
 | 273 |             return 42 | 
|---|
 | 274 |         } | 
|---|
 | 275 |     } | 
|---|
 | 276 |     list [catch {rename test_ns_basic::q :::george::martha} msg] $msg | 
|---|
 | 277 | } {1 {can't rename to ":::george::martha": command already exists}} | 
|---|
 | 278 | test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} { | 
|---|
 | 279 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 280 |     catch {rename p ""} | 
|---|
 | 281 |     catch {rename q ""} | 
|---|
 | 282 |     proc p {} { | 
|---|
 | 283 |         return "p in [namespace current]" | 
|---|
 | 284 |     } | 
|---|
 | 285 |     proc q {} { | 
|---|
 | 286 |         return "q in [namespace current]" | 
|---|
 | 287 |     } | 
|---|
 | 288 |     namespace eval test_ns_basic { | 
|---|
 | 289 |         proc callP {} { | 
|---|
 | 290 |             p | 
|---|
 | 291 |         } | 
|---|
 | 292 |     } | 
|---|
 | 293 |     list [test_ns_basic::callP] \ | 
|---|
 | 294 |          [rename q test_ns_basic::p] \ | 
|---|
 | 295 |          [test_ns_basic::callP] | 
|---|
 | 296 | } {{p in ::} {} {q in ::test_ns_basic}} | 
|---|
 | 297 |  | 
|---|
 | 298 | test basic-19.1 {Tcl_SetCommandInfo} {emptyTest} { | 
|---|
 | 299 | } {} | 
|---|
 | 300 |  | 
|---|
 | 301 | test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespaces} {testcmdtoken} { | 
|---|
 | 302 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 303 |     catch {rename p ""} | 
|---|
 | 304 |     catch {rename q ""} | 
|---|
 | 305 |     catch {unset x} | 
|---|
 | 306 |     set x [namespace eval test_ns_basic::test_ns_basic2 { | 
|---|
 | 307 |         # the following creates a cmd in the global namespace | 
|---|
 | 308 |         testcmdtoken create p | 
|---|
 | 309 |     }] | 
|---|
 | 310 |     list [testcmdtoken name $x] \ | 
|---|
 | 311 |          [rename ::p q] \ | 
|---|
 | 312 |          [testcmdtoken name $x] | 
|---|
 | 313 | } {{p ::p} {} {q ::q}} | 
|---|
 | 314 | test basic-20.2 {Tcl_GetCommandInfo, names for commands created outside namespaces} {testcmdtoken} { | 
|---|
 | 315 |     catch {rename q ""} | 
|---|
 | 316 |     set x [testcmdtoken create test_ns_basic::test_ns_basic2::p] | 
|---|
 | 317 |     list [testcmdtoken name $x] \ | 
|---|
 | 318 |          [rename test_ns_basic::test_ns_basic2::p q] \ | 
|---|
 | 319 |          [testcmdtoken name $x] | 
|---|
 | 320 | } {{p ::test_ns_basic::test_ns_basic2::p} {} {q ::q}} | 
|---|
 | 321 | test basic-20.3 {Tcl_GetCommandInfo, #-quoting} testcmdtoken { | 
|---|
 | 322 |     catch {rename \# ""} | 
|---|
 | 323 |     set x [testcmdtoken create \#] | 
|---|
 | 324 |     testcmdtoken name $x | 
|---|
 | 325 | } {{#} ::#} | 
|---|
 | 326 |  | 
|---|
 | 327 | test basic-21.1 {Tcl_GetCommandName} {emptyTest} { | 
|---|
 | 328 | } {} | 
|---|
 | 329 |  | 
|---|
 | 330 | test basic-22.1 {Tcl_GetCommandFullName} { | 
|---|
 | 331 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 332 |     namespace eval test_ns_basic1 { | 
|---|
 | 333 |         namespace export cmd* | 
|---|
 | 334 |         proc cmd1 {} {} | 
|---|
 | 335 |         proc cmd2 {} {} | 
|---|
 | 336 |     } | 
|---|
 | 337 |     namespace eval test_ns_basic2 { | 
|---|
 | 338 |         namespace export * | 
|---|
 | 339 |         namespace import ::test_ns_basic1::* | 
|---|
 | 340 |         proc p {} {} | 
|---|
 | 341 |     } | 
|---|
 | 342 |     namespace eval test_ns_basic3 { | 
|---|
 | 343 |         namespace import ::test_ns_basic2::* | 
|---|
 | 344 |         proc q {} {} | 
|---|
 | 345 |         list [namespace which -command foreach] \ | 
|---|
 | 346 |              [namespace which -command q] \ | 
|---|
 | 347 |              [namespace which -command p] \ | 
|---|
 | 348 |              [namespace which -command cmd1] \ | 
|---|
 | 349 |              [namespace which -command ::test_ns_basic2::cmd2] | 
|---|
 | 350 |     } | 
|---|
 | 351 | } {::foreach ::test_ns_basic3::q ::test_ns_basic3::p ::test_ns_basic3::cmd1 ::test_ns_basic2::cmd2} | 
|---|
 | 352 |  | 
|---|
 | 353 | test basic-23.1 {Tcl_DeleteCommand} {emptyTest} { | 
|---|
 | 354 | } {} | 
|---|
 | 355 |  | 
|---|
 | 356 | test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} { | 
|---|
 | 357 |     catch {interp delete test_interp} | 
|---|
 | 358 |     catch {unset x} | 
|---|
 | 359 |     interp create test_interp | 
|---|
 | 360 |     interp eval test_interp { | 
|---|
 | 361 |         proc useSet {} { | 
|---|
 | 362 |             return [set a 123] | 
|---|
 | 363 |         } | 
|---|
 | 364 |     } | 
|---|
 | 365 |     set x [interp eval test_interp {useSet}] | 
|---|
 | 366 |     interp eval test_interp { | 
|---|
 | 367 |         rename set "" | 
|---|
 | 368 |         proc set {args} { | 
|---|
 | 369 |             return "set called with $args" | 
|---|
 | 370 |         } | 
|---|
 | 371 |     } | 
|---|
 | 372 |     list $x \ | 
|---|
 | 373 |          [interp eval test_interp {useSet}] \ | 
|---|
 | 374 |          [interp delete test_interp] | 
|---|
 | 375 | } {123 {set called with a 123} {}} | 
|---|
 | 376 | test basic-24.2 {Tcl_DeleteCommandFromToken, deleting commands changes command epoch} { | 
|---|
 | 377 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 378 |     catch {rename p ""} | 
|---|
 | 379 |     proc p {} { | 
|---|
 | 380 |         return "global p" | 
|---|
 | 381 |     } | 
|---|
 | 382 |     namespace eval test_ns_basic { | 
|---|
 | 383 |         proc p {} { | 
|---|
 | 384 |             return "namespace p" | 
|---|
 | 385 |         } | 
|---|
 | 386 |         proc callP {} { | 
|---|
 | 387 |             p | 
|---|
 | 388 |         } | 
|---|
 | 389 |     } | 
|---|
 | 390 |     list [test_ns_basic::callP] \ | 
|---|
 | 391 |          [rename test_ns_basic::p ""] \ | 
|---|
 | 392 |          [test_ns_basic::callP] | 
|---|
 | 393 | } {{namespace p} {} {global p}} | 
|---|
 | 394 | test basic-24.3 {Tcl_DeleteCommandFromToken, delete imported cmds that refer to a deleted cmd} { | 
|---|
 | 395 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 396 |     catch {rename p ""} | 
|---|
 | 397 |     namespace eval test_ns_basic { | 
|---|
 | 398 |         namespace export p | 
|---|
 | 399 |         proc p {} {return 42} | 
|---|
 | 400 |     } | 
|---|
 | 401 |     namespace eval test_ns_basic2 { | 
|---|
 | 402 |         namespace import ::test_ns_basic::* | 
|---|
 | 403 |         proc callP {} { | 
|---|
 | 404 |             p | 
|---|
 | 405 |         } | 
|---|
 | 406 |     } | 
|---|
 | 407 |     list [test_ns_basic2::callP] \ | 
|---|
 | 408 |          [info commands test_ns_basic2::*] \ | 
|---|
 | 409 |          [rename test_ns_basic::p ""] \ | 
|---|
 | 410 |          [catch {test_ns_basic2::callP} msg] $msg \ | 
|---|
 | 411 |          [info commands test_ns_basic2::*] | 
|---|
 | 412 | } {42 {::test_ns_basic2::callP ::test_ns_basic2::p} {} 1 {invalid command name "p"} ::test_ns_basic2::callP} | 
|---|
 | 413 |  | 
|---|
 | 414 | test basic-25.1 {TclCleanupCommand} {emptyTest} { | 
|---|
 | 415 | } {} | 
|---|
 | 416 |  | 
|---|
 | 417 | test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} -setup { | 
|---|
 | 418 |     proc myHandler {msg options} { | 
|---|
 | 419 |         set ::x [dict get $options -errorinfo] | 
|---|
 | 420 |     } | 
|---|
 | 421 |     set handler [interp bgerror {}] | 
|---|
 | 422 |     interp bgerror {} [namespace which myHandler] | 
|---|
 | 423 |     set fName [makeFile {} test1] | 
|---|
 | 424 | } -body { | 
|---|
 | 425 |     # If object isn't preserved, errorInfo would be set to | 
|---|
 | 426 |     # "foo\n    while executing\n\"garbage bytes\"" because the object's | 
|---|
 | 427 |     # string would have been freed, leaving garbage bytes for the error | 
|---|
 | 428 |     # message. | 
|---|
 | 429 |     set f [open $fName w] | 
|---|
 | 430 |     fileevent $f writable "fileevent $f writable {}; error foo" | 
|---|
 | 431 |     set x {} | 
|---|
 | 432 |     vwait x | 
|---|
 | 433 |     close $f | 
|---|
 | 434 |     set x | 
|---|
 | 435 | } -cleanup { | 
|---|
 | 436 |     removeFile test1 | 
|---|
 | 437 |     interp bgerror {} $handler | 
|---|
 | 438 |     rename myHandler {} | 
|---|
 | 439 | } -result "foo\n    while executing\n\"error foo\"" | 
|---|
 | 440 |  | 
|---|
 | 441 | test basic-26.2 {Tcl_EvalObjEx, pure-list branch: preserve "objv"} -body { | 
|---|
 | 442 |     # | 
|---|
 | 443 |     # Follow the pure-list branch in a manner that | 
|---|
 | 444 |     #   a - the pure-list internal rep is destroyed by shimmering | 
|---|
 | 445 |     #   b - the command returns an error | 
|---|
 | 446 |     # As the error code in Tcl_EvalObjv accesses the list elements, this will | 
|---|
 | 447 |     # cause a segfault if [Bug 1119369] has not been fixed.  | 
|---|
 | 448 |     # NOTE: a MEM_DEBUG build may be necessary to guarantee the segfault. | 
|---|
 | 449 |     # | 
|---|
 | 450 |  | 
|---|
 | 451 |     set SRC [list foo 1] ;# pure-list command  | 
|---|
 | 452 |     proc foo str { | 
|---|
 | 453 |         # Shimmer pure-list to cmdName, cleanup and error | 
|---|
 | 454 |         proc $::SRC {} {}; $::SRC | 
|---|
 | 455 |         error "BAD CALL" | 
|---|
 | 456 |     } | 
|---|
 | 457 |     catch {eval $SRC} | 
|---|
 | 458 | } -result 1 -cleanup { | 
|---|
 | 459 |     rename foo {} | 
|---|
 | 460 |     rename $::SRC {} | 
|---|
 | 461 |     unset ::SRC | 
|---|
 | 462 | } | 
|---|
 | 463 |  | 
|---|
 | 464 | test basic-26.3 {Tcl_EvalObjEx, pure-list branch: preserve "objv"} -body { | 
|---|
 | 465 |     # | 
|---|
 | 466 |     # Follow the pure-list branch in a manner that | 
|---|
 | 467 |     #   a - the pure-list internal rep is destroyed by shimmering | 
|---|
 | 468 |     #   b - the command accesses its command line | 
|---|
 | 469 |     # This will cause a segfault if [Bug 1119369] has not been fixed.  | 
|---|
 | 470 |     # NOTE: a MEM_DEBUG build may be necessary to guarantee the segfault. | 
|---|
 | 471 |     # | 
|---|
 | 472 |  | 
|---|
 | 473 |     set SRC [list foo 1] ;# pure-list command  | 
|---|
 | 474 |     proc foo str { | 
|---|
 | 475 |         # Shimmer pure-list to cmdName, cleanup and error | 
|---|
 | 476 |         proc $::SRC {} {}; $::SRC | 
|---|
 | 477 |         info level 0 | 
|---|
 | 478 |     } | 
|---|
 | 479 |     catch {eval $SRC} | 
|---|
 | 480 | } -result 0 -cleanup { | 
|---|
 | 481 |     rename foo {} | 
|---|
 | 482 |     rename $::SRC {} | 
|---|
 | 483 |     unset ::SRC | 
|---|
 | 484 | } | 
|---|
 | 485 |  | 
|---|
 | 486 | test basic-27.1 {Tcl_ExprLong} {emptyTest} { | 
|---|
 | 487 | } {} | 
|---|
 | 488 |  | 
|---|
 | 489 | test basic-28.1 {Tcl_ExprDouble} {emptyTest} { | 
|---|
 | 490 | } {} | 
|---|
 | 491 |  | 
|---|
 | 492 | test basic-29.1 {Tcl_ExprBoolean} {emptyTest} { | 
|---|
 | 493 | } {} | 
|---|
 | 494 |  | 
|---|
 | 495 | test basic-30.1 {Tcl_ExprLongObj} {emptyTest} { | 
|---|
 | 496 | } {} | 
|---|
 | 497 |  | 
|---|
 | 498 | test basic-31.1 {Tcl_ExprDoubleObj} {emptyTest} { | 
|---|
 | 499 | } {} | 
|---|
 | 500 |  | 
|---|
 | 501 | test basic-32.1 {Tcl_ExprBooleanObj} {emptyTest} { | 
|---|
 | 502 | } {} | 
|---|
 | 503 |  | 
|---|
 | 504 | test basic-36.1 {Tcl_EvalObjv, lookup of "unknown" command} { | 
|---|
 | 505 |     catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 506 |     catch {interp delete test_interp} | 
|---|
 | 507 |     interp create test_interp | 
|---|
 | 508 |     interp eval test_interp { | 
|---|
 | 509 |         proc unknown {args} { | 
|---|
 | 510 |             return "global unknown" | 
|---|
 | 511 |         } | 
|---|
 | 512 |         namespace eval test_ns_basic { | 
|---|
 | 513 |             proc unknown {args} { | 
|---|
 | 514 |                 return "namespace unknown" | 
|---|
 | 515 |             } | 
|---|
 | 516 |         } | 
|---|
 | 517 |     } | 
|---|
 | 518 |     list [interp alias test_interp newAlias test_interp doesntExist] \ | 
|---|
 | 519 |          [catch {interp eval test_interp {newAlias}} msg] $msg \ | 
|---|
 | 520 |          [interp delete test_interp] | 
|---|
 | 521 | } {newAlias 0 {global unknown} {}} | 
|---|
 | 522 |  | 
|---|
 | 523 | test basic-37.1 {Tcl_ExprString: see expr.test} {emptyTest} { | 
|---|
 | 524 | } {} | 
|---|
 | 525 |  | 
|---|
 | 526 | test basic-38.1 {Tcl_ExprObj} {emptyTest} { | 
|---|
 | 527 | } {} | 
|---|
 | 528 |  | 
|---|
 | 529 | # Tests basic-39.* and basic-40.* refactored into trace.test | 
|---|
 | 530 |  | 
|---|
 | 531 | test basic-41.1 {Tcl_AddErrorInfo} {emptyTest} { | 
|---|
 | 532 | } {} | 
|---|
 | 533 |  | 
|---|
 | 534 | test basic-42.1 {Tcl_AddObjErrorInfo} {emptyTest} { | 
|---|
 | 535 | } {} | 
|---|
 | 536 |  | 
|---|
 | 537 | test basic-43.1 {Tcl_VarEval} {emptyTest} { | 
|---|
 | 538 | } {} | 
|---|
 | 539 |  | 
|---|
 | 540 | test basic-44.1 {Tcl_GlobalEval} {emptyTest} { | 
|---|
 | 541 | } {} | 
|---|
 | 542 |  | 
|---|
 | 543 | test basic-45.1 {Tcl_SetRecursionLimit: see interp.test} {emptyTest} { | 
|---|
 | 544 | } {} | 
|---|
 | 545 |  | 
|---|
 | 546 | test basic-46.1 {Tcl_AllowExceptions: exception return not allowed} {stdio} { | 
|---|
 | 547 |     catch {close $f} | 
|---|
 | 548 |     set res [catch { | 
|---|
 | 549 |         set f [open |[list [interpreter]] w+] | 
|---|
 | 550 |         fconfigure $f -buffering line | 
|---|
 | 551 |         puts $f {fconfigure stdout -buffering line} | 
|---|
 | 552 |         puts $f continue | 
|---|
 | 553 |         puts $f {puts $::errorInfo} | 
|---|
 | 554 |         puts $f {puts DONE} | 
|---|
 | 555 |         set newMsg {} | 
|---|
 | 556 |         set msg {} | 
|---|
 | 557 |         while {$newMsg != "DONE"} { | 
|---|
 | 558 |             set newMsg [gets $f] | 
|---|
 | 559 |             append msg "${newMsg}\n" | 
|---|
 | 560 |         } | 
|---|
 | 561 |         close $f | 
|---|
 | 562 |     } error] | 
|---|
 | 563 |     list $res $msg | 
|---|
 | 564 | } {1 {invoked "continue" outside of a loop | 
|---|
 | 565 |     while executing | 
|---|
 | 566 | "continue" | 
|---|
 | 567 | DONE | 
|---|
 | 568 | }} | 
|---|
 | 569 |  | 
|---|
 | 570 | test basic-46.2 {Tcl_AllowExceptions: exception return not allowed} -setup { | 
|---|
 | 571 |     set fName [makeFile { | 
|---|
 | 572 |         puts hello | 
|---|
 | 573 |         break | 
|---|
 | 574 |     } BREAKtest] | 
|---|
 | 575 | } -constraints { | 
|---|
 | 576 |     exec | 
|---|
 | 577 | } -body { | 
|---|
 | 578 |     exec [interpreter] $fName | 
|---|
 | 579 | } -cleanup { | 
|---|
 | 580 |     removeFile BREAKtest | 
|---|
 | 581 | } -returnCodes error -match glob -result {hello | 
|---|
 | 582 | invoked "break" outside of a loop | 
|---|
 | 583 |     while executing | 
|---|
 | 584 | "break" | 
|---|
 | 585 |     (file "*BREAKtest" line 3)}     | 
|---|
 | 586 |  | 
|---|
 | 587 | test basic-46.3 {Tcl_AllowExceptions: exception return not allowed} -setup { | 
|---|
 | 588 |     set fName [makeFile { | 
|---|
 | 589 |         interp alias {} patch {} info patchlevel | 
|---|
 | 590 |         patch | 
|---|
 | 591 |         break | 
|---|
 | 592 |     } BREAKtest] | 
|---|
 | 593 | } -constraints { | 
|---|
 | 594 |     exec | 
|---|
 | 595 | } -body { | 
|---|
 | 596 |     exec [interpreter] $fName | 
|---|
 | 597 | } -cleanup { | 
|---|
 | 598 |     removeFile BREAKtest | 
|---|
 | 599 | } -returnCodes error -match glob -result {invoked "break" outside of a loop | 
|---|
 | 600 |     while executing | 
|---|
 | 601 | "break" | 
|---|
 | 602 |     (file "*BREAKtest" line 4)}     | 
|---|
 | 603 |  | 
|---|
 | 604 | test basic-46.4 {Tcl_AllowExceptions: exception return not allowed} -setup { | 
|---|
 | 605 |     set fName [makeFile { | 
|---|
 | 606 |         foo [set a 1] [break] | 
|---|
 | 607 |     } BREAKtest] | 
|---|
 | 608 | } -constraints { | 
|---|
 | 609 |     exec | 
|---|
 | 610 | } -body { | 
|---|
 | 611 |     exec [interpreter] $fName | 
|---|
 | 612 | } -cleanup { | 
|---|
 | 613 |     removeFile BREAKtest | 
|---|
 | 614 | } -returnCodes error -match glob -result {invoked "break" outside of a loop | 
|---|
 | 615 |     while executing* | 
|---|
 | 616 | "foo \[set a 1] \[break]" | 
|---|
 | 617 |     (file "*BREAKtest" line 2)} | 
|---|
 | 618 |  | 
|---|
 | 619 | test basic-46.5 {Tcl_AllowExceptions: exception return not allowed} -setup { | 
|---|
 | 620 |     set fName [makeFile { | 
|---|
 | 621 |         return -code return | 
|---|
 | 622 |     } BREAKtest] | 
|---|
 | 623 | } -constraints { | 
|---|
 | 624 |     exec | 
|---|
 | 625 | } -body { | 
|---|
 | 626 |     exec [interpreter] $fName | 
|---|
 | 627 | } -cleanup { | 
|---|
 | 628 |     removeFile BREAKtest | 
|---|
 | 629 | } -returnCodes error -match glob -result {command returned bad code: 2 | 
|---|
 | 630 |     while executing | 
|---|
 | 631 | "return -code return" | 
|---|
 | 632 |     (file "*BREAKtest" line 2)} | 
|---|
 | 633 |  | 
|---|
 | 634 | test basic-47.1 {Tcl_EvalEx: check for missing close-bracket} -body { | 
|---|
 | 635 |     subst {a[set b [format cd]} | 
|---|
 | 636 | } -returnCodes error -result {missing close-bracket} | 
|---|
 | 637 |  | 
|---|
 | 638 | # Some lists for expansion tests to work with | 
|---|
 | 639 | set l1 [list a {b b} c d] | 
|---|
 | 640 | set l2 [list e f {g g} h] | 
|---|
 | 641 | proc l3 {} { | 
|---|
 | 642 |     list i j k {l l} | 
|---|
 | 643 | } | 
|---|
 | 644 |  | 
|---|
 | 645 | # Do all tests once byte compiled and once with direct string evaluation | 
|---|
 | 646 | for {set noComp 0} {$noComp <= 1} {incr noComp} { | 
|---|
 | 647 |  | 
|---|
 | 648 | if $noComp { | 
|---|
 | 649 |     interp alias {} run {} testevalex | 
|---|
 | 650 |     set constraints testevalex | 
|---|
 | 651 | } else { | 
|---|
 | 652 |     interp alias {} run {} if 1 | 
|---|
 | 653 |     set constraints {} | 
|---|
 | 654 | } | 
|---|
 | 655 |  | 
|---|
 | 656 | test basic-47.2.$noComp {Tcl_EvalEx: error during word expansion} -body { | 
|---|
 | 657 |     run {{*}\{} | 
|---|
 | 658 | } -constraints $constraints -returnCodes error -result {unmatched open brace in list} | 
|---|
 | 659 |  | 
|---|
 | 660 | test basic-47.3.$noComp {Tcl_EvalEx, error during substitution} -body { | 
|---|
 | 661 |     run {{*}[error foo]} | 
|---|
 | 662 | } -constraints $constraints -returnCodes error -result foo | 
|---|
 | 663 |  | 
|---|
 | 664 | test basic-47.4.$noComp {Tcl_EvalEx: no expansion} $constraints { | 
|---|
 | 665 |     run {list {*} {*}   {*}} | 
|---|
 | 666 | } {* * *} | 
|---|
 | 667 |  | 
|---|
 | 668 | test basic-47.5.$noComp {Tcl_EvalEx: expansion} $constraints { | 
|---|
 | 669 |     run {list {*}{} {*} {*}x {*}"y z"} | 
|---|
 | 670 | } {* x y z} | 
|---|
 | 671 |  | 
|---|
 | 672 | test basic-47.6.$noComp {Tcl_EvalEx: expansion to zero args} $constraints { | 
|---|
 | 673 |     run {list {*}{}} | 
|---|
 | 674 | } {} | 
|---|
 | 675 |  | 
|---|
 | 676 | test basic-47.7.$noComp {Tcl_EvalEx: expansion to one arg} $constraints { | 
|---|
 | 677 |     run {list {*}x} | 
|---|
 | 678 | } x | 
|---|
 | 679 |  | 
|---|
 | 680 | test basic-47.8.$noComp {Tcl_EvalEx: expansion to many args} $constraints { | 
|---|
 | 681 |     run {list {*}"y z"} | 
|---|
 | 682 | } {y z} | 
|---|
 | 683 |  | 
|---|
 | 684 | test basic-47.9.$noComp {Tcl_EvalEx: expansion and subst order} $constraints { | 
|---|
 | 685 |     set x 0 | 
|---|
 | 686 |     run {list [incr x] {*}[incr x] [incr x] \ | 
|---|
 | 687 |                 {*}[list [incr x] [incr x]] [incr x]} | 
|---|
 | 688 | } {1 2 3 4 5 6} | 
|---|
 | 689 |  | 
|---|
 | 690 | test basic-47.10.$noComp {Tcl_EvalEx: expand and memory management} $constraints { | 
|---|
 | 691 |     run {concat {*}{} a b c d e f g h i j k l m n o p q r} | 
|---|
 | 692 | } {a b c d e f g h i j k l m n o p q r} | 
|---|
 | 693 |  | 
|---|
 | 694 | test basic-47.11.$noComp {Tcl_EvalEx: expand and memory management} $constraints { | 
|---|
 | 695 |     run {concat {*}1 a b c d e f g h i j k l m n o p q r} | 
|---|
 | 696 | } {1 a b c d e f g h i j k l m n o p q r} | 
|---|
 | 697 |  | 
|---|
 | 698 | test basic-47.12.$noComp {Tcl_EvalEx: expand and memory management} $constraints { | 
|---|
 | 699 |     run {concat {*}{1 2} a b c d e f g h i j k l m n o p q r} | 
|---|
 | 700 | } {1 2 a b c d e f g h i j k l m n o p q r} | 
|---|
 | 701 |  | 
|---|
 | 702 | test basic-47.13.$noComp {Tcl_EvalEx: expand and memory management} $constraints { | 
|---|
 | 703 |     run {concat {*}{} {*}{1 2} a b c d e f g h i j k l m n o p q} | 
|---|
 | 704 | } {1 2 a b c d e f g h i j k l m n o p q} | 
|---|
 | 705 |  | 
|---|
 | 706 | test basic-47.14.$noComp {Tcl_EvalEx: expand and memory management} $constraints { | 
|---|
 | 707 |     run {concat {*}{} a b c d e f g h i j k l m n o p q r s} | 
|---|
 | 708 | } {a b c d e f g h i j k l m n o p q r s} | 
|---|
 | 709 |  | 
|---|
 | 710 | test basic-47.15.$noComp {Tcl_EvalEx: expand and memory management} $constraints { | 
|---|
 | 711 |     run {concat {*}1 a b c d e f g h i j k l m n o p q r s} | 
|---|
 | 712 | } {1 a b c d e f g h i j k l m n o p q r s} | 
|---|
 | 713 |  | 
|---|
 | 714 | test basic-47.16.$noComp {Tcl_EvalEx: expand and memory management} $constraints { | 
|---|
 | 715 |     run {concat {*}{1 2} a b c d e f g h i j k l m n o p q r s} | 
|---|
 | 716 | } {1 2 a b c d e f g h i j k l m n o p q r s} | 
|---|
 | 717 |  | 
|---|
 | 718 | test basic-47.17.$noComp {Tcl_EvalEx: expand and memory management} $constraints { | 
|---|
 | 719 |     run {concat {*}{} {*}{1 2} a b c d e f g h i j k l m n o p q r} | 
|---|
 | 720 | } {1 2 a b c d e f g h i j k l m n o p q r} | 
|---|
 | 721 |  | 
|---|
 | 722 | test basic-48.1.$noComp {expansion: parsing} $constraints { | 
|---|
 | 723 |         run { # A comment | 
|---|
 | 724 |  | 
|---|
 | 725 |                 # Another comment | 
|---|
 | 726 |                 list 1  2\ | 
|---|
 | 727 |                         3   {*}$::l1 | 
|---|
 | 728 |              | 
|---|
 | 729 |                 # Comment again | 
|---|
 | 730 |         } | 
|---|
 | 731 | } {1 2 3 a {b b} c d} | 
|---|
 | 732 |  | 
|---|
 | 733 | test basic-48.2.$noComp {no expansion} $constraints { | 
|---|
 | 734 |         run {list $::l1 $::l2 [l3]} | 
|---|
 | 735 | } {{a {b b} c d} {e f {g g} h} {i j k {l l}}} | 
|---|
 | 736 |  | 
|---|
 | 737 | test basic-48.3.$noComp {expansion} $constraints { | 
|---|
 | 738 |         run {list {*}$::l1 $::l2 {*}[l3]} | 
|---|
 | 739 | } {a {b b} c d {e f {g g} h} i j k {l l}} | 
|---|
 | 740 |  | 
|---|
 | 741 | test basic-48.4.$noComp {expansion: really long cmd} $constraints { | 
|---|
 | 742 |         set cmd [list list] | 
|---|
 | 743 |         for {set t 0} {$t < 500} {incr t} { | 
|---|
 | 744 |             lappend cmd {{*}$::l1} | 
|---|
 | 745 |         } | 
|---|
 | 746 |         llength [run [join $cmd]] | 
|---|
 | 747 | } 2000 | 
|---|
 | 748 |  | 
|---|
 | 749 | test basic-48.5.$noComp {expansion: error detection} -setup { | 
|---|
 | 750 |         set l "a {a b}x y" | 
|---|
 | 751 | } -constraints $constraints -body { | 
|---|
 | 752 |         run {list $::l1 {*}$l} | 
|---|
 | 753 | } -cleanup { | 
|---|
 | 754 |         unset l | 
|---|
 | 755 | } -returnCodes 1 -result {list element in braces followed by "x" instead of space} | 
|---|
 | 756 |  | 
|---|
 | 757 | test basic-48.6.$noComp {expansion: odd usage} $constraints { | 
|---|
 | 758 |         run {list {*}$::l1$::l2} | 
|---|
 | 759 | } {a {b b} c de f {g g} h} | 
|---|
 | 760 |  | 
|---|
 | 761 | test basic-48.7.$noComp {expansion: odd usage} -constraints $constraints -body { | 
|---|
 | 762 |         run {list {*}[l3]$::l1} | 
|---|
 | 763 | } -returnCodes 1 -result {list element in braces followed by "a" instead of space} | 
|---|
 | 764 |  | 
|---|
 | 765 | test basic-48.8.$noComp {expansion: odd usage} $constraints { | 
|---|
 | 766 |         run {list {*}hej$::l1} | 
|---|
 | 767 | } {heja {b b} c d} | 
|---|
 | 768 |  | 
|---|
 | 769 | test basic-48.9.$noComp {expansion: Not all {*} should trigger} $constraints { | 
|---|
 | 770 |         run {list {*}$::l1 \{*\}$::l2 "{*}$::l1" {{*} i j k}} | 
|---|
 | 771 | } {a {b b} c d {{*}e f {g g} h} {{*}a {b b} c d} {{*} i j k}} | 
|---|
 | 772 |  | 
|---|
 | 773 | test basic-48.10.$noComp {expansion: expansion of command word} -setup { | 
|---|
 | 774 |         set cmd [list string range jultomte] | 
|---|
 | 775 | } -constraints $constraints -body { | 
|---|
 | 776 |         run {{*}$cmd 2 6} | 
|---|
 | 777 | } -cleanup { | 
|---|
 | 778 |         unset cmd | 
|---|
 | 779 | } -result ltomt | 
|---|
 | 780 |  | 
|---|
 | 781 | test basic-48.11.$noComp {expansion: expansion into nothing} -setup { | 
|---|
 | 782 |         set cmd {} | 
|---|
 | 783 |         set bar {} | 
|---|
 | 784 | } -constraints $constraints -body { | 
|---|
 | 785 |         run {{*}$cmd {*}$bar} | 
|---|
 | 786 | } -cleanup { | 
|---|
 | 787 |         unset cmd bar | 
|---|
 | 788 | } -result {} | 
|---|
 | 789 |  | 
|---|
 | 790 | test basic-48.12.$noComp {expansion: odd usage} $constraints { | 
|---|
 | 791 |         run {list {*}$::l1 {*}"hej hopp" {*}$::l2} | 
|---|
 | 792 | } {a {b b} c d hej hopp e f {g g} h} | 
|---|
 | 793 |  | 
|---|
 | 794 | test basic-48.13.$noComp {expansion: odd usage} $constraints { | 
|---|
 | 795 |         run {list {*}$::l1 {*}{hej hopp} {*}$::l2} | 
|---|
 | 796 | } {a {b b} c d hej hopp e f {g g} h} | 
|---|
 | 797 |  | 
|---|
 | 798 | test basic-48.14.$noComp {expansion: hash command} -setup { | 
|---|
 | 799 |         catch {rename \# ""} | 
|---|
 | 800 |         set cmd "#" | 
|---|
 | 801 |     } -constraints $constraints -body {  | 
|---|
 | 802 |            run { {*}$cmd apa bepa } | 
|---|
 | 803 |     } -cleanup { | 
|---|
 | 804 |         unset cmd | 
|---|
 | 805 | } -returnCodes 1 -result {invalid command name "#"} | 
|---|
 | 806 |  | 
|---|
 | 807 | test basic-48.15.$noComp {expansion: complex words} -setup { | 
|---|
 | 808 |             set a(x) [list a {b c} d e] | 
|---|
 | 809 |             set b x | 
|---|
 | 810 |             set c [list {f\ g h\ i j k} x y] | 
|---|
 | 811 |             set d {0\ 1 2 3} | 
|---|
 | 812 |     } -constraints $constraints -body { | 
|---|
 | 813 |             run { lappend d {*}$a($b) {*}[lindex $c 0] } | 
|---|
 | 814 |     } -cleanup { | 
|---|
 | 815 |         unset a b c d | 
|---|
 | 816 | } -result {{0 1} 2 3 a {b c} d e {f g} {h i} j k} | 
|---|
 | 817 |  | 
|---|
 | 818 | testConstraint memory [llength [info commands memory]] | 
|---|
 | 819 | test basic-48.16.$noComp {expansion: testing for leaks} -setup { | 
|---|
 | 820 |         proc getbytes {} { | 
|---|
 | 821 |             set lines [split [memory info] "\n"] | 
|---|
 | 822 |             lindex [lindex $lines 3] 3 | 
|---|
 | 823 |         } | 
|---|
 | 824 |         # This test is made to stress the allocation, reallocation and | 
|---|
 | 825 |         # object reference management in Tcl_EvalEx. | 
|---|
 | 826 |         proc stress {} { | 
|---|
 | 827 |             set a x | 
|---|
 | 828 |             # Create free objects that should disappear | 
|---|
 | 829 |             set l [list 1$a 2$a 3$a 4$a 5$a 6$a 7$a] | 
|---|
 | 830 |             # A short number of words and a short result (8) | 
|---|
 | 831 |             set l [run {list {*}$l $a$a}] | 
|---|
 | 832 |             # A short number of words and a longer result (27) | 
|---|
 | 833 |             set l [run {list {*}$l $a$a {*}$l $a$a {*}$l $a$a}] | 
|---|
 | 834 |             # A short number of words and a longer result, with an error | 
|---|
 | 835 |             # This is to stress the cleanup in the error case | 
|---|
 | 836 |             if {![catch {run {_moo_ {*}$l $a$a {*}$l $a$a {*}$l}}]} { | 
|---|
 | 837 |                 error "An error was expected in the previous statement" | 
|---|
 | 838 |             } | 
|---|
 | 839 |             # Many words | 
|---|
 | 840 |             set l [run {list {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 841 |                                  {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 842 |                                  {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 843 |                                  {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 844 |                                  {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 845 |                                  {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 846 |                                  {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 847 |                                  {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 848 |                                  {*}$l $a$a {*}$l $a$a \ | 
|---|
 | 849 |                                  {*}$l $a$a}] | 
|---|
 | 850 |  | 
|---|
 | 851 |             if {[llength $l] != 19*28} { | 
|---|
 | 852 |                 error "Bad Length: [llength $l] should be [expr {19*28}]" | 
|---|
 | 853 |             } | 
|---|
 | 854 |         } | 
|---|
 | 855 |     } -constraints [linsert $constraints 0 memory] -body { | 
|---|
 | 856 |         set end [getbytes] | 
|---|
 | 857 |         for {set i 0} {$i < 5} {incr i} { | 
|---|
 | 858 |             stress | 
|---|
 | 859 |             set tmp $end | 
|---|
 | 860 |             set end [getbytes] | 
|---|
 | 861 |         }     | 
|---|
 | 862 |         set leak [expr {$end - $tmp}] | 
|---|
 | 863 |     } -cleanup { | 
|---|
 | 864 |         unset end i tmp | 
|---|
 | 865 |         rename getbytes {} | 
|---|
 | 866 |         rename stress {} | 
|---|
 | 867 | } -result 0 | 
|---|
 | 868 |  | 
|---|
 | 869 | test basic-48.17.$noComp {expansion: object safety} -setup { | 
|---|
 | 870 |         set old_precision $::tcl_precision | 
|---|
 | 871 |         set ::tcl_precision 4 | 
|---|
 | 872 |     } -constraints $constraints -body {  | 
|---|
 | 873 |             set third [expr {1.0/3.0}] | 
|---|
 | 874 |             set l [list $third $third] | 
|---|
 | 875 |             set x [run {list $third {*}$l $third}] | 
|---|
 | 876 |             set res [list] | 
|---|
 | 877 |             foreach t $x { | 
|---|
 | 878 |                 lappend res [expr {$t * 3.0}] | 
|---|
 | 879 |             } | 
|---|
 | 880 |             set res | 
|---|
 | 881 |     } -cleanup { | 
|---|
 | 882 |         set ::tcl_precision $old_precision | 
|---|
 | 883 |         unset old_precision res t l x third | 
|---|
 | 884 | } -result {1.0 1.0 1.0 1.0} | 
|---|
 | 885 |  | 
|---|
 | 886 | test basic-48.18.$noComp {expansion: list semantics} -constraints $constraints -body { | 
|---|
 | 887 |         set badcmd { | 
|---|
 | 888 |             list a b | 
|---|
 | 889 |             set apa 10 | 
|---|
 | 890 |         } | 
|---|
 | 891 |         set apa 0 | 
|---|
 | 892 |         list [llength [run { {*}$badcmd }]] $apa | 
|---|
 | 893 |     } -cleanup { | 
|---|
 | 894 |         unset apa badcmd | 
|---|
 | 895 | } -result {5 0} | 
|---|
 | 896 |  | 
|---|
 | 897 | test basic-48.19.$noComp {expansion: error checking order} -body { | 
|---|
 | 898 |         set badlist "a {}x y" | 
|---|
 | 899 |         set a 0 | 
|---|
 | 900 |         set b 0 | 
|---|
 | 901 |         catch {run {list [incr a] {*}$badlist [incr b]}} | 
|---|
 | 902 |         list $a $b | 
|---|
 | 903 |     } -constraints $constraints -cleanup { | 
|---|
 | 904 |         unset badlist a b | 
|---|
 | 905 | } -result {1 0} | 
|---|
 | 906 |  | 
|---|
 | 907 | test basic-48.20.$noComp {expansion: odd case with word boundaries} $constraints { | 
|---|
 | 908 |     run {list {*}$::l1 {*}"hej hopp" {*}$::l2} | 
|---|
 | 909 | } {a {b b} c d hej hopp e f {g g} h} | 
|---|
 | 910 |  | 
|---|
 | 911 | test basic-48.21.$noComp {expansion: odd case with word boundaries} $constraints { | 
|---|
 | 912 |     run {list {*}$::l1 {*}{hej hopp} {*}$::l2} | 
|---|
 | 913 | } {a {b b} c d hej hopp e f {g g} h} | 
|---|
 | 914 |  | 
|---|
 | 915 | test basic-48.22.$noComp {expansion: odd case with word boundaries} -body { | 
|---|
 | 916 |     run {list {*}$::l1 {*}"hej hopp {*}$::l2} | 
|---|
 | 917 | } -constraints $constraints -returnCodes error -result {missing "} | 
|---|
 | 918 |  | 
|---|
 | 919 | test basic-48.23.$noComp {expansion: handle return codes} -constraints $constraints -body { | 
|---|
 | 920 |         set res {} | 
|---|
 | 921 |         for {set t 0} {$t < 10} {incr t} { | 
|---|
 | 922 |             run { {*}break } | 
|---|
 | 923 |         } | 
|---|
 | 924 |         lappend res $t | 
|---|
 | 925 |  | 
|---|
 | 926 |         for {set t 0} {$t < 10} {incr t} { | 
|---|
 | 927 |             run { {*}continue } | 
|---|
 | 928 |             set t 20 | 
|---|
 | 929 |         } | 
|---|
 | 930 |         lappend res $t | 
|---|
 | 931 |  | 
|---|
 | 932 |         lappend res [catch { run { {*}{error Hejsan} } } err] | 
|---|
 | 933 |         lappend res $err | 
|---|
 | 934 |     } -cleanup { | 
|---|
 | 935 |         unset res t | 
|---|
 | 936 | } -result {0 10 1 Hejsan} | 
|---|
 | 937 |  | 
|---|
 | 938 | } ;# End of noComp loop | 
|---|
 | 939 |  | 
|---|
 | 940 | test basic-49.1 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex { | 
|---|
 | 941 |     set ::x global | 
|---|
 | 942 |     namespace eval ns { | 
|---|
 | 943 |         variable x namespace | 
|---|
 | 944 |         testevalex {set x changed} global | 
|---|
 | 945 |         set ::result [list $::x $x] | 
|---|
 | 946 |     } | 
|---|
 | 947 |     namespace delete ns | 
|---|
 | 948 |     set ::result | 
|---|
 | 949 | } {changed namespace} | 
|---|
 | 950 | test basic-49.2 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex { | 
|---|
 | 951 |     set ::x global | 
|---|
 | 952 |     namespace eval ns { | 
|---|
 | 953 |         variable x namespace | 
|---|
 | 954 |         testevalex {set ::context $x} global | 
|---|
 | 955 |     } | 
|---|
 | 956 |     namespace delete ns | 
|---|
 | 957 |     set ::context | 
|---|
 | 958 | } {global} | 
|---|
 | 959 |  | 
|---|
 | 960 | # Clean up after expand tests | 
|---|
 | 961 | unset noComp l1 l2 constraints | 
|---|
 | 962 | rename l3 {} | 
|---|
 | 963 | rename run {} | 
|---|
 | 964 |  | 
|---|
 | 965 |  #cleanup | 
|---|
 | 966 | catch {namespace delete {*}[namespace children :: test_ns_*]} | 
|---|
 | 967 | catch {namespace delete george} | 
|---|
 | 968 | catch {interp delete test_interp} | 
|---|
 | 969 | catch {rename p ""} | 
|---|
 | 970 | catch {rename q ""} | 
|---|
 | 971 | catch {rename cmd ""} | 
|---|
 | 972 | catch {rename value:at: ""} | 
|---|
 | 973 | catch {unset x} | 
|---|
 | 974 | ::tcltest::cleanupTests | 
|---|
 | 975 | return | 
|---|