if {[lsearch [namespace children] ::tcltest] == -1} {
    package require tcltest
    namespace import ::tcltest::*
}

try {
	package require parse_args
} on error {errmsg options} {
	puts stderr "Error loading parse_args:\n$options"
	return
}

test parse_args-1.1 {no args, dict mode} -body { #<<<
	parse_args::parse_args {} {} d
	set d
} -cleanup {
	unset -nocomplain d
} -result {}
#>>>
test parse_args-1.2 {no args, vars mode} -body { #<<<
	parse_args::parse_args {} {}
} -result {}
#>>>
test parse_args-2.1 {basic option, dict mode} -body { #<<<
	parse_args::parse_args {-foo bar} {-foo {}} d
	set d
} -cleanup {
	unset -nocomplain d
} -result {foo bar}
#>>>
test parse_args-2.2 {basic option, vars mode} -body { #<<<
	parse_args::parse_args {-foo bar} {-foo {}}
	set foo
} -cleanup {
	unset -nocomplain foo
} -result bar
#>>>
test parse_args-3.2 {option escape} -body { #<<<
	parse_args::parse_args {-foo bar -- -baz quux} {
		-foo	{}
		-bar	{}
		-baz	{-default def}
		a		{}
		b		{}
	}
	list $foo [info exists bar] $baz $a $b
} -cleanup {
	unset -nocomplain foo bar baz a b
} -result {bar 0 def -baz quux}
#>>>
test parse_args-3.3 {default positional arg} -body { #<<<
	parse_args::parse_args {a b} {
		-foo	{}
		first	{}
		second	{-default default_second}
		third	{-default default_third}
	}
	list $first $second $third
} -cleanup {
	unset -nocomplain foo first second third
} -result {a b default_third}
#>>>
test parse_args-4.1 {-all} -body { #<<<
	parse_args::parse_args {-ex first -foo a -iex First -ex second -iex Second -ex third -foo b} {
		-ex		{-all}
		-iex	{-all}
		-foo	{}
	}
	list $ex $iex $foo
} -cleanup {
	unset -nocomplain ex iex foo
} -result {{first second third} {First Second} b}
#>>>
test parse_args-4.2 {-all -multi} -body { #<<<
	parse_args::parse_args {-ascii -dictionary -ascii -increasing -decreasing} {
		-ascii			{-multi -name mode -all}
		-dictionary		{-multi -name mode}
		-increasing		{-multi -name order}
		-decreasing		{-multi -name order -all}
	}
	list $mode $order
} -cleanup {
	unset -nocomplain mode order
} -result {{ascii dictionary ascii} {increasing decreasing}}
#>>>
test parse_args-4.3 {-all} -body { #<<<
	parse_args::parse_args {-foo "hello, multi"} {
		-foo	{-all}
	}
	set foo
} -cleanup {
	unset -nocomplain foo
} -result {{hello, multi}}
#>>>
test parse_args-4.4 {-all, omitted, default} -body { #<<<
	parse_args::parse_args {} {
		-foo	{-all -default {}}
	}
	set foo
} -cleanup {
	unset -nocomplain foo
} -result {}
#>>>
test parse_args-10.1 {reject negative -args} -body { #<<<
	parse_args::parse_args {-foo bar} {
		-foo	{-args -1}
	}
	set foo
} -cleanup {
	unset -nocomplain foo
} -returnCodes error -result {-args cannot be negative}
#>>>
test parse_args-10.2 {-args 0, supplied} -body { #<<<
	parse_args::parse_args {-foo} {
		-foo	{-args 0}
	}
	set foo
} -cleanup {
	unset -nocomplain foo
} -result 1
#>>>
test parse_args-10.3 {-args 0, omitted} -body { #<<<
	parse_args::parse_args {-bar ""} {
		-foo	{-args 0}
		-bar	{}
	}
	set foo
} -cleanup {
	unset -nocomplain foo bar
} -result 0
#>>>
test parse_args-10.4 {-args 3, enough} -body { #<<<
	parse_args::parse_args {-foo a "b c" d e f g h i j} {
		-foo	{-args 3}
		-bar	{}
		p1		{}
		p2		{}
		args	{}
	}
	list $foo $p1 $p2 $args
} -cleanup {
	unset -nocomplain foo bar args
} -result [list [list a "b c" d] e f {g h i j}]
#>>>
test parse_args-10.5 {-args 3, too few} -body { #<<<
	parse_args::parse_args {-foo a "b c"} {
		-foo	{-args 3}
		-bar	{}
	}
} -cleanup {
	unset -nocomplain foo bar
} -returnCodes error -match glob -result *
#>>>
test parse_args-10.6 {-args all, omitted, no default} -body { #<<<
	parse_args::parse_args {-bar ""} {
		-foo	{-args all}
		-bar	{}
	}
	info exists foo
} -cleanup {
	unset -nocomplain foo bar
} -result 0
#>>>
test parse_args-10.7 {-args all, omitted, default} -body { #<<<
	parse_args::parse_args {-bar ""} {
		-foo	{-args all -default {foo bar}}
		-bar	{}
	}
	set foo
} -cleanup {
	unset -nocomplain foo bar
} -result {foo bar}
#>>>
test parse_args-10.8 {-args all, omitted, required} -body { #<<<
	parse_args::parse_args {-bar ""} {
		-foo	{-args all -required}
		-bar	{}
	}
} -cleanup {
	unset -nocomplain foo bar
} -returnCodes error -errorCode {PARSE_ARGS REQUIRED -foo} -result {option -foo is required}
#>>>
test parse_args-10.9 {-args all, 0 supplied, default} -body { #<<<
	parse_args::parse_args {-bar "" -foo} {
		-foo	{-args all -default {foo bar}}
		-bar	{}
	}
	set foo
} -cleanup {
	unset -nocomplain foo bar
} -result {}
#>>>
test parse_args-10.10 {-args all, 1 supplied, default} -body { #<<<
	parse_args::parse_args {-bar "" -foo "hello, world"} {
		-foo	{-args all -default {foo bar}}
		-bar	{}
	}
	set foo
} -cleanup {
	unset -nocomplain foo bar
} -result {{hello, world}}
#>>>
test parse_args-10.11 {-args all, 4 supplied, required} -body { #<<<
	parse_args::parse_args {-bar "" -foo "hello, world" x y z} {
		-foo	{-args all -required}
		-bar	{}
	}
	set foo
} -cleanup {
	unset -nocomplain foo bar
} -result {{hello, world} x y z}
#>>>
test parse_args-10.12 {-args all, 4 supplied, looks like option} -body { #<<<
	parse_args::parse_args {-foo "hello, world" -bar "" z} {
		-foo	{-args all}
		-bar	{}
	}
	list [info exists bar] $foo
} -cleanup {
	unset -nocomplain foo bar
} -result {0 {{hello, world} -bar {} z}}
#>>>
test parse_args-10.13 {-args 3, positional, supplied} -body { #<<<
	parse_args::parse_args {a b c d e} {
		foo			{-required}
		bar			{-args 3 -required}
		baz			{-required}
	}
	list $foo $bar $baz
} -cleanup {
	unset -nocomplain foo bar baz
} -result {a {b c d} e}
#>>>
test parse_args-10.14 {-args 3, positional, omitted, required} -body { #<<<
	parse_args::parse_args {a} {
		foo			{-required}
		bar			{-args 3 -required}
	}
} -cleanup {
	unset -nocomplain foo bar
} -returnCodes error -errorCode {PARSE_ARGS REQUIRED bar} -result {argument bar is required}
#>>>
test parse_args-10.15 {-args 3, positional, omitted, optional} -body { #<<<
	parse_args::parse_args {a} {
		foo			{-required}
		bar			{-args 3}
	}
	list [info exists foo] [info exists bar]
} -cleanup {
	unset -nocomplain foo bar
} -result {1 0}
#>>>
test parse_args-10.16 {-args 3, positional, omitted, default} -body { #<<<
	parse_args::parse_args {a} {
		foo			{-required}
		bar			{-args 3 -default {x y z}}
	}
	list $foo $bar
} -cleanup {
	unset -nocomplain foo bar
} -result {a {x y z}}
#>>>
test parse_args-10.17 {-args 3, positional, insufficient, required} -body { #<<<
	parse_args::parse_args {a b c} {
		foo			{-required}
		bar			{-args 3 -required}
	}
} -cleanup {
	unset -nocomplain foo bar
} -returnCodes error -errorCode {PARSE_ARGS WRONGARGS bar} -result {Expecting 3 arguments for bar}
#>>>
test parse_args-10.18 {-args 3, positional, insufficient, optional} -body { #<<<
	parse_args::parse_args {a b c} {
		foo			{-required}
		bar			{-args 3}
	}
} -cleanup {
	unset -nocomplain foo bar
} -returnCodes error -errorCode {PARSE_ARGS WRONGARGS bar} -result {Expecting 3 arguments for bar}
#>>>
test parse_args-10.18 {-args 3, positional, insufficient, default} -body { #<<<
	parse_args::parse_args {a b c} {
		foo			{-required}
		bar			{-args 3 -default {x y z}}
	}
} -cleanup {
	unset -nocomplain foo bar
} -returnCodes error -errorCode {PARSE_ARGS WRONGARGS bar} -result {Expecting 3 arguments for bar}
#>>>
test parse_args-11.1 {invalid setting} -body { #<<<
	parse_args::parse_args {} {
		-foo	{-foo 3}
		-bar	{}
	}
} -cleanup {
	unset -nocomplain foo bar
} -returnCodes error -result {bad setting "-foo": must be -default, -required, -validate, -name, -boolean, -args, -enum, -#, -multi, -alias, -all, or -end}
#>>>
test parse_args-12.1 {-end, -boolean, supplied} -body { #<<<
	parse_args::parse_args {-ex a --args -ex e c d} {
		-ex		{-all -default {}}
		--args	{-name se_args -boolean -end}
		first	{}
		second	{}
		rest	{-args all}
	}
	list $ex $se_args $first $second $rest
} -cleanup {
	unset -nocomplain ex se_args first second rest
} -result {a 1 -ex e {c d}}
#>>>
test parse_args-12.2 {-end, -boolean, omitted} -body { #<<<
	parse_args::parse_args {-ex a -ex e c d} {
		-ex		{-all -default {}}
		--args	{-name se_args -boolean -end}
		first	{}
		second	{}
		rest	{-args all}
	}
	list $ex $se_args $first $second [info exists rest]
} -cleanup {
	unset -nocomplain ex se_args first second rest
} -result {{a e} 0 c d 0}
#>>>
test parse_args-20.1 {no args} -body { #<<<
	parse_args::parse_args
} -returnCodes error -result {wrong # args: should be "parse_args::parse_args args args_spec ?dict?"}
#>>>
test parse_args-30.1 {Doesn't generate string rep} -constraints knownBug -body { # Known to fail currently - it's an still open problem to find a way to avoid this <<<
	set i	[expr {2-1}]
	parse_args::parse_args [list $i] {
		foo {}
	}
	tcl::unsupported::representation $i
} -cleanup {
	unset -nocomplain i foo
} -match glob -result {value is a int * no string representation}
#>>>
test parse_args-40.1 {namespace import} -body { #<<<
	set interp	[interp create]
	$interp eval {
		load {} Parse_args
		namespace import ::parse_args::*
		parse_args {-foo foo-parse_args-40.1} {
			-foo	{-default x}
		}
		set foo
	}
} -cleanup {
	interp delete $interp
	unset -nocomplain interp
} -result foo-parse_args-40.1
#>>>

# cleanup
::tcltest::cleanupTests
return

# vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4
