proc.test
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:11k
源码类别:

通讯编程

开发平台:

Visual C++

  1. # This file contains tests for the tclProc.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 includes only new tests, in particular
  4. # tests for code changed for the addition of Tcl namespaces. Other
  5. # procedure-related tests appear in other test files such as proc-old.test.
  6. #
  7. # Sourcing this file into Tcl runs the tests and generates output for
  8. # errors.  No output means no errors were found.
  9. #
  10. # Copyright (c) 1997 Sun Microsystems, Inc.
  11. # Copyright (c) 1998-1999 by Scriptics Corporation.
  12. #
  13. # See the file "license.terms" for information on usage and redistribution
  14. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  15. #
  16. # RCS: @(#) $Id: proc.test,v 1.11.2.1 2004/05/02 21:07:16 msofer Exp $
  17. if {[lsearch [namespace children] ::tcltest] == -1} {
  18.     package require tcltest
  19.     namespace import -force ::tcltest::*
  20. }
  21. catch {eval namespace delete [namespace children :: test_ns_*]}
  22. catch {rename p ""}
  23. catch {rename {} ""}
  24. catch {unset msg}
  25. test proc-1.1 {Tcl_ProcObjCmd, put proc in namespace specified in name, if any} {
  26.     catch {eval namespace delete [namespace children :: test_ns_*]}
  27.     namespace eval test_ns_1 {
  28.         namespace eval baz {}
  29.     }
  30.     proc test_ns_1::baz::p {} {
  31.         return "p in [namespace current]"
  32.     }
  33.     list [test_ns_1::baz::p] 
  34.          [namespace eval test_ns_1 {baz::p}] 
  35.          [info commands test_ns_1::baz::*]
  36. } {{p in ::test_ns_1::baz} {p in ::test_ns_1::baz} ::test_ns_1::baz::p}
  37. test proc-1.2 {Tcl_ProcObjCmd, namespace specified in proc name must exist} {
  38.     catch {eval namespace delete [namespace children :: test_ns_*]}
  39.     list [catch {proc test_ns_1::baz::p {} {}} msg] $msg
  40. } {1 {can't create procedure "test_ns_1::baz::p": unknown namespace}}
  41. test proc-1.3 {Tcl_ProcObjCmd, empty proc name} {
  42.     catch {eval namespace delete [namespace children :: test_ns_*]}
  43.     proc :: {} {
  44.         return "empty called"
  45.     }
  46.     list [::] 
  47.          [info body {}]
  48. } {{empty called} {
  49.         return "empty called"
  50.     }}
  51. test proc-1.4 {Tcl_ProcObjCmd, simple proc name and proc defined in namespace} {
  52.     catch {eval namespace delete [namespace children :: test_ns_*]}
  53.     namespace eval test_ns_1 {
  54.         namespace eval baz {
  55.             proc p {} {
  56.                 return "p in [namespace current]"
  57.             }
  58.         }
  59.     }
  60.     list [test_ns_1::baz::p] 
  61.          [info commands test_ns_1::baz::*]
  62. } {{p in ::test_ns_1::baz} ::test_ns_1::baz::p}
  63. test proc-1.5 {Tcl_ProcObjCmd, qualified proc name and proc defined in namespace} {
  64.     catch {eval namespace delete [namespace children :: test_ns_*]}
  65.     namespace eval test_ns_1::baz {}
  66.     namespace eval test_ns_1 {
  67.         proc baz::p {} {
  68.             return "p in [namespace current]"
  69.         }
  70.     }
  71.     list [test_ns_1::baz::p] 
  72.          [info commands test_ns_1::baz::*] 
  73.          [namespace eval test_ns_1::baz {namespace which p}]
  74. } {{p in ::test_ns_1::baz} ::test_ns_1::baz::p ::test_ns_1::baz::p}
  75. test proc-1.6 {Tcl_ProcObjCmd, namespace code ignores single ":"s in middle or end of command names} {
  76.     catch {eval namespace delete [namespace children :: test_ns_*]}
  77.     namespace eval test_ns_1 {
  78.         proc q: {} {return "q:"}
  79.         proc value:at: {} {return "value:at:"}
  80.     }
  81.     list [namespace eval test_ns_1 {q:}] 
  82.          [namespace eval test_ns_1 {value:at:}] 
  83.          [test_ns_1::q:] 
  84.          [test_ns_1::value:at:] 
  85.          [lsort [info commands test_ns_1::*]] 
  86.          [namespace eval test_ns_1 {namespace which q:}] 
  87.          [namespace eval test_ns_1 {namespace which value:at:}]
  88. } {q: value:at: q: value:at: {::test_ns_1::q: ::test_ns_1::value:at:} ::test_ns_1::q: ::test_ns_1::value:at:}
  89. test proc-1.7 {Tcl_ProcObjCmd, check that formal parameter names are not array elements} {
  90.     catch {rename p ""}
  91.     list [catch {proc p {a(1) a(2)} { 
  92.             set z [expr $a(1)+$a(2)]
  93.             puts "$z=z, $a(1)=$a(1)"
  94.         }} msg] $msg
  95. } {1 {procedure "p" has formal parameter "a(1)" that is an array element}}
  96. test proc-1.8 {Tcl_ProcObjCmd, check that formal parameter names are simple names} {
  97.     catch {rename p ""}
  98.     list [catch {proc p {b:a b::a} { 
  99.     }} msg] $msg
  100. } {1 {procedure "p" has formal parameter "b::a" that is not a simple name}}
  101. test proc-2.1 {TclFindProc, simple proc name and proc not in namespace} {
  102.     catch {eval namespace delete [namespace children :: test_ns_*]}
  103.     catch {rename p ""}
  104.     proc p {} {return "p in [namespace current]"}
  105.     info body p
  106. } {return "p in [namespace current]"}
  107. test proc-2.2 {TclFindProc, simple proc name and proc defined in namespace} {
  108.     catch {eval namespace delete [namespace children :: test_ns_*]}
  109.     namespace eval test_ns_1 {
  110.         namespace eval baz {
  111.             proc p {} {return "p in [namespace current]"}
  112.         }
  113.     }
  114.     namespace eval test_ns_1::baz {info body p}
  115. } {return "p in [namespace current]"}
  116. test proc-2.3 {TclFindProc, qualified proc name and proc defined in namespace} {
  117.     catch {eval namespace delete [namespace children :: test_ns_*]}
  118.     namespace eval test_ns_1::baz {}
  119.     namespace eval test_ns_1 {
  120.         proc baz::p {} {return "p in [namespace current]"}
  121.     }
  122.     namespace eval test_ns_1 {info body baz::p}
  123. } {return "p in [namespace current]"}
  124. test proc-2.4 {TclFindProc, global proc and executing in namespace} {
  125.     catch {eval namespace delete [namespace children :: test_ns_*]}
  126.     catch {rename p ""}
  127.     proc p {} {return "global p"}
  128.     namespace eval test_ns_1::baz {info body p}
  129. } {return "global p"}
  130. test proc-3.1 {TclObjInterpProc, proc defined and executing in same namespace} {
  131.     catch {eval namespace delete [namespace children :: test_ns_*]}
  132.     proc p {} {return "p in [namespace current]"}
  133.     p
  134. } {p in ::}
  135. test proc-3.2 {TclObjInterpProc, proc defined and executing in same namespace} {
  136.     catch {eval namespace delete [namespace children :: test_ns_*]}
  137.     namespace eval test_ns_1::baz {
  138.         proc p {} {return "p in [namespace current]"}
  139.         p
  140.     }
  141. } {p in ::test_ns_1::baz}
  142. test proc-3.3 {TclObjInterpProc, proc defined and executing in different namespaces} {
  143.     catch {eval namespace delete [namespace children :: test_ns_*]}
  144.     catch {rename p ""}
  145.     proc p {} {return "p in [namespace current]"}
  146.     namespace eval test_ns_1::baz {
  147.         p
  148.     }
  149. } {p in ::}
  150. test proc-3.4 {TclObjInterpProc, procs execute in the namespace in which they were defined unless renamed into new namespace} {
  151.     catch {eval namespace delete [namespace children :: test_ns_*]}
  152.     catch {rename p ""}
  153.     namespace eval test_ns_1::baz {
  154.         proc p {} {return "p in [namespace current]"}
  155.         rename ::test_ns_1::baz::p ::p
  156.         list [p] [namespace which p]
  157.     }
  158. } {{p in ::} ::p}
  159. test proc-3.5 {TclObjInterpProc, any old result is reset before appending error msg about missing arguments} {
  160.     proc p {x} {info commands 3m}
  161.     list [catch {p} msg] $msg
  162. } {1 {wrong # args: should be "p x"}}
  163. test proc-3.6 {TclObjInterpProc, proper quoting of proc name, Bug 942757} {
  164.     proc {a b  c} {x} {info commands 3m}
  165.     list [catch {{a b  c}} msg] $msg
  166. } {1 {wrong # args: should be "{a b  c} x"}}
  167. catch {eval namespace delete [namespace children :: test_ns_*]}
  168. catch {rename p ""}
  169. catch {rename {} ""}
  170. catch {rename {a b  c} {}}
  171. catch {unset msg}
  172. if {[catch {package require procbodytest}]} {
  173.     puts "This application couldn't load the "procbodytest" package, so I"
  174.     puts "can't test creation of procs whose bodies have type "procbody"."
  175.     ::tcltest::cleanupTests
  176.     return
  177. }
  178. catch {rename p ""}
  179. catch {rename t ""}
  180. # Note that the test require that procedures whose body is used to create
  181. # procbody objects must be executed before the procbodytest::proc command
  182. # is executed, so that the Proc struct is populated correctly (CompiledLocals
  183. # are added at compile time).
  184. test proc-4.1 {TclCreateProc, procbody obj} {
  185.     catch {
  186. proc p x {return "$x:$x"}
  187. set rv [p P]
  188. procbodytest::proc t x p
  189. lappend rv [t T]
  190. set rv
  191.     } result
  192.     catch {rename p ""}
  193.     catch {rename t ""}
  194.     set result
  195. } {P:P T:T}
  196. test proc-4.2 {TclCreateProc, procbody obj, use compiled locals} {
  197.     catch {
  198. proc p x {
  199.     set y [string tolower $x]
  200.     return "$x:$y"
  201. }
  202. set rv [p P]
  203. procbodytest::proc t x p
  204. lappend rv [t T]
  205. set rv
  206.     } result
  207.     catch {rename p ""}
  208.     catch {rename t ""}
  209.     set result
  210. } {P:p T:t}
  211. test proc-4.3 {TclCreateProc, procbody obj, too many args} {
  212.     catch {
  213. proc p x {
  214.     set y [string tolower $x]
  215.     return "$x:$y"
  216. }
  217. set rv [p P]
  218. procbodytest::proc t {x x1 x2} p
  219. lappend rv [t T]
  220. set rv
  221.     } result
  222.     catch {rename p ""}
  223.     catch {rename t ""}
  224.     set result
  225. } {procedure "t": arg list contains 3 entries, precompiled header expects 1}
  226. test proc-4.4 {TclCreateProc, procbody obj, inconsitent arg name} {
  227.     catch {
  228. proc p {x y z} {
  229.     set v [join [list $x $y $z]]
  230.     set w [string tolower $v]
  231.     return "$v:$w"
  232. }
  233. set rv [p P Q R]
  234. procbodytest::proc t {x x1 z} p
  235. lappend rv [t S T U]
  236. set rv
  237.     } result
  238.     catch {rename p ""}
  239.     catch {rename t ""}
  240.     set result
  241. } {procedure "t": formal parameter 1 is inconsistent with precompiled body}
  242. test proc-4.5 {TclCreateProc, procbody obj, inconsitent arg default type} {
  243.     catch {
  244. proc p {x y {z Z}} {
  245.     set v [join [list $x $y $z]]
  246.     set w [string tolower $v]
  247.     return "$v:$w"
  248. }
  249. set rv [p P Q R]
  250. procbodytest::proc t {x y z} p
  251. lappend rv [t S T U]
  252. set rv
  253.     } result
  254.     catch {rename p ""}
  255.     catch {rename t ""}
  256.     set result
  257. } {procedure "t": formal parameter 2 is inconsistent with precompiled body}
  258. test proc-4.6 {TclCreateProc, procbody obj, inconsitent arg default type} {
  259.     catch {
  260. proc p {x y z} {
  261.     set v [join [list $x $y $z]]
  262.     set w [string tolower $v]
  263.     return "$v:$w"
  264. }
  265. set rv [p P Q R]
  266. procbodytest::proc t {x y {z Z}} p
  267. lappend rv [t S T U]
  268. set rv
  269.     } result
  270.     catch {rename p ""}
  271.     catch {rename t ""}
  272.     set result
  273. } {procedure "t": formal parameter 2 is inconsistent with precompiled body}
  274. test proc-4.7 {TclCreateProc, procbody obj, inconsitent arg default value} {
  275.     catch {
  276. proc p {x y {z Z}} {
  277.     set v [join [list $x $y $z]]
  278.     set w [string tolower $v]
  279.     return "$v:$w"
  280. }
  281. set rv [p P Q R]
  282. procbodytest::proc t {x y {z ZZ}} p
  283. lappend rv [t S T U]
  284. set rv
  285.     } result
  286.     catch {rename p ""}
  287.     catch {rename t ""}
  288.     set result
  289. } {procedure "t": formal parameter "z" has default value inconsistent with precompiled body}
  290. test proc-5.1 {Bytecompiling noop; test for correct argument substitution} {
  291.     proc p args {} ; # this will be bytecompiled into t
  292.     proc t {} {
  293. set res {}
  294. set a 0
  295. set b 0
  296. trace add variable a read {append res a ;#}
  297. trace add variable b write {append res b ;#}
  298. p $a ccccccw {bfe} {$a} [incr b] [incr a] {[incr b]} {$a} hello
  299. set res
  300.     }
  301.     set result [t]
  302.     catch {rename p ""}
  303.     catch {rename t ""}
  304.     set result
  305. } {aba}    
  306. test proc-6.1 {ProcessProcResultCode: Bug 647307 (negative return code)} {
  307.     proc a {} {return -code -5}
  308.     proc b {} a
  309.     set result [catch b]
  310.     rename a {}
  311.     rename b {}
  312.     set result
  313. } -5
  314. # cleanup
  315. catch {rename p ""}
  316. catch {rename t ""}
  317. ::tcltest::cleanupTests
  318. return