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

通讯编程

开发平台:

Visual C++

  1. # Functionality covered: this file contains a collection of tests for the
  2. # procedures in tclNamesp.c that implement Tcl's basic support for
  3. # namespaces. Other namespace-related tests appear in variable.test.
  4. #
  5. # Sourcing this file into Tcl runs the tests and generates output for
  6. # errors. No output means no errors were found.
  7. #
  8. # Copyright (c) 1997 Sun Microsystems, Inc.
  9. # Copyright (c) 1998-2000 by Scriptics Corporation.
  10. #
  11. # See the file "license.terms" for information on usage and redistribution
  12. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  13. #
  14. # RCS: @(#) $Id: namespace.test,v 1.21.2.10 2006/10/04 17:59:06 dgp Exp $
  15. if {[lsearch [namespace children] ::tcltest] == -1} {
  16.     package require tcltest 2
  17.     namespace import -force ::tcltest::*
  18. }
  19. # Clear out any namespaces called test_ns_*
  20. catch {eval namespace delete [namespace children :: test_ns_*]}
  21. test namespace-1.1 {TclInitNamespaces, GetNamespaceFromObj, NamespaceChildrenCmd} {
  22.     namespace children :: test_ns_*
  23. } {}
  24. catch {unset l}
  25. test namespace-2.1 {Tcl_GetCurrentNamespace} {
  26.     list [namespace current] [namespace eval {} {namespace current}] 
  27.         [namespace eval {} {namespace current}]
  28. } {:: :: ::}
  29. test namespace-2.2 {Tcl_GetCurrentNamespace} {
  30.     set l {}
  31.     lappend l [namespace current]
  32.     namespace eval test_ns_1 {
  33.         lappend l [namespace current]
  34.         namespace eval foo {
  35.             lappend l [namespace current]
  36.         }
  37.     }
  38.     lappend l [namespace current]
  39.     set l
  40. } {:: ::test_ns_1 ::test_ns_1::foo ::}
  41. test namespace-3.1 {Tcl_GetGlobalNamespace} {
  42.     namespace eval test_ns_1 {namespace eval foo {namespace eval bar {} } }
  43.     # namespace children uses Tcl_GetGlobalNamespace 
  44.     namespace eval test_ns_1 {namespace children foo b*}
  45. } {::test_ns_1::foo::bar}
  46. test namespace-4.1 {Tcl_PushCallFrame with isProcCallFrame=1} {
  47.     namespace eval test_ns_1 {
  48.         variable v 123
  49.         proc p {} {
  50.             variable v
  51.             return $v
  52.         }
  53.     }
  54.     test_ns_1::p    ;# does Tcl_PushCallFrame to push p's namespace
  55. } {123}
  56. test namespace-4.2 {Tcl_PushCallFrame with isProcCallFrame=0} {
  57.     namespace eval test_ns_1::baz {}  ;# does Tcl_PushCallFrame to create baz
  58.     proc test_ns_1::baz::p {} {
  59.         variable v
  60.         set v 789
  61.         set v}
  62.     test_ns_1::baz::p
  63. } {789}
  64. test namespace-5.1 {Tcl_PopCallFrame, no vars} {
  65.     namespace eval test_ns_1::blodge {}  ;# pushes then pops frame
  66. } {}
  67. test namespace-5.2 {Tcl_PopCallFrame, local vars must be deleted} {
  68.     proc test_ns_1::r {} {
  69.         set a 123
  70.     }
  71.     test_ns_1::r   ;# pushes then pop's r's frame
  72. } {123}
  73. test namespace-6.1 {Tcl_CreateNamespace} {
  74.     catch {eval namespace delete [namespace children :: test_ns_*]}
  75.     list [lsort [namespace children :: test_ns_*]] 
  76.         [namespace eval test_ns_1 {namespace current}] 
  77. [namespace eval test_ns_2 {namespace current}] 
  78. [namespace eval ::test_ns_3 {namespace current}] 
  79. [namespace eval ::test_ns_4 
  80.             {namespace eval foo {namespace current}}] 
  81. [namespace eval ::test_ns_5 
  82.             {namespace eval ::test_ns_6 {namespace current}}] 
  83.         [lsort [namespace children :: test_ns_*]]
  84. } {{} ::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4::foo ::test_ns_6 {::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4 ::test_ns_5 ::test_ns_6}}
  85. test namespace-6.2 {Tcl_CreateNamespace, odd number of :'s in name is okay} {
  86.     list [namespace eval :::test_ns_1::::foo {namespace current}] 
  87.          [namespace eval test_ns_2:::::foo {namespace current}]
  88. } {::test_ns_1::foo ::test_ns_2::foo}
  89. test namespace-6.3 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
  90.     list [catch {namespace eval test_ns_7::: {namespace current}} msg] $msg 
  91. } {0 ::test_ns_7}
  92. test namespace-6.4 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
  93.     catch {eval namespace delete [namespace children :: test_ns_*]}
  94.     namespace eval test_ns_1:: {
  95.         namespace eval test_ns_2:: {}
  96.         namespace eval test_ns_3:: {}
  97.     }
  98.     lsort [namespace children ::test_ns_1]
  99. } [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_3}]
  100. test namespace-6.5 {Tcl_CreateNamespace, relative ns names now only looked up in current ns} {
  101.     set trigger {
  102.         namespace eval test_ns_2 {namespace current}
  103.     }
  104.     set l {}
  105.     lappend l [namespace eval test_ns_1 $trigger]
  106.     namespace eval test_ns_1::test_ns_2 {}
  107.     lappend l [namespace eval test_ns_1 $trigger]
  108. } {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_2}
  109. test namespace-7.1 {Tcl_DeleteNamespace, active call frames in ns} {
  110.     catch {eval namespace delete [namespace children :: test_ns_*]}
  111.     namespace eval test_ns_1 {
  112.         proc p {} {
  113.             namespace delete [namespace current]
  114.             return [namespace current]
  115.         }
  116.     }
  117.     list [test_ns_1::p] [catch {test_ns_1::p} msg] $msg
  118. } {::test_ns_1 1 {invalid command name "test_ns_1::p"}}
  119. test namespace-7.2 {Tcl_DeleteNamespace, no active call frames in ns} {
  120.     namespace eval test_ns_2 {
  121.         proc p {} {
  122.             return [namespace current]
  123.         }
  124.     }
  125.     list [test_ns_2::p] [namespace delete test_ns_2]
  126. } {::test_ns_2 {}}
  127. test namespace-7.3 {recursive Tcl_DeleteNamespace, active call frames in ns} {
  128.     # [Bug 1355942]
  129.     namespace eval test_ns_2 {
  130.         set x 1
  131. trace add variable x unset "namespace delete [namespace current];#"
  132. namespace delete [namespace current]
  133.     }
  134. } {}
  135. test namespace-7.4 {recursive Tcl_DeleteNamespace, active call frames in ns} {
  136.     # [Bug 1355942]
  137.     namespace eval test_ns_2 {
  138.         proc x {} {}
  139. trace add command x delete "namespace delete [namespace current];#"
  140. namespace delete [namespace current]
  141.     }
  142. } {}
  143. test namespace-7.5 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
  144.     # [Bug 1355942]
  145.     namespace eval test_ns_2 {
  146.         set x 1
  147. trace add variable x unset "namespace delete [namespace current];#"
  148.     }
  149.     namespace delete test_ns_2
  150. } {}
  151. test namespace-7.6 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
  152.     # [Bug 1355942]
  153.     namespace eval test_ns_2 {
  154.         proc x {} {}
  155. trace add command x delete "namespace delete [namespace current];#"
  156.     }
  157.     namespace delete test_ns_2
  158. } {}
  159. test namespace-8.1 {TclTeardownNamespace, delete global namespace} {
  160.     catch {interp delete test_interp}
  161.     interp create test_interp
  162.     interp eval test_interp {
  163.         namespace eval test_ns_1 {
  164.             namespace export p
  165.             proc p {} {
  166.                 return [namespace current]
  167.             }
  168.         }
  169.         namespace eval test_ns_2 {
  170.             namespace import ::test_ns_1::p
  171.             variable v 27
  172.             proc q {} {
  173.                 variable v
  174.                 return "[p] $v"
  175.             }
  176.         }
  177.         set x [test_ns_2::q]
  178.         catch {set xxxx}
  179.     }
  180.     list [interp eval test_interp {test_ns_2::q}] 
  181.          [interp eval test_interp {namespace delete ::}] 
  182.          [catch {interp eval test_interp {set a 123}} msg] $msg 
  183.          [interp delete test_interp]
  184. } {{::test_ns_1 27} {} 1 {invalid command name "set"} {}}
  185. test namespace-8.2 {TclTeardownNamespace, remove deleted ns from parent} {
  186.     catch {eval namespace delete [namespace children :: test_ns_*]}
  187.     namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
  188.     namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
  189.     list [namespace children test_ns_1] 
  190.          [namespace delete test_ns_1::test_ns_2] 
  191.          [namespace children test_ns_1]
  192. } {::test_ns_1::test_ns_2 {} {}}
  193. test namespace-8.3 {TclTeardownNamespace, delete child namespaces} {
  194.     catch {eval namespace delete [namespace children :: test_ns_*]}
  195.     namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
  196.     namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
  197.     list [namespace children test_ns_1] 
  198.          [namespace delete test_ns_1::test_ns_2] 
  199.          [namespace children test_ns_1] 
  200.          [catch {namespace children test_ns_1::test_ns_2} msg] $msg 
  201.          [info commands test_ns_1::test_ns_2::test_ns_3a::*]
  202. } {::test_ns_1::test_ns_2 {} {} 1 {unknown namespace "test_ns_1::test_ns_2" in namespace children command} {}}
  203. test namespace-8.4 {TclTeardownNamespace, cmds imported from deleted ns go away} {
  204.     catch {eval namespace delete [namespace children :: test_ns_*]}
  205.     namespace eval test_ns_export {
  206.         namespace export cmd1 cmd2
  207.         proc cmd1 {args} {return "cmd1: $args"}
  208.         proc cmd2 {args} {return "cmd2: $args"}
  209.     }
  210.     namespace eval test_ns_import {
  211.         namespace import ::test_ns_export::*
  212.         proc p {} {return foo}
  213.     }
  214.     list [lsort [info commands test_ns_import::*]] 
  215.          [namespace delete test_ns_export] 
  216.          [info commands test_ns_import::*]
  217. } [list [lsort {::test_ns_import::p ::test_ns_import::cmd1 ::test_ns_import::cmd2}] {} ::test_ns_import::p]
  218. test namespace-8.5 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
  219.     interp create slave
  220.     slave eval {trace add execution error leave {namespace delete :: ;#}}
  221.     catch {slave eval error foo bar baz}
  222.     interp delete slave
  223.     set ::errorInfo
  224. } {bar
  225.     invoked from within
  226. "slave eval error foo bar baz"}
  227. test namespace-8.6 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
  228.     interp create slave
  229.     slave eval {trace add variable errorCode write {namespace delete :: ;#}}
  230.     catch {slave eval error foo bar baz}
  231.     interp delete slave
  232.     set ::errorInfo
  233. } {bar
  234.     invoked from within
  235. "slave eval error foo bar baz"}
  236. test namespace-8.7 {TclTeardownNamespace: preserve errorInfo; errorCode values} {   
  237.     interp create slave
  238.     slave eval {trace add execution error leave {namespace delete :: ;#}}
  239.     catch {slave eval error foo bar baz}
  240.     interp delete slave
  241.     set ::errorCode 
  242. } baz
  243. test namespace-9.1 {Tcl_Import, empty import pattern} {
  244.     catch {eval namespace delete [namespace children :: test_ns_*]}
  245.     list [catch {namespace eval test_ns_import {namespace import {}}} msg] $msg
  246. } {1 {empty import pattern}}
  247. test namespace-9.2 {Tcl_Import, unknown namespace in import pattern} {
  248.     list [catch {namespace eval test_ns_import {namespace import fred::x}} msg] $msg
  249. } {1 {unknown namespace in import pattern "fred::x"}}
  250. test namespace-9.3 {Tcl_Import, import ns == export ns} {
  251.     list [catch {namespace eval test_ns_import {namespace import ::test_ns_import::puts}} msg] $msg
  252. } {1 {import pattern "::test_ns_import::puts" tries to import from namespace "test_ns_import" into itself}}
  253. test namespace-9.4 {Tcl_Import, simple import} {
  254.     catch {eval namespace delete [namespace children :: test_ns_*]}
  255.     namespace eval test_ns_export {
  256.         namespace export cmd1
  257.         proc cmd1 {args} {return "cmd1: $args"}
  258.         proc cmd2 {args} {return "cmd2: $args"}
  259.     }
  260.     namespace eval test_ns_import {
  261.         namespace import ::test_ns_export::*
  262.         proc p {} {return [cmd1 123]}
  263.     }
  264.     test_ns_import::p
  265. } {cmd1: 123}
  266. test namespace-9.5 {Tcl_Import, can't redefine cmd unless allowOverwrite!=0} {
  267.     list [catch {namespace eval test_ns_import {namespace import ::test_ns_export::*}} msg] $msg
  268. } {0 {}}
  269. test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} {
  270.     namespace eval test_ns_import {
  271.         namespace import -force ::test_ns_export::*
  272.         cmd1 555
  273.     }
  274. } {cmd1: 555}
  275. test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
  276.     catch {eval namespace delete [namespace children :: test_ns_*]}
  277.     namespace eval test_ns_export {
  278.         namespace export cmd1
  279.         proc cmd1 {args} {return "cmd1: $args"}
  280.     }
  281.     namespace eval test_ns_import {
  282.         namespace import -force ::test_ns_export::*
  283.     }
  284.     list [test_ns_import::cmd1 a b c] 
  285.          [test_ns_export::cmd1 d e f] 
  286.          [proc test_ns_export::cmd1 {args} {return "new1: $args"}] 
  287.          [namespace origin test_ns_import::cmd1] 
  288.          [namespace origin test_ns_export::cmd1] 
  289.          [test_ns_import::cmd1 g h i] 
  290.          [test_ns_export::cmd1 j k l]
  291. } {{cmd1: a b c} {cmd1: d e f} {} ::test_ns_export::cmd1 ::test_ns_export::cmd1 {new1: g h i} {new1: j k l}}
  292. test namespace-9.8 {Tcl_Import: Bug 1017299} -setup {
  293.     namespace eval one {
  294. namespace export cmd
  295. proc cmd {} {}
  296.     }
  297.     namespace eval two {
  298. namespace export cmd
  299. proc other args {}
  300.     }
  301.     namespace eval two 
  302.     [list namespace import [namespace current]::one::cmd]
  303.     namespace eval three 
  304.     [list namespace import [namespace current]::two::cmd]
  305.     namespace eval three {
  306. rename cmd other
  307. namespace export other
  308.     }
  309. } -body {
  310.     namespace eval two [list namespace import -force 
  311.     [namespace current]::three::other]
  312.     namespace origin two::other
  313. } -cleanup {
  314.     namespace delete one two three
  315. } -match glob -result *::one::cmd
  316. test namespace-9.9 {Tcl_Import: Bug 1017299} -setup {
  317.     namespace eval one {
  318. namespace export cmd
  319. proc cmd {} {}
  320.     }
  321.     namespace eval two namespace export cmd
  322.     namespace eval two 
  323.     [list namespace import [namespace current]::one::cmd]
  324.     namespace eval three namespace export cmd
  325.     namespace eval three 
  326.     [list namespace import [namespace current]::two::cmd]
  327. } -body {
  328.     namespace eval two [list namespace import -force 
  329.     [namespace current]::three::cmd]
  330.     namespace origin two::cmd
  331. } -cleanup {
  332.     namespace delete one two three
  333. } -returnCodes error -match glob -result {import pattern * would create a loop*}
  334. test namespace-10.1 {Tcl_ForgetImport, check for valid namespaces} {
  335.     catch {eval namespace delete [namespace children :: test_ns_*]}
  336.     list [catch {namespace forget xyzzy::*} msg] $msg
  337. } {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
  338. test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
  339.     namespace eval test_ns_export {
  340.         namespace export cmd1
  341.         proc cmd1 {args} {return "cmd1: $args"}
  342.         proc cmd2 {args} {return "cmd2: $args"}
  343.     }
  344.     namespace eval test_ns_import {
  345.         namespace forget ::test_ns_export::wombat
  346.     }
  347. } {}
  348. test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} {
  349.     namespace eval test_ns_import {
  350.         namespace import ::test_ns_export::*
  351.         proc p {} {return [cmd1 123]}
  352.         set l {}
  353.         lappend l [lsort [info commands ::test_ns_import::*]]
  354.         namespace forget ::test_ns_export::cmd1
  355.         lappend l [info commands ::test_ns_import::*]
  356.         lappend l [catch {cmd1 777} msg] $msg
  357.     }
  358. } [list [lsort {::test_ns_import::p ::test_ns_import::cmd1}] ::test_ns_import::p 1 {invalid command name "cmd1"}]
  359. test namespace-10.4 {Tcl_ForgetImport: Bug 560297} -setup {
  360.     namespace eval origin {
  361. namespace export cmd
  362. proc cmd {} {}
  363.     }
  364.     namespace eval unrelated {
  365. proc cmd {} {}
  366.     }
  367.     namespace eval my 
  368.     [list namespace import [namespace current]::origin::cmd]
  369. } -body {
  370.     namespace eval my 
  371.     [list namespace forget [namespace current]::unrelated::cmd]
  372.     my::cmd
  373. } -cleanup {
  374.     namespace delete origin unrelated my
  375. }
  376. test namespace-10.5 {Tcl_ForgetImport: Bug 560297} -setup {
  377.     namespace eval origin {
  378. namespace export cmd
  379. proc cmd {} {}
  380.     }
  381.     namespace eval my 
  382.     [list namespace import [namespace current]::origin::cmd]
  383.     namespace eval my rename cmd newname
  384. } -body {
  385.     namespace eval my 
  386.     [list namespace forget [namespace current]::origin::cmd]
  387.     my::newname
  388. } -cleanup {
  389.     namespace delete origin my
  390. } -returnCodes error -match glob -result *
  391. test namespace-10.6 {Tcl_ForgetImport: Bug 560297} -setup {
  392.     namespace eval origin {
  393. namespace export cmd
  394. proc cmd {} {}
  395.     }
  396.     namespace eval my 
  397.     [list namespace import [namespace current]::origin::cmd]
  398.     namespace eval your {}
  399.     namespace eval my 
  400.     [list rename cmd [namespace current]::your::newname]
  401. } -body {
  402.     namespace eval your namespace forget newname
  403.     your::newname
  404. } -cleanup {
  405.     namespace delete origin my your
  406. } -returnCodes error -match glob -result *
  407. test namespace-10.7 {Tcl_ForgetImport: Bug 560297} -setup {
  408.     namespace eval origin {
  409. namespace export cmd
  410. proc cmd {} {}
  411.     }
  412.     namespace eval link namespace export cmd
  413.     namespace eval link 
  414.     [list namespace import [namespace current]::origin::cmd]
  415.     namespace eval link2 namespace export cmd
  416.     namespace eval link2 
  417.     [list namespace import [namespace current]::link::cmd]
  418.     namespace eval my 
  419.     [list namespace import [namespace current]::link2::cmd]
  420. } -body {
  421.     namespace eval my 
  422.     [list namespace forget [namespace current]::origin::cmd]
  423.     my::cmd
  424. } -cleanup {
  425.     namespace delete origin link link2 my
  426. } -returnCodes error -match glob -result *
  427. test namespace-10.8 {Tcl_ForgetImport: Bug 560297} -setup {
  428.     namespace eval origin {
  429. namespace export cmd
  430. proc cmd {} {}
  431.     }
  432.     namespace eval link namespace export cmd
  433.     namespace eval link 
  434.     [list namespace import [namespace current]::origin::cmd]
  435.     namespace eval link2 namespace export cmd
  436.     namespace eval link2 
  437.     [list namespace import [namespace current]::link::cmd]
  438.     namespace eval my 
  439.     [list namespace import [namespace current]::link2::cmd]
  440. } -body {
  441.     namespace eval my 
  442.     [list namespace forget [namespace current]::link::cmd]
  443.     my::cmd
  444. } -cleanup {
  445.     namespace delete origin link link2 my
  446. }
  447. test namespace-10.9 {Tcl_ForgetImport: Bug 560297} -setup {
  448.     namespace eval origin {
  449. namespace export cmd
  450. proc cmd {} {}
  451.     }
  452.     namespace eval link namespace export cmd
  453.     namespace eval link 
  454.     [list namespace import [namespace current]::origin::cmd]
  455.     namespace eval link2 namespace export cmd
  456.     namespace eval link2 
  457.     [list namespace import [namespace current]::link::cmd]
  458.     namespace eval my 
  459.     [list namespace import [namespace current]::link2::cmd]
  460. } -body {
  461.     namespace eval my 
  462.     [list namespace forget [namespace current]::link2::cmd]
  463.     my::cmd
  464. } -cleanup {
  465.     namespace delete origin link link2 my
  466. } -returnCodes error -match glob -result *
  467. test namespace-11.1 {TclGetOriginalCommand, check if not imported cmd} {
  468.     catch {eval namespace delete [namespace children :: test_ns_*]}
  469.     namespace eval test_ns_export {
  470.         namespace export cmd1
  471.         proc cmd1 {args} {return "cmd1: $args"}
  472.     }
  473.     list [namespace origin set] [namespace origin test_ns_export::cmd1]
  474. } {::set ::test_ns_export::cmd1}
  475. test namespace-11.2 {TclGetOriginalCommand, directly imported cmd} {
  476.     namespace eval test_ns_import1 {
  477.         namespace import ::test_ns_export::*
  478.         namespace export *
  479.         proc p {} {namespace origin cmd1}
  480.     }
  481.     list [test_ns_import1::p] [namespace origin test_ns_import1::cmd1]
  482. } {::test_ns_export::cmd1 ::test_ns_export::cmd1}
  483. test namespace-11.3 {TclGetOriginalCommand, indirectly imported cmd} {
  484.     namespace eval test_ns_import2 {
  485.         namespace import ::test_ns_import1::*
  486.         proc q {} {return [cmd1 123]}
  487.     }
  488.     list [test_ns_import2::q] [namespace origin test_ns_import2::cmd1]
  489. } {{cmd1: 123} ::test_ns_export::cmd1}
  490. test namespace-12.1 {InvokeImportedCmd} {
  491.     catch {eval namespace delete [namespace children :: test_ns_*]}
  492.     namespace eval test_ns_export {
  493.         namespace export cmd1
  494.         proc cmd1 {args} {namespace current}
  495.     }
  496.     namespace eval test_ns_import {
  497.         namespace import ::test_ns_export::*
  498.     }
  499.     list [test_ns_import::cmd1]
  500. } {::test_ns_export}
  501. test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} {
  502.     namespace eval test_ns_import {
  503.         set l {}
  504.         lappend l [info commands ::test_ns_import::*]
  505.         namespace forget ::test_ns_export::cmd1
  506.         lappend l [info commands ::test_ns_import::*]
  507.     }
  508. } {::test_ns_import::cmd1 {}}
  509. test namespace-14.1 {TclGetNamespaceForQualName, absolute names} {
  510.     catch {eval namespace delete [namespace children :: test_ns_*]}
  511.     variable v 10
  512.     namespace eval test_ns_1::test_ns_2 {
  513.         variable v 20
  514.     }
  515.     namespace eval test_ns_2 {
  516.         variable v 30
  517.     }
  518.     namespace eval test_ns_1 {
  519.         list $::v $::test_ns_2::v $::test_ns_1::test_ns_2::v 
  520. [lsort [namespace children :: test_ns_*]]
  521.     }
  522. } [list 10 30 20 [lsort {::test_ns_1 ::test_ns_2}]]
  523. test namespace-14.2 {TclGetNamespaceForQualName, invalid absolute names} {
  524.     namespace eval test_ns_1 {
  525.         list [catch {set ::test_ns_777::v} msg] $msg 
  526.              [catch {namespace children test_ns_777} msg] $msg
  527.     }
  528. } {1 {can't read "::test_ns_777::v": no such variable} 1 {unknown namespace "test_ns_777" in namespace children command}}
  529. test namespace-14.3 {TclGetNamespaceForQualName, relative names} {
  530.     namespace eval test_ns_1 {
  531.         list $v $test_ns_2::v
  532.     }
  533. } {10 20}
  534. test namespace-14.4 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
  535.     namespace eval test_ns_1::test_ns_2 {
  536.         namespace eval foo {}
  537.     }
  538.     namespace eval test_ns_1 {
  539.         list [namespace children test_ns_2] 
  540.              [catch {namespace children test_ns_1} msg] $msg
  541.     }
  542. } {::test_ns_1::test_ns_2::foo 1 {unknown namespace "test_ns_1" in namespace children command}}
  543. test namespace-14.5 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
  544.     namespace eval ::test_ns_2 {
  545.         namespace eval bar {}
  546.     }
  547.     namespace eval test_ns_1 {
  548.         set l [list [catch {namespace delete test_ns_2::bar} msg] $msg]
  549.     }
  550.     set l
  551. } {1 {unknown namespace "test_ns_2::bar" in namespace delete command}}
  552. test namespace-14.6 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
  553.     namespace eval test_ns_1::test_ns_2 {
  554.         namespace eval foo {}
  555.     }
  556.     namespace eval test_ns_1 {
  557.         list [namespace children test_ns_2] 
  558.              [catch {namespace children test_ns_1} msg] $msg
  559.     }
  560. } {::test_ns_1::test_ns_2::foo 1 {unknown namespace "test_ns_1" in namespace children command}}
  561. test namespace-14.7 {TclGetNamespaceForQualName, ignore extra :s if ns} {
  562.     namespace children test_ns_1:::
  563. } {::test_ns_1::test_ns_2}
  564. test namespace-14.8 {TclGetNamespaceForQualName, ignore extra :s if ns} {
  565.     namespace children :::test_ns_1:::::test_ns_2:::
  566. } {::test_ns_1::test_ns_2::foo}
  567. test namespace-14.9 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
  568.     set l {}
  569.     lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
  570.     namespace eval test_ns_1::test_ns_2 {variable {} 2525}
  571.     lappend l [set test_ns_1::test_ns_2::]
  572. } {1 {can't read "test_ns_1::test_ns_2::": no such variable} 2525}
  573. test namespace-14.10 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
  574.     catch {unset test_ns_1::test_ns_2::}
  575.     set l {}
  576.     lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
  577.     set test_ns_1::test_ns_2:: 314159
  578.     lappend l [set test_ns_1::test_ns_2::]
  579. } {1 {can't read "test_ns_1::test_ns_2::": no such variable} 314159}
  580. test namespace-14.11 {TclGetNamespaceForQualName, extra ::s are significant for commands} {
  581.     catch {rename test_ns_1::test_ns_2:: {}}
  582.     set l {}
  583.     lappend l [catch {test_ns_1::test_ns_2:: hello} msg] $msg
  584.     proc test_ns_1::test_ns_2:: {args} {return "{}: $args"}
  585.     lappend l [test_ns_1::test_ns_2:: hello]
  586. } {1 {invalid command name "test_ns_1::test_ns_2::"} {{}: hello}}
  587. test namespace-14.12 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
  588.     catch {eval namespace delete [namespace children :: test_ns_*]}
  589.     namespace eval test_ns_1 {
  590.         variable {}
  591.         set test_ns_1::(x) y
  592.     }
  593.     set test_ns_1::(x)
  594. } y
  595. test namespace-14.13 {TclGetNamespaceForQualName, namespace other than global ns can't have empty name} {
  596.     catch {eval namespace delete [namespace children :: test_ns_*]}
  597.     list [catch {namespace eval test_ns_1 {proc {} {} {}; namespace eval {} {}; {}}} msg] $msg
  598. } {1 {can't create namespace "": only global namespace can have empty name}}
  599. test namespace-15.1 {Tcl_FindNamespace, absolute name found} {
  600.     catch {eval namespace delete [namespace children :: test_ns_*]}
  601.     namespace eval test_ns_delete {
  602.         namespace eval test_ns_delete2 {}
  603.         proc cmd {args} {namespace current}
  604.     }
  605.     list [namespace delete ::test_ns_delete::test_ns_delete2] 
  606.          [namespace children ::test_ns_delete]
  607. } {{} {}}
  608. test namespace-15.2 {Tcl_FindNamespace, absolute name not found} {
  609.     list [catch {namespace delete ::test_ns_delete::test_ns_delete2} msg] $msg
  610. } {1 {unknown namespace "::test_ns_delete::test_ns_delete2" in namespace delete command}}
  611. test namespace-15.3 {Tcl_FindNamespace, relative name found} {
  612.     namespace eval test_ns_delete {
  613.         namespace eval test_ns_delete2 {}
  614.         namespace eval test_ns_delete3 {}
  615.         list [namespace delete test_ns_delete2] 
  616.              [namespace children [namespace current]]
  617.     }
  618. } {{} ::test_ns_delete::test_ns_delete3}
  619. test namespace-15.4 {Tcl_FindNamespace, relative name not found} {
  620.     namespace eval test_ns_delete2 {}
  621.     namespace eval test_ns_delete {
  622.         list [catch {namespace delete test_ns_delete2} msg] $msg
  623.     }
  624. } {1 {unknown namespace "test_ns_delete2" in namespace delete command}}
  625. test namespace-16.1 {Tcl_FindCommand, absolute name found} {
  626.     catch {eval namespace delete [namespace children :: test_ns_*]}
  627.     namespace eval test_ns_1 {
  628.         proc cmd {args} {return "[namespace current]::cmd: $args"}
  629.         variable v "::test_ns_1::cmd"
  630.         eval $v one
  631.     }
  632. } {::test_ns_1::cmd: one}
  633. test namespace-16.2 {Tcl_FindCommand, absolute name found} {
  634.     eval $test_ns_1::v two
  635. } {::test_ns_1::cmd: two}
  636. test namespace-16.3 {Tcl_FindCommand, absolute name not found} {
  637.     namespace eval test_ns_1 {
  638.         variable v2 "::test_ns_1::ladidah"
  639.         list [catch {eval $v2} msg] $msg
  640.     }
  641. } {1 {invalid command name "::test_ns_1::ladidah"}}
  642. # save the "unknown" proc, which is redefined by the following two tests
  643. catch {rename unknown unknown.old}
  644. proc unknown {args} {
  645.     return "unknown: $args"
  646. }
  647. test namespace-16.4 {Tcl_FindCommand, absolute name and TCL_GLOBAL_ONLY} {
  648.     ::test_ns_1::foobar x y z
  649. } {unknown: ::test_ns_1::foobar x y z}
  650. test namespace-16.5 {Tcl_FindCommand, absolute name and TCL_GLOBAL_ONLY} {
  651.     ::foobar 1 2 3 4 5
  652. } {unknown: ::foobar 1 2 3 4 5}
  653. test namespace-16.6 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
  654.     test_ns_1::foobar x y z
  655. } {unknown: test_ns_1::foobar x y z}
  656. test namespace-16.7 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
  657.     foobar 1 2 3 4 5
  658. } {unknown: foobar 1 2 3 4 5}
  659. # restore the "unknown" proc saved previously
  660. catch {rename unknown {}}
  661. catch {rename unknown.old unknown}
  662. test namespace-16.8 {Tcl_FindCommand, relative name found} {
  663.     namespace eval test_ns_1 {
  664.         cmd a b c
  665.     }
  666. } {::test_ns_1::cmd: a b c}
  667. test namespace-16.9 {Tcl_FindCommand, relative name found} {
  668.     catch {rename cmd2 {}}
  669.     proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
  670.     namespace eval test_ns_1 {
  671.        cmd2 a b c
  672.     }
  673. } {::::cmd2: a b c}
  674. test namespace-16.10 {Tcl_FindCommand, relative name found, only look in current then global ns} {
  675.     namespace eval test_ns_1 {
  676.         proc cmd2 {args} {
  677.             return "[namespace current]::cmd2 in test_ns_1: $args"
  678.         }
  679.         namespace eval test_ns_12 {
  680.             cmd2 a b c
  681.         }
  682.     }
  683. } {::::cmd2: a b c}
  684. test namespace-16.11 {Tcl_FindCommand, relative name not found} {
  685.     namespace eval test_ns_1 {
  686.        list [catch {cmd3 a b c} msg] $msg
  687.     }
  688. } {1 {invalid command name "cmd3"}}
  689. catch {unset x}
  690. test namespace-17.1 {Tcl_FindNamespaceVar, absolute name found} {
  691.     catch {eval namespace delete [namespace children :: test_ns_*]}
  692.     set x 314159
  693.     namespace eval test_ns_1 {
  694.         set ::x
  695.     }
  696. } {314159}
  697. test namespace-17.2 {Tcl_FindNamespaceVar, absolute name found} {
  698.     namespace eval test_ns_1 {
  699.         variable x 777
  700.         set ::test_ns_1::x
  701.     }
  702. } {777}
  703. test namespace-17.3 {Tcl_FindNamespaceVar, absolute name found} {
  704.     namespace eval test_ns_1 {
  705.         namespace eval test_ns_2 {
  706.             variable x 1111
  707.         }
  708.         set ::test_ns_1::test_ns_2::x
  709.     }
  710. } {1111}
  711. test namespace-17.4 {Tcl_FindNamespaceVar, absolute name not found} {
  712.     namespace eval test_ns_1 {
  713.         namespace eval test_ns_2 {
  714.             variable x 1111
  715.         }
  716.         list [catch {set ::test_ns_1::test_ns_2::y} msg] $msg
  717.     }
  718. } {1 {can't read "::test_ns_1::test_ns_2::y": no such variable}}
  719. test namespace-17.5 {Tcl_FindNamespaceVar, absolute name and TCL_GLOBAL_ONLY} {
  720.     namespace eval test_ns_1 {
  721.         namespace eval test_ns_3 {
  722.             variable ::test_ns_1::test_ns_2::x 2222
  723.         }
  724.     }
  725.     set ::test_ns_1::test_ns_2::x
  726. } {2222}
  727. test namespace-17.6 {Tcl_FindNamespaceVar, relative name found} {
  728.     namespace eval test_ns_1 {
  729.         set x
  730.     }
  731. } {777}
  732. test namespace-17.7 {Tcl_FindNamespaceVar, relative name found} {
  733.     namespace eval test_ns_1 {
  734.         unset x
  735.         set x  ;# must be global x now
  736.     }
  737. } {314159}
  738. test namespace-17.8 {Tcl_FindNamespaceVar, relative name not found} {
  739.     namespace eval test_ns_1 {
  740.         list [catch {set wuzzat} msg] $msg
  741.     }
  742. } {1 {can't read "wuzzat": no such variable}}
  743. test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
  744.     namespace eval test_ns_1 {
  745.         variable a hello
  746.     }
  747.     set test_ns_1::a
  748. } {hello}
  749. catch {unset x}
  750. catch {unset l}
  751. catch {rename foo {}}
  752. test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadowing} {
  753.     catch {eval namespace delete [namespace children :: test_ns_*]}
  754.     proc foo {} {return "global foo"}
  755.     namespace eval test_ns_1 {
  756.         proc trigger {} {
  757.             return [foo]
  758.         }
  759.     }
  760.     set l ""
  761.     lappend l [test_ns_1::trigger]
  762.     namespace eval test_ns_1 {
  763.         # force invalidation of cached ref to "foo" in proc trigger
  764.         proc foo {} {return "foo in test_ns_1"}
  765.     }
  766.     lappend l [test_ns_1::trigger]
  767.     set l
  768. } {{global foo} {foo in test_ns_1}}
  769. test namespace-18.2 {TclResetShadowedCmdRefs, multilevel check for command shadowing} {
  770.     namespace eval test_ns_2 {
  771.         proc foo {} {return "foo in ::test_ns_2"}
  772.     }
  773.     namespace eval test_ns_1 {
  774.         namespace eval test_ns_2 {}
  775.         proc trigger {} {
  776.             return [test_ns_2::foo]
  777.         }
  778.     }
  779.     set l ""
  780.     lappend l [test_ns_1::trigger]
  781.     namespace eval test_ns_1 {
  782.         namespace eval test_ns_2 {
  783.             # force invalidation of cached ref to "foo" in proc trigger
  784.             proc foo {} {return "foo in ::test_ns_1::test_ns_2"}
  785.         }
  786.     }
  787.     lappend l [test_ns_1::trigger]
  788.     set l
  789. } {{foo in ::test_ns_2} {foo in ::test_ns_1::test_ns_2}}
  790. catch {unset l}
  791. catch {rename foo {}}
  792. test namespace-19.1 {GetNamespaceFromObj, global name found} {
  793.     catch {eval namespace delete [namespace children :: test_ns_*]}
  794.     namespace eval test_ns_1::test_ns_2 {}
  795.     namespace children ::test_ns_1
  796. } {::test_ns_1::test_ns_2}
  797. test namespace-19.2 {GetNamespaceFromObj, relative name found} {
  798.     namespace eval test_ns_1 {
  799.         namespace children test_ns_2
  800.     }
  801. } {}
  802. test namespace-19.3 {GetNamespaceFromObj, name not found} {
  803.     namespace eval test_ns_1 {
  804.         list [catch {namespace children test_ns_99} msg] $msg
  805.     }
  806. } {1 {unknown namespace "test_ns_99" in namespace children command}}
  807. test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} {
  808.     namespace eval test_ns_1 {
  809.         proc foo {} {
  810.             return [namespace children test_ns_2]
  811.         }
  812.         list [catch {namespace children test_ns_99} msg] $msg
  813.     }
  814.     set l {}
  815.     lappend l [test_ns_1::foo]
  816.     namespace delete test_ns_1::test_ns_2
  817.     namespace eval test_ns_1::test_ns_2::test_ns_3 {}
  818.     lappend l [test_ns_1::foo]
  819.     set l
  820. } {{} ::test_ns_1::test_ns_2::test_ns_3}
  821. test namespace-20.1 {Tcl_NamespaceObjCmd, bad subcommand} {
  822.     catch {eval namespace delete [namespace children :: test_ns_*]}
  823.     list [catch {namespace} msg] $msg
  824. } {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}
  825. test namespace-20.2 {Tcl_NamespaceObjCmd, bad subcommand} {
  826.     list [catch {namespace wombat {}} msg] $msg
  827. } {1 {bad option "wombat": must be children, code, current, delete, eval, exists, export, forget, import, inscope, origin, parent, qualifiers, tail, or which}}
  828. test namespace-20.3 {Tcl_NamespaceObjCmd, abbreviations are okay} {
  829.     namespace ch :: test_ns_*
  830. } {}
  831. test namespace-21.1 {NamespaceChildrenCmd, no args} {
  832.     catch {eval namespace delete [namespace children :: test_ns_*]}
  833.     namespace eval test_ns_1::test_ns_2 {}
  834.     expr {[string first ::test_ns_1 [namespace children]] != -1}
  835. } {1}
  836. test namespace-21.2 {NamespaceChildrenCmd, no args} {
  837.     namespace eval test_ns_1 {
  838.         namespace children
  839.     }
  840. } {::test_ns_1::test_ns_2}
  841. test namespace-21.3 {NamespaceChildrenCmd, ns name given} {
  842.     namespace children ::test_ns_1
  843. } {::test_ns_1::test_ns_2}
  844. test namespace-21.4 {NamespaceChildrenCmd, ns name given} {
  845.     namespace eval test_ns_1 {
  846.         namespace children test_ns_2
  847.     }
  848. } {}
  849. test namespace-21.5 {NamespaceChildrenCmd, too many args} {
  850.     namespace eval test_ns_1 {
  851.         list [catch {namespace children test_ns_2 xxx yyy} msg] $msg
  852.     }
  853. } {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
  854. test namespace-21.6 {NamespaceChildrenCmd, glob-style pattern given} {
  855.     namespace eval test_ns_1::test_ns_foo {}
  856.     namespace children test_ns_1 *f*
  857. } {::test_ns_1::test_ns_foo}
  858. test namespace-21.7 {NamespaceChildrenCmd, glob-style pattern given} {
  859.     namespace eval test_ns_1::test_ns_foo {}
  860.     lsort [namespace children test_ns_1 test*]
  861. } [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_foo}]
  862. test namespace-22.1 {NamespaceCodeCmd, bad args} {
  863.     catch {eval namespace delete [namespace children :: test_ns_*]}
  864.     list [catch {namespace code} msg] $msg 
  865.          [catch {namespace code xxx yyy} msg] $msg
  866. } {1 {wrong # args: should be "namespace code arg"} 1 {wrong # args: should be "namespace code arg"}}
  867. test namespace-22.2 {NamespaceCodeCmd, arg is already scoped value} {
  868.     namespace eval test_ns_1 {
  869.         proc cmd {} {return "test_ns_1::cmd"}
  870.     }
  871.     namespace code {namespace inscope ::test_ns_1 cmd}
  872. } {namespace inscope ::test_ns_1 cmd}
  873. test namespace-22.3 {NamespaceCodeCmd, arg is already scoped value} {
  874.     namespace code {namespace     inscope     ::test_ns_1 cmd}
  875. } {namespace     inscope     ::test_ns_1 cmd}
  876. test namespace-22.4 {NamespaceCodeCmd, in :: namespace} {
  877.     namespace code unknown
  878. } {::namespace inscope :: unknown}
  879. test namespace-22.5 {NamespaceCodeCmd, in other namespace} {
  880.     namespace eval test_ns_1 {
  881.         namespace code cmd
  882.     }
  883. } {::namespace inscope ::test_ns_1 cmd}
  884. test namespace-22.6 {NamespaceCodeCmd, in other namespace} { 
  885.     namespace eval test_ns_1 { 
  886. variable v 42 
  887.     } 
  888.     namespace eval test_ns_2 { 
  889. proc namespace args {} 
  890.     } 
  891.     namespace eval test_ns_2 [namespace eval test_ns_1 { 
  892. namespace code {set v} 
  893.     }] 
  894. } {42} 
  895. test namespace-23.1 {NamespaceCurrentCmd, bad args} {
  896.     catch {eval namespace delete [namespace children :: test_ns_*]}
  897.     list [catch {namespace current xxx} msg] $msg 
  898.          [catch {namespace current xxx yyy} msg] $msg
  899. } {1 {wrong # args: should be "namespace current"} 1 {wrong # args: should be "namespace current"}}
  900. test namespace-23.2 {NamespaceCurrentCmd, at global level} {
  901.     namespace current
  902. } {::}
  903. test namespace-23.3 {NamespaceCurrentCmd, in nested ns} {
  904.     namespace eval test_ns_1::test_ns_2 {
  905.         namespace current
  906.     }
  907. } {::test_ns_1::test_ns_2}
  908. test namespace-24.1 {NamespaceDeleteCmd, no args} {
  909.     catch {eval namespace delete [namespace children :: test_ns_*]}
  910.     namespace delete
  911. } {}
  912. test namespace-24.2 {NamespaceDeleteCmd, one arg} {
  913.     namespace eval test_ns_1::test_ns_2 {}
  914.     namespace delete ::test_ns_1
  915. } {}
  916. test namespace-24.3 {NamespaceDeleteCmd, two args} {
  917.     namespace eval test_ns_1::test_ns_2 {}
  918.     list [namespace delete ::test_ns_1::test_ns_2] [namespace delete ::test_ns_1]
  919. } {{} {}}
  920. test namespace-24.4 {NamespaceDeleteCmd, unknown ns} {
  921.     list [catch {namespace delete ::test_ns_foo} msg] $msg
  922. } {1 {unknown namespace "::test_ns_foo" in namespace delete command}}
  923. test namespace-25.1 {NamespaceEvalCmd, bad args} {
  924.     catch {eval namespace delete [namespace children :: test_ns_*]}
  925.     list [catch {namespace eval} msg] $msg
  926. } {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
  927. test namespace-25.2 {NamespaceEvalCmd, bad args} {
  928.     list [catch {namespace test_ns_1} msg] $msg
  929. } {1 {bad option "test_ns_1": must be children, code, current, delete, eval, exists, export, forget, import, inscope, origin, parent, qualifiers, tail, or which}}
  930. catch {unset v}
  931. test namespace-25.3 {NamespaceEvalCmd, new namespace} {
  932.     set v 123
  933.     namespace eval test_ns_1 {
  934.         variable v 314159
  935.         proc p {} {
  936.             variable v
  937.             return $v
  938.         }
  939.     }
  940.     test_ns_1::p
  941. } {314159}
  942. test namespace-25.4 {NamespaceEvalCmd, existing namespace} {
  943.     namespace eval test_ns_1 {
  944.         proc q {} {return [expr {[p]+1}]}
  945.     }
  946.     test_ns_1::q
  947. } {314160}
  948. test namespace-25.5 {NamespaceEvalCmd, multiple args} {
  949.     namespace eval test_ns_1 "set" "v"
  950. } {314159}
  951. test namespace-25.6 {NamespaceEvalCmd, error in eval'd script} {
  952.     list [catch {namespace eval test_ns_1 {xxxx}} msg] $msg $errorInfo
  953. } {1 {invalid command name "xxxx"} {invalid command name "xxxx"
  954.     while executing
  955. "xxxx"
  956.     (in namespace eval "::test_ns_1" script line 1)
  957.     invoked from within
  958. "namespace eval test_ns_1 {xxxx}"}}
  959. test namespace-25.7 {NamespaceEvalCmd, error in eval'd script} {
  960.     list [catch {namespace eval test_ns_1 {error foo bar baz}} msg] $msg $errorInfo
  961. } {1 foo {bar
  962.     (in namespace eval "::test_ns_1" script line 1)
  963.     invoked from within
  964. "namespace eval test_ns_1 {error foo bar baz}"}}
  965. test namespace-25.8 {NamespaceEvalCmd, error in eval'd script} knownBug {
  966.     list [catch {namespace eval test_ns_1 error foo bar baz} msg] $msg $errorInfo
  967. } {1 foo {bar
  968.     (in namespace eval "::test_ns_1" script line 1)
  969.     invoked from within
  970. "namespace eval test_ns_1 error foo bar baz"}}
  971. catch {unset v}
  972. test namespace-25.9 {NamespaceEvalCmd, 545325} {
  973.     namespace eval test_ns_1 info level 0
  974. } {namespace eval test_ns_1 info level 0}
  975. test namespace-26.1 {NamespaceExportCmd, no args and new ns} {
  976.     catch {eval namespace delete [namespace children :: test_ns_*]}
  977.     namespace export
  978. } {}
  979. test namespace-26.2 {NamespaceExportCmd, just -clear arg} {
  980.     namespace export -clear
  981. } {}
  982. test namespace-26.3 {NamespaceExportCmd, pattern can't specify a namespace} {
  983.     namespace eval test_ns_1 {
  984.         list [catch {namespace export ::zzz} msg] $msg
  985.     }
  986. } {1 {invalid export pattern "::zzz": pattern can't specify a namespace}}
  987. test namespace-26.4 {NamespaceExportCmd, one pattern} {
  988.     namespace eval test_ns_1 {
  989.         namespace export cmd1
  990.         proc cmd1 {args} {return "cmd1: $args"}
  991.         proc cmd2 {args} {return "cmd2: $args"}
  992.         proc cmd3 {args} {return "cmd3: $args"}
  993.         proc cmd4 {args} {return "cmd4: $args"}
  994.     }
  995.     namespace eval test_ns_2 {
  996.         namespace import ::test_ns_1::*
  997.     }
  998.     list [info commands test_ns_2::*] [test_ns_2::cmd1 hello]
  999. } {::test_ns_2::cmd1 {cmd1: hello}}
  1000. test namespace-26.5 {NamespaceExportCmd, sequence of patterns, patterns accumulate} {
  1001.     namespace eval test_ns_1 {
  1002.         namespace export cmd1 cmd3
  1003.     }
  1004.     namespace eval test_ns_2 {
  1005.         namespace import -force ::test_ns_1::*
  1006.     }
  1007.     list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd3 hello]
  1008. } [list [lsort {::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd3: hello}]
  1009. test namespace-26.6 {NamespaceExportCmd, no patterns means return uniq'ed export list} {
  1010.     namespace eval test_ns_1 {
  1011.         namespace export
  1012.     }
  1013. } {cmd1 cmd3}
  1014. test namespace-26.7 {NamespaceExportCmd, -clear resets export list} {
  1015.     namespace eval test_ns_1 {
  1016.         namespace export -clear cmd4
  1017.     }
  1018.     namespace eval test_ns_2 {
  1019.         namespace import ::test_ns_1::*
  1020.     }
  1021.     list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello]
  1022. } [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
  1023. test namespace-27.1 {NamespaceForgetCmd, no args} {
  1024.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1025.     namespace forget
  1026. } {}
  1027. test namespace-27.2 {NamespaceForgetCmd, args must be valid namespaces} {
  1028.     list [catch {namespace forget ::test_ns_1::xxx} msg] $msg
  1029. } {1 {unknown namespace in namespace forget pattern "::test_ns_1::xxx"}}
  1030. test namespace-27.3 {NamespaceForgetCmd, arg is forgotten} {
  1031.     namespace eval test_ns_1 {
  1032.         namespace export cmd*
  1033.         proc cmd1 {args} {return "cmd1: $args"}
  1034.         proc cmd2 {args} {return "cmd2: $args"}
  1035.     }
  1036.     namespace eval test_ns_2 {
  1037.         namespace import ::test_ns_1::*
  1038.         namespace forget ::test_ns_1::cmd1
  1039.     }
  1040.     info commands ::test_ns_2::*
  1041. } {::test_ns_2::cmd2}
  1042. test namespace-28.1 {NamespaceImportCmd, no args} {
  1043.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1044.     namespace import
  1045. } {}
  1046. test namespace-28.2 {NamespaceImportCmd, no args and just "-force"} {
  1047.     namespace import -force
  1048. } {}
  1049. test namespace-28.3 {NamespaceImportCmd, arg is imported} {
  1050.     namespace eval test_ns_1 {
  1051.         namespace export cmd2
  1052.         proc cmd1 {args} {return "cmd1: $args"}
  1053.         proc cmd2 {args} {return "cmd2: $args"}
  1054.     }
  1055.     namespace eval test_ns_2 {
  1056.         namespace import ::test_ns_1::*
  1057.         namespace forget ::test_ns_1::cmd1
  1058.     }
  1059.     info commands test_ns_2::*
  1060. } {::test_ns_2::cmd2}
  1061. test namespace-29.1 {NamespaceInscopeCmd, bad args} {
  1062.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1063.     list [catch {namespace inscope} msg] $msg
  1064. } {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
  1065. test namespace-29.2 {NamespaceInscopeCmd, bad args} {
  1066.     list [catch {namespace inscope ::} msg] $msg
  1067. } {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
  1068. test namespace-29.3 {NamespaceInscopeCmd, specified ns must exist} {
  1069.     list [catch {namespace inscope test_ns_1 {set v}} msg] $msg
  1070. } {1 {unknown namespace "test_ns_1" in inscope namespace command}}
  1071. test namespace-29.4 {NamespaceInscopeCmd, simple case} {
  1072.     namespace eval test_ns_1 {
  1073.         variable v 747
  1074.         proc cmd {args} {
  1075.             variable v
  1076.             return "[namespace current]::cmd: v=$v, args=$args"
  1077.         }
  1078.     }
  1079.     namespace inscope test_ns_1 cmd
  1080. } {::test_ns_1::cmd: v=747, args=}
  1081. test namespace-29.5 {NamespaceInscopeCmd, has lappend semantics} {
  1082.     list [namespace inscope test_ns_1 cmd x y z] 
  1083.          [namespace eval test_ns_1 [concat cmd [list x y z]]]
  1084. } {{::test_ns_1::cmd: v=747, args=x y z} {::test_ns_1::cmd: v=747, args=x y z}}
  1085. test namespace-29.6 {NamespaceInscopeCmd, 1400572} knownBug {
  1086.     namespace inscope test_ns_1 {info level 0}
  1087. } {namespace inscope test_ns_1 {info level 0}}
  1088. test namespace-30.1 {NamespaceOriginCmd, bad args} {
  1089.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1090.     list [catch {namespace origin} msg] $msg
  1091. } {1 {wrong # args: should be "namespace origin name"}}
  1092. test namespace-30.2 {NamespaceOriginCmd, bad args} {
  1093.     list [catch {namespace origin x y} msg] $msg
  1094. } {1 {wrong # args: should be "namespace origin name"}}
  1095. test namespace-30.3 {NamespaceOriginCmd, command not found} {
  1096.     list [catch {namespace origin fred} msg] $msg
  1097. } {1 {invalid command name "fred"}}
  1098. test namespace-30.4 {NamespaceOriginCmd, command isn't imported} {
  1099.     namespace origin set
  1100. } {::set}
  1101. test namespace-30.5 {NamespaceOriginCmd, imported command} {
  1102.     namespace eval test_ns_1 {
  1103.         namespace export cmd*
  1104.         proc cmd1 {args} {return "cmd1: $args"}
  1105.         proc cmd2 {args} {return "cmd2: $args"}
  1106.     }
  1107.     namespace eval test_ns_2 {
  1108.         namespace export *
  1109.         namespace import ::test_ns_1::*
  1110.         proc p {} {}
  1111.     }
  1112.     namespace eval test_ns_3 {
  1113.         namespace import ::test_ns_2::*
  1114.         list [namespace origin foreach] 
  1115.              [namespace origin p] 
  1116.              [namespace origin cmd1] 
  1117.              [namespace origin ::test_ns_2::cmd2]
  1118.     }
  1119. } {::foreach ::test_ns_2::p ::test_ns_1::cmd1 ::test_ns_1::cmd2}
  1120. test namespace-31.1 {NamespaceParentCmd, bad args} {
  1121.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1122.     list [catch {namespace parent a b} msg] $msg
  1123. } {1 {wrong # args: should be "namespace parent ?name?"}}
  1124. test namespace-31.2 {NamespaceParentCmd, no args} {
  1125.     namespace parent
  1126. } {}
  1127. test namespace-31.3 {NamespaceParentCmd, namespace specified} {
  1128.     namespace eval test_ns_1 {
  1129.         namespace eval test_ns_2 {
  1130.             namespace eval test_ns_3 {}
  1131.         }
  1132.     }
  1133.     list [namespace parent ::] 
  1134.          [namespace parent test_ns_1::test_ns_2] 
  1135.          [namespace eval test_ns_1::test_ns_2::test_ns_3 {namespace parent ::test_ns_1::test_ns_2}]
  1136. } {{} ::test_ns_1 ::test_ns_1}
  1137. test namespace-31.4 {NamespaceParentCmd, bad namespace specified} {
  1138.     list [catch {namespace parent test_ns_1::test_ns_foo} msg] $msg
  1139. } {1 {unknown namespace "test_ns_1::test_ns_foo" in namespace parent command}}
  1140. test namespace-32.1 {NamespaceQualifiersCmd, bad args} {
  1141.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1142.     list [catch {namespace qualifiers} msg] $msg
  1143. } {1 {wrong # args: should be "namespace qualifiers string"}}
  1144. test namespace-32.2 {NamespaceQualifiersCmd, bad args} {
  1145.     list [catch {namespace qualifiers x y} msg] $msg
  1146. } {1 {wrong # args: should be "namespace qualifiers string"}}
  1147. test namespace-32.3 {NamespaceQualifiersCmd, simple name} {
  1148.     namespace qualifiers foo
  1149. } {}
  1150. test namespace-32.4 {NamespaceQualifiersCmd, leading ::} {
  1151.     namespace qualifiers ::x::y::z
  1152. } {::x::y}
  1153. test namespace-32.5 {NamespaceQualifiersCmd, no leading ::} {
  1154.     namespace qualifiers a::b
  1155. } {a}
  1156. test namespace-32.6 {NamespaceQualifiersCmd, :: argument} {
  1157.     namespace qualifiers ::
  1158. } {}
  1159. test namespace-32.7 {NamespaceQualifiersCmd, odd number of :s} {
  1160.     namespace qualifiers :::::
  1161. } {}
  1162. test namespace-32.8 {NamespaceQualifiersCmd, odd number of :s} {
  1163.     namespace qualifiers foo:::
  1164. } {foo}
  1165. test namespace-33.1 {NamespaceTailCmd, bad args} {
  1166.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1167.     list [catch {namespace tail} msg] $msg
  1168. } {1 {wrong # args: should be "namespace tail string"}}
  1169. test namespace-33.2 {NamespaceTailCmd, bad args} {
  1170.     list [catch {namespace tail x y} msg] $msg
  1171. } {1 {wrong # args: should be "namespace tail string"}}
  1172. test namespace-33.3 {NamespaceTailCmd, simple name} {
  1173.     namespace tail foo
  1174. } {foo}
  1175. test namespace-33.4 {NamespaceTailCmd, leading ::} {
  1176.     namespace tail ::x::y::z
  1177. } {z}
  1178. test namespace-33.5 {NamespaceTailCmd, no leading ::} {
  1179.     namespace tail a::b
  1180. } {b}
  1181. test namespace-33.6 {NamespaceTailCmd, :: argument} {
  1182.     namespace tail ::
  1183. } {}
  1184. test namespace-33.7 {NamespaceTailCmd, odd number of :s} {
  1185.     namespace tail :::::
  1186. } {}
  1187. test namespace-33.8 {NamespaceTailCmd, odd number of :s} {
  1188.     namespace tail foo:::
  1189. } {}
  1190. test namespace-34.1 {NamespaceWhichCmd, bad args} {
  1191.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1192.     list [catch {namespace which} msg] $msg
  1193. } {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
  1194. test namespace-34.2 {NamespaceWhichCmd, bad args} {
  1195.     list [catch {namespace which -fred} msg] $msg
  1196. } {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
  1197. test namespace-34.3 {NamespaceWhichCmd, bad args} {
  1198.     list [catch {namespace which -command} msg] $msg
  1199. } {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
  1200. test namespace-34.4 {NamespaceWhichCmd, bad args} {
  1201.     list [catch {namespace which a b} msg] $msg
  1202. } {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
  1203. test namespace-34.5 {NamespaceWhichCmd, command lookup} {
  1204.     namespace eval test_ns_1 {
  1205.         namespace export cmd*
  1206.         variable v1 111
  1207.         proc cmd1 {args} {return "cmd1: $args"}
  1208.         proc cmd2 {args} {return "cmd2: $args"}
  1209.     }
  1210.     namespace eval test_ns_2 {
  1211.         namespace export *
  1212.         namespace import ::test_ns_1::*
  1213.         variable v2 222
  1214.         proc p {} {}
  1215.     }
  1216.     namespace eval test_ns_3 {
  1217.         namespace import ::test_ns_2::*
  1218.         variable v3 333
  1219.         list [namespace which -command foreach] 
  1220.              [namespace which -command p] 
  1221.              [namespace which -command cmd1] 
  1222.              [namespace which -command ::test_ns_2::cmd2] 
  1223.              [catch {namespace which -command ::test_ns_2::noSuchCmd} msg] $msg
  1224.     }
  1225. } {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2 0 {}}
  1226. test namespace-34.6 {NamespaceWhichCmd, -command is default} {
  1227.     namespace eval test_ns_3 {
  1228.         list [namespace which foreach] 
  1229.              [namespace which p] 
  1230.              [namespace which cmd1] 
  1231.              [namespace which ::test_ns_2::cmd2]
  1232.     }
  1233. } {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2}
  1234. test namespace-34.7 {NamespaceWhichCmd, variable lookup} {
  1235.     namespace eval test_ns_3 {
  1236.         list [namespace which -variable env] 
  1237.              [namespace which -variable v3] 
  1238.              [namespace which -variable ::test_ns_2::v2] 
  1239.              [catch {namespace which -variable ::test_ns_2::noSuchVar} msg] $msg
  1240.     }
  1241. } {::env ::test_ns_3::v3 ::test_ns_2::v2 0 {}}
  1242. test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} {
  1243.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1244.     namespace eval test_ns_1 {
  1245.         proc p {} {
  1246.             namespace delete [namespace current]
  1247.             return [namespace current]
  1248.         }
  1249.     }
  1250.     test_ns_1::p
  1251. } {::test_ns_1}
  1252. test namespace-35.2 {FreeNsNameInternalRep, resulting ref count == 0} {
  1253.     namespace eval test_ns_1 {
  1254.         proc q {} {
  1255.             return [namespace current]
  1256.         }
  1257.     }
  1258.     list [test_ns_1::q] 
  1259.          [namespace delete test_ns_1] 
  1260.          [catch {test_ns_1::q} msg] $msg
  1261. } {::test_ns_1 {} 1 {invalid command name "test_ns_1::q"}}
  1262. catch {unset x}
  1263. catch {unset y}
  1264. test namespace-36.1 {DupNsNameInternalRep} {
  1265.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1266.     namespace eval test_ns_1 {}
  1267.     set x "::test_ns_1"
  1268.     list [namespace parent $x] [set y $x] [namespace parent $y]
  1269. } {:: ::test_ns_1 ::}
  1270. catch {unset x}
  1271. catch {unset y}
  1272. test namespace-37.1 {SetNsNameFromAny, ns name found} {
  1273.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1274.     namespace eval test_ns_1::test_ns_2 {}
  1275.     namespace eval test_ns_1 {
  1276.         namespace children ::test_ns_1
  1277.     }
  1278. } {::test_ns_1::test_ns_2}
  1279. test namespace-37.2 {SetNsNameFromAny, ns name not found} {
  1280.     namespace eval test_ns_1 {
  1281.         list [catch {namespace children ::test_ns_1::test_ns_foo} msg] $msg
  1282.     }
  1283. } {1 {unknown namespace "::test_ns_1::test_ns_foo" in namespace children command}}
  1284. test namespace-38.1 {UpdateStringOfNsName} {
  1285.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1286.     ;# Tcl_NamespaceObjCmd calls UpdateStringOfNsName to get subcmd name
  1287.     list [namespace eval {} {namespace current}] 
  1288.          [namespace eval {} {namespace current}]
  1289. } {:: ::}
  1290. test namespace-39.1 {NamespaceExistsCmd} {
  1291.     catch {eval namespace delete [namespace children :: test_ns_*]}
  1292.     namespace eval ::test_ns_z::test_me { variable foo }
  1293.     list [namespace exists ::] 
  1294.     [namespace exists ::bogus_namespace] 
  1295.     [namespace exists ::test_ns_z] 
  1296.     [namespace exists test_ns_z] 
  1297.     [namespace exists ::test_ns_z::foo] 
  1298.     [namespace exists ::test_ns_z::test_me] 
  1299.     [namespace eval ::test_ns_z { namespace exists ::test_me }] 
  1300.     [namespace eval ::test_ns_z { namespace exists test_me }] 
  1301.     [namespace exists :::::test_ns_z]
  1302. } {1 0 1 1 0 1 0 1 1}
  1303. test namespace-39.2 {NamespaceExistsCmd error} {
  1304.     list [catch {namespace exists} msg] $msg
  1305. } {1 {wrong # args: should be "namespace exists name"}}
  1306. test namespace-39.3 {NamespaceExistsCmd error} {
  1307.     list [catch {namespace exists a b} msg] $msg
  1308. } {1 {wrong # args: should be "namespace exists name"}}
  1309. test namespace-40.1 {Ignoring namespace proc "unknown"} {
  1310.     rename unknown _unknown
  1311.     proc unknown args {return global}
  1312.     namespace eval ns {proc unknown args {return local}}
  1313.     set l [list [namespace eval ns aaa bbb] [namespace eval ns aaa]]
  1314.     rename unknown {}   
  1315.     rename _unknown unknown
  1316.     namespace delete ns
  1317.     set l
  1318. } {global global}
  1319. test namespace-41.1 {Shadowing byte-compiled commands, Bug: 231259} {
  1320.     set res {}
  1321.     namespace eval ns {
  1322. set res {}
  1323. proc test {} {
  1324.     set ::g 0
  1325. }  
  1326. lappend ::res [test]
  1327. proc set {a b} {
  1328.     ::set a [incr b]
  1329. }
  1330. lappend ::res [test]
  1331.     }
  1332.     namespace delete ns
  1333.     set res
  1334. } {0 1}
  1335. test namespace-41.2 {Shadowing byte-compiled commands, Bug: 231259} {
  1336.     set res {}
  1337.     namespace eval ns {}
  1338.     proc ns::a {i} {
  1339. variable b
  1340. proc set args {return "New proc is called"}
  1341. return [set b $i]
  1342.     }
  1343.     ns::a 1
  1344.     set res [ns::a 2]
  1345.     namespace delete ns
  1346.     set res
  1347. } {New proc is called}
  1348. test namespace-41.3 {Shadowing byte-compiled commands, Bug: 231259} {knownBug} {
  1349.     set res {}
  1350.     namespace eval ns {
  1351. variable b 0
  1352.     }
  1353.     proc ns::a {i} {
  1354. variable b
  1355. proc set args {return "New proc is called"}
  1356. return [set b $i]
  1357.     }
  1358.     
  1359.     set res [list [ns::a 1] $ns::b]
  1360.     namespace delete ns
  1361.     set res
  1362. } {{New proc is called} 0}
  1363. # cleanup
  1364. catch {rename cmd1 {}}
  1365. catch {unset l}
  1366. catch {unset msg}
  1367. catch {unset trigger}
  1368. eval namespace delete [namespace children :: test_ns_*]
  1369. ::tcltest::cleanupTests
  1370. return