# -*- tcl -*- me_util.test # ### ### ### ######### ######### ######### ## Suite 1: Values to tree objects. set tname [expr {$impl eq "critcl" ? "t" : "::t"}] test ast2tree-${impl}-1.0 {Call without enough arguments} \ -returnCodes error \ -body { grammar::me::util::ast2tree } -result {wrong # args: should be "grammar::me::util::ast2tree ast tree ?root?"} test ast2tree-${impl}-1.1 {Call with to many arguments} \ -returnCodes error \ -body { grammar::me::util::ast2tree a b c d } -result {wrong # args: should be "grammar::me::util::ast2tree ast tree ?root?"} test ast2tree-${impl}-1.2 {Call with bad tree object} \ -returnCodes error \ -body { grammar::me::util::ast2tree {a 1 2} foo } -result {invalid command name "foo"} test ast2tree-${impl}-1.3 {Call with bad node in tree} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2tree {a 1 2} t blub } -result "parent node \"blub\" does not exist in tree \"$tname\"" test ast2tree-${impl}-1.4 {Call with bad AST, terminal node with children} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2tree {{} 1 2 {a 3 4} {c 5 6}} t } -result {Terminal node "{} 1 2" has children} foreach {n range} { 0 {0 a} 1 {0 -1} 2 {a 0} 3 {-1 0} 4 {a b} 5 {a -1} 6 {-1 b} 7 {-1 -1} } { test ast2tree-${impl}-1.5.$n {Call with bad AST, bad location information} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2tree [linsert $range 0 {}] t } -result "Bad range information \"[lrange $range 0 end]\"" } foreach {n node} { 0 {} 1 {{}} 2 {{} 0} } { test ast2tree-${impl}-1.6.$n {Call with bad AST, node representation too short} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2tree $node t } -result "Bad node \"[lrange $node 0 end]\", not enough elements" } test ast2tree-${impl}-2.0 {Regular conversion} \ -setup { struct::tree t struct::tree tex deserialize $serial_0 } -cleanup { t destroy tex destroy } -body { grammar::me::util::ast2tree $ast t tree_equal t tex } -result 1 test ast2tree-${impl}-2.1 {Regular conversion under non-root root} \ -setup { struct::tree t t insert root end foo struct::tree tex deserialize $serial_1 } -cleanup { t destroy tex destroy } -body { grammar::me::util::ast2tree $ast t foo tree_equal t tex } -result 1 # ### ### ### ######### ######### ######### ## Suite 2: Values to extended tree objects proc tinfo {cmd args} { # 'tinfo lc 0' is a nice check that things work. switch -exact -- $cmd { lc { return [list l[lindex $args 0] c[lindex $args 0]] } tok { foreach {s e} $args break set res {} for {set i $s} {$i <= $e} {incr i} { lappend res [list T$i l$i c$i L$i] } return $res } } return -code error BOGUS } test ast2etree-${impl}-1.0 {Call without enough arguments} \ -returnCodes error \ -body { grammar::me::util::ast2etree } -result {wrong # args: should be "grammar::me::util::ast2etree ast mcmd tree ?root?"} test ast2etree-${impl}-1.1 {Call with to many arguments} \ -returnCodes error \ -body { grammar::me::util::ast2etree a b c d e } -result {wrong # args: should be "grammar::me::util::ast2etree ast mcmd tree ?root?"} test ast2etree-${impl}-1.2 {Call with bad tree object} \ -returnCodes error \ -body { grammar::me::util::ast2etree {a 1 2} tinfo foo } -result {invalid command name "foo"} test ast2etree-${impl}-1.3 {Call with bad info callback} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2etree {a 1 2} foo t } -result {invalid command name "foo"} test ast2etree-${impl}-1.4 {Call with bad node in tree} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2etree {a 1 2} tinfo t blub } -result "parent node \"blub\" does not exist in tree \"$tname\"" test ast2etree-${impl}-1.6 {Call with bad AST, terminal node with children} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2etree {{} 1 2 {a 3 4} {c 5 6}} tinfo t } -result {Terminal node "{} 1 2" has children} foreach {n range} { 0 {0 a} 1 {0 -1} 2 {a 0} 3 {-1 0} 4 {a b} 5 {a -1} 6 {-1 b} 7 {-1 -1} } { test ast2etree-${impl}-1.7.$n {Call with bad AST, bad location information} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2etree [linsert $range 0 {}] tinfo t } -result "Bad range information \"[lrange $range 0 end]\"" } foreach {n node} { 0 {} 1 {{}} 2 {{} 0} } { test ast2tree-${impl}-1.8.$n {Call with bad AST, node representation too short} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::ast2etree $node tinfo t } -result "Bad node \"[lrange $node 0 end]\", not enough elements" } test ast2etree-${impl}-2.0 {Regular conversion} \ -setup { struct::tree t struct::tree tex deserialize $serial_2 } -cleanup { t destroy tex destroy } -body { grammar::me::util::ast2etree $ast tinfo t tree_equal t tex } -result 1 test ast2etree-${impl}-2.1 {Regular conversion under non-root root} \ -setup { struct::tree t t insert root end foo struct::tree tex deserialize $serial_3 } -cleanup { t destroy tex destroy } -body { grammar::me::util::ast2etree $ast tinfo t foo tree_equal t tex } -result 1 # ### ### ### ######### ######### ######### ## Suite 3: Tree objects to values. test tree2ast-1.0 {Call without enough arguments} \ -returnCodes error \ -body { grammar::me::util::tree2ast } -result {wrong # args: should be "grammar::me::util::tree2ast tree ?root?"} test tree2ast-1.1 {Call with to many arguments} \ -returnCodes error \ -body { grammar::me::util::tree2ast a b c } -result {wrong # args: should be "grammar::me::util::tree2ast tree ?root?"} test tree2ast-1.2 {Call with bad tree object} \ -returnCodes error \ -body { grammar::me::util::tree2ast foo } -result {invalid command name "foo"} test tree2ast-1.3 {Call with bad node in tree} \ -returnCodes error \ -setup { struct::tree t } -cleanup { t destroy } -body { grammar::me::util::tree2ast t blub } -result "node \"blub\" does not exist in tree \"$tname\"" test tree2ast-1.4 {Call with broken tree, missing type} \ -returnCodes error \ -setup { struct::tree t deserialize {root {} {range {0 2} detail x}} } -cleanup { t destroy } -body { grammar::me::util::tree2ast t } -result {Bad node "root", type information is missing} test tree2ast-1.5.0 {Call with broken tree, missing range, nonterminal} \ -returnCodes error \ -setup { struct::tree t deserialize {root {} {type nonterminal detail x}} } -cleanup { t destroy } -body { grammar::me::util::tree2ast t } -result {Bad node "root", range information is missing} test tree2ast-1.5.1 {Call with broken tree, missing range, terminal} \ -returnCodes error \ -setup { struct::tree t deserialize {root {} {type terminal}} } -cleanup { t destroy } -body { grammar::me::util::tree2ast t } -result {Bad node "root", range information is missing} test tree2ast-1.6 {Call with broken tree, missing detail} \ -returnCodes error \ -setup { struct::tree t deserialize {root {} {type nonterminal range {0 2}}} } -cleanup { t destroy } -body { grammar::me::util::tree2ast t } -result {Bad node "root", nonterminal detail is missing} foreach {n range} { 0 {0 a} 1 {0 -1} 2 {a 0} 3 {-1 0} 4 {a b} 5 {a -1} 6 {-1 b} 7 {-1 -1} 8 {} 9 {1} 10 {1 2 3} } { test tree2ast-1.7.$n {Call with broken tree, bad location, terminal} \ -returnCodes error \ -setup { struct::tree t deserialize [list root {} [list type terminal range $range]] } -cleanup { t destroy } -body { grammar::me::util::tree2ast t } -result "Bad node \"root\", bad range information \"$range\"" test tree2ast-1.8.$n {Call with broken tree, bad location, nonterminal} \ -returnCodes error \ -setup { struct::tree t deserialize [list root {} [list type nonterminal detail x range $range]] } -cleanup { t destroy } -body { grammar::me::util::tree2ast t } -result "Bad node \"root\", bad range information \"$range\"" } test tree2ast-2.0 {Regular conversion} \ -setup { struct::tree t deserialize $serial_0a } -cleanup { t destroy } -body { grammar::me::util::tree2ast t } -result $ast test tree2ast-2.1 {Regular conversion under non-root root} \ -setup { struct::tree t deserialize $serial_1 } -cleanup { t destroy } -body { grammar::me::util::tree2ast t node0 } -result $ast test tree2ast-2.2 {Regular conversion, of extended tree} \ -setup { struct::tree t deserialize $serial_2a } -cleanup { t destroy } -body { grammar::me::util::tree2ast t } -result $ast test tree2ast-2.3 {Regular conversion under non-root root} \ -setup { struct::tree t deserialize $serial_3 } -cleanup { t destroy } -body { grammar::me::util::tree2ast t node0 } -result $ast