diff options
Diffstat (limited to 'tests/dict.test')
-rw-r--r-- | tests/dict.test | 536 |
1 files changed, 531 insertions, 5 deletions
diff --git a/tests/dict.test b/tests/dict.test index c7d186d..72a336c 100644 --- a/tests/dict.test +++ b/tests/dict.test @@ -8,8 +8,6 @@ # Copyright (c) 2003-2009 Donal K. Fellows # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: dict.test,v 1.37 2010/05/20 08:37:09 ferrieux Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 @@ -80,6 +78,24 @@ test dict-2.7 {dict create command - #-quoting in string rep} { test dict-2.8 {dict create command - #-quoting in string rep} -body { dict create #a x #b x } -match glob -result {{#?} x #? x} +test dict-2.9 {dict create command: compilation} { + apply {{} {dict create [format a] b}} +} {a b} +test dict-2.10 {dict create command: compilation} { + apply {{} {dict create [format a] b c d}} +} {a b c d} +test dict-2.11 {dict create command: compilation} { + apply {{} {dict create [format a] b c d a x}} +} {a x c d} +test dict-2.12 {dict create command: non-compilation} { + dict create [format a] b +} {a b} +test dict-2.13 {dict create command: non-compilation} { + dict create [format a] b c d +} {a b c d} +test dict-2.14 {dict create command: non-compilation} { + dict create [format a] b c d a x +} {a x c d} test dict-3.1 {dict get command} {dict get {a b} a} b test dict-3.2 {dict get command} {dict get {a b c d} a} b @@ -216,9 +232,7 @@ test dict-9.2 {dict exists command} {dict exists {a b} b} 0 test dict-9.3 {dict exists command} {dict exists {a {b c}} a b} 1 test dict-9.4 {dict exists command} {dict exists {a {b c}} a c} 0 test dict-9.5 {dict exists command} {dict exists {a {b c}} b c} 0 -test dict-9.6 {dict exists command} -returnCodes error -body { - dict exists {a {b c d}} a c -} -result {missing value to go with key} +test dict-9.6 {dict exists command} {dict exists {a {b c d}} a c} 0 test dict-9.7 {dict exists command} -returnCodes error -body { dict exists } -result {wrong # args: should be "dict exists dictionary key ?key ...?"} @@ -426,6 +440,9 @@ test dict-12.10 {dict lappend command: write failure} -setup { } -returnCodes error -cleanup { unset dictVar } -result {can't set "dictVar": variable is array} +test dict-12.11 {compiled dict append: invalidate string rep - Bug 3079830} { + apply {{} {set d {a 1 b 2 c 3}; dict lappend d b 22}} +} {a 1 b {2 22} c 3} test dict-13.1 {dict append command} -body { set dictv {a a} @@ -487,6 +504,9 @@ test dict-13.9 {dict append command: write failure} -setup { test dict-13.10 {compiled dict append: crash case} { apply {{} {dict append dictVar a o k}} } {a ok} +test dict-13.11 {compiled dict append: invalidate string rep - Bug 3079830} { + apply {{} {set d {a 1 b 2 c 3}; dict append d b 22}} +} {a 1 b 222 c 3} test dict-14.1 {dict for command: syntax} -returnCodes error -body { dict for @@ -779,6 +799,55 @@ test dict-16.9 {dict unset command: write failure} -setup { } -returnCodes error -cleanup { unset dictVar } -result {can't set "dictVar": variable is array} +# Now test with an LVT present (i.e., the bytecoded version). +test dict-16.10 {dict unset command} -body { + apply {{} { + set dictVar {a b c d} + dict unset dictVar a + }} +} -result {c d} +test dict-16.11 {dict unset command} -body { + apply {{} { + set dictVar {a b c d} + dict unset dictVar c + }} +} -result {a b} +test dict-16.12 {dict unset command} -body { + apply {{} { + set dictVar {a b} + dict unset dictVar c + }} +} -result {a b} +test dict-16.13 {dict unset command} -body { + apply {{} { + set dictVar {a {b c d e}} + dict unset dictVar a b + }} +} -result {a {d e}} +test dict-16.14 {dict unset command} -returnCodes error -body { + apply {{} { + set dictVar a + dict unset dictVar a + }} +} -result {missing value to go with key} +test dict-16.15 {dict unset command} -returnCodes error -body { + apply {{} { + set dictVar {a b} + dict unset dictVar c d + }} +} -result {key "c" not known in dictionary} +test dict-16.16 {dict unset command} -body { + apply {{} {list [info exists dictVar] [dict unset dictVar a] [info exists dictVar]}} +} -result {0 {} 1} +test dict-16.17 {dict unset command} -returnCodes error -body { + apply {{} {dict unset dictVar}} +} -result {wrong # args: should be "dict unset varName key ?key ...?"} +test dict-16.18 {dict unset command: write failure} -body { + apply {{} { + set dictVar(block) {} + dict unset dictVar a + }} +} -returnCodes error -result {can't set "dictVar": variable is array} test dict-17.1 {dict filter command: key} -body { set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo} @@ -1109,6 +1178,36 @@ test dict-20.9 {dict merge command} { test dict-20.10 {dict merge command} { dict merge {a b c d e f} {a x 1 2 3 4} {a - 1 -} } {a - c d e f 1 - 3 4} +test dict-20.11 {dict merge command} { + apply {{} {dict merge}} +} {} +test dict-20.12 {dict merge command} { + apply {{} {dict merge {a b c d e f}}} +} {a b c d e f} +test dict-20.13 {dict merge command} -body { + apply {{} {dict merge {a b c d e}}} +} -result {missing value to go with key} -returnCodes error +test dict-20.14 {dict merge command} { + apply {{} {dict merge {a b c d} {e f g h}}} +} {a b c d e f g h} +test dict-20.15 {dict merge command} -body { + apply {{} {dict merge {a b c d e} {e f g h}}} +} -result {missing value to go with key} -returnCodes error +test dict-20.16 {dict merge command} -body { + apply {{} {dict merge {a b c d} {e f g h i}}} +} -result {missing value to go with key} -returnCodes error +test dict-20.17 {dict merge command} { + apply {{} {dict merge {a b c d e f} {e x g h}}} +} {a b c d e x g h} +test dict-20.18 {dict merge command} { + apply {{} {dict merge {a b c d} {a x c y}}} +} {a x c y} +test dict-20.19 {dict merge command} { + apply {{} {dict merge {a b c d} {c y a x}}} +} {a x c y} +test dict-20.20 {dict merge command} { + apply {{} {dict merge {a b c d e f} {a x 1 2 3 4} {a - 1 -}}} +} {a - c d e f 1 - 3 4} test dict-21.1 {dict update command} -returnCodes 1 -body { dict update @@ -1354,6 +1453,433 @@ test dict-22.11 {dict with command: no recursive structures [Bug 1786481]} -body } -cleanup { unset foo t inner } -result OK +test dict-22.12 {dict with: compiled} { + apply {{} { + set d {a 1 b 2} + list [dict with d { + set a $b + unset b + dict set d c 3 + list ok + }] $d + }} +} {ok {a 2 c 3}} +test dict-22.13 {dict with: compiled} { + apply {i { + set d($i) {a 1 b 2} + list [dict with d($i) { + set a $b + unset b + dict set d($i) c 3 + list ok + }] [array get d] + }} e +} {ok {e {a 2 c 3}}} +test dict-22.14 {dict with: compiled} { + apply {{} { + set d {a 1 b 2} + foreach x {1 2 3} { + dict with d { + incr a $b + if {$x == 2} break + } + unset a b + } + list $a $b $x $d + }} +} {5 2 2 {a 5 b 2}} +test dict-22.15 {dict with: compiled} { + apply {i { + set d($i) {a 1 b 2} + foreach x {1 2 3} { + dict with d($i) { + incr a $b + if {$x == 2} break + } + unset a b + } + list $a $b $x [array get d] + }} e +} {5 2 2 {e {a 5 b 2}}} +test dict-22.16 {dict with: compiled} { + apply {{} { + set d {p {q {a 1 b 2}}} + dict with d p q { + set a $b.$a + } + return $d + }} +} {p {q {a 2.1 b 2}}} +test dict-22.17 {dict with: compiled} { + apply {i { + set d($i) {p {q {a 1 b 2}}} + dict with d($i) p q { + set a $b.$a + } + array get d + }} e +} {e {p {q {a 2.1 b 2}}}} +test dict-22.18 {dict with: compiled} { + set ::d {a 1 b 2} + apply {{} { + dict with ::d { + set a $b.$a + } + return $::d + }} +} {a 2.1 b 2} +test dict-22.19 {dict with: compiled} { + set ::d {p {q {r {a 1 b 2}}}} + apply {{} { + dict with ::d p q r { + set a $b.$a + } + return $::d + }} +} {p {q {r {a 2.1 b 2}}}} +test dict-22.20 {dict with: compiled} { + apply {d { + dict with d { + } + return $a,$b + }} {a 1 b 2} +} 1,2 +test dict-22.21 {dict with: compiled} { + apply {d { + dict with d p q { + } + return $a,$b + }} {p {q {a 1 b 2}}} +} 1,2 +test dict-22.22 {dict with: compiled} { + set ::d {a 1 b 2} + apply {{} { + dict with ::d { + } + return $a,$b + }} +} 1,2 +test dict-22.23 {dict with: compiled} { + set ::d {p {q {a 1 b 2}}} + apply {{} { + dict with ::d p q { + } + return $a,$b + }} +} 1,2 + +proc linenumber {} { + dict get [info frame -1] line +} +test dict-23.1 {dict compilation crash: Bug 3487626} { + apply {{} {apply {n { + set e {} + set k {} + dict for {a b} {c {d {e {f g}}}} { + ::tcl::dict::for {h i} $b { + dict update i e j { + ::tcl::dict::update j f k { + return [expr {$n - [linenumber]}] + } + } + } + } + }} [linenumber]}} +} 5 +test dict-23.2 {dict compilation crash: Bug 3487626} knownBug { + # Something isn't quite right in line number and continuation line + # tracking; at time of writing, this test produces 7, not 5, which + # indicates that the extra newlines in the non-script argument are + # confusing things. + apply {{} {apply {n { + set e {} + set k {} + dict for {a { +b +}} {c {d {e {f g}}}} { + ::tcl::dict::for {h { +i +}} ${ +b +} { + dict update { +i +} e { +j +} { + ::tcl::dict::update { +j +} f k { + return [expr {$n - [linenumber]}] + } + } + } + } + }} [linenumber]}} +} 5 +rename linenumber {} + +test dict-24.1 {dict map command: syntax} -returnCodes error -body { + dict map +} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"} +test dict-24.2 {dict map command: syntax} -returnCodes error -body { + dict map x +} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"} +test dict-24.3 {dict map command: syntax} -returnCodes error -body { + dict map x x +} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"} +test dict-24.4 {dict map command: syntax} -returnCodes error -body { + dict map x x x x +} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"} +test dict-24.5 {dict map command: syntax} -returnCodes error -body { + dict map x x x +} -result {must have exactly two variable names} +test dict-24.6 {dict map command: syntax} -returnCodes error -body { + dict map {x x x} x x +} -result {must have exactly two variable names} +test dict-24.7 {dict map command: syntax} -returnCodes error -body { + dict map "\{x" x x +} -result {unmatched open brace in list} +test dict-24.8 {dict map command} -setup { + set values {} + set keys {} +} -body { + # This test confirms that [dict keys], [dict values] and [dict map] + # all traverse a dictionary in the same order. + set dictv {a A b B c C} + dict map {k v} $dictv { + lappend keys $k + lappend values $v + } + set result [expr { + $keys eq [dict keys $dictv] && $values eq [dict values $dictv] + }] + expr {$result ? "YES" : [list "NO" $dictv $keys $values]} +} -cleanup { + unset result keys values k v dictv +} -result YES +test dict-24.9 {dict map command} { + dict map {k v} {} { + error "unexpected execution of 'dict map' body" + } +} {} +test dict-24.10 {dict map command: script results} -body { + set times 0 + dict map {k v} {a a b b} { + incr times + continue + error "shouldn't get here" + } + return $times +} -cleanup { + unset times k v +} -result 2 +test dict-24.11 {dict map command: script results} -body { + set times 0 + dict map {k v} {a a b b} { + incr times + break + error "shouldn't get here" + } + return $times +} -cleanup { + unset times k v +} -result 1 +test dict-24.12 {dict map command: script results} -body { + set times 0 + list [catch { + dict map {k v} {a a b b} { + incr times + error test + } + } msg] $msg $times $::errorInfo +} -cleanup { + unset times k v msg +} -result {1 test 1 {test + while executing +"error test" + ("dict map" body line 3) + invoked from within +"dict map {k v} {a a b b} { + incr times + error test + }"}} +test dict-24.13 {dict map command: script results} { + apply {{} { + dict map {k v} {a b} { + return ok,$k,$v + error "skipped return completely" + } + error "return didn't go far enough" + }} +} ok,a,b +test dict-24.14 {dict map command: handle representation loss} -setup { + set keys {} + set values {} +} -body { + set dictVar {a b c d e f g h} + list [dict size [dict map {k v} $dictVar { + if {[llength $dictVar]} { + lappend keys $k + lappend values $v + return -level 0 $k + } + }]] [lsort $keys] [lsort $values] +} -cleanup { + unset dictVar keys values k v +} -result {4 {a c e g} {b d f h}} +test dict-24.14a {dict map command: handle representation loss} -body { + apply {{} { + set dictVar {a b c d e f g h} + list [dict size [dict map {k v} $dictVar { + if {[llength $dictVar]} { + lappend keys $k + lappend values $v + return -level 0 $k + } + }]] [lsort $keys] [lsort $values] + }} +} -result {4 {a c e g} {b d f h}} +test dict-24.15 {dict map command: keys are unique and iterated over once only} -setup { + unset -nocomplain accum + array set accum {} +} -body { + set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo} + dict map {k v} $dictVar { + append accum($k) $v, + } + set result [lsort [array names accum]] + lappend result : + foreach k $result { + catch {lappend result $accum($k)} + } + return $result +} -cleanup { + unset dictVar k v result accum +} -result {a1 a2 b1 b2 bar foo : a, b, c, d, foo, bar,} +test dict-24.16 {dict map command in compilation context} { + apply {{} { + set res {x x x x x x} + dict map {k v} {a 0 b 1 c 2 d 3 e 4 f 5} { + lset res $v $k + continue + } + return $res + }} +} {a b c d e f} +test dict-24.17 {dict map command in compilation context} { + # Bug 1379349 (dict for) + apply {{} { + set d [dict create a 1] ;# Dict must be unshared! + dict map {k v} $d { + dict set d $k 0 ;# Any modification will do + } + return $d + }} +} {a 0} +test dict-24.17a {dict map command in compilation context} { + # Bug 1379349 (dict for) + apply {{} { + set d [dict create a 1] ;# Dict must be unshared! + dict map {k v} $d { + dict set d $k 0 ;# Any modification will do + } + }} +} {a {a 0}} +test dict-24.18 {dict map command in compilation context} { + # Bug 1382528 (dict for) + apply {{} { + dict map {k v} {} {} ;# Note empty dict + catch { error foo } ;# Note compiled [catch] + }} +} 1 +test dict-24.19 {dict map and invalid dicts: 'dict for' bug 1531184} -body { + di[list]ct map {k v} x {} +} -returnCodes 1 -result {missing value to go with key} +test dict-24.20 {dict map stack space compilation: 'dict for' bug 1903325} { + apply {{x y args} { + dict map {a b} $x {} + concat "c=$y,$args" + }} {} 1 2 3 +} {c=1,2 3} +proc linenumber {} { + dict get [info frame -1] line +} +test dict-24.20.1 {dict compilation crash: 'dict for' bug 3487626} { + apply {{} {apply {n { + set e {} + set k {} + dict map {a b} {c {d {e {f g}}}} { + ::tcl::dict::map {h i} $b { + dict update i e j { + ::tcl::dict::update j f k { + return [expr {$n - [linenumber]}] + } + } + } + } + }} [linenumber]}} +} 5 +test dict-24.21 {dict compilation crash: 'dict for' bug 3487626} knownBug { + apply {{} {apply {n { + set e {} + set k {} + dict map {a { +b +}} {c {d {e {f g}}}} { + ::tcl::dict::map {h { +i +}} ${ +b +} { + dict update { +i +} e { +j +} { + ::tcl::dict::update { +j +} f k { + return [expr {$n - [linenumber]}] + } + } + } + } + }} [linenumber]}} +} 5 +rename linenumber {} +test dict-24.22 {dict map results (non-compiled)} { + dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] { + return -level 0 "$k,$v" + } +} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}} +test dict-24.23 {dict map results (compiled)} { + apply {{} { + dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] { + return -level 0 "$k,$v" + } + }} +} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}} +test dict-24.23a {dict map results (compiled)} { + apply {{list} { + dict map {k v} [dict map {k v} $list { list $v $k }] { + return -level 0 "$k,$v" + } + }} {a 1 b 2 c 3 d 4} +} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}} +test dict-24.24 {dict map with huge dict (non-compiled)} { + tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat 100000 x] x] { + expr { $k * $v } + }] +} 166666666600000 +test dict-24.25 {dict map with huge dict (compiled)} { + apply {{n} { + tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat $n y] y] { + expr { $k * $v } + }] + }} 100000 +} 166666666600000 + # cleanup ::tcltest::cleanupTests |