# -*- tcl -*- Include file for cmdr.test.
# # ## ### ##### ######## ############# #####################
## DSL commands under test:
## (1) alias
## (2) default
## (3) generate
## (4) interact
## (5) list
## (6) optional
## (7) test
## (8) validate
## (9) when-complete

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'alias' across parameters (input, option, state)

test cmdr-parameter-1.0 {parameter DSL, alias, wrong num args, not enough} -body {
    BadParamSpec input { alias }
} -returnCodes error \
    -result "wrong # args: should be \"alias name\""

test cmdr-parameter-1.1 {parameter DSL, alias, wrong num args, too many} -body {
    BadParamSpec input { alias X Y }
} -returnCodes error \
    -result "wrong # args: should be \"alias name\""

test cmdr-parameter-1.2 {parameter DSL, input, alias} -body {
    BadParamSpec input { alias X }
} -returnCodes error \
    -result {Non-option parameter "A" cannot have alias}

test cmdr-parameter-1.3 {parameter DSL, option, alias} -body {
    NiceParamSpec option { alias X }
} -result {
    foo bar = {
        description: ''
        option (--no-A) = A
        option (-A) = A
        option (-X) = A
        map --n --> (--no-A)
        map --no --> (--no-A)
        map --no- --> (--no-A)
        map --no-A --> (--no-A)
        map -A --> (-A)
        map -X --> (-X)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A -X]
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

test cmdr-parameter-1.4 {parameter DSL, state, alias} -body {
    BadParamSpec state { alias X }
} -returnCodes error \
    -result {Non-option parameter "A" cannot have alias}

test cmdr-parameter-1.5 {parameter DSL, negative option, alias} -body {
    NiceParamSpec option { alias X } no-A
} -result {
    foo bar = {
        description: ''
        option (--no-A) = no-A
        option (-A) = no-A
        option (-X) = no-A
        map --n --> (--no-A)
        map --no --> (--no-A)
        map --no- --> (--no-A)
        map --no-A --> (--no-A)
        map -A --> (-A)
        map -X --> (-X)
        para (no-A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A -X]
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'default' across parameters (input, option, state)

test cmdr-parameter-2.0 {parameter DSL, default, wrong num args, not enough} -body {
    BadParamSpec input { default }
} -returnCodes error \
    -result "wrong # args: should be \"default value\""

test cmdr-parameter-2.1 {parameter DSL, default, wrong num args, too many} -body {
    BadParamSpec input { default X Y }
} -returnCodes error \
    -result "wrong # args: should be \"default value\""

test cmdr-parameter-2.2 {(C6) parameter DSL, input, default, forbidden} -body {
    BadParamSpec input { default VALUE }
} -returnCodes error \
    -result {Required argument "A" must not have default value}

test cmdr-parameter-2.3 {parameter DSL, optional input, default, auto validate boolean} -body {
    NiceParamSpec input { optional ; default 0 }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, optional, silent, immediate
            default: '0'
            mode=threshold 0
            flags []
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

test cmdr-parameter-2.4 {parameter DSL, optional input, default, auto validate integer} -body {
    NiceParamSpec input { optional ; default 2 }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, optional, silent, immediate
            default: '2'
            mode=threshold 0
            flags []
            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

test cmdr-parameter-2.5 {parameter DSL, optional input, default, auto validate identity} -body {
    NiceParamSpec input { optional ; default X }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, optional, silent, immediate
            default: 'X'
            mode=threshold 0
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-2.6 {parameter DSL, option, default, auto validate boolean} -body {
    NiceParamSpec option { default 0 }
} -result {
    foo bar = {
        description: ''
        option (--no-A) = A
        option (-A) = A
        map --n --> (--no-A)
        map --no --> (--no-A)
        map --no- --> (--no-A)
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '0'
            flags [--no-A -A]
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

test cmdr-parameter-2.7 {parameter DSL, option, default, auto validate integer } -body {
    NiceParamSpec option { default 2 }
} -result {
    foo bar = {
        description: ''
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '2'
            flags [-A]
            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

test cmdr-parameter-2.8 {parameter DSL, option, default, auto validate identity} -body {
    NiceParamSpec option { default X }
} -result {
    foo bar = {
        description: ''
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'X'
            flags [-A]
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-2.9 {parameter DSL, state, default, auto validate boolean} -body {
    NiceParamSpec state { default 0 }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, single, required, silent, defered
            default: '0'
            flags []
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

test cmdr-parameter-2.10 {parameter DSL, state, default, auto validate integer} -body {
    NiceParamSpec state { default 2 }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, single, required, silent, defered
            default: '2'
            flags []
            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

test cmdr-parameter-2.11 {parameter DSL, state, default, auto validate identity} -body {
    NiceParamSpec state { default X }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, single, required, silent, defered
            default: 'X'
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-2.12 {(C7) parameter DSL, optional input, default after generate} -body {
    BadParamSpec input { optional ; generate X ; default VALUE }
} -returnCodes error \
    -result {Default value and generator command for parameter "A" are in conflict}

test cmdr-parameter-2.13 {(C7) parameter DSL, option, default after generate} -body {
    BadParamSpec option { generate X ; default VALUE }
} -returnCodes error \
    -result {Default value and generator command for parameter "A" are in conflict}

test cmdr-parameter-2.14 {(C7) parameter DSL, state, default after generate} -body {
    BadParamSpec state { generate X ; default VALUE }
} -returnCodes error \
    -result {Default value and generator command for parameter "A" are in conflict}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'generate' across parameters (input, option, state)

test cmdr-parameter-3.0 {parameter DSL, optional, wrong num args, too many} -body {
    BadParamSpec input { generate X Y }
} -returnCodes error \
    -result "wrong # args: should be \"generate cmd\""

test cmdr-parameter-3.1 {parameter DSL, optional, wrong num args, too many} -body {
    BadParamSpec input { generate X Y }
} -returnCodes error \
    -result "wrong # args: should be \"generate cmd\""

test cmdr-parameter-3.1 {(C6) parameter DSL, input, generate, forbidden} -body {
    BadParamSpec input { generate G }
} -returnCodes error \
    -result {Required argument "A" must not have generator command}

test cmdr-parameter-3.2 {parameter DSL, optional input, generate} -body {
    NiceParamSpec input { optional ; generate G }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, optional, silent, immediate
            no default
            mode=threshold 0
            flags []
            ge (G)
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-3.3 {parameter DSL, option, generate} -body {
    NiceParamSpec option { generate G }
} -result {
    foo bar = {
        description: ''
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            no default
            flags [-A]
            ge (G)
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-3.4 {parameter DSL, state, generate} -body {
    NiceParamSpec state { generate G }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, single, required, silent, defered
            no default
            flags []
            ge (G)
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-3.5 {(C7) parameter DSL, optional input, generate after default} -body {
    BadParamSpec input { optional ; default VALUE ; generate X }
} -returnCodes error \
    -result {Default value and generator command for parameter "A" are in conflict}

test cmdr-parameter-3.6 {(C7) parameter DSL, option, generate after default} -body {
    BadParamSpec option { default VALUE ; generate X }
} -returnCodes error \
    -result {Default value and generator command for parameter "A" are in conflict}

test cmdr-parameter-3.7 {(C7) parameter DSL, state, generate after default} -body {
    BadParamSpec state { default VALUE ; generate X }
} -returnCodes error \
    -result {Default value and generator command for parameter "A" are in conflict}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'interact' across parameters (input, option, state)

test cmdr-parameter-4.0 {parameter DSL, optional, wrong num args, too many} -body {
    BadParamSpec input { interact X Y }
} -returnCodes error \
    -result "wrong # args: should be \"interact ?prompt?\""

test cmdr-parameter-4.1 {(C6) parameter DSL, input, interact, forbidden} -body {
    BadParamSpec input { interact }
} -returnCodes error \
    -result {Required argument "A" must not have user interaction}

test cmdr-parameter-4.2 {parameter DSL, optional input, interact, default prompt} -body {
    NiceParamSpec input { optional ; interact }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, optional, interact, immediate
            default: ''
            prompt: 'Enter A: '
            mode=threshold 0
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-4.3 {parameter DSL, optional input, interact, custom prompt} -body {
    NiceParamSpec input { optional ; interact HERE }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, optional, interact, immediate
            default: ''
            prompt: 'HERE'
            mode=threshold 0
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-4.4 {parameter DSL, option, interact} -body {
    NiceParamSpec option { interact }
} -result {
    foo bar = {
        description: ''
        option (--no-A) = A
        option (-A) = A
        map --n --> (--no-A)
        map --no --> (--no-A)
        map --no- --> (--no-A)
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, interact, immediate
            default: 'no'
            prompt: 'Enter A: '
            flags [--no-A -A]
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

test cmdr-parameter-4.5 {parameter DSL, state, interact} -body {
    NiceParamSpec state { interact }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, single, required, interact, defered
            default: ''
            prompt: 'Enter A: '
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'list' across parameters (input, option, state)

test cmdr-parameter-5.0 {parameter DSL, list, wrong num args, too many} -body {
    BadParamSpec input { list X }
} -returnCodes error \
    -result "wrong # args: should be \"list\""

test cmdr-parameter-5.1 {parameter DSL, list input} -body {
    NiceParamSpec input { list }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, splat, required, silent, immediate
            no default
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-5.2 {parameter DSL, list input not last} -body {
    # Double input, BadParamSpec not suitable
    cmdr create x foo {
	private bar {
	    input A - { list }
	    input X -
	} {}
    }
    [x lookup bar] keys
} -cleanup {
    x destroy
} -returnCodes error \
    -result {A splat must be the last argument in the specification}

test cmdr-parameter-5.3 {parameter DSL, list option} -body {
    NiceParamSpec option { list }
} -result {
    foo bar = {
        description: ''
        option (--no-A) = A
        option (-A) = A
        map --n --> (--no-A)
        map --no --> (--no-A)
        map --no- --> (--no-A)
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, splat, optional, silent, immediate
            default: ''
            flags [--no-A -A]
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

test cmdr-parameter-5.4 {parameter DSL, list state} -body {
    NiceParamSpec state { list }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, splat, required, silent, defered
            default: ''
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'optional' across parameters (input, option, state)

test cmdr-parameter-6.0 {parameter DSL, optional, wrong num args, too many} -body {
    BadParamSpec input { optional X }
} -returnCodes error \
    -result "wrong # args: should be \"optional\""

test cmdr-parameter-6.1 {parameter DSL, optional input} -body {
    NiceParamSpec input { optional }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, optional, silent, immediate
            default: ''
            mode=threshold 0
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-6.2 {parameter DSL, optional option} -body {
    BadParamSpec option { optional }
} -returnCodes error \
    -result {Option "A" is already optional}

test cmdr-parameter-6.3 {parameter DSL, optional state} -body {
    BadParamSpec state { optional }
} -returnCodes error \
    -result {State parameter "A" cannot be optional}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'test' across parameters (input, option, state)

test cmdr-parameter-7.0 {parameter DSL, test, wrong num args, too many} -body {
    BadParamSpec input { test X }
} -returnCodes error \
    -result "wrong # args: should be \"test\""

test cmdr-parameter-7.1 {parameter DSL, input, test} -body {
    BadParamSpec input { test }
} -returnCodes error \
    -result {Required argument "A" has no test-mode}

test cmdr-parameter-7.2 {parameter DSL, optional input, test} -body {
    NiceParamSpec input { optional ; test }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, optional, silent, immediate
            default: ''
            mode=peek+test
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-7.3 {parameter DSL, option, test} -body {
    BadParamSpec option { test }
} -returnCodes error \
    -result {Option "A" has no test-mode}

test cmdr-parameter-7.4 {parameter DSL, state, test} -body {
    BadParamSpec state { test }
} -returnCodes error \
    -result {State parameter "A" has no test-mode}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'validate' across parameters (input, option, state)

test cmdr-parameter-8.0 {parameter DSL, validate, wrong num args, not enough} -body {
    BadParamSpec input { validate }
} -returnCodes error \
    -result "wrong # args: should be \"validate cmdprefix\""

test cmdr-parameter-8.1 {parameter DSL, validate, wrong num args, too many} -body {
    BadParamSpec input { validate X Y }
} -returnCodes error \
    -result "wrong # args: should be \"validate cmdprefix\""

test cmdr-parameter-8.2 {parameter DSL, input, validate, shorthand} -body {
    NiceParamSpec input { validate integer }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, required, silent, immediate
            no default
            flags []
            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

test cmdr-parameter-8.3 {parameter DSL, input, validate} -body {
    NiceParamSpec input { validate ::cmdr::validate::identity }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, required, silent, immediate
            no default
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-8.4 {parameter DSL, option, validate, shorthand} -body {
    NiceParamSpec option { validate integer }
} -result {
    foo bar = {
        description: ''
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '0'
            flags [-A]
            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

test cmdr-parameter-8.5 {parameter DSL, option, validate} -body {
    NiceParamSpec option { validate ::cmdr::validate::identity }
} -result {
    foo bar = {
        description: ''
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: ''
            flags [-A]
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

test cmdr-parameter-8.6 {parameter DSL, state, validate, shorthand} -body {
    NiceParamSpec state { validate integer }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, single, required, silent, defered
            default: '0'
            flags []
            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

test cmdr-parameter-8.7 {parameter DSL, state, validate} -body {
    NiceParamSpec state { validate ::cmdr::validate::identity }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, single, required, silent, defered
            default: ''
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'when-complete' across parameters (input, option, state)

test cmdr-parameter-9.0 {parameter DSL, when-complete, wrong num args, not enough} -body {
    BadParamSpec input { when-complete }
} -returnCodes error \
    -result "wrong # args: should be \"when-complete cmd\""

test cmdr-parameter-9.1 {parameter DSL, when-complete, wrong num args, too many} -body {
    BadParamSpec input { when-complete X Y }
} -returnCodes error \
    -result "wrong # args: should be \"when-complete cmd\""

test cmdr-parameter-9.2 {parameter DSL, input, when-complete} -body {
    NiceParamSpec input { when-complete X }
} -result {
    foo bar = {
        description: ''
        argument (A)
        para (A) {
            description: '-'
            ordered, cmdline, single, required, silent, immediate
            no default
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd (X)
        }
    }
}

test cmdr-parameter-9.3 {parameter DSL, option, when-complete} -body {
    NiceParamSpec option { when-complete X }
} -result {
    foo bar = {
        description: ''
        option (--no-A) = A
        option (-A) = A
        map --n --> (--no-A)
        map --no --> (--no-A)
        map --no- --> (--no-A)
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A]
            ge ()
            va (::cmdr::validate::boolean)
            wd (X)
        }
    }
}

test cmdr-parameter-9.4 {parameter DSL, state, when-complete} -body {
    NiceParamSpec state { when-complete X }
} -result {
    foo bar = {
        description: ''
        para (A) {
            description: '-'
            unordered, hidden, single, required, silent, defered
            default: ''
            flags []
            ge ()
            va (::cmdr::validate::identity)
            wd (X)
        }
    }
}

# # ## ### ##### ######## ############# #####################
return
