Index: tests/aliastest.xotcl =================================================================== diff -u -r48d5751e9aeb6a4f388f6531a9248c1847b22cae -r2880a345930ceabfec83d491f26b8254099c8991 --- tests/aliastest.xotcl (.../aliastest.xotcl) (revision 48d5751e9aeb6a4f388f6531a9248c1847b22cae) +++ tests/aliastest.xotcl (.../aliastest.xotcl) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -2,252 +2,288 @@ package require xotcl::test Test parameter count 10 +Test case alias-preliminaries { + + # The system methods of Object are either alias or forwarders + ? {lsort [::xotcl::ObjectParameterSlot info methods -methodtype alias]} {assign get} + ? {::xotcl::ObjectParameterSlot info method definition get} "::xotcl::ObjectParameterSlot alias get ::xotcl::setinstvar" -# The system methods of Object are either alias or forwarders -? {lsort [::xotcl::ObjectParameterSlot info methods -methodtype alias]} {assign get} -? {::xotcl::ObjectParameterSlot info method definition get} "::xotcl::ObjectParameterSlot alias get ::xotcl::setinstvar" - -# define an alias and retrieve its definition -set cmd "::xotcl2::Object alias -objscope set ::set" -eval $cmd -? {Object info method definition set} $cmd - -# define an alias and retrieve its definition -Class create Base { - :method foo {{-x 1}} {return $x} + # define an alias and retrieve its definition + set cmd "::xotcl2::Object alias -objscope set ::set" + eval $cmd + ? {Object info method definition set} $cmd + } -Class create Foo -::xotcl::alias ::Foo foo ::xotcl::classes::Base::foo +Test case alias-simple { + # define an alias and retrieve its definition + Class create Base { + :method foo {{-x 1}} {return $x} + } -? {Foo info method definition foo} "::Foo alias foo ::xotcl::classes::Base::foo" + Class create Foo + ::xotcl::alias ::Foo foo ::xotcl::classes::Base::foo + + ? {Foo info method definition foo} "::Foo alias foo ::xotcl::classes::Base::foo" + + Foo create f1 + ? {f1 foo} 1 + ? {f1 foo -x 2} 2 + ? {Foo info methods -methodtype alias} "foo" + + ? {Base info methods -methodtype scripted} {foo} + ? {Foo info methods -methodtype scripted} {} + ? {Foo info methods -methodtype alias} {foo} + Base method foo {} {} + ? {Foo info methods -methodtype alias} "" + ? {Base info methods -methodtype scripted} {} + ? {Foo info methods -methodtype scripted} {} + ? {Foo info method definition foo} "" + -Foo create f1 -? {f1 foo} 1 -? {f1 foo -x 2} 2 -? {Foo info methods -methodtype alias} "foo" + Base method foo {{-x 1}} {return $x} + ::xotcl::alias ::Foo foo ::xotcl::classes::Base::foo + + ? {Base info methods -methodtype scripted} {foo} "defined again" + ? {Foo info methods -methodtype alias} {foo} "aliased again" + Foo method foo {} {} + ? {Base info methods -methodtype scripted} {foo} "still defined" + ? {Foo info methods -methodtype alias} {} "removed" +} -? {Base info methods -methodtype scripted} {foo} -? {Foo info methods -methodtype scripted} {} -? {Foo info methods -methodtype alias} {foo} -Base method foo {} {} -? {Foo info methods -methodtype alias} "" -? {Base info methods -methodtype scripted} {} -? {Foo info methods -methodtype scripted} {} -? {Foo info method definition foo} "" +Test case alias-chaining { + # + # chaining aliases + # + + Class create T + Class create S + T create t + S create s + + + T method foo args { return [self class]->[self proc] } + ::xotcl::alias T FOO ::xotcl::classes::T::foo + + ? {t foo} ::T->foo + ? {t FOO} ::T->foo + + ? {lsort [T info methods]} {FOO foo} + T method foo {} {} + ? {lsort [T info methods]} {} "alias is deleted" + + # puts stderr "double indirection" + T method foo args { return [self class]->[self proc] } + ::xotcl::alias T FOO ::xotcl::classes::T::foo + ::xotcl::alias S BAR ::xotcl::classes::T::FOO + + ? {T info methods -methodtype alias} "FOO" + ? {T info method definition FOO} "::T alias FOO ::xotcl::classes::T::foo" + ? {lsort [T info methods]} {FOO foo} + ? {S info methods} {BAR} + T method FOO {} {} + ? {T info methods} {foo} + ? {S info methods} {BAR} + ? {s BAR} ::S->foo + ? {t foo} ::T->foo + ? {S info method definition BAR} "::S alias BAR ::xotcl::classes::T::FOO" + + + T method foo {} {} + ? {T info methods} {} + ? {S info methods} {} + + T method foo args { return [self class]->[self proc] } + ::xotcl::alias T FOO ::xotcl::classes::T::foo + ::xotcl::alias S BAR ::xotcl::classes::T::FOO + + ? {lsort [T info methods]} {FOO foo} + ? {S info methods} {BAR} + T method foo {} {} + ? {S info methods} {} + ? {T info methods} {} + + T method foo args { return [self class]->[self proc] } + T object method bar args { return [self class]->[self proc] } + ::xotcl::alias T -per-object FOO ::xotcl::classes::T::foo + ::xotcl::alias T -per-object BAR ::T::FOO + ::xotcl::alias T -per-object ZAP ::T::BAR + ? {T info methods} {foo} + ? {lsort [T object info methods -methodtype alias]} {BAR FOO ZAP} + ? {lsort [T object info methods]} {BAR FOO ZAP bar} + ? {t foo} ::T->foo + ? {T object info method definition ZAP} {::T object alias ZAP ::T::BAR} + + ? {T FOO} ->foo + ? {T BAR} ->foo + ? {T ZAP} ->foo + ? {T bar} ->bar + T object method FOO {} {} + ? {T info methods} {foo} + ? {lsort [T object info methods]} {BAR ZAP bar} + ? {T BAR} ->foo + ? {T ZAP} ->foo + rename ::T::BAR "" + ? {T info methods} {foo} + ? {lsort [T object info methods]} {ZAP bar} + #? {T BAR} ""; # now calling the proc defined above, alias chain seems intact + ? {T ZAP} ->foo; # is ok, still pointing to 'foo' + #T object method BAR {} {} + ? {T info methods} {foo} + ? {lsort [T object info methods]} {ZAP bar} + ? {T ZAP} ->foo + T method foo {} {} + ? {T info methods} {} + ? {lsort [T object info methods]} {bar} +} +Test case alias-per-object { -Base method foo {{-x 1}} {return $x} -::xotcl::alias ::Foo foo ::xotcl::classes::Base::foo + Class create T { + :object method bar args { return [self class]->[self proc] } + :create t + } + proc ::foo args { return [self class]->[self proc] } -? {Base info methods -methodtype scripted} {foo} "defined again" -? {Foo info methods -methodtype alias} {foo} "aliased again" -Foo method foo {} {} -? {Base info methods -methodtype scripted} {foo} "still defined" -? {Foo info methods -methodtype alias} {} "removed" + # + # per-object methods as per-object aliases + # + T object method m1 args { return [self class]->[self proc] } + ::xotcl::alias T -per-object M1 ::T::m1 + ::xotcl::alias T -per-object M11 ::T::M1 + ? {lsort [T object info methods]} {M1 M11 bar m1} + ? {T m1} ->m1 + ? {T M1} ->m1 + ? {T M11} ->m1 + T object method M1 {} {} + ? {lsort [T object info methods]} {M11 bar m1} + ? {T m1} ->m1 + ? {T M11} ->m1 + T object method m1 {} {} + ? {lsort [T object info methods]} {bar} + + # + # a proc as alias + # + + proc foo args { return [self class]->[self proc] } + ::xotcl::alias T FOO1 ::foo + ::xotcl::alias T -per-object FOO2 ::foo + # + # ! per-object alias referenced as per-class alias ! + # + ::xotcl::alias T BAR ::T::FOO2 + ? {lsort [T object info methods]} {FOO2 bar} + ? {lsort [T info methods]} {BAR FOO1} + ? {T FOO2} ->foo + ? {t FOO1} ::T->foo + ? {t BAR} ::T->foo + # + # delete proc + # + rename ::foo "" + ? {lsort [T object info methods]} {bar} + ? {lsort [T info methods]} {} +} -# -# chaining aliases -# -Class create T -Class create S -T create t -S create s - - -T method foo args { return [self class]->[self proc] } -::xotcl::alias T FOO ::xotcl::classes::T::foo - -? {t foo} ::T->foo -? {t FOO} ::T->foo - -? {lsort [T info methods]} {FOO foo} -T method foo {} {} -? {lsort [T info methods]} {} "alias is deleted" - -# puts stderr "double indirection" -T method foo args { return [self class]->[self proc] } -::xotcl::alias T FOO ::xotcl::classes::T::foo -::xotcl::alias S BAR ::xotcl::classes::T::FOO - -? {T info methods -methodtype alias} "FOO" -? {T info method definition FOO} "::T alias FOO ::xotcl::classes::T::foo" -? {lsort [T info methods]} {FOO foo} -? {S info methods} {BAR} -T method FOO {} {} -? {T info methods} {foo} -? {S info methods} {BAR} -? {s BAR} ::S->foo -? {t foo} ::T->foo -? {S info method definition BAR} "::S alias BAR ::xotcl::classes::T::FOO" - - -T method foo {} {} -? {T info methods} {} -? {S info methods} {} - -T method foo args { return [self class]->[self proc] } -::xotcl::alias T FOO ::xotcl::classes::T::foo -::xotcl::alias S BAR ::xotcl::classes::T::FOO - -? {lsort [T info methods]} {FOO foo} -? {S info methods} {BAR} -T method foo {} {} -? {S info methods} {} -? {T info methods} {} - -T method foo args { return [self class]->[self proc] } -T object method bar args { return [self class]->[self proc] } -::xotcl::alias T -per-object FOO ::xotcl::classes::T::foo -::xotcl::alias T -per-object BAR ::T::FOO -::xotcl::alias T -per-object ZAP ::T::BAR -? {T info methods} {foo} -? {lsort [T object info methods -methodtype alias]} {BAR FOO ZAP} -? {lsort [T object info methods]} {BAR FOO ZAP bar} -? {t foo} ::T->foo -? {T object info method definition ZAP} {::T object alias ZAP ::T::BAR} - -? {T FOO} ->foo -? {T BAR} ->foo -? {T ZAP} ->foo -? {T bar} ->bar -T object method FOO {} {} -? {T info methods} {foo} -? {lsort [T object info methods]} {BAR ZAP bar} -? {T BAR} ->foo -? {T ZAP} ->foo -rename ::T::BAR "" -? {T info methods} {foo} -? {lsort [T object info methods]} {ZAP bar} -#? {T BAR} ""; # now calling the proc defined above, alias chain seems intact -? {T ZAP} ->foo; # is ok, still pointing to 'foo' -#T object method BAR {} {} -? {T info methods} {foo} -? {lsort [T object info methods]} {ZAP bar} -? {T ZAP} ->foo -T method foo {} {} -? {T info methods} {} -? {lsort [T object info methods]} {bar} - -# -# per-object methods as per-object aliases -# -T object method m1 args { return [self class]->[self proc] } -::xotcl::alias T -per-object M1 ::T::m1 -::xotcl::alias T -per-object M11 ::T::M1 -? {lsort [T object info methods]} {M1 M11 bar m1} -? {T m1} ->m1 -? {T M1} ->m1 -? {T M11} ->m1 -T object method M1 {} {} -? {lsort [T object info methods]} {M11 bar m1} -? {T m1} ->m1 -? {T M11} ->m1 -T object method m1 {} {} -? {lsort [T object info methods]} {bar} - -# -# a proc as alias -# - -proc foo args { return [self class]->[self proc] } -::xotcl::alias T FOO1 ::foo -::xotcl::alias T -per-object FOO2 ::foo -# -# ! per-object alias referenced as per-class alias ! -# -::xotcl::alias T BAR ::T::FOO2 -? {lsort [T object info methods]} {FOO2 bar} -? {lsort [T info methods]} {BAR FOO1} -? {T FOO2} ->foo -? {t FOO1} ::T->foo -? {t BAR} ::T->foo -# -# delete proc -# -rename foo "" -? {lsort [T object info methods]} {bar} -? {lsort [T info methods]} {} - # namespaced procs + namespace deletion +Test case alias-namespaced { + Class create T { + :object method bar args { return [self class]->[self proc] } + :create t + } + + namespace eval ::ns1 { + proc foo args { return [self class]->[self proc] } + proc bar args { return [uplevel 2 {set _}] } + proc bar2 args { upvar 2 _ __; return $__} + } + + ::xotcl::alias T FOO ::ns1::foo + ::xotcl::alias T BAR ::ns1::bar + ::xotcl::alias T BAR2 ::ns1::bar2 + ? {lsort [T info methods]} {BAR BAR2 FOO} + set ::_ GOTYA + ? {t FOO} ::T->foo + ? {t BAR} GOTYA + ? {t BAR2} GOTYA + namespace delete ::ns1 + ? {info procs ::ns1::*} {} + ? {lsort [T info methods]} {} + + # per-object namespaces + + Class create U + U create u + ? {namespace exists ::U} 0 + U object method zap args { return [self class]->[self proc] } + ::xotcl::alias ::U -per-object ZAP ::U::zap + U requireNamespace + ? {namespace exists ::U} 1 + + U object method bar args { return [self class]->[self proc] } + ::xotcl::alias U -per-object BAR ::U::bar + ? {lsort [U object info methods]} {BAR ZAP bar zap} + ? {U BAR} ->bar + ? {U ZAP} ->zap + namespace delete ::U + ? {namespace exists ::U} 0 + ? {lsort [U object info methods]} {} + ? {U info callable BAR} "" + ? {U info callable ZAP} "" + + ::U destroy +} -namespace eval ::ns1 { - proc foo args { return [self class]->[self proc] } - proc bar args { return [uplevel 2 {set _}] } - proc bar2 args { upvar 2 _ __; return $__} +Class create V { + set :z 1 } +? {lsort [V info vars]} {z} -::xotcl::alias T FOO ::ns1::foo -::xotcl::alias T BAR ::ns1::bar -::xotcl::alias T BAR2 ::ns1::bar2 -? {lsort [T info methods]} {BAR BAR2 FOO} -set _ GOTYA -? {t FOO} ::T->foo -? {t BAR} GOTYA -? {t BAR2} GOTYA -namespace delete ::ns1 -? {info procs ::ns1::*} {} -? {lsort [T info methods]} {} -# per-object namespaces +# dot-resolver/ dot-dispatcher used in aliased proc -Class create U -U create u -? {namespace exists ::U} 0 -U object method zap args { return [self class]->[self proc] } -::xotcl::alias ::U -per-object ZAP ::U::zap -U requireNamespace -? {namespace exists ::U} 1 +Test case alias-dot-resolver { -U object method bar args { return [self class]->[self proc] } -::xotcl::alias U -per-object BAR ::U::bar -? {lsort [U object info methods]} {BAR ZAP bar zap} -? {U BAR} ->bar -? {U ZAP} ->zap -namespace delete ::U -? {namespace exists ::U} 0 -? {lsort [U object info methods]} {} -? {U info callable BAR} "" -? {U info callable ZAP} "" + Class create V { + set :z 1 + :method bar {z} { return $z } + :object method bar {z} { return $z } + :create v { + set :z 2 + } + } + ? {lsort [V info vars]} {z} + puts stderr =====1 -::U destroy + puts stderr =====0 + ? {lsort [V info vars]} {z} + ? {lsort [v info vars]} {z} -# dot-resolver/ dot-dispatcher used in aliased proc + proc ::foo args { return [:bar ${:z}]-[set :z]-[my bar [set :z]] } -Class create V { - set :z 1 -} + ::xotcl::alias V FOO1 ::foo + ::xotcl::alias V -per-object FOO2 ::foo -V create v { - set :z 2 + ? {lsort [V object info methods]} {FOO2 bar} + ? {lsort [V info methods]} {FOO1 bar} +puts stderr =====1 + ? {V FOO2} 1-1-1 + ? {v FOO1} 2-2-2 + V method FOO1 {} {} + ? {lsort [V info methods]} {bar} + rename ::foo "" + ? {lsort [V object info methods]} {bar} } -V method bar {z} { return $z } -V object method bar {z} { return $z } - -proc foo args { return [:bar ${:z}]-[set :z]-[my bar [set :z]] } - -::xotcl::alias V FOO1 ::foo -::xotcl::alias V -per-object FOO2 ::foo -? {lsort [V object info methods]} {FOO2 bar} -? {lsort [V info methods]} {FOO1 bar} -? {V FOO2} 1-1-1 -? {v FOO1} 2-2-2 -V method FOO1 {} {} -? {lsort [V info methods]} {bar} -rename ::foo "" -? {lsort [V object info methods]} {bar} - - # # Tests for the ::xotcl::alias store, used for introspection for # aliases. The alias store (an associative variable) is mostly # necessary for for the direct aliases (e.g. aliases to C implemented # tcl commands), for which we have no stubs at the place where the # alias was registered. # -::xotcl::use xotcl2 # # structure of the ::xotcl::alias store: