You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
424 lines
18 KiB
424 lines
18 KiB
|
|
package require tcltest |
|
|
|
namespace eval ::testspace { |
|
namespace import ::tcltest::* |
|
variable common { |
|
set result "" |
|
} |
|
|
|
|
|
test parse_withdef_leaders_ordering_defaults {Test ordering of leaders when some have defaults}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {a b} withdef @leaders x {y -default 1}] |
|
set vals [dict get $argd leaders] |
|
set result $vals |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
x a y b |
|
] |
|
|
|
test parse_withdef_option_ordering_defaults {Test ordering of options when some have defaults}\ |
|
-setup $common -body { |
|
#for consistency with leaders and values dicts - try to maintain definition order for options too |
|
set argd [punk::args::parse {-x a -y b} withdef @opts -x {-y -default 1}] |
|
set vals [dict get $argd opts] |
|
set result $vals |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
-x a -y b |
|
] |
|
|
|
test parse_withdef_option_ordering_defaults2 {Test ordering of options when some have defaults and -any is true}\ |
|
-setup $common -body { |
|
#for consistency with leaders and values dicts - try to maintain definition order for options too |
|
set argd [punk::args::parse {-blah etc -x a -y b -solo -z c} withdef {@opts -any 1} -x {-y -default 1} {-solo -type none} -z] |
|
set vals [dict get $argd opts] |
|
set result $vals |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
-x a -y b -solo 1 -z c -blah etc |
|
] |
|
|
|
test parse_withdef_values_ordering_defaults {Test ordering of values when some have defaults}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {a b} withdef @values x {y -default 1}] |
|
set vals [dict get $argd values] |
|
set result $vals |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
x a y b |
|
] |
|
|
|
test parse_withdef_values_no_phantom_default {Test no phantom default with intermediate optional argument}\ |
|
-setup $common -body { |
|
#y was not received, and has no default, so should not appear in 'values' element |
|
#we don't want to see {x a y {} z b} |
|
set argd [punk::args::parse {a b} withdef @values x {y -optional 1} z] |
|
set vals [dict get $argd values] |
|
set result $vals |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
x a z b |
|
] |
|
test parse_withdef_value_multiple1 {Test named value with -multiple true and required trailing value}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {a b c} withdef @values {arg -type string -multiple 1} endval] |
|
lappend result [dict get $argd leaders] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{} {arg {a b} endval c} |
|
] |
|
|
|
test parse_withdef_value_multiple2 {Test named value followed by named value with -multiple true and a default}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {a b c} withdef @values A {arg -type string -multiple 1 -default X}] |
|
lappend result [dict get $argd leaders] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{} {A a arg {b c}} |
|
] |
|
|
|
test parse_withdef_leader_multiple1 {Test named leader with -multiple true and 1 value required}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {a b c} withdef {@leaders -min 0} {L -multiple 1} {@values -min 1 -max 1} V] |
|
lappend result [dict get $argd leaders] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{L {a b}} {V c} |
|
] |
|
|
|
test parse_withdef_leader_min_max1 {Test unnamed leaders with @leaders -min and -max}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {a b c d} withdef {@leaders -min 1 -max 3 -unnamed true} {@values -unnamed true} ] |
|
lappend result [dict get $argd leaders] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{0 a 1 b 2 c} {3 d} |
|
] |
|
test parse_withdef_leader_min_max_with_required_value {Test unnamed leaders with -min and -max followed by required unnamed value}\ |
|
-setup $common -body { |
|
#should not error - should allocate d to values |
|
set argd [punk::args::parse {a b c d} withdef {@leaders -min 1 -max 4 -unnamed true} {@values -min 1 -max 1 -unnamed true}] |
|
lappend result [dict get $argd leaders] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{0 a 1 b 2 c} {3 d} |
|
] |
|
|
|
test parse_withdef_leaderclause_trailing_optional_members_followed_by_value {Test that last leader clause with optional members works with following required value}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {a z} withdef {@leaders} {ldr -type {char ?int? ?int?}} {@values} val] |
|
lappend result [dict get $argd leaders] |
|
set argd [punk::args::parse {a 1 z} withdef {@leaders} {ldr -type {char ?int? ?int?}} {@values} val] |
|
lappend result [dict get $argd leaders] |
|
set argd [punk::args::parse {a 1 2 z} withdef {@leaders} {ldr -type {char ?int? ?int?}} {@values} val] |
|
lappend result [dict get $argd leaders] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{ldr {a {} {}}}\ |
|
{ldr {a 1 {}}}\ |
|
{ldr {a 1 2}}\ |
|
] |
|
test parse_withdef_leaderclause_trailing_optional_members_followed_by_optional_leader_and_value {Test that last leader clause with optional members works with following required value}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {x y z} withdef {@leaders} {ldr -type {char ?int? ?int?}} {ldr2 -type string -optional 1} {@values} val] |
|
lappend result [dict get $argd leaders] |
|
|
|
set argd [punk::args::parse {x 1 z} withdef {@leaders} {ldr -type {char ?int? ?int?}} {ldr2 -type string -optional 1} {@values} val] |
|
lappend result [dict get $argd leaders] |
|
|
|
set argd [punk::args::parse {x 1 y z} withdef {@leaders} {ldr -type {char ?int? ?int?}} {ldr2 -type string -optional 1} {@values} val] |
|
lappend result [dict get $argd leaders] |
|
|
|
set argd [punk::args::parse {x 1 2 y z} withdef {@leaders} {ldr -type {char ?int? ?int?}} {ldr2 -type string -optional 1} {@values} val] |
|
lappend result [dict get $argd leaders] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{ldr {x {} {}} ldr2 y}\ |
|
{ldr {x 1 {}}}\ |
|
{ldr {x 1 {}} ldr2 y}\ |
|
{ldr {x 1 2} ldr2 y}\ |
|
] |
|
|
|
test parse_withdef_value_clause_typedefaults {test clause with optional element and -typedefaults specified}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {1} withdef @values {v -type {int ?int?} -typedefaults {"" 12}}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{v {1 12}} |
|
] |
|
test parse_withdef_value_clause_typedefaults2 {test clause with optional element and -typedefaults specified - entire arg optional -default}\ |
|
-setup $common -body { |
|
#-default has deliberate type violations - should still produce result as default is not meant to be subject to validation. |
|
set argd [punk::args::parse {} withdef @values {v -type {int ?int?} -typedefaults {"" 12} -default {x y} -optional 1}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{v {x y}} |
|
] |
|
|
|
test parse_withdef_value_clause_defaulted_optional {test clause with optional element and -typedefaults not matching all types}\ |
|
-setup $common -body { |
|
#-typedefaults has deliberate type violations - should still produce result as defaulted value is not meant to be subject to validation. |
|
#(uses the ?defaulted-<type>? typelist mechanism) |
|
set argd [punk::args::parse {1} withdef @values {v -type {int ?int?} -typedefaults {"" xxx}}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{v {1 xxx}} |
|
] |
|
test parse_withdef_value_clause_missing_optional {test clause with optional element and no -typedefaults}\ |
|
-setup $common -body { |
|
#an optional clause member will be replaced with empty string when missing if there is no -typedefaults |
|
#This empty string needs to be in the result, but not be subject to validation |
|
#(uses the ?ommitted-<type>? typelist mechanism) |
|
set argd [punk::args::parse {1} withdef @values {v -type {int ?int?}}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{v {1 {}}} |
|
] |
|
|
|
test parse_withdef_value_clause_arity1 {Test value clause result with optional member}\ |
|
-setup $common -body { |
|
#default for missing optional member ?literal(then)? should be empty string |
|
set argd [punk::args::parse {elseif 1 x} withdef {@values} {"elseifclause" -type {literal(elseif) expr ?literal(then)? any}}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{elseifclause {elseif 1 {} x}} |
|
] |
|
|
|
test parse_withdef_value_clause_missing_optional_multiple {test -multiple true clauses with optional members}\ |
|
-setup $common -body { |
|
#this test is applicable to situations such as the elseif clause in the ::if definition: |
|
#e.g literal(elseif) expr ?literal(then)? script |
|
#the 'then' needs to be omitable arbitrarily in a list of elseif clauses |
|
|
|
#first test with all values supplied |
|
set argd [punk::args::parse {x 1 y x 2 y} withdef @values {triple -type {literal(x) ?int? literal(y)} -multiple 1}] |
|
lappend result [dict get $argd values] |
|
|
|
#missing value in second instance only |
|
set argd [punk::args::parse {x 1 y x y} withdef @values {triple -type {literal(x) ?int? literal(y)} -multiple 1}] |
|
lappend result [dict get $argd values] |
|
|
|
#missing value in first instance only |
|
#this can trigger a problem whereby the missing value in the first instance (which is empty string) gets processed in validation against 'int' and fails. |
|
#(updating of required type to a validationless value such as ... ?omitted-int? ... needs to be tied to specific clause instances) |
|
set argd [punk::args::parse {x y x 2 y} withdef @values {triple -type {literal(x) ?int? literal(y)} -multiple 1}] |
|
lappend result [dict get $argd values] |
|
|
|
#for completeness - no optional values supplid |
|
set argd [punk::args::parse {x y x y} withdef @values {triple -type {literal(x) ?int? literal(y)} -multiple 1}] |
|
lappend result [dict get $argd values] |
|
|
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{triple {{x 1 y} {x 2 y}}}\ |
|
{triple {{x 1 y} {x {} y}}}\ |
|
{triple {{x {} y} {x 2 y}}}\ |
|
{triple {{x {} y} {x {} y}}}\ |
|
] |
|
|
|
test parse_withdef_value_clause_arity2 {Test value clause result with missing optional member in optional clauses at tail}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {1 2 x 1 y} withdef {@values -unnamed true} {arg -multiple 1} {X -type {literal(x) any} -optional 1} {Y -type {literal(y) ?int?} -optional 1}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{arg {1 2} X {x 1} Y {y {}}} |
|
] |
|
|
|
test parse_withdef_value_clause_arity3 {Test value clause result with filled optional member in optional clauses at tail}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {1 2 x 1 y 2} withdef {@values -unnamed true} {arg -multiple 1} {X -type {literal(x) any} -optional 1} {Y -type {literal(y) ?int?} -optional 1}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{arg {1 2} X {x 1} Y {y 2}} |
|
] |
|
|
|
|
|
#todo - test L1 parsed to Lit1 not arg |
|
#punk::args::parse {x y L1} withdef @values (arg -multiple 1) {lit1 -type literal(L1) -optional 1} {lit2 -type literal(L2) -optional 1} |
|
|
|
#todo |
|
#see i -form 1 file copy -- x |
|
#fix end-of-opts handling |
|
#see also file copy -force x |
|
#(not handled by punk::args as the command does..) |
|
|
|
test parse_withdef_leader_clause {Test leader clause with multiple}\ |
|
-setup $common -body { |
|
#see for example ::tcl::dict::create which has a clause length of 2 |
|
set argd [punk::args::parse {k v e k1 v1 k2 v2} withdef {@leaders} {"key val etc" -type {any any any} -multiple 0} {"key val" -type {any any} -multiple 1} {@values -min 0 -max 0}] |
|
lappend result [dict get $argd leaders] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{{key val etc} {k v e} {key val} {{k1 v1} {k2 v2}}} |
|
] |
|
|
|
test parse_withdef_value_clause_multiple {Test value clause with multiple}\ |
|
-setup $common -body { |
|
#see for example ::tcl::dict::create which has a clause length of 2 |
|
set argd [punk::args::parse {k v e k1 v1 k2 v2} withdef {@values} {"key val etc" -type {any any any} -multiple 0} {"key val" -type {any any} -multiple 1}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{{key val etc} {k v e} {key val} {{k1 v1} {k2 v2}}} |
|
] |
|
|
|
test parse_withdef_value_clause_error {Test value clause with error due to not enough args for clause}\ |
|
-setup $common -body { |
|
#see for example ::tcl::dict::create which has a clause length of 2 |
|
if {[catch {punk::args::parse {k v} withdef {@values} {"key val etc" -type {any any any} -multiple 0}} emsg eopts]} { |
|
set expected [dict get $eopts -errorcode] |
|
if {[lindex $expected 0] eq "PUNKARGS" && [lindex $expected 1] eq "VALIDATION" && [lindex $expected 2 0] eq "missingrequiredvalue"} { |
|
lappend result "RECEIVED_EXPECTED_ERROR" |
|
} else { |
|
lappend result "WRONG_ERROR_RECEIVED - $expected (expected PUNKARGS VALIDATION {missingrequiredvalue ...} ..." |
|
} |
|
} else { |
|
lappend result "MISSING_REQUIRED_ERROR" |
|
} |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
"RECEIVED_EXPECTED_ERROR" |
|
] |
|
|
|
|
|
test parse_withdef_parsekey_repeat_ordering {Ensure last flag has precedence}\ |
|
-setup $common -body { |
|
#It must always be possible to override earlier (non -multiple) options |
|
set argd [punk::args::parse {-incr -decr -incr} withdef {@opts -type none -parsekey -direction} {-incr -typedefaults u} {-decr -typedefaults u}] |
|
lappend result [dict get $argd opts] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{-direction u} |
|
] |
|
|
|
test parse_withdef_leader_literalprefix_fullvalue {leaders - ensure supplying a prefix of literalprefix(test) returns full value 'test'}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {t} withdef @leaders {A -type literalprefix(test)}] |
|
lappend result [dict get $argd leaders] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{A test} |
|
] |
|
|
|
test parse_withdef_value_literalprefix_fullvalue {values - ensure supplying a prefix of literalprefix(test) returns full value 'test'}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {t} withdef @values {A -type literalprefix(test)}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{A test} |
|
] |
|
|
|
test parse_withdef_value_literal_alternates_case {values - ensure literal alternates work and preserve case}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {abc} withdef @values {A -type literal(abc)|literal(DeF)}] |
|
lappend result [dict get $argd values] |
|
set argd [punk::args::parse {DeF} withdef @values {A -type literal(abc)|literal(DeF)}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{A abc} {A DeF} |
|
] |
|
|
|
test parse_withdef_value_literalprefix_literal_combo {values - ensure literal/literalprefix prefix calculation works}\ |
|
-setup $common -body { |
|
set argd [punk::args::parse {test} withdef @values {A -type literalprefix(testinfo)|literal(test)}] |
|
lappend result [dict get $argd values] |
|
set argd [punk::args::parse {testin} withdef @values {A -type literalprefix(testinfo)|literal(test)}] |
|
lappend result [dict get $argd values] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{A test} {A testinfo} |
|
] |
|
|
|
test parse_withdef_value_alternatetypes {values - ensure alternate types (in simple-syntax) pass validation}\ |
|
-setup $common -body { |
|
#both should pass validation |
|
set argd [punk::args::parse {a} withdef @values {A -type int|char}] |
|
lappend result [dict get $argd values] |
|
set argd [punk::args::parse {11} withdef @values {A -type char|int}] |
|
lappend result [dict get $argd values] |
|
|
|
#todo RPN? |
|
#set argd [punk::args::parse {11} withdef @values {A -type {char int OR}}] |
|
#set argd [punk::args::parse {11} withdef @values {A -type {char int stringstartswith | OR}}] |
|
}\ |
|
-cleanup { |
|
}\ |
|
-result [list\ |
|
{A a} {A 11} |
|
] |
|
|
|
|
|
|
|
} |