diff options
Diffstat (limited to 'tests/coroutine.test')
-rw-r--r-- | tests/coroutine.test | 739 |
1 files changed, 0 insertions, 739 deletions
diff --git a/tests/coroutine.test b/tests/coroutine.test deleted file mode 100644 index 05b58c9..0000000 --- a/tests/coroutine.test +++ /dev/null @@ -1,739 +0,0 @@ -# Commands covered: coroutine, yield, yieldto, [info coroutine] -# -# This file contains a collection of tests for experimental commands that are -# found in ::tcl::unsupported. The tests will migrate to normal test files -# if/when the commands find their way into the core. -# -# Copyright (c) 2008 by Miguel Sofer. -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. - -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest - namespace import -force ::tcltest::* -} - -::tcltest::loadTestedCommands -catch [list package require -exact Tcltest [info patchlevel]] - -testConstraint testnrelevels [llength [info commands testnrelevels]] -testConstraint memory [llength [info commands memory]] - -set lambda [list {{start 0} {stop 10}} { - # init - set i $start - set imax $stop - yield - while {$i < $imax} { - yield [expr {$i*$stop}] - incr i - } -}] - -test coroutine-1.1 {coroutine basic} -setup { - coroutine foo ::apply $lambda - set res {} -} -body { - for {set k 1} {$k < 4} {incr k} { - lappend res [foo] - } - set res -} -cleanup { - rename foo {} - unset res -} -result {0 10 20} -test coroutine-1.2 {coroutine basic} -setup { - coroutine foo ::apply $lambda 2 8 - set res {} -} -body { - for {set k 1} {$k < 4} {incr k} { - lappend res [foo] - } - set res -} -cleanup { - rename foo {} - unset res -} -result {16 24 32} -test coroutine-1.3 {yield returns new arg} -setup { - set body { - # init - set i $start - set imax $stop - yield - while {$i < $imax} { - set stop [yield [expr {$i*$stop}]] - incr i - } - } - coroutine foo ::apply [list {{start 2} {stop 10}} $body] - set res {} -} -body { - for {set k 1} {$k < 4} {incr k} { - lappend res [foo $k] - } - set res -} -cleanup { - rename foo {} - unset res -} -result {20 6 12} -test coroutine-1.4 {yield in nested proc} -setup { - proc moo {} { - upvar 1 i i stop stop - yield [expr {$i*$stop}] - } - set body { - # init - set i $start - set imax $stop - yield - while {$i < $imax} { - moo - incr i - } - } - coroutine foo ::apply [list {{start 0} {stop 10}} $body] - set res {} -} -body { - for {set k 1} {$k < 4} {incr k} { - lappend res [foo $k] - } - set res -} -cleanup { - rename foo {} - rename moo {} - unset body res -} -result {0 10 20} -test coroutine-1.5 {just yield} -body { - coroutine foo yield - list [foo] [catch foo msg] $msg -} -cleanup { - unset msg -} -result {{} 1 {invalid command name "foo"}} -test coroutine-1.6 {just yield} -body { - coroutine foo [list yield] - list [foo] [catch foo msg] $msg -} -cleanup { - unset msg -} -result {{} 1 {invalid command name "foo"}} -test coroutine-1.7 {yield in nested uplevel} -setup { - set body { - # init - set i $start - set imax $stop - yield - while {$i < $imax} { - uplevel 0 [list yield [expr {$i*$stop}]] - incr i - } - } - coroutine foo ::apply [list {{start 0} {stop 10}} $body] - set res {} -} -body { - for {set k 1} {$k < 4} {incr k} { - lappend res [eval foo $k] - } - set res -} -cleanup { - rename foo {} - unset body res -} -result {0 10 20} -test coroutine-1.8 {yield in nested uplevel} -setup { - set body { - # init - set i $start - set imax $stop - yield - while {$i < $imax} { - uplevel 0 yield [expr {$i*$stop}] - incr i - } - } - coroutine foo ::apply [list {{start 0} {stop 10}} $body] - set res {} -} -body { - for {set k 1} {$k < 4} {incr k} { - lappend res [eval foo $k] - } - set res -} -cleanup { - rename foo {} - unset body res -} -result {0 10 20} -test coroutine-1.9 {yield in nested eval} -setup { - proc moo {} { - upvar 1 i i stop stop - yield [expr {$i*$stop}] - } - set body { - # init - set i $start - set imax $stop - yield - while {$i < $imax} { - eval moo - incr i - } - } - coroutine foo ::apply [list {{start 0} {stop 10}} $body] - set res {} -} -body { - for {set k 1} {$k < 4} {incr k} { - lappend res [foo $k] - } - set res -} -cleanup { - rename moo {} - unset body res -} -result {0 10 20} -test coroutine-1.10 {yield in nested eval} -setup { - set body { - # init - set i $start - set imax $stop - yield - while {$i < $imax} { - eval yield [expr {$i*$stop}] - incr i - } - } - coroutine foo ::apply [list {{start 0} {stop 10}} $body] - set res {} -} -body { - for {set k 1} {$k < 4} {incr k} { - lappend res [eval foo $k] - } - set res -} -cleanup { - unset body res -} -result {0 10 20} -test coroutine-1.11 {yield outside coroutine} -setup { - proc moo {} { - upvar 1 i i stop stop - yield [expr {$i*$stop}] - } -} -body { - variable i 5 stop 6 - moo -} -cleanup { - rename moo {} - unset i stop -} -returnCodes error -result {yield can only be called in a coroutine} -test coroutine-1.12 {proc as coroutine} -setup { - set body { - # init - set i $start - set imax $stop - yield - while {$i < $imax} { - uplevel 0 [list yield [expr {$i*$stop}]] - incr i - } - } - proc moo {{start 0} {stop 10}} $body - coroutine foo moo 2 8 -} -body { - list [foo] [foo] -} -cleanup { - unset body - rename moo {} - rename foo {} -} -result {16 24} -test coroutine-1.13 {subst as coroutine: literal} { - list [coroutine foo eval {subst {>>[yield a],[yield b]<<}}] [foo x] [foo y] -} {a b >>x,y<<} -test coroutine-1.14 {subst as coroutine: in variable} { - set pattern {>>[yield c],[yield d]<<} - list [coroutine foo eval {subst $pattern}] [foo p] [foo q] -} {c d >>p,q<<} - -test coroutine-2.1 {self deletion on return} -body { - coroutine foo set x 3 - foo -} -returnCodes error -result {invalid command name "foo"} -test coroutine-2.2 {self deletion on return} -body { - coroutine foo ::apply [list {} {yield; yield 1; return 2}] - list [foo] [foo] [catch foo msg] $msg -} -result {1 2 1 {invalid command name "foo"}} -test coroutine-2.3 {self deletion on error return} -body { - coroutine foo ::apply [list {} {yield;yield 1; error ouch!}] - list [foo] [catch foo msg] $msg [catch foo msg] $msg -} -result {1 1 ouch! 1 {invalid command name "foo"}} -test coroutine-2.4 {self deletion on other return} -body { - coroutine foo ::apply [list {} {yield;yield 1; return -code 100 ouch!}] - list [foo] [catch foo msg] $msg [catch foo msg] $msg -} -result {1 100 ouch! 1 {invalid command name "foo"}} -test coroutine-2.5 {deletion of suspended coroutine} -body { - coroutine foo ::apply [list {} {yield; yield 1; return 2}] - list [foo] [rename foo {}] [catch foo msg] $msg -} -result {1 {} 1 {invalid command name "foo"}} -test coroutine-2.6 {deletion of running coroutine} -body { - coroutine foo ::apply [list {} {yield; rename foo {}; yield 1; return 2}] - list [foo] [catch foo msg] $msg -} -result {1 1 {invalid command name "foo"}} - -test coroutine-3.1 {info level computation} -setup { - proc a {} {while 1 {yield [info level]}} - proc b {} foo -} -body { - # note that coroutines execute in uplevel #0 - set l0 [coroutine foo a] - set l1 [foo] - set l2 [b] - list $l0 $l1 $l2 -} -cleanup { - rename a {} - rename b {} -} -result {1 1 1} -test coroutine-3.2 {info frame computation} -setup { - proc a {} {while 1 {yield [info frame]}} - proc b {} foo -} -body { - set l0 [coroutine foo a] - set l1 [foo] - set l2 [b] - expr {$l2 - $l1} -} -cleanup { - rename a {} - rename b {} -} -result 1 -test coroutine-3.3 {info coroutine} -setup { - proc a {} {info coroutine} - proc b {} a -} -body { - b -} -cleanup { - rename a {} - rename b {} -} -result {} -test coroutine-3.4 {info coroutine} -setup { - proc a {} {info coroutine} - proc b {} a -} -body { - coroutine foo b -} -cleanup { - rename a {} - rename b {} -} -result ::foo -test coroutine-3.5 {info coroutine} -setup { - proc a {} {info coroutine} - proc b {} {rename [info coroutine] {}; a} -} -body { - coroutine foo b -} -cleanup { - rename a {} - rename b {} -} -result {} -test coroutine-3.6 {info frame, bug #2910094} -setup { - proc stack {} { - set res [list "LEVEL:[set lev [info frame]]"] - for {set i 1} {$i < $lev} {incr i} { - lappend res [info frame $i] - } - set res - # the precise command depends on line numbers and such, is likely not - # to be stable: just check that the test completes! - return - } - proc a {} stack -} -body { - coroutine aa a -} -cleanup { - rename stack {} - rename a {} -} -result {} -test coroutine-3.7 {bug 0b874c344d} { - dict get [coroutine X coroutine Y info frame 0] cmd -} {coroutine X coroutine Y info frame 0} - -test coroutine-4.1 {bug #2093188} -setup { - proc foo {} { - set v 1 - trace add variable v {write unset} bar - yield - set v 2 - yield - set v 3 - } - proc bar args {lappend ::res $args} - coroutine a foo -} -body { - list [a] [a] $::res -} -cleanup { - rename foo {} - rename bar {} - unset ::res -} -result {{} 3 {{v {} write} {v {} write} {v {} unset}}} -test coroutine-4.2 {bug #2093188} -setup { - proc foo {} { - set v 1 - trace add variable v {read unset} bar - yield - set v 2 - set v - yield - set v 3 - } - proc bar args {lappend ::res $args} - coroutine a foo -} -body { - list [a] [a] $::res -} -cleanup { - rename foo {} - rename bar {} - unset ::res -} -result {{} 3 {{v {} read} {v {} unset}}} - -test coroutine-4.3 {bug #2093947} -setup { - proc foo {} { - set v 1 - trace add variable v {write unset} bar - yield - set v 2 - yield - set v 3 - } - proc bar args {lappend ::res $args} -} -body { - coroutine a foo - a - a - coroutine a foo - a - rename a {} - set ::res -} -cleanup { - rename foo {} - rename bar {} - unset ::res -} -result {{v {} write} {v {} write} {v {} unset} {v {} write} {v {} unset}} - -test coroutine-4.4 {bug #2917627: cmd resolution} -setup { - proc a {} {return global} - namespace eval b {proc a {} {return local}} -} -body { - namespace eval b {coroutine foo a} -} -cleanup { - rename a {} - namespace delete b -} -result local - -test coroutine-4.5 {bug #2724403} -constraints {memory} \ --setup { - proc getbytes {} { - set lines [split [memory info] "\n"] - lindex $lines 3 3 - } -} -body { - set end [getbytes] - for {set i 0} {$i < 5} {incr i} { - set ns ::y$i - namespace eval $ns {} - proc ${ns}::start {} {yield; puts hello} - coroutine ${ns}::run ${ns}::start - namespace delete $ns - set start $end - set end [getbytes] - } - set leakedBytes [expr {$end - $start}] -} -cleanup { - rename getbytes {} - unset i ns start end -} -result 0 - -test coroutine-4.6 {compile context, bug #3282869} -setup { - unset -nocomplain ::x - proc f x { - coroutine D eval {yield X$x;yield Y} - } -} -body { - f 12 -} -cleanup { - rename f {} -} -returnCodes error -match glob -result {can't read *} - -test coroutine-4.7 {compile context, bug #3282869} -setup { - proc f x { - coroutine D eval {yield X$x;yield Y$x} - } -} -body { - set ::x 15 - set ::x [f 12] - D -} -cleanup { - D - unset ::x - rename f {} -} -result YX15 - -test coroutine-5.1 {right numLevels on coro return} -constraints {testnrelevels} \ --setup { - proc nestedYield {{val {}}} { - yield $val - } - proc getNumLevel {} { - # remove the level for this proc's call - expr {[lindex [testnrelevels] 1] - 1} - } - proc relativeLevel base { - # remove the level for this proc's call - expr {[getNumLevel] - $base - 1} - } - proc foo {} { - while 1 { - nestedYield - } - } - set res {} -} -body { - set base [getNumLevel] - lappend res [relativeLevel $base] - eval {coroutine a foo} - # back to base level - lappend res [relativeLevel $base] - a - lappend res [relativeLevel $base] - eval a - lappend res [relativeLevel $base] - eval {eval a} - lappend res [relativeLevel $base] - rename a {} - lappend res [relativeLevel $base] - set res -} -cleanup { - rename foo {} - rename nestedYield {} - rename getNumLevel {} - rename relativeLevel {} - unset res -} -result {0 0 0 0 0 0} -test coroutine-5.2 {right numLevels within coro} -constraints {testnrelevels} \ --setup { - proc nestedYield {{val {}}} { - yield $val - } - proc getNumLevel {} { - # remove the level for this proc's call - expr {[lindex [testnrelevels] 1] - 1} - } - proc relativeLevel base { - # remove the level for this proc's call - expr {[getNumLevel] - $base - 1} - } - proc foo base { - while 1 { - set base [nestedYield [relativeLevel $base]] - } - } - set res {} -} -body { - lappend res [eval {coroutine a foo [getNumLevel]}] - lappend res [a [getNumLevel]] - lappend res [eval {a [getNumLevel]}] - lappend res [eval {eval {a [getNumLevel]}}] - set base [lindex $res 0] - foreach x $res[set res {}] { - lappend res [expr {$x-$base}] - } - set res -} -cleanup { - rename a {} - rename foo {} - rename nestedYield {} - rename getNumLevel {} - rename relativeLevel {} - unset res -} -result {0 0 0 0} - -test coroutine-6.1 {coroutine nargs} -body { - coroutine a ::apply $lambda - a -} -cleanup { - rename a {} -} -result 0 -test coroutine-6.2 {coroutine nargs} -body { - coroutine a ::apply $lambda - a a -} -cleanup { - rename a {} -} -result 0 -test coroutine-6.3 {coroutine nargs} -body { - coroutine a ::apply $lambda - a a a -} -cleanup { - rename a {} -} -returnCodes error -result {wrong # args: should be "a ?arg?"} - -test coroutine-7.1 {yieldto} -body { - coroutine c apply {{} { - yield - yieldto return -level 0 -code 1 quux - return quuy - }} - set res [list [catch c msg] $msg] - lappend res [catch c msg] $msg - lappend res [catch c msg] $msg -} -cleanup { - unset res -} -result [list 1 quux 0 quuy 1 {invalid command name "c"}] -test coroutine-7.2 {multi-argument yielding with yieldto} -body { - proc corobody {} { - set a 1 - while 1 { - set a [yield $a] - set a [yieldto return -level 0 $a] - lappend a [llength $a] - } - } - coroutine a corobody - coroutine b corobody - list [a x] [a y z] [a \{p] [a \{q r] [a] [a] [rename a {}] \ - [b ok] [rename b {}] -} -cleanup { - rename corobody {} -} -result {x {y z 2} \{p {\{q r 2} {} 0 {} ok {}} -test coroutine-7.3 {yielding between coroutines} -body { - proc juggler {target {value ""}} { - if {$value eq ""} { - set value [yield [info coroutine]] - } - while {[llength $value]} { - lappend ::result $value [info coroutine] - set value [lrange $value 0 end-1] - lassign [yieldto $target $value] value - } - # Clear nested collection of coroutines - catch $target - } - set result "" - coroutine j1 juggler [coroutine j2 juggler [coroutine j3 juggler j1]]\ - {a b c d e} - list $result [info command j1] [info command j2] [info command j3] -} -cleanup { - catch {rename juggler ""} -} -result {{{a b c d e} ::j1 {a b c d} ::j2 {a b c} ::j3 {a b} ::j1 a ::j2} {} {} {}} -test coroutine-7.4 {Bug 8ff0cb9fe1} -setup { - proc foo {a b} {catch yield; return 1} -} -cleanup { - rename foo {} -} -body { - coroutine demo lsort -command foo {a b} -} -result {b a} -test coroutine-7.5 {return codes} { - set result {} - foreach code {0 1 2 3 4 5} { - lappend result [catch {coroutine demo return -level 0 -code $code}] - } - set result -} {0 1 2 3 4 5} -test coroutine-7.6 {Early yield crashes} { - proc foo args {} - trace add execution foo enter {catch yield} - coroutine demo foo - rename foo {} -} {} -test coroutine-7.7 {Bug 2486550} -setup { - interp hide {} yield -} -body { - coroutine demo interp invokehidden {} yield ok -} -cleanup { - demo - interp expose {} yield -} -result ok -test coroutine-7.8 {yieldto context nuke: Bug a90d9331bc} -setup { - namespace eval cotest {} - set ::result "" -} -body { - proc cotest::body {} { - lappend ::result a - yield OUT - lappend ::result b - yieldto ::return -level 0 123 - lappend ::result c - return - } - lappend ::result [coroutine cotest cotest::body] - namespace delete cotest - namespace eval cotest {} - lappend ::result [cotest] - cotest - return $result -} -returnCodes error -cleanup { - catch {namespace delete ::cotest} - catch {rename cotest ""} -} -result {yieldto called in deleted namespace} -test coroutine-7.9 {yieldto context nuke: Bug a90d9331bc} -setup { - namespace eval cotest {} - set ::result "" -} -body { - proc cotest::body {} { - set y ::yieldto - lappend ::result a - yield OUT - lappend ::result b - $y ::return -level 0 123 - lappend ::result c - return - } - lappend ::result [coroutine cotest cotest::body] - namespace delete cotest - namespace eval cotest {} - lappend ::result [cotest] - cotest - return $result -} -returnCodes error -cleanup { - catch {namespace delete ::cotest} - catch {rename cotest ""} -} -result {yieldto called in deleted namespace} -test coroutine-7.10 {yieldto context nuke: Bug a90d9331bc} -setup { - namespace eval cotest {} - set ::result "" -} -body { - proc cotest::body {} { - lappend ::result a - yield OUT - lappend ::result b - yieldto ::return -level 0 -cotest [namespace delete ::cotest] 123 - lappend ::result c - return - } - lappend ::result [coroutine cotest cotest::body] - lappend ::result [cotest] - cotest - return $result -} -returnCodes error -cleanup { - catch {namespace delete ::cotest} - catch {rename cotest ""} -} -result {yieldto called in deleted namespace} -test coroutine-7.11 {yieldto context nuke: Bug a90d9331bc} -setup { - namespace eval cotest {} - set ::result "" -} -body { - proc cotest::body {} { - set y ::yieldto - lappend ::result a - yield OUT - lappend ::result b - $y ::return -level 0 -cotest [namespace delete ::cotest] 123 - lappend ::result c - return - } - lappend ::result [coroutine cotest cotest::body] - lappend ::result [cotest] - cotest - return $result -} -returnCodes error -cleanup { - catch {namespace delete ::cotest} - catch {rename cotest ""} -} -result {yieldto called in deleted namespace} - - -# cleanup -unset lambda -::tcltest::cleanupTests - -return - -# Local Variables: -# mode: tcl -# End: |