# -*- Tcl -*- package prefer latest package require nx set ::tcl86 [package vsatisfies [package req Tcl] 8.6] # # Intentionally, we do not want to make a "namespace import" in this # test file. Run this file via a pure tclsh! # namespace path nx # Don't use test, since both, package test and contains redefine "new", # so we have a conflict.... proc ? {cmd expected {msg ""}} { #puts "??? $cmd" set r [uplevel $cmd] if {$msg eq ""} {set msg $cmd} if {$r ne $expected} { puts stderr "ERROR $msg returned '$r' ne '$expected'" error "FAILED $msg returned '$r' ne '$expected'" } else { puts stderr "OK $msg" } } # # We define here a few attributes of type method, such we can add # arbitrary "-" calls # Class create Tree { :property label :property contains:alias :property foo:alias :public method foo {arg} {set :x $arg} } set y [Tree new -foo hu] ? [list $y eval {set :x}] hu # # actually, the intention was to define an xotcl-like -contains # set x [Tree create 1 -label 1 -contains { ? {self} ::1 ? {namespace current} ::1 Tree create 1.1 -label 1.1 Tree create 1.2 -label 1.2 -contains { ? {self} ::1::1.2 ? {namespace current} ::1::1.2 Tree create 1.2.1 -label 1.2.1 Tree create 1.2.2 -label 1.2.2 -contains { Tree create 1.2.2.1 -label 1.2.2.1 ? {self} ::1::1.2::1.2.2 } Tree create 1.2.3 -label 1.2.3 } Tree create 1.3 -label 1.3 }] set x [Tree create t -contains { ? {Tree create branch} ::t::branch ? {Tree new} ::t::__#1 }] # # error and errorcode propagation from within contains # Class create Arbre ? {catch {Arbre create root { :contains { Arbre create level1 { :contains { Arbre level2 } } } }} msg opts; set msg} "method 'level2' unknown for ::Arbre; in order to create an instance of class ::Arbre, consider using '::Arbre create level2 ?...?'" Class create Arbre ? {catch {Arbre create root { :contains { Arbre create level1 { :contains { return -code error -errorcode MYERR } } } }} msg opts; dict get $opts -errorcode} "MYERR" # # Test resolving next without namespace import/path # namespace path "" # make sure, we have no "::next" defined or globally imported ? {info command ::next} "" nx::Class create C { :public method foo {} {next; return 12} :create c1 } ? {c1 foo} 12 ? {c1 foo} 12 C create c2 { set :s [self] set :c [current] :public object method bar {} {return "[set :s]-[set :c]"} } ? {c2 bar} "::c2-::c2" # # Test potential crash, when methodNamePath is computed without a # stack frame # C public method foo {{-new 0} name value} { return $value} catch {c1 foo -name a b} errMsg ? {set errMsg} \ {invalid argument 'b', maybe too many arguments; should be "::c1 foo ?-new /value/? /name/ /value/"} # Test resolving of implicit namespaces in relationcmds (here # superclass) in the nx namespace. namespace path "" namespace eval ::nx { #puts stderr =====1 set c [Class create C -superclass Class { :object method foo {} {;} }] ? {set c} ::C # recreate set c [Class create C -superclass Class ] ? {set c} ::C #puts stderr =====3 } # # Forget and reload nx # #puts ====NX-[package versions nx]-[set auto_path] package forget nx package req nx #puts ====XOTCL-[package versions XOTcl]-[set auto_path] package require XOTcl 2.0 package forget XOTcl package require XOTcl 2.0 ######################################################################## # # Test that we do not allow one to mix object systems within the intrinsic # classes of an object. Otherwise we would have problems with the # recreate "C0 create c0". On a recreate of c0 the object system for # C0 is ::xotcl, therefore we try to call recreate. In the C0 class # hierarchy is from nx and contains no "recreate" method. ? {catch {::xotcl::Class create C0 -superclass ::nx::Object} errorMsg} 1 ? {set ::errorMsg} {class "::C0" has a different object system as class "::nx::Object"} ::nx::Class create C1 -superclass ::nx::Object # trigger the call of "cleanup" to work via method dispatch ::xotcl::Object create o1 o1 proc cleanup {} {puts stderr "CLEANUP"; return} #C0 create c0 #C0 create c0 C1 create c1 C1 create c1 c1 destroy C1 destroy ? {nx::Object create o} ::o ? {o contains { nx::Object create p}} ::o::p ? {catch {o contains { return -code error -errorcode {FOO bar baz} somethingwrong}} errorMsg} 1 set ::errorinfo $::errorInfo set ::errorcode $::errorCode ? {set ::errorMsg} {somethingwrong} if {$::tcl86} { set r {somethingwrong while executing "o contains { return -code error -errorcode {FOO bar baz} somethingwrong}"} } else { set r {somethingwrong ::o ::nx::Object->contains invoked from within "o contains { return -code error -errorcode {FOO bar baz} somethingwrong}"} } ? {set ::errorinfo} $r ? {set ::errorcode} {FOO bar baz} puts stderr "====EXIT [info script]" # # Local variables: # mode: tcl # tcl-indent-level: 2 # indent-tabs-mode: nil # End: