Index: tests/parameters.test =================================================================== diff -u -rf9a705afeb75b5fb944821b3d3da27d969941293 -r7c2e28b93b02c29f19dc1f58642c5a29a894d24e --- tests/parameters.test (.../parameters.test) (revision f9a705afeb75b5fb944821b3d3da27d969941293) +++ tests/parameters.test (.../parameters.test) (revision 7c2e28b93b02c29f19dc1f58642c5a29a894d24e) @@ -1,9 +1,10 @@ # -*- Tcl -*- package require nx package require nx::test + #::nx::configure defaultMethodCallProtection false -nx::Test case dummy { +nx::test case dummy { ? {::namespace current} :: set o [Object create o] @@ -14,26 +15,26 @@ # # simple test case for parameter passing # -nx::Test case syntax { +nx::test case syntax { ::nx::Class create C ? {::nsf::method::alias C} \ {required argument 'methodName' is missing, should be: - ::nsf::method::alias object ?-per-object? methodName ?-frame method|object|default? cmdName} + ::nsf::method::alias /object/ ?-per-object? /methodName/ ?-frame method|object|default? /cmdName/} ? {::nsf::method::alias C foo ::set} "::nsf::classes::C::foo" ? {::nsf::method::alias C foo ::set 1} \ - {invalid argument '1', maybe too many arguments; should be "::nsf::method::alias object ?-per-object? methodName ?-frame method|object|default? cmdName"} + {invalid argument '1', maybe too many arguments; should be "::nsf::method::alias /object/ ?-per-object? /methodName/ ?-frame method|object|default? /cmdName/"} - ? {C eval {:property x -class D}} {invalid argument 'D', maybe too many arguments; should be "::C property ?-accessor value? ?-config boolean? ?-incremental? ?-class value? spec ?initblock?"} "Test whether the colon prefix is suppressed" + ? {C eval {:property x -class D}} {invalid argument 'D', maybe too many arguments; should be "::C property ?-accessor /value/? ?-configurable /boolean/? ?-incremental? ?-class /value/? /spec/ ?/initblock/?"} "Test whether the colon prefix is suppressed" } ####################################################### # parametercheck ####################################################### -nx::Test parameter count 1000 -nx::Test case parametercheck { +nx::test configure -count 1000 +nx::test case parametercheck { nx::Object create o1 nx::Class create C { @@ -43,18 +44,18 @@ } C create c1 nx::Class create M - c1 mixin M + c1 object mixin M ? {::nsf::object::exists o1} 1 ? {::nsf::object::exists o1000} 0 ? {::nsf::is class C} 1 - ? {C info is class} 1 + ? {C info has type ::nx::Class} 1 ? {::nsf::is baseclass ::nx::Object} 1 - ? {::nx::Object info is baseclass} 1 + #? {::nx::Object info is baseclass} 1 ? {::nsf::is baseclass C} 0 - ? {C info is baseclass} 0 + #? {C info is baseclass} 0 ? {::nsf::is class ::nx::Object} 1 ? {::nsf::is ::nx::Object class} {invalid value constraints "::nx::Object"} @@ -119,8 +120,8 @@ ? {::nsf::is -complain class o1} {expected class but got "o1"} ? {::nsf::is class o1} 0 - ? {::nsf::is -complain class nx::Test} 1 - ? {::nsf::is -complain object,1..* [list o1 nx::Test]} 1 + ? {::nsf::is -complain class nx::test} 1 + ? {::nsf::is -complain object,1..* [list o1 nx::test]} 1 ? {::nsf::is -complain integer,1..* [list 1 2 3]} 1 ? {::nsf::is -complain integer,1..* [list 1 2 3 a]} \ @@ -145,20 +146,20 @@ ? {::nsf::is -complain {i:integer 1} 2} {invalid value constraints "i:integer 1"} } -nx::Test parameter count 10 -nx::Test case multiple-method-checkers { +nx::test configure -count 10 +nx::test case multiple-method-checkers { nx::Object create o { - :public method foo {} { + :public object method foo {} { ::nsf::is metaclass ::XYZ ::nsf::is metaclass ::nx::Object } - :public method bar {} { + :public object method bar {} { ::nsf::is metaclass ::XYZ ::nsf::is metaclass ::XYZ } - :public method bar2 {} { + :public object method bar2 {} { ::nsf::is metaclass ::nx::Object ::nsf::is metaclass ::nx::Object } @@ -177,11 +178,11 @@ ####################################################### # param manager ####################################################### -nx::Test parameter count 10000 -nx::Test case param-manager { +nx::test configure -count 10000 +nx::test case param-manager { nx::Object create ::paramManager { - :method type=sex {name value} { + :object method type=sex {name value} { return "agamous" } } @@ -263,8 +264,8 @@ ####################################################### # objectparameter ####################################################### -nx::Test parameter count 10 -nx::Test case objectparameter { +nx::test configure -count 10 +nx::test case objectparameter { nx::Class create C { :property a @@ -274,7 +275,7 @@ C create c1 ? {C eval :__objectparameter} \ - "{-superclass:class,alias,method=::nsf::methods::class::superclass,1..n ::nx::Object} -object-mixin:mixinreg,alias,method=::nsf::classes::nx::Object::mixin -mixin:mixinreg,alias,0..n -object-filter:filterreg,alias,method=::nsf::classes::nx::Object::filter -filter:filterreg,alias,0..n -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -class:class,alias,method=::nsf::methods::object::class __initcmd:initcmd,optional,noleadingdash" + "{-superclass:class,alias,method=::nsf::methods::class::superclass,1..n ::nx::Object} -mixin:mixinreg,alias,0..n -filter:filterreg,alias,0..n -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" #### TOOD: remove or add #? {c1 eval :__objectparameter} \ @@ -284,7 +285,7 @@ ####################################################### # reclass to nx::Object, no need to do anything on caching ####################################################### -nx::Test case reclass { +nx::test case reclass { nx::Class create C { :property a @@ -306,13 +307,13 @@ "::D::slot::d ::C::slot::a ::C::slot::b ::C::slot::c" ? {d1 eval :__objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" + "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" } ####################################################### # Add mixin ####################################################### -nx::Test case objparam-mixins { +nx::test case objparam-mixins { nx::Class create C { :property a @@ -335,36 +336,36 @@ D mixin M ? {d1 eval :__objectparameter} \ - "-b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" \ + "-b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" \ "mixin added" M mixin M2 ? {d1 eval :__objectparameter} \ - "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" \ + "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" \ "transitive mixin added" D mixin "" #we should have again the old interface ? {d1 eval :__objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" + "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" C mixin M ? {d1 eval :__objectparameter} \ - "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" \ + "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" \ "mixin added" C mixin "" #we should have again the old interface ? {d1 eval :__objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" + "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" } ####################################################### # test passed arguments ####################################################### -nx::Test case passed-arguments { +nx::test case passed-arguments { nx::Class create C { :property a @@ -379,7 +380,7 @@ ? {D create d1} \ {required argument 'd' is missing, should be: - ::d1 __configure -d value ?-a value? ?-b boolean? ?-c value? ?-volatile? ?-noinit? ?-mixin mixinreg ...? ?-class class? ?-filter filterreg ...? ?__initcmd?} + ::d1 __configure -d /value/ ?-a /value/? ?-b /boolean/? ?-c /value/? ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?} ? {D create d2 -d x -b a} \ {expected boolean but got "a" for parameter "-b"} \ @@ -392,7 +393,7 @@ ? {d1 foo} \ {required argument 'r' is missing, should be: - ::d1 foo ?-b boolean? -r integer ?-x integer? ?-object object? ?-class class?} \ + ::d1 foo ?-b /boolean/? -r /integer/ ?-x /integer/? ?-object /object/? ?-class /class/?} \ "call method without a required argument" ? {d1 foo -r a} \ @@ -429,13 +430,13 @@ ? {d1 foo 1} 1 "check int as double" ? {d1 foo 1.1} 1.1 "check double as double" ? {d1 foo 1.1a} {expected double but got "1.1a" for parameter "a"} "check non-double as double" - ? {D info method parameter foo} a:double + ? {D info method parameters foo} a:double } ####################################################### # non required positional arguments ####################################################### -nx::Test case non-reg-args { +nx::test case non-reg-args { nx::Class create D D create d1 @@ -457,7 +458,7 @@ ####################################################### # multivalued arguments ####################################################### -nx::Test case multivalued { +nx::test case multivalued { nx::Class create D D create d1 @@ -505,7 +506,7 @@ ####################################################### # subst default tests ####################################################### -nx::Test case subst-default { +nx::test case subst-default { nx::Class create D { :property {c 1} @@ -526,13 +527,13 @@ ? {d1 bar -c 1} {::d1-[current]-1-2} "substdefault in method parameter" nx::Class create Bar -superclass D { - :property {s "[current]"} - :property {literal "\\[current\\]"} - :property {c "[:info class]"} - :property {d "literal $d"} + :property -accessor public {s "[current]"} + :property -accessor public {literal "\\[current\\]"} + :property -accessor public {c "[:info class]"} + :property -accessor public {d "literal $d"} } - ? {Bar property ss:switch} "::nsf::classes::Bar::ss" + ? {Bar property -accessor public ss:switch} "::nsf::classes::Bar::ss" Bar create bar1 #puts stderr [bar1 __objectparameter] @@ -576,7 +577,7 @@ } ? {D info method args bar} {s literal c d switch optflag x y z} "all args" - ? {D info method parameter bar} \ + ? {D info method parameters bar} \ {{-s:substdefault "[current]"} {-literal "[current]"} {-c:substdefault "[:c]"} {-d:integer,substdefault "$d"} -switch:switch -optflag x y:integer {z 1}} \ "query method parameter" @@ -610,40 +611,40 @@ # Query method parameter ####################################################### - ? {D info method parameter foo} \ + ? {D info method parameters foo} \ "a b c {end 100}" \ "query instparams with default, no paramdefs needed" - ? {nx::Class info method parameter method} \ - "name arguments:parameter,0..* -returns body -precondition -postcondition" \ + ? {nx::Class info method parameters method} \ + "name arguments:parameter,0..* -checkalways:switch -returns body -precondition -postcondition" \ "query instparams for scripted method 'method'" - ? {nx::Object info method parameter ::nsf::method::forward} \ + ? {nx::Object info method parameters ::nsf::method::forward} \ "object:object -per-object:switch method -default -earlybinding:switch -methodprefix -objframe:switch -onerror -verbose:switch target:optional args" \ "query parameter for C-defined cmd 'nsf::forward'" nx::Object require method autoname - ? {nx::Object info method parameter autoname} \ + ? {nx::Object info method parameters autoname} \ "-instance:switch -reset:switch name" \ "query parameter for C-defined method 'autoname'" - # TODO: how to query the params/instparams of info subcommands? - #? {::xotcl::objectInfo info params params} \ - # "xxx" \ - # "query instparams for info method 'params' method" + D method "a b" {x y} {return $x-$y} + D object method "c d" {x y z} {return $x-$y} + ? {D info method parameters "a b"} "x y" + ? {D info object method parameters "c d"} "x y z" } ####################################################### # user defined parameter value checkers ####################################################### -nx::Test case user-value-checker { +nx::test case user-value-checker { nx::Class create D {:property d} D create d1 # Create a user-defined value checker for method parameters, # without extra argument - ::nx::methodParameterSlot method type=mytype {name value} { + ::nx::methodParameterSlot object method type=mytype {name value} { if {$value < 1 || $value > 3} { error "value '$value' of parameter $name is not between 1 and 3" } @@ -670,7 +671,7 @@ # Create a user-defined value-checker for method parameters, # with a extra argument # - ::nx::methodParameterSlot method type=in {name value arg} { + ::nx::methodParameterSlot object method type=in {name value arg} { if {$value ni [split $arg |]} { error "value '$value' of parameter $name not in permissible values $arg" } @@ -708,7 +709,7 @@ # Create a user-defined value checker for method parameters, # without extra argument # - ::nx::methodParameterSlot method type=commaRange {name value arg} { + ::nx::methodParameterSlot object method type=commaRange {name value arg} { lassign [split $arg ,] min max if {$value < $min || $value > $max} { error "value '$value' of parameter $name not between $min and $max" @@ -740,7 +741,7 @@ # # Classical range check # - ::nx::methodParameterSlot method type=range {name value arg} { + ::nx::methodParameterSlot object method type=range {name value arg} { lassign [split $arg -] min max if {$value < $min || $value > $max} { error "value '$value' of parameter $name not between $min and $max" @@ -765,7 +766,7 @@ # # handling of arg with spaces/arg as list # - ::nx::methodParameterSlot public method type=list {name value arg} { + ::nx::methodParameterSlot public object method type=list {name value arg} { #puts $value/$arg return $value } @@ -781,47 +782,47 @@ ####################################################### # testing object types in method parameters ####################################################### -nx::Test case mp-object-types { +nx::test case mp-object-types { nx::Class create C nx::Class create D -superclass C {:property d} nx::Class create M nx::Class create M2 D create d1 -d 1 - C create c1 -mixin M - C create c2 -mixin {{M -guard true}} - C create c3 -mixin {M ::M2} - C create c4 -mixin {{M -guard 1} M2} - C create c5 -mixin {M {M2 -guard 2}} + C create c1 -object-mixin M + C create c2 -object-mixin {{M -guard true}} + C create c3 -object-mixin {M ::M2} + C create c4 -object-mixin {{M -guard 1} M2} + C create c5 -object-mixin {M {M2 -guard 2}} nx::Object create o - ? {c1 info mixin classes} ::M - ? {c1 info mixin guard ::M} "" + ? {c1 info object mixin classes} ::M + ? {c1 info object mixin guard ::M} "" - ? {c2 info mixin classes} ::M - ? {c2 info mixin guard ::M} "true" + ? {c2 info object mixin classes} ::M + ? {c2 info object mixin guard ::M} "true" - ? {c3 info mixin classes} {::M ::M2} - ? {c3 info mixin guard M} "" - ? {c3 info mixin guard M2} "" + ? {c3 info object mixin classes} {::M ::M2} + ? {c3 info object mixin guard M} "" + ? {c3 info object mixin guard M2} "" - ? {c4 info mixin classes} {::M ::M2} - ? {c4 info mixin guard M} "1" - ? {c4 info mixin guard M2} "" + ? {c4 info object mixin classes} {::M ::M2} + ? {c4 info object mixin guard M} "1" + ? {c4 info object mixin guard M2} "" - ? {c5 info mixin classes} {::M ::M2} - ? {c5 info mixin guard M} "" - ? {c5 info mixin guard M2} "2" + ? {c5 info object mixin classes} {::M ::M2} + ? {c5 info object mixin guard M} "" + ? {c5 info object mixin guard M2} "2" D public method foo-base {x:baseclass} {return $x} D public method foo-class {x:class} {return $x} D public method foo-object {x:object} {return $x} D public method foo-meta {x:metaclass} {return $x} D public method foo-type {x:object,type=::C} {return $x} - ? {D info method parameter foo-base} "x:baseclass" - ? {D info method parameter foo-type} "x:object,type=::C" + ? {D info method parameters foo-base} "x:baseclass" + ? {D info method parameters foo-type} "x:object,type=::C" ? {d1 foo-base ::nx::Object} "::nx::Object" ? {d1 foo-base C} \ @@ -856,31 +857,31 @@ ####################################################### # substdefault ####################################################### -nx::Test case substdefault { +nx::test case substdefault { nx::Class create S { :property {x 1} :property {y b} :property {z {1 2 3}} } S create s1 { - :public method foo {{y:substdefault ${:x}}} { + :public object method foo {{y:substdefault ${:x}}} { return $y } - :public method bar {{y:integer,substdefault ${:x}}} { + :public object method bar {{y:integer,substdefault ${:x}}} { return $y } - :public method baz {{x:integer,substdefault ${:y}}} { + :public object method baz {{x:integer,substdefault ${:y}}} { return $x } - :public method boz {{x:integer,0..n,substdefault ${:z}}} { + :public object method boz {{x:integer,0..n,substdefault ${:z}}} { return $x } } ? {s1 foo} 1 ? {s1 foo 2} 2 - ? {S method foo {a:substdefault} {return 1}} \ + ? {S object method foo {a:substdefault} {return 1}} \ {parameter option substdefault specified for parameter "a" without default value} ? {s1 bar} 1 @@ -889,33 +890,33 @@ ? {s1 baz} {expected integer but got "b" for parameter "x"} ? {s1 baz 20} 20 - s1 y 100 + s1 configure -y 100 ? {s1 baz} 100 ? {s1 baz 101} 101 ? {s1 boz} {1 2 3} - s1 z {1 x 100} + s1 configure -z {1 x 100} ? {s1 boz} {invalid value in "1 x 100": expected integer but got "x" for parameter "x"} ? {s1 boz {100 200}} {100 200} set ::aaa 100 - ? {s1 public method foo {{a:substdefault $::aaa}} {return $a}} ::s1::foo + ? {s1 public object method foo {{a:substdefault $::aaa}} {return $a}} ::s1::foo ? {s1 foo} 100 unset ::aaa ? {s1 foo} {can't read "::aaa": no such variable} - ? {s1 public method foo {{a:substdefault $aaa}} {return $a}} ::s1::foo + ? {s1 public object method foo {{a:substdefault $aaa}} {return $a}} ::s1::foo ? {s1 foo} {can't read "aaa": no such variable} - ? {s1 public method foo {{a:substdefault [current]}} {return $a}} ::s1::foo + ? {s1 public object method foo {{a:substdefault [current]}} {return $a}} ::s1::foo ? {s1 foo} ::s1 } ####################################################### # testing substdefault for object parameters ####################################################### -nx::Test case substdefault-objparam { +nx::test case substdefault-objparam { nx::Class create Bar { @@ -933,16 +934,16 @@ } Bar create ::b - ? {b s0} "::b" - ? {b s1} "::b" - ? {b s2} "::b" - ? {b s3} "::b" + ? {b cget -s0} "::b" + ? {b cget -s1} "::b" + ? {b cget -s2} "::b" + ? {b cget -s3} "::b" } # # Test call of configure within constructor # -nx::Test case parameter-alias-default { +nx::test case parameter-alias-default { ::nsf::method::require nx::Object __configure nx::Class create C { @@ -966,7 +967,7 @@ ####################################################### # testing object types in object parameters ####################################################### -nx::Test case op-object-types { +nx::test case op-object-types { nx::Class create C nx::Class create D -superclass C {:property d} @@ -975,7 +976,7 @@ MC create MC1 nx::Class create M D create d1 -d 1 - C create c1 -mixin M + C create c1 -object-mixin M nx::Object create o nx::Class create ParamTest { @@ -988,24 +989,19 @@ :property b:baseclass :property u:upper :property us:upper,1..* + :property -incremental us2:upper,1..* :property {x:object,1..* {o}} } - # TODO: we have no good interface for querying the slot notation for parameters - proc ::parameterFromSlot {class objectparameter} { - set slot ${class}::slot::$objectparameter - return [$slot getParameterSpec] - } + ? {ParamTest info configure parameters o} "-o:object" + ? {ParamTest info configure parameters c} "-c:class" + ? {ParamTest info configure parameters c1} "-c1:class,type=::MC" + ? {ParamTest info configure parameters d} "-d:object,type=::C" + ? {ParamTest info configure parameters d1} "-d1:object,type=::C" + ? {ParamTest info configure parameters x} "{-x:object,1..* o}" + ? {ParamTest info configure parameters u} "-u:upper,slot=::ParamTest::slot::u" + ? {ParamTest info configure parameters us} "-us:upper,slot=::ParamTest::slot::us,1..*" - ? {::parameterFromSlot ParamTest o} "-o:object" - ? {::parameterFromSlot ParamTest c} "-c:class" - ? {::parameterFromSlot ParamTest c1} "-c1:class,type=::MC" - ? {::parameterFromSlot ParamTest d} "-d:object,type=::C" - ? {::parameterFromSlot ParamTest d1} "-d1:object,type=::C" - ? {::parameterFromSlot ParamTest x} "-x:object,1..* o" - ? {::parameterFromSlot ParamTest u} "-u:upper,slot=::ParamTest::slot::u" - ? {::parameterFromSlot ParamTest us} "-us:upper,slot=::ParamTest::slot::us,1..*" - ? {ParamTest create p -o o} ::p ? {ParamTest create p -o xxx} \ {expected object but got "xxx" for parameter "-o"} \ @@ -1041,23 +1037,24 @@ set :incremental 1 :reconfigure } - ? {ParamTest create p -us {A B}} ::p + ? {ParamTest create p -us {A B} -us2 {A B}} ::p ? {p us add C end} "A B C" + ? {p us2 add C end} "A B C" - ? {p o o} \ - "o" \ + ? {p configure -o o} \ + "" \ "value is an object" - ? {p o xxx} \ - {expected object but got "xxx" for parameter "o"} \ + ? {p configure -o xxx} \ + {expected object but got "xxx" for parameter "-o"} \ "value is not an object" # # define multivalued property "os" via instance variables of the # slot object # ParamTest eval { - :property os { + :property -accessor public os { :type object :multiplicity 1..n } @@ -1081,9 +1078,9 @@ ####################################################### # application specific multivalued converter ####################################################### -nx::Test case multivalued-app-converter { +nx::test case multivalued-app-converter { - ::nx::methodParameterSlot public method type=sex {name value args} { + ::nx::methodParameterSlot public object method type=sex {name value args} { #puts stderr "[current] slot specific converter" switch -glob $value { m* {return m} @@ -1100,7 +1097,7 @@ ? {c1 bar {male female mann frau}} "male female mann frau" nx::Object create tmpObj - tmpObj method type=mType {name value arg:optional} { + tmpObj object method type=mType {name value arg:optional} { if {$value} { error "expected false but got $value" } @@ -1118,15 +1115,15 @@ ####################################################### # application specific multivalued converter ####################################################### -nx::Test case shadowing-app-converter { +nx::test case shadowing-app-converter { nx::Object create mySlot { - :public method type=integer {name value arg:optional} { + :public object method type=integer {name value arg:optional} { return [expr {$value + 1}] } } nx::Object create o { - :public method foo {x:integer,slot=::mySlot,convert} { + :public object method foo {x:integer,slot=::mySlot,convert} { return $x } } @@ -1139,14 +1136,14 @@ ####################################################### # allow empty values ####################################################### -nx::Test case allow-empty { +nx::test case allow-empty { nx::Object create o1 nx::Object create o2 nx::Object create o3 nx::Object create o { - :public method foo {x:integer,0..1 y:integer os:object,0..*} { + :public object method foo {x:integer,0..1 y:integer os:object,0..*} { return $x } } @@ -1156,9 +1153,9 @@ ? {o foo 1 "" {o1 o2}} {expected integer but got "" for parameter "y"} "second is empty" ? {o foo 1 2 {}} 1 "empty list" - ? {o info method parameter foo} "x:integer,0..1 y:integer os:object,0..*" + ? {o info object method parameters foo} "x:integer,0..1 y:integer os:object,0..*" - o public method foo {x:integer,0..1 y:integer os:object,1..*} {return $x} + o public object method foo {x:integer,0..1 y:integer os:object,1..*} {return $x} ? {o foo 1 2 {o1 "" o2}} {invalid value in "o1 "" o2": expected object but got "" for parameter "os"} \ "list contains empty value" ? {o foo "" 2 {}} {invalid value for parameter 'os': list is not allowed to be empty} \ @@ -1167,13 +1164,13 @@ ####################################################### # slot specific converter ####################################################### -nx::Test case slot-specfic-converter { +nx::test case slot-specfic-converter { nx::Class create Person { - :property sex { + :property -accessor public sex { :type "sex" :convert true - :method type=sex {name value} { + :object method type=sex {name value} { #puts stderr "[self] slot specific converter" switch -glob $value { m* {return m} @@ -1185,6 +1182,7 @@ } Person create p1 -sex male + ? {p1 cget -sex} m ? {p1 sex} m Person public method foo {s:sex,slot=::Person::slot::sex,convert} {return $s} ? {p1 foo male} m @@ -1194,32 +1192,32 @@ ####################################################### # test for setters with parameters ####################################################### -nx::Test case setters { +nx::test case setters { nx::Object create o nx::Class create C ? {::nsf::method::setter ::o :a} {invalid setter name ":a" (must not start with a dash or colon)} ? {::nsf::method::setter o a} "::o::a" ? {::nsf::method::setter C c} "::nsf::classes::C::c" - ? {o info method definition a} "::o public setter a" - ? {o info method parameter a} "a" - ? {o info method args a} "a" + ? {o info object method definition a} "::o public object setter a" + ? {o info object method parameters a} "a" + ? {o info object method args a} "a" ? {C info method definition c} "::C public setter c" ? {o a 1} "1" ? {::nsf::method::setter o a:integer} "::o::a" ? {::nsf::method::setter o ints:integer,1..*} "::o::ints" ? {::nsf::method::setter o o:object} "::o::o" - ? {o info method registrationhandle ints} "::o::ints" - ? {o info method definition ints} "::o public setter ints:integer,1..*" - ? {o info method parameter ints} "ints:integer,1..*" - ? {o info method args ints} "ints" + ? {o info object method registrationhandle ints} "::o::ints" + ? {o info object method definition ints} "::o public object setter ints:integer,1..*" + ? {o info object method parameters ints} "ints:integer,1..*" + ? {o info object method args ints} "ints" - ? {o info method registrationhandle o} "::o::o" - ? {o info method definition o} "::o public setter o:object" - ? {o info method parameter o} "o:object" - ? {o info method args o} "o" + ? {o info object method registrationhandle o} "::o::o" + ? {o info object method definition o} "::o public object setter o:object" + ? {o info object method parameters o} "o:object" + ? {o info object method args o} "o" ? {o a 2} 2 ? {o a hugo} {expected integer but got "hugo" for parameter "a"} @@ -1236,13 +1234,13 @@ ####################################################### # test for slot-optimizer ####################################################### -nx::Test parameter count 1000 -nx::Test case slot-optimizer { +nx::test configure -count 1000 +nx::test case slot-optimizer { nx::Class create C { - :property a - :property b:integer - :property c:integer,0..n + :property -accessor public a + :property -accessor public b:integer + :property -accessor public c:integer,0..n } C create c1 @@ -1251,10 +1249,10 @@ ? {c1 c 1} 1 } -nx::Test parameter count 10 -nx::Test case slot-nosetter { +nx::test configure -count 10 +nx::test case slot-nosetter { nx::Class create C { - :property a + :property -accessor public a :property -accessor none b:integer :property -accessor none {c ""} } @@ -1266,8 +1264,8 @@ ? {c1 c 102} {::c1: unable to dispatch method 'c'} } -nx::Test parameter count 1000 -nx::Test case check-arguments { +nx::test configure -count 1000 +nx::test case check-arguments { nx::Class create Foo { :public method noarg {} {return ""} @@ -1300,11 +1298,11 @@ ? {f1 metaclassarg ::Foo} {expected metaclass but got "::Foo" for parameter "x"} } -nx::Test case slot-traces { +nx::test case slot-traces { ::nx::Object create o { - :property a {set :defaultcmd { set _ 4 } } - :property b {set :valuecmd { set _ 44 } } - :property c {set :valuechangedcmd { ::nsf::var::set $obj $var 999 }} + :object property -accessor public a {set :defaultcmd { set _ 4 } } + :object property -accessor public b {set :valuecmd { set _ 44 } } + :object property -accessor public c {set :valuechangedcmd { ::nsf::var::set $obj $var 999 }} } ? {o a} 4 @@ -1320,9 +1318,9 @@ ? {::nsf::object::property o2 hasperobjectslots} 1 ::nx::Class create C { - :property a {set :defaultcmd { set _ 4 } } - :property b {set :valuecmd { set _ 44 } } - :property c {set :valuechangedcmd { ::nsf::var::set $obj $var 999 }} + :property -accessor public a {set :defaultcmd { set _ 4 } } + :property -accessor public b {set :valuecmd { set _ 44 } } + :property -accessor public c {set :valuechangedcmd { ::nsf::var::set $obj $var 999 }} :create c1 } ? {c1 a} 4 @@ -1343,7 +1341,7 @@ ? {d1 c 5} 999 } -nx::Test case slot-trace-interaction { +nx::test case slot-trace-interaction { # # 1) Verify the controlled interactions between trace types # @@ -1355,20 +1353,20 @@ Object create o ? {o eval {info exists :a}} 0 - ? {o property {a 0} { + ? {o object property {a 0} { set :defaultcmd {set _ 4} }} "defaultcmd can't be used together with default value" ? {o eval {info exists :a}} 0 ? {o eval {info exists :b}} 0 - ? {o property {b 0} { + ? {o object property {b 0} { set :valuecmd {set _ 44} }} "valuecmd can't be used together with default value" ? {o eval {info exists :b}} 0 ? {o eval {info exists :c}} 0 - ? {o property c { + ? {o object property c { set :defaultcmd {set _ 4} set :valuecmd {set _ 44} }} "valuecmd can't be used together with defaultcmd" @@ -1379,7 +1377,7 @@ # ? {o eval {info exists :a}} 0 - o property {a 0} { + o object property -accessor public {a 0} { set :valuechangedcmd {::nsf::var::set $obj $var [expr [list [::nsf::var::set $obj $var] + 1]]} } ? {o eval {info exists :a}} 1 @@ -1388,8 +1386,17 @@ ? {o a 1} 2 ? {o a} 2 ? {o a 2} 3 - # per-class: + ? {o eval {info exists :A}} 0 + o object property {A 0} { + set :valuechangedcmd {::nsf::var::set $obj $var [expr [list [::nsf::var::set $obj $var] + 1]]} + } + ? {o eval {info exists :A}} 1 + ? {o cget -A} 0 + ? {o configure -A 1} "" + ? {o cget -A} 2 + + # per-class: Class create Klass ? {Klass property {a 0} { @@ -1405,7 +1412,7 @@ set :valuecmd {set _ 44} }} "valuecmd can't be used together with defaultcmd" - Klass property {a 0} { + Klass property -accessor public {a 0} { set :valuechangedcmd {::nsf::var::set $obj $var [expr [list [::nsf::var::set $obj $var] + 1]]} } @@ -1448,31 +1455,27 @@ ::nx::Class create CC { :property a:0..n { set :defaultcmd { - if 1 { - set _ 4 - } + set _ 4 } } - :property b:0..n {set :valuecmd {if 1 {set _ 44}} } - :property c:0..n { + :property b:0..n {set :valuecmd {set _ 44} } + :property -accessor public c:0..n { set :valuechangedcmd { - if 1 { - ::nsf::var::set $obj $var 999 - } + ::nsf::var::set $obj $var 999 } } :create ::cc } - ? {cc a} 4 - ? {cc b} 44 + ? {cc cget -a} 4 + ? {cc cget -b} 44 ? {cc c 5} 999 } ::nsf::configure checkarguments off -nx::Test case check-arguments-nocheck { +nx::test case check-arguments-nocheck { nx::Class create Foo { :public method noarg {} {return ""} @@ -1505,20 +1508,17 @@ ? {f1 metaclassarg ::Foo} ::Foo } -## TODO regression test for type checking, parameter options (initcmd, -## substdefault, combinations with defaults, ...), etc. +nx::test configure -count 100 -nx::Test parameter count 100 - -nx::Test case checktype { +nx::test case checktype { nx::Object create o { - :public method f01 {} {::nsf::dispatch o ::nsf::methods::object::info::hastype ::nx::Object} - :public method f02 {} {::nsf::dispatch o ::nsf::methods::object::info::hastype nx::Object} - :public method f03 {} {::nsf::dispatch o ::nsf::methods::object::info::hastype nx::Object} + :public object method f01 {} {::nsf::dispatch o ::nsf::methods::object::info::hastype ::nx::Object} + :public object method f02 {} {::nsf::dispatch o ::nsf::methods::object::info::hastype nx::Object} + :public object method f03 {} {::nsf::dispatch o ::nsf::methods::object::info::hastype nx::Object} - :public method f11 {} {::nsf::is object,type=::nx::Object o} - :public method f12 {} {::nsf::is object,type=nx::Object o} - :public method f13 {} {::nsf::is object,type=Object o} + :public object method f11 {} {::nsf::is object,type=::nx::Object o} + :public object method f12 {} {::nsf::is object,type=nx::Object o} + :public object method f13 {} {::nsf::is object,type=Object o} } ? {o f01} 1 @@ -1543,17 +1543,17 @@ } nx::Object create o { - :public method f01 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype ::nx::Object} - :public method f02 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype nx::Object} - :public method f03 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype nx::Object} - :public method f04 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype foo::C} - :public method f05 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype C} + :public object method f01 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype ::nx::Object} + :public object method f02 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype nx::Object} + :public object method f03 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype nx::Object} + :public object method f04 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype foo::C} + :public object method f05 {} {::nsf::dispatch c1 ::nsf::methods::object::info::hastype C} - :public method f11 {} {::nsf::is object,type=::nx::Object c1} - :public method f12 {} {::nsf::is object,type=nx::Object c1} - :public method f13 {} {::nsf::is object,type=Object c1} - :public method f14 {} {::nsf::is object,type=foo::C c1} - :public method f15 {} {::nsf::is object,type=C c1} + :public object method f11 {} {::nsf::is object,type=::nx::Object c1} + :public object method f12 {} {::nsf::is object,type=nx::Object c1} + :public object method f13 {} {::nsf::is object,type=Object c1} + :public object method f14 {} {::nsf::is object,type=foo::C c1} + :public object method f15 {} {::nsf::is object,type=C c1} } ? {o f01} 1 @@ -1574,7 +1574,7 @@ ? {c1 f32} 1 } -nx::Test case check-arguments { +nx::test case check-arguments { nx::Class create Foo { :method noarg {} {return ""} @@ -1587,27 +1587,27 @@ :method metaclassarg {-x:metaclass} {return $x} } - ? {Foo info method syntax noarg} "" - ? {Foo info method syntax onearg} "?-x value?" - ? {Foo info method syntax intarg} "?-x integer?" - ? {Foo info method syntax intsarg} "?-x integer ...?" - ? {Foo info method syntax boolarg} "?-x boolean?" - ? {Foo info method syntax classarg} "?-x class?" - ? {Foo info method syntax upperarg} "?-x upper?" - ? {Foo info method syntax metaclassarg} "?-x metaclass?" + ? {Foo info method syntax noarg} "/cls/ noarg" + ? {Foo info method syntax onearg} "/cls/ onearg ?-x /value/?" + ? {Foo info method syntax intarg} "/cls/ intarg ?-x /integer/?" + ? {Foo info method syntax intsarg} "/cls/ intsarg ?-x /integer .../?" + ? {Foo info method syntax boolarg} "/cls/ boolarg ?-x /boolean/?" + ? {Foo info method syntax classarg} "/cls/ classarg ?-x /class/?" + ? {Foo info method syntax upperarg} "/cls/ upperarg ?-x /upper/?" + ? {Foo info method syntax metaclassarg} "/cls/ metaclassarg ?-x /metaclass/?" # return enumeration type ? {nx::Class info method syntax "info mixinof"} \ - "?-closure? ?-scope all|class|object? ?pattern?" + "/cls/ info mixinof ?-closure? ?-scope all|class|object? ?/pattern/?" } # # Check whether resetting via method "configure" changes values in the # initialzed object state. # -nx::Test case dont-reset-to-defaults { +nx::test case dont-reset-to-defaults { nx::Class create C { - :property {a 1} + :property -accessor public {a 1} :create c1 } ? {c1 a} 1 @@ -1621,7 +1621,7 @@ ? {c1 a} 2 } -nx::Test case setter-under-coloncmd-and-interpvarresolver { +nx::test case setter-under-coloncmd-and-interpvarresolver { # There are (at least) three forms of object-namespace alignment in # NSF: # 1. Same-named namespace (::omon) predates a same-named object @@ -1663,43 +1663,88 @@ } } -nx::Test case req-param { +# +# test required configure parameter +# + +nx::test case req-param { ::nx::Class create C { :property y:required :property x:required - :method init args {set ::_ $args} + :method init args {set ::_ "passed args '$args'"} } set ::_ "" ? {C create c2 -y 1 -x} {value for parameter '-x' expected} + + # Was the constructor called? Should not. ? {set ::_} "" - ? {c2 x} {can't read "x": no such variable} - ? {C create c3 -y 1 -x 0} "::c3" + + # Did the object survive the error? Should not. + ? {::nsf::is object c2} 0 + + set ::_ "" + ? {C create c2} \ +"required argument 'x' is missing, should be: + ::c2 __configure -x /value/ -y /value/ ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" + + # Was the constructor called? Should not. ? {set ::_} "" - ? {c3 x} "0" + + # Did the object survive the error? Should not. + ? {::nsf::is object c2} 0 + + # The following should run through without erros + ? {C create c3 -y 1 -x 0} "::c3" + ? {set ::_} "passed args ''" + ? {c3 cget -x} "0" + + # + # incremental property adding vs. required + # + nx::Class create D + + ? {D create d1} ::d1 + ? {d1 configure} "" + + D property x:required + ? {d1 info configure} \ + "-x /value/ ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" + + ? {d1 configure} \ + "required argument 'x' is missing, should be: + ::d1 configure -x /value/ ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" + + ? {d1 configure -x 123} "" + ? {d1 cget -x} 123 + + ? {d1 configure} "" } + + + ::nsf::configure checkarguments on # -# nx::Test type any (or other typechecker) in combination with +# Test type any (or other typechecker) in combination with # substdefault via object parameter # -nx::Test case nsf-subdefault { +nx::test case nsf-subdefault { nx::Class create C { :property {n1 "[namespace tail [::nsf::self]]"} :property {n2:any "[namespace tail [::nsf::self]]"} :create c1 } - ? {c1 n1} c1 - ? {c1 n2} c1 + ? {c1 cget -n1} c1 + ? {c1 cget -n2} c1 } # -# nx::Test argument processing and namespace handling in nsf::procs +# Test argument processing and namespace handling in nsf::procs # -nx::Test case nsf-proc { +nx::test case nsf-proc { # # test inner namespace and handling of switches # @@ -1731,7 +1776,7 @@ nsf::proc -ad pass1 {-s:boolean} {foo -s=$s_p} } - nx::Test parameter count 1 + nx::test configure -count 1 ? {::nsf::mix} "::nsf-0-NULL" ? {::nsf::mix -per-object} "::nsf-1-NULL" ? {::nsf::mix -x true} "::nsf-0-true" @@ -1753,19 +1798,20 @@ return [namespace current]-[lsort [info vars]]-$html_p-$allow_complete_url_p } - nx::Test parameter count 1000 + nx::test configure -count 1000 ? {::ns1::pass1} "::ns1-0" ? {::ns1::pass1 -s} "::ns1-1" ? {::ns1::pass0} "::ns1-0" ? {::ns1::pass0 -s} "::ns1-1" } + # # Test argument processing and namespace handling in nsf::procs # -nx::Test case xotcl-list-notation { - nx::Test parameter count 1 +nx::test case xotcl-list-notation { + nx::test configure -count 1 package prefer latest package req XOTcl 2.0 @@ -1787,7 +1833,7 @@ # # Test parameter alias and parameter forwarder # -nx::Test case parameter-alias { +nx::test case parameter-alias { nx::Class create C { :property {x:alias} @@ -1803,13 +1849,13 @@ ? {c1 eval {set :x}} "x1" ? {c1 eval {set :foo}} "123 a b c F" ? {c1 eval {set :bar}} "aha" - ? {lsort [c1 info lookup methods -source application]} "D bar foo x" + ? {lsort [c1 info lookup methods -source application]} "bar foo x" } # # Test parameter alias and parameter forwarder with default value # -nx::Test case parameter-alias-default { +nx::test case parameter-alias-default { nx::Class create C { :property {x1:alias "hugo"} @@ -1825,16 +1871,18 @@ ? {c1 eval {set :foo}} "a habicht b c F" ? {c1 eval {set :x2}} "::c1" ? {lsort [c1 info lookup methods -source application]} "foo x1 x2" - ? {lsort [C info slot objects]} "::C::slot::F ::C::slot::x1 ::C::slot::x2" + ? {lsort [C info slots]} "::C::slot::F ::C::slot::x1 ::C::slot::x2" ? {::C::slot::x1 getParameterSpec} {-x1:alias hugo} ? {::C::slot::x2 getParameterSpec} {-x2:alias,substdefault {[self]}} } + + # # Test interactions between per-object-mixins and objectparameters # (case without per-object property) # -nx::Test case parameter-object-mixin-dependency { +nx::test case parameter-object-mixin-dependency { nx::Class create C { :property a1 :create c1 @@ -1843,13 +1891,13 @@ nx::Class create M1 {:property b1:required} nx::Class create M2 {:property b2:required} - ? {c1 eval :__objectparameter} "-a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" + ? {c1 eval :__objectparameter} "-a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" - c1 mixin M1 + c1 object mixin M1 ? {c1 info precedence} "::M1 ::C ::nx::Object" - ? {c1 eval :__objectparameter} "-b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" + ? {c1 eval :__objectparameter} "-b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" # # Invalidate the object parameter and expect that the per-class @@ -1858,17 +1906,16 @@ ::nsf::parameter:invalidate::classcache C # - # We have now "-b1:required" in the object parameters. + # We have now "-b1:required" in the configure parameters. # - # TODO: Actually we should enforce it. We could check, if the - # associate variable is already set, but this does not work for - # aliases.... we could track, if the slot is already initialized for - # this object. This can be a potentially huge table containing - # potentially all objects (relation slots). Maybe keep the table - # just for "required" parameters? or look for an approach based on - # epoch counting? + # NSF checks, if the associated variable is already set, but + # this does not work for aliases.... we could track whether or + # not a required parameter was already provided, but that + # requires most likely a more general handling. # - ? {c1 configure -a1 x} "" + ? {c1 configure -a1 x} \ +"required argument 'b1' is missing, should be: + ::c1 configure -b1 /value/ ?-a1 /value/? ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" # # The object parameter based on the per-object-mixin must not be @@ -1886,86 +1933,92 @@ # we have now per-object mixin of M1, we should have "-b1" but no # "-b2" # - ? {c1 info mixin classes} ::M1 - ? {c1 cget -mixin} ::M1 - ? {c1 info lookup parameter names b*} "b1" + ? {c1 info object mixin classes} ::M1 + ? {c1 cget -object-mixin} ::M1 + ? {c1 info lookup configure parameters b*} "-b1:required" # # add one more mixin. # - c1 mixin add ::M2 - ? {c1 info mixin classes} {::M2 ::M1} - ? {c1 cget -mixin} {::M2 ::M1} - ? {c1 info lookup parameter syntax b1} "-b1 value" - ? {c1 info lookup parameter syntax b2} "-b2 value" - ? {lsort [c1 info lookup parameter names b*]} "b1 b2" + c1 object mixin add ::M2 + ? {c1 info object mixin classes} {::M2 ::M1} + ? {c1 cget -object-mixin} {::M2 ::M1} + ? {c1 info lookup configure parameters b1} "-b1:required" + ? {c1 info lookup configure parameters b2} "-b2:required" + ? {lsort [c1 info lookup configure parameters b*]} "-b1:required -b2:required" # # drop the mixins, the b* properties should be gone. # - c1 mixin "" - ? {c1 info mixin classes} {} - ? {lsort [c1 info lookup parameter names b*]} "" + c1 object mixin "" + ? {c1 info object mixin classes} {} + ? {lsort [c1 info lookup configure parameters b*]} "" # # add M1 again # - c1 mixin add ::M1 - ? {c1 info mixin classes} {::M1} - ? {c1 info lookup parameter syntax b1} "-b1 value" - ? {lsort [c1 info lookup parameter names b*]} "b1" + c1 object mixin add ::M1 + ? {c1 info object mixin classes} {::M1} + ? {c1 info lookup configure parameters b1} "-b1:required" + ? {lsort [c1 info lookup configure parameters b*]} "-b1:required" # # We have the per-object cache; adding a per-object property should # flush the cache # - c1 property bo1 - ? {lsort [c1 info lookup parameter names b*]} "b1 bo1" - c1 property bo2 - ? {lsort [c1 info lookup parameter names b*]} "b1 bo1 bo2" + c1 object property bo1 + ? {lsort [c1 info lookup configure parameters b*]} "-b1:required -bo1" + c1 object property bo2 + ? {lsort [c1 info lookup configure parameters b*]} "-b1:required -bo1 -bo2" # # property deletion should invalidate the cache as well # - c1 delete property bo2 - ? {lsort [c1 info lookup parameter names b*]} "b1 bo1" + c1 delete object property bo2 + ? {lsort [c1 info lookup configure parameters b*]} "-b1:required -bo1" } # # Test interactions between per-object-mixins and objectparameters # (case with per-object property) # -nx::Test case parameter-object-mixin-dependency-object-property { +nx::test case parameter-object-mixin-dependency-object-property { nx::Class create C { :property a1 :create c1 { - :property a2 + :object property a2 } } nx::Class create D -superclass C nx::Class create M {:property b1:required} - c1 mixin M + c1 object mixin M ? {c1 info precedence} "::M ::C ::nx::Object" - ? {C info slot objects -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" + ? {C info slots -closure} \ + "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::__initblock ::nx::Object::slot::noinit ::nx::Object::slot::object-mixin ::nx::Object::slot::class ::nx::Object::slot::object-filter" - ? {c1 eval :__objectparameter} "-a2 -b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" + ? {c1 eval :__objectparameter} \ + "-a2 -b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" # # invalidate object parameter and expect that the per-class mixin # does not harm # ::nsf::parameter:invalidate::classcache C - c1 __configure -a1 x + ? {c1 __configure -a1 x} \ +"required argument 'b1' is missing, should be: + ::c1 __configure ?-a2 /value/? -b1 /value/ ?-a1 /value/? ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" ? {c1 info precedence} "::M ::C ::nx::Object" - ? {C info slot objects -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" + ? {C info slots -closure} \ + "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::__initblock ::nx::Object::slot::noinit ::nx::Object::slot::object-mixin ::nx::Object::slot::class ::nx::Object::slot::object-filter" - ? {c1 eval :__objectparameter} "-a2 -b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,0..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,0..n __initcmd:initcmd,optional,noleadingdash" + ? {c1 eval :__objectparameter} "-a2 -b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,0..n __initblock:cmd,optional,noleadingdash" + # should not require b1 ? {C create c2} ::c2 @@ -1976,14 +2029,14 @@ # # Test integer, wideinteger and bignums # -nx::Test parameter count 1000 -nx::Test case bignums { +nx::test configure -count 1000 +nx::test case bignums { ::nx::Object create o { - :public method foo {x:int} { return $x } - :public method foo32 {x:int32} { return $x } - :public method bar {x:wideinteger} { return $x } - :public method baz {x:double} { return $x } + :public object method foo {x:int} { return $x } + :public object method foo32 {x:int32} { return $x } + :public object method bar {x:wideinteger} { return $x } + :public object method baz {x:double} { return $x } } # @@ -2057,12 +2110,12 @@ } -nx::Test case reconfigure-perobj-default { +nx::test case reconfigure-perobj-default { nx::Object create o ? {o eval {info exists :a}} 0 - o property {a oldvalue} + o object property {a oldvalue} ? {o eval {info exists :a}} 1 - ? {o a} oldvalue + ? {o cget -a} oldvalue # # By unsetting the var, upon recreating the property slot (or # calling reconfigure upon the property) we can trigger @@ -2073,19 +2126,19 @@ # # re-assignment of the default is handled by init # - o property {a newvalue} + o object property {a newvalue} ? {o eval {info exists :a}} 1 - ? {o a} newvalue + ? {o cget -a} newvalue o eval {unset :a} ? {o eval {info exists :a}} 0 - [o info slot objects a] default anothervalue + [o info object slots a] default anothervalue ? {o eval {info exists :a}} 0 # # re-assignment must be requested by a reconfigure call # - [o info slot objects a] reconfigure + [o info object slots a] reconfigure ? {o eval {info exists :a}} 1 - ? {o a} anothervalue + ? {o cget -a} anothervalue } # @@ -2128,53 +2181,53 @@ # # test object level property and variable # -nx::Test case object-level-variable { +nx::test case object-level-variable { nx::Object create ::enterprise { # just to get a reference value for the timing ? [list [self] eval {set :dummy 1}] "1" # set 2 variables, one via variable, one via property - ? [list [self] variable -nocomplain captain1 "James Kirk"] "" - ? [list [self] property -nocomplain [list captain2 "Jean Luc"]] "::enterprise::captain2" + ? [list [self] object variable -nocomplain captain1 "James Kirk"] "" + ? [list [self] object property -nocomplain [list captain2 "Jean Luc"]] "" # in both cases, we expect instance variables ? [list [self] eval {set :captain1}] "James Kirk" ? [list [self] eval {set :captain2}] "Jean Luc" # just for the property, we have accessors ? [list [self] info lookup method captain1] "" - ? [list [self] info lookup method captain2] "::enterprise::captain2" + ? [list [self] info lookup method captain2] "" # set variable with a value checker - ? [list [self] variable -nocomplain x1:int 1] "" - ? [list [self] property -nocomplain [list x2:int 2]] "::enterprise::x2" + ? [list [self] object variable -nocomplain x1:int 1] "" + ? [list [self] object property -nocomplain [list x2:int 2]] "" # set variable with a value checker and an invalid value - ? [list [self] variable y1:int a] {expected integer but got "a"} - ? [list [self] property [list y2:int b]] {expected integer but got "b"} + ? [list [self] object variable y1:int a] {expected integer but got "a"} + ? [list [self] object property [list y2:int b]] {expected integer but got "b" for parameter "y2"} # set variable again, without -nocomplain - ? [list [self] variable x1:int 1] {object ::enterprise has already an instance variable named 'x1'} - ? [list [self] property [list x2:int 2]] {object ::enterprise has already an instance variable named 'x2'} + ? [list [self] object variable x1:int 1] {object ::enterprise has already an instance variable named 'x1'} + ? [list [self] object property [list x2:int 2]] {object ::enterprise has already an instance variable named 'x2'} # set variable with a value checker, multiple - ? [list [self] variable -nocomplain xm1:int,1..n {1 2 3}] "" - ? [list [self] property -nocomplain [list xm2:int,1..n {1 2 3}]] "::enterprise::xm2" + ? [list [self] object variable -nocomplain xm1:int,1..n {1 2 3}] "" + ? [list [self] object property -nocomplain [list xm2:int,1..n {1 2 3}]] "" # in both cases, we expect instance variables ? [list [self] eval {set :xm1}] "1 2 3" ? [list [self] eval {set :xm2}] "1 2 3" # set variable with a value checker, multiple with invalid value - ? [list [self] variable -nocomplain xm1:int,1..n {1 2a 3}] \ + ? [list [self] object variable -nocomplain xm1:int,1..n {1 2a 3}] \ {invalid value in "1 2a 3": expected integer but got "2a"} - ? [list [self] property -nocomplain [list xm2:int,1..n {1 2a 3}]] \ - {invalid value in "1 2a 3": expected integer but got "2a"} + ? [list [self] object property -nocomplain [list xm2:int,1..n {1 2a 3}]] \ + {invalid value in "1 2a 3": expected integer but got "2a" for parameter "xm2"} # useless definition - ? [list [self] variable dummy:int] \ + ? [list [self] object variable dummy:int] \ {variable definition for 'dummy' (without value and accessor) is useless} # @@ -2191,19 +2244,18 @@ # # Test usage of application specific converter in "variable" and # "property"; invalid value - ? [list [self] variable -nocomplain r1:range,arg=1-10 11] \ + ? [list [self] object variable -nocomplain r1:range,arg=1-10 11] \ {value '11' of parameter value not between 1 and 10} - ? [list [self] property -nocomplain [list r2:range,arg=1-10 11]] \ - {value '11' of parameter value not between 1 and 10} + ? [list [self] object property -nocomplain [list r2:range,arg=1-10 11]] \ + {value '11' of parameter r2 not between 1 and 10} # valid value - ? [list [self] variable -nocomplain r1:range,arg=1-10 5] "" - ? [list [self] property -nocomplain [list r2:range,arg=1-10 5]] \ - {::enterprise::r2} + ? [list [self] object variable -nocomplain r1:range,arg=1-10 5] "" + ? [list [self] object property -nocomplain [list r2:range,arg=1-10 5]] "" # testing incremental - ? [list [self] variable -incremental -nocomplain i:int,0..* {}] "::enterprise::i" - ? [list [self] property -incremental -nocomplain j:int,0..* {}] "::enterprise::j" + ? [list [self] object variable -incremental -nocomplain i:int,0..* {}] "::enterprise::i" + ? [list [self] object property -incremental -nocomplain j:int,0..* {}] "::enterprise::j" :i add 1 :j add 1 ? [list [self] i] "1" @@ -2218,29 +2270,29 @@ nx::Class create C { # set 2 class variables, one via variable, one via property - ? [list [self] class variable -nocomplain v "v0"] "" - ? [list [self] class property -nocomplain [list a "a0"]] "::C::a" + ? [list [self] object variable -nocomplain v "v0"] "" + ? [list [self] object property -nocomplain [list a "a0"]] "" # in both cases, we expect instance variables ? [list [self] eval {set :v}] "v0" ? [list [self] eval {set :a}] "a0" # check variable with value constraint - ? [list [self] class variable -nocomplain x:int "0"] "" - ? [list [self] class variable -nocomplain y:int "a0"] {expected integer but got "a0"} + ? [list [self] object variable -nocomplain x:int "0"] "" + ? [list [self] object variable -nocomplain y:int "a0"] {expected integer but got "a0"} } } # # test class level property and variable # -nx::Test case class-level-variable { +nx::test case class-level-variable { nx::Class create C { # define 2 class-level variables, one via variable, one via property :variable v v0 - :property {a a0} + :property -accessor public {a a0} # create an instance :create c1 @@ -2256,19 +2308,20 @@ # The parameter for v can be obtained via spec, but is not listed in # "info parameter syntax" or "info parameter definitions". # - ? {C info parameter list a} "-a" - ? {C info parameter definitions a} "{-a a0}" - ? {C info parameter syntax a} "?-a value?" +# ? {C info parameter list a} "-a" + ? {C info configure parameters a} "{-a a0}" +# ? {C info configure syntax a} "?-a /value/?" + ? {C info configure syntax} "/::C/ ?-a /value/? ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" - ? {C info parameter definitions v} "" - ? {C info slot definitions v} "{::C variable v v0}" - ? {C info parameter list v} "" - ? {C info parameter syntax v} "" + ? {C info configure parameters v} "" + ? {[C info slots v] definition} "::C variable -accessor none v v0" +# ? {C info parameter list v} "" +# ? {C info configure parameter v} "" ? {C create c2 -a 10} ::c2 ? {C create c2 -v 10} \ - {invalid non-positional argument '-v', valid are : -a, -volatile, -noinit, -mixin, -class, -filter; - should be "::c2 configure ?-a value? ?-volatile? ?-noinit? ?-mixin mixinreg ...? ?-class class? ?-filter filterreg ...? ?__initcmd?"} + {invalid non-positional argument '-v', valid are : -a, -volatile, -noinit, -object-mixin, -class, -object-filter; + should be "::c2 configure ?-a /value/? ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?"} # # We expect a setter for "a" but not for "v". @@ -2280,7 +2333,7 @@ # # test classes with single variable definitions, and illegal names # -nx::Test case single-variable { +nx::test case single-variable { ? {nx::Class create C { :variable v 1 :create c1 @@ -2295,12 +2348,12 @@ # # test deletion of class level property and variable # -nx::Test case delete-class-level-variable-and-property { +nx::test case delete-class-level-variable-and-property { nx::Class create C { # define 2 class-level variables, one via variable, one via property :variable v v0 - :property {a a0} + :property -accessor public {a a0} # create an instance :create c1 @@ -2310,8 +2363,8 @@ ? {lsort [c1 info vars]} {a v} # ... and we expect an object parameter for a but not for v ... - ? {C info parameter list a} "-a" - ? {C info parameter list v} "" + ? {C info configure parameters a} "{-a a0}" + ? {C info configure parameters v} "" # ... and we expect a setter for a but not for v ? {c1 info lookup method a} "::nsf::classes::C::a" @@ -2321,7 +2374,7 @@ # the object parameter and setters for "a" will be gone C delete variable v C delete property a - ? {C info parameter list a} "" + ? {C info configure parameters a} "" ? {c1 info lookup method a} "" # already created instance variables will continue to exist @@ -2335,12 +2388,12 @@ # # test deletion of class level property and variable # -nx::Test case delete-object-level-variable-and-property { +nx::test case delete-object-level-variable-and-property { nx::Object create o { # define 2 object-level variables, one via variable, one via property - :variable v v0 - :property {a a0} + :object variable v v0 + :object property -accessor public {a a0} } # the instance of C will have the two variables set ... @@ -2353,8 +2406,8 @@ # nx::Object-level attributes and variables set und unset instance # variables. If we delete an object-level property or variable, # the setters for "a" will be unset. - o delete variable v - o delete property a + o delete object variable v + o delete object property a ? {o info lookup method a} "" # Both instance variables are unset @@ -2365,12 +2418,12 @@ # Testing object parameters of type "switch" # -nx::Test case object-parameter-switch { +nx::test case object-parameter-switch { # Create a class with an property of type switch and an instance of # the class ? {::nx::Class create C { - :property foo:switch + :property -accessor public foo:switch :create c1 }} "::C" @@ -2414,95 +2467,98 @@ # boolean, except that without the specified value argument # (variable foo below), it sets the the variable to "false". ? {::nx::Object create o1 { - :variable foo:switch - :variable bar:switch 1 + :object variable foo:switch + :object variable bar:switch 1 }} ::o1 ? {o1 eval {set :foo}} 0 ? {o1 eval {set :bar}} 1 } # # Test slots with configparameter true/false, accessor true/false -# against "info slot definitions" and "info parameter" +# against "slot definitions" and "info parameter" # -nx::Test case class-info-slots-types { +nx::test case class-info-slots-types { # # "/cls/ info slot ..." shows all slots, including variables # "/cls/ info parameter ..." shows the parameter available for object parameterization # nx::Class create C { - # variable has no config parameter and no accessor + # variable has no configure parameter and no accessor :variable v 100 } - # "v" does NOT show up in "info parameter" - ? {C info parameter list} "-volatile -noinit -mixin -class -filter __initcmd" - ? {C info parameter names} "volatile noinit mixin class filter __initcmd" + # "v" does NOT show up in "info configure parameters" + ? {C info configure parameters v} "" +# ? {C info parameter names} "volatile noinit object-mixin class object-filter __initblock" # "v" does show up in "info slot ..." - ? {C info slot objects} "::C::slot::v" - ? {C info slot definitions} "{::C variable v 100}" + ? {C info slots} "::C::slot::v" + ? {::C::slot::v definition} "::C variable -accessor none v 100" nx::Class create D { - :property {p0 200} + :property -accessor public {p0 200} :property -accessor none {p1 201} :property -accessor none {p2:noconfig 202} - :property {p3:noconfig 203} + :property -accessor public {p3:noconfig 203} } # "p2" and "p3" do NOT show up in "info parameter" - ? {D info parameter list} "-p0 -p1 -volatile -noinit -mixin -class -filter __initcmd" - ? {D info parameter names} "p0 p1 volatile noinit mixin class filter __initcmd" + ? {D info configure parameters p*} "{-p0 200} {-p1 201}" # "p1" and "p2" do NOT show up in "info methods" ? {D info methods} "p0 p3" # all properties show up in "info slot" - ? {D info slot objects} "::D::slot::p0 ::D::slot::p1 ::D::slot::p2 ::D::slot::p3" - ? {D info slot definitions} "{::D property {p0 200}} {::D property -accessor none {p1 201}} {::D variable p2 202} {::D variable -accessor public p3 203}" + ? {D info slots} "::D::slot::p0 ::D::slot::p1 ::D::slot::p2 ::D::slot::p3" + #? {D info slot definitions} "{::D property {p0 200}} {::D property -accessor none {p1 201}} {::D variable p2 202} {::D variable -accessor public p3 203}" #? {D info properties} "{p0 200} {p1 201} {p2:noconfig 202} {p3:noconfig 203}" } -nx::Test case object-info-slots-types { +nx::test case object-info-slots-types { # # "/obj/ info slot ..." shows all slots, including variables # nx::Object create o1 { # plain object variable has no slot object - :variable v0 100 + :object variable v0 100 # In case we require an accessor or e.g. incremental, slot objects # are created; incremental implies accessor - :variable -accessor public v1 100 - :variable -incremental v2 100 + :object variable -accessor public v1 100 + :object variable -incremental v2 100 } # only the variables with slots show up in "info slot ..." - ? {o1 info slot objects} "::o1::per-object-slot::v2 ::o1::per-object-slot::v1" - ? {o1 info slot definitions} "{::o1 variable -accessor public v2:0..n 100} {::o1 variable -accessor public v1 100}" + ? {o1 info object slots} "::o1::per-object-slot::v2 ::o1::per-object-slot::v1" + ? {::o1::per-object-slot::v2 definition} "::o1 object variable -accessor public v2:0..n 100" + ? {::o1::per-object-slot::v1 definition} "::o1 object variable -accessor public v1 100" nx::Object create o2 { - :property {p0 200} - :property -accessor none {p1 201} - :property -accessor none {p2:noconfig 202} - :property {p3:noconfig 203} + :object property -accessor public {p0 200} + :object property -accessor none {p1 201} + :object property -accessor none {p2:noconfig 202} + :object property -accessor public {p3:noconfig 203} } # "p1" and "p2" do NOT show up in "info methods" - ? {o2 info methods} "p0 p3" + ? {o2 info object methods} "p0 p3" # all properties with slots show up in "info slot" - ? {o2 info slot objects} "::o2::per-object-slot::p0 ::o2::per-object-slot::p1 ::o2::per-object-slot::p3" - ? {o2 info slot definitions} "{::o2 property {p0 200}} {::o2 property -accessor none {p1 201}} {::o2 variable -accessor public p3 203}" + ? {o2 info object slots} "::o2::per-object-slot::p0 ::o2::per-object-slot::p1 ::o2::per-object-slot::p3" + ? {[o2 info object slots p0] definition} "::o2 object property -accessor public {p0 200}" + ? {[o2 info object slots p1] definition} "::o2 object property -accessor none {p1 201}" + ? {[o2 info object slots p3] definition} "::o2 object variable -accessor public p3 203" + #? {o2 info properties} "{p0 200} {p1 201} {p3:noconfig 203}" } # # testing method properties # -nx::Test case properties { +nx::test case properties { # simple properties #nx::Class create Foo -properties {a {b 1}} @@ -2511,7 +2567,8 @@ :property {b 1} } - ? {Foo info slot definitions} "{::Foo property a} {::Foo property {b 1}}" + ? {[Foo info slots a] definition} "::Foo property -accessor none a" + ? {[Foo info slots b] definition} "::Foo property -accessor none {b 1}" #? {Foo info properties} "a {b 1}" @@ -2520,22 +2577,26 @@ :property a:boolean :property {b:integer 1} } - ? {Foo info slot definitions} "{::Foo property a:boolean} {::Foo property {b:integer 1}}" + ? {[Foo info slots a] definition} "::Foo property -accessor none a:boolean" + ? {[Foo info slots b] definition} "::Foo property -accessor none {b:integer 1}" # required/optional properties nx::Class create Foo { :property a:required :property b:boolean,required } - ? {Foo info slot definitions} "{::Foo property a:required} {::Foo property b:boolean,required}" + ? {[Foo info slots a] definition} "::Foo property -accessor none a:required" + ? {[Foo info slots b] definition} "::Foo property -accessor none b:boolean,required" # properties with multiplicity nx::Class create Foo { :property {ints:integer,0..n ""} :property objs:object,1..n :property obj:object,0..1 } - ? {Foo info slot definitions} "{::Foo property objs:object,1..n} {::Foo property {ints:integer,0..n {}}} {::Foo property obj:object,0..1}" + ? {[Foo info slots objs] definition} "::Foo property -accessor none objs:object,1..n" + ? {[Foo info slots ints] definition} "::Foo property -accessor none {ints:integer,0..n {}}" + ? {[Foo info slots obj] definition} "::Foo property -accessor none obj:object,0..1" } # @@ -2547,10 +2608,10 @@ # Note that the order, in which is the arguments are provided is not # significant for the evaluation order. # -nx::Test case side-effect-set-value { +nx::test case side-effect-set-value { nx::Class create C { - :public class method setObjectParams {spec} { + :public object method setObjectParams {spec} { :protected method __objectparameter {} [list return $spec] ::nsf::parameter:invalidate::classcache [self] } @@ -2568,8 +2629,8 @@ ? {[C new -second Y] eval {set :first}} Y "side-effect determines value" } -nx::Test case xotcl-configure-method { - nx::Test parameter count 1 +nx::test case xotcl-configure-method { + nx::test configure -count 1 package prefer latest package req XOTcl 2.0 @@ -2584,11 +2645,11 @@ # # Test forwarding to slot object, when assign is overloaded # -nx::Test case forward-to-assign { +nx::test case forward-to-assign { set ::slotcalls 0 nx::Class create Foo { - :property bar { - :public method assign { object property value } { + :property -accessor public bar { + :public object method assign { object property value } { incr ::slotcalls 1 nsf::var::set $object $property $value } @@ -2611,8 +2672,8 @@ # test cases for default set ::slotcalls 0 nx::Class create Foo { - :property {baz 1} { - :public method assign { object property value } { + :property -accessor public {baz 1} { + :public object method assign { object property value } { incr ::slotcalls 1 nsf::var::set $object $property $value } @@ -2639,12 +2700,12 @@ # # Test forwarding to slot vs. accessor none # -nx::Test case forward-to-assign { +nx::test case forward-to-assign { set ::slotcalls 0 ? {nx::Class create Foo { :property -accessor none bar { - :public method assign { object property value } { + :public object method assign { object property value } { incr ::slotcalls 1 nsf::var::set $object $property $value } @@ -2658,7 +2719,7 @@ # test cases for default nx::Class create Foo { :property -accessor none {baz 1} { - :public method assign { object property value } { + :public object method assign { object property value } { incr ::slotcalls 1 nsf::var::set $object $property $value } @@ -2679,12 +2740,12 @@ # # Test slot initialize # -nx::Test case forward-to-incremental { +nx::test case forward-to-incremental { set ::slotcalls 0 ? {nx::Class create Foo { :property bar { - :public method initialize { object property } { + :public object method initialize { object property } { incr ::slotcalls 1 } }} @@ -2702,14 +2763,14 @@ # property named "list" leads to a call to the container object # ::Test2::slot::list instead of the intended ::list. # -nx::Test case slot-container-name-interaction { +nx::test case slot-container-name-interaction { nx::Class create Test2 { - :property list { - :public method assign { obj var val } { + :property -accessor public list { + :public object method assign { obj var val } { nsf::var::set $obj $var [list $obj $var $val] } - :method unknown { val obj var args } { + :object method unknown { val obj var args } { return unknown } } @@ -2721,7 +2782,7 @@ ? {t2 list this should call unknown} "unknown" } -nx::Test case object-level-defaults { +nx::test case object-level-defaults { # # In the scenario below, setCheckedInstVar is executed and performs # an ::nsf::is value check on the default value. However, given the @@ -2731,16 +2792,116 @@ # 'invalid value constraints # "slot=::objekt::per-object-slot::a,slotassign"' # - nx::Object create objekt - ? {objekt eval {info exists :a}} 0 + nx::Object create o + ? {o eval {info exists :a}} 0 ? {catch { - objekt variable -accessor public -initblock { - :public method assign args { + o object variable -accessor public -initblock { + :public object method assign args { incr :assignCalled next } } a 1}} 0 - ? {objekt eval {info exists :a}} 1 - ? {objekt eval {info exists :assignCalled}} 0; # !!! should be 1 - ? {objekt a} 1 -} \ No newline at end of file + ? {o eval {info exists :a}} 1 + ? {o eval {info exists :assignCalled}} 0; # !!! should be 1 + ? {o a} 1 +} + +nx::test case cmd-error-propagation { + ? {nx::Object new { + error "bow-wow" + }} "bow-wow" + + ? {nx::Object new { + :object method foo {} { + error "bow-wow" + } + :foo + }} "bow-wow" + + ? {nx::Object new { + # Note: Creating a slot causes a destroy() to perform some cascading + # operations which eventually reset the interp result at some + # point. + :object property x + :object method foo {} { error "bow-wow" } + :foo + }} "bow-wow" + + ? {nx::Object new { + :object method destroy {} { + # This (inner) error message is swallowed and written to stderr + # directly. The original (outer) error message is preserved. + error "BOW-WOW" + } + :object method foo {} { error "bow-wow" } + :foo + }} "bow-wow" + +} + +# +# test argument processing in nsf::proc with checkalways +# + +nx::test case nsf-proc-checkalways { + + # + # one proc with checkalways + # + nsf::proc p1 {-x:integer} { return $x} + nsf::proc -checkalways p2 {-x:integer} { return $x} + + ? {p1 -x 100} 100 + ? {p1 -x a100} {expected integer but got "a100" for parameter "-x"} + + ? {p2 -x 100} 100 + ? {p2 -x a100} {expected integer but got "a100" for parameter "-x"} + + nsf::configure checkarguments off + ? {p1 -x a100} a100 + ? {p2 -x a100} {expected integer but got "a100" for parameter "-x"} + + nsf::configure checkarguments on +} + +# +# test argument processing in methods with checkalways +# + +nx::test case nsf-method-checkalways { + + # + # one method with checkalways + # + + nx::Class create C { + :public method m1 {-x:integer} { return $x} + :public method m2 {-x:integer} -checkalways { return $x} + + :public object method om1 {-x:integer} { return $x} + :public object method om2 {-x:integer} -checkalways { return $x} + + :create c1 + } + + ? {c1 m1 -x 100} 100 + ? {c1 m2 -x 100} 100 + + ? {c1 m1 -x a100} {expected integer but got "a100" for parameter "-x"} + ? {c1 m2 -x a100} {expected integer but got "a100" for parameter "-x"} + + ? {C om1 -x 200} 200 + ? {C om2 -x 200} 200 + + ? {C om1 -x a} {expected integer but got "a" for parameter "-x"} + ? {C om2 -x a} {expected integer but got "a" for parameter "-x"} + + nsf::configure checkarguments off + ? {c1 m1 -x a100} a100 + ? {c1 m2 -x a100} {expected integer but got "a100" for parameter "-x"} + + ? {C om1 -x a} a + ? {C om2 -x a} {expected integer but got "a" for parameter "-x"} + + nsf::configure checkarguments on +}