mirror of
https://github.com/apple/swift-argument-parser.git
synced 2026-06-06 20:18:23 +00:00
610 lines
20 KiB
Swift
610 lines
20 KiB
Swift
//===----------------------------------------------------------*- swift -*-===//
|
|
//
|
|
// This source file is part of the Swift Argument Parser open source project
|
|
//
|
|
// Copyright (c) 2020 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import XCTest
|
|
import ArgumentParser
|
|
import ArgumentParserTestHelpers
|
|
|
|
final class MathExampleTests: XCTestCase {
|
|
func testMath_Simple() throws {
|
|
try AssertExecuteCommand(command: "math 1 2 3 4 5", expected: "15")
|
|
try AssertExecuteCommand(command: "math multiply 1 2 3 4 5", expected: "120")
|
|
}
|
|
|
|
func testMath_Help() throws {
|
|
let helpText = """
|
|
OVERVIEW: A utility for performing maths.
|
|
|
|
USAGE: math <subcommand>
|
|
|
|
OPTIONS:
|
|
--version Show the version.
|
|
-h, --help Show help information.
|
|
|
|
SUBCOMMANDS:
|
|
add (default) Print the sum of the values.
|
|
multiply Print the product of the values.
|
|
stats Calculate descriptive statistics.
|
|
|
|
See 'math help <subcommand>' for detailed help.
|
|
"""
|
|
|
|
try AssertExecuteCommand(command: "math -h", expected: helpText)
|
|
try AssertExecuteCommand(command: "math --help", expected: helpText)
|
|
try AssertExecuteCommand(command: "math help", expected: helpText)
|
|
}
|
|
|
|
func testMath_AddHelp() throws {
|
|
let helpText = """
|
|
OVERVIEW: Print the sum of the values.
|
|
|
|
USAGE: math add [--hex-output] [<values> ...]
|
|
|
|
ARGUMENTS:
|
|
<values> A group of integers to operate on.
|
|
|
|
OPTIONS:
|
|
-x, --hex-output Use hexadecimal notation for the result.
|
|
--version Show the version.
|
|
-h, --help Show help information.
|
|
"""
|
|
|
|
try AssertExecuteCommand(command: "math add -h", expected: helpText)
|
|
try AssertExecuteCommand(command: "math add --help", expected: helpText)
|
|
try AssertExecuteCommand(command: "math help add", expected: helpText)
|
|
|
|
// Verify that extra help flags are ignored.
|
|
try AssertExecuteCommand(command: "math help add -h", expected: helpText)
|
|
try AssertExecuteCommand(command: "math help add -help", expected: helpText)
|
|
try AssertExecuteCommand(command: "math help add --help", expected: helpText)
|
|
}
|
|
|
|
func testMath_StatsMeanHelp() throws {
|
|
let helpText = """
|
|
OVERVIEW: Print the average of the values.
|
|
|
|
USAGE: math stats average [--kind <kind>] [<values> ...]
|
|
|
|
ARGUMENTS:
|
|
<values> A group of floating-point values to operate on.
|
|
|
|
OPTIONS:
|
|
--kind <kind> The kind of average to provide. (default: mean)
|
|
--version Show the version.
|
|
-h, --help Show help information.
|
|
"""
|
|
|
|
try AssertExecuteCommand(command: "math stats average -h", expected: helpText)
|
|
try AssertExecuteCommand(command: "math stats average --help", expected: helpText)
|
|
try AssertExecuteCommand(command: "math help stats average", expected: helpText)
|
|
}
|
|
|
|
func testMath_StatsQuantilesHelp() throws {
|
|
let helpText = """
|
|
OVERVIEW: Print the quantiles of the values (TBD).
|
|
|
|
USAGE: math stats quantiles [<one-of-four>] [<custom-arg>] [<values> ...] [--file <file>] [--directory <directory>] [--shell <shell>] [--custom <custom>]
|
|
|
|
ARGUMENTS:
|
|
<one-of-four>
|
|
<custom-arg>
|
|
<values> A group of floating-point values to operate on.
|
|
|
|
OPTIONS:
|
|
--file <file>
|
|
--directory <directory>
|
|
--shell <shell>
|
|
--custom <custom>
|
|
--version Show the version.
|
|
-h, --help Show help information.
|
|
"""
|
|
|
|
// The "quantiles" subcommand's run() method is unimplemented, so it
|
|
// just generates the help text.
|
|
try AssertExecuteCommand(command: "math stats quantiles", expected: helpText)
|
|
|
|
try AssertExecuteCommand(command: "math stats quantiles -h", expected: helpText)
|
|
try AssertExecuteCommand(command: "math stats quantiles --help", expected: helpText)
|
|
try AssertExecuteCommand(command: "math help stats quantiles", expected: helpText)
|
|
}
|
|
|
|
func testMath_CustomValidation() throws {
|
|
try AssertExecuteCommand(
|
|
command: "math stats average --kind mode",
|
|
expected: """
|
|
Error: Please provide at least one value to calculate the mode.
|
|
Usage: math stats average [--kind <kind>] [<values> ...]
|
|
See 'math stats average --help' for more information.
|
|
""",
|
|
exitCode: .validationFailure)
|
|
}
|
|
|
|
func testMath_Versions() throws {
|
|
try AssertExecuteCommand(
|
|
command: "math --version",
|
|
expected: "1.0.0")
|
|
try AssertExecuteCommand(
|
|
command: "math stats --version",
|
|
expected: "1.0.0")
|
|
try AssertExecuteCommand(
|
|
command: "math stats average --version",
|
|
expected: "1.5.0-alpha")
|
|
}
|
|
|
|
func testMath_ExitCodes() throws {
|
|
try AssertExecuteCommand(
|
|
command: "math stats quantiles --test-success-exit-code",
|
|
expected: "",
|
|
exitCode: .success)
|
|
try AssertExecuteCommand(
|
|
command: "math stats quantiles --test-failure-exit-code",
|
|
expected: "",
|
|
exitCode: .failure)
|
|
try AssertExecuteCommand(
|
|
command: "math stats quantiles --test-validation-exit-code",
|
|
expected: "",
|
|
exitCode: .validationFailure)
|
|
try AssertExecuteCommand(
|
|
command: "math stats quantiles --test-custom-exit-code 42",
|
|
expected: "",
|
|
exitCode: ExitCode(42))
|
|
}
|
|
|
|
func testMath_Fail() throws {
|
|
try AssertExecuteCommand(
|
|
command: "math --foo",
|
|
expected: """
|
|
Error: Unknown option '--foo'
|
|
Usage: math add [--hex-output] [<values> ...]
|
|
See 'math add --help' for more information.
|
|
""",
|
|
exitCode: .validationFailure)
|
|
|
|
try AssertExecuteCommand(
|
|
command: "math ZZZ",
|
|
expected: """
|
|
Error: The value 'ZZZ' is invalid for '<values>'
|
|
Help: <values> A group of integers to operate on.
|
|
Usage: math add [--hex-output] [<values> ...]
|
|
See 'math add --help' for more information.
|
|
""",
|
|
exitCode: .validationFailure)
|
|
}
|
|
}
|
|
|
|
// MARK: - Completion Script
|
|
|
|
extension MathExampleTests {
|
|
func testMath_CompletionScript() throws {
|
|
try AssertExecuteCommand(
|
|
command: "math --generate-completion-script=bash",
|
|
expected: bashCompletionScriptText)
|
|
try AssertExecuteCommand(
|
|
command: "math --generate-completion-script bash",
|
|
expected: bashCompletionScriptText)
|
|
try AssertExecuteCommand(
|
|
command: "math --generate-completion-script=zsh",
|
|
expected: zshCompletionScriptText)
|
|
try AssertExecuteCommand(
|
|
command: "math --generate-completion-script zsh",
|
|
expected: zshCompletionScriptText)
|
|
try AssertExecuteCommand(
|
|
command: "math --generate-completion-script=fish",
|
|
expected: fishCompletionScriptText)
|
|
try AssertExecuteCommand(
|
|
command: "math --generate-completion-script fish",
|
|
expected: fishCompletionScriptText)
|
|
}
|
|
|
|
func testMath_CustomCompletion() throws {
|
|
try AssertExecuteCommand(
|
|
command: "math ---completion stats quantiles -- --custom",
|
|
expected: """
|
|
hello
|
|
helicopter
|
|
heliotrope
|
|
""")
|
|
|
|
try AssertExecuteCommand(
|
|
command: "math ---completion stats quantiles -- --custom h",
|
|
expected: """
|
|
hello
|
|
helicopter
|
|
heliotrope
|
|
""")
|
|
|
|
try AssertExecuteCommand(
|
|
command: "math ---completion stats quantiles -- --custom a",
|
|
expected: """
|
|
aardvark
|
|
aaaaalbert
|
|
""")
|
|
}
|
|
}
|
|
|
|
private let bashCompletionScriptText = """
|
|
#!/bin/bash
|
|
|
|
_math() {
|
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
COMPREPLY=()
|
|
opts="--version -h --help add multiply stats help"
|
|
if [[ $COMP_CWORD == "1" ]]; then
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
return
|
|
fi
|
|
case ${COMP_WORDS[1]} in
|
|
(add)
|
|
_math_add 2
|
|
return
|
|
;;
|
|
(multiply)
|
|
_math_multiply 2
|
|
return
|
|
;;
|
|
(stats)
|
|
_math_stats 2
|
|
return
|
|
;;
|
|
(help)
|
|
_math_help 2
|
|
return
|
|
;;
|
|
esac
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
}
|
|
_math_add() {
|
|
opts="--hex-output -x --version -h --help"
|
|
if [[ $COMP_CWORD == "$1" ]]; then
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
return
|
|
fi
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
}
|
|
_math_multiply() {
|
|
opts="--hex-output -x --version -h --help"
|
|
if [[ $COMP_CWORD == "$1" ]]; then
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
return
|
|
fi
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
}
|
|
_math_stats() {
|
|
opts="--version -h --help average stdev quantiles"
|
|
if [[ $COMP_CWORD == "$1" ]]; then
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
return
|
|
fi
|
|
case ${COMP_WORDS[$1]} in
|
|
(average)
|
|
_math_stats_average $(($1+1))
|
|
return
|
|
;;
|
|
(stdev)
|
|
_math_stats_stdev $(($1+1))
|
|
return
|
|
;;
|
|
(quantiles)
|
|
_math_stats_quantiles $(($1+1))
|
|
return
|
|
;;
|
|
esac
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
}
|
|
_math_stats_average() {
|
|
opts="--kind --version -h --help"
|
|
if [[ $COMP_CWORD == "$1" ]]; then
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
return
|
|
fi
|
|
case $prev in
|
|
--kind)
|
|
COMPREPLY=( $(compgen -W "mean median mode" -- "$cur") )
|
|
return
|
|
;;
|
|
esac
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
}
|
|
_math_stats_stdev() {
|
|
opts="--version -h --help"
|
|
if [[ $COMP_CWORD == "$1" ]]; then
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
return
|
|
fi
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
}
|
|
_math_stats_quantiles() {
|
|
opts="--file --directory --shell --custom --version -h --help"
|
|
opts="$opts alphabet alligator branch braggart"
|
|
opts="$opts $("${COMP_WORDS[0]}" ---completion stats quantiles -- customArg "${COMP_WORDS[@]}")"
|
|
if [[ $COMP_CWORD == "$1" ]]; then
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
return
|
|
fi
|
|
case $prev in
|
|
--file)
|
|
COMPREPLY=( $(compgen -f -- "$cur") )
|
|
return
|
|
;;
|
|
--directory)
|
|
COMPREPLY=( $(compgen -d -- "$cur") )
|
|
return
|
|
;;
|
|
--shell)
|
|
COMPREPLY=( $(head -100 /usr/share/dict/words | tail -50) )
|
|
return
|
|
;;
|
|
--custom)
|
|
COMPREPLY=( $(compgen -W "$("${COMP_WORDS[0]}" ---completion stats quantiles -- --custom "${COMP_WORDS[@]}")" -- "$cur") )
|
|
return
|
|
;;
|
|
esac
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
}
|
|
_math_help() {
|
|
opts="--version"
|
|
if [[ $COMP_CWORD == "$1" ]]; then
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
return
|
|
fi
|
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
}
|
|
|
|
|
|
complete -F _math math
|
|
"""
|
|
|
|
private let zshCompletionScriptText = """
|
|
#compdef math
|
|
local context state state_descr line
|
|
_math_commandname=$words[1]
|
|
typeset -A opt_args
|
|
|
|
_math() {
|
|
integer ret=1
|
|
local -a args
|
|
args+=(
|
|
'--version[Show the version.]'
|
|
'(-h --help)'{-h,--help}'[Show help information.]'
|
|
'(-): :->command'
|
|
'(-)*:: :->arg'
|
|
)
|
|
_arguments -w -s -S $args[@] && ret=0
|
|
case $state in
|
|
(command)
|
|
local subcommands
|
|
subcommands=(
|
|
'add:Print the sum of the values.'
|
|
'multiply:Print the product of the values.'
|
|
'stats:Calculate descriptive statistics.'
|
|
'help:Show subcommand help information.'
|
|
)
|
|
_describe "subcommand" subcommands
|
|
;;
|
|
(arg)
|
|
case ${words[1]} in
|
|
(add)
|
|
_math_add
|
|
;;
|
|
(multiply)
|
|
_math_multiply
|
|
;;
|
|
(stats)
|
|
_math_stats
|
|
;;
|
|
(help)
|
|
_math_help
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
return ret
|
|
}
|
|
|
|
_math_add() {
|
|
integer ret=1
|
|
local -a args
|
|
args+=(
|
|
'(--hex-output -x)'{--hex-output,-x}'[Use hexadecimal notation for the result.]'
|
|
':values:'
|
|
'--version[Show the version.]'
|
|
'(-h --help)'{-h,--help}'[Show help information.]'
|
|
)
|
|
_arguments -w -s -S $args[@] && ret=0
|
|
|
|
return ret
|
|
}
|
|
|
|
_math_multiply() {
|
|
integer ret=1
|
|
local -a args
|
|
args+=(
|
|
'(--hex-output -x)'{--hex-output,-x}'[Use hexadecimal notation for the result.]'
|
|
':values:'
|
|
'--version[Show the version.]'
|
|
'(-h --help)'{-h,--help}'[Show help information.]'
|
|
)
|
|
_arguments -w -s -S $args[@] && ret=0
|
|
|
|
return ret
|
|
}
|
|
|
|
_math_stats() {
|
|
integer ret=1
|
|
local -a args
|
|
args+=(
|
|
'--version[Show the version.]'
|
|
'(-h --help)'{-h,--help}'[Show help information.]'
|
|
'(-): :->command'
|
|
'(-)*:: :->arg'
|
|
)
|
|
_arguments -w -s -S $args[@] && ret=0
|
|
case $state in
|
|
(command)
|
|
local subcommands
|
|
subcommands=(
|
|
'average:Print the average of the values.'
|
|
'stdev:Print the standard deviation of the values.'
|
|
'quantiles:Print the quantiles of the values (TBD).'
|
|
)
|
|
_describe "subcommand" subcommands
|
|
;;
|
|
(arg)
|
|
case ${words[1]} in
|
|
(average)
|
|
_math_stats_average
|
|
;;
|
|
(stdev)
|
|
_math_stats_stdev
|
|
;;
|
|
(quantiles)
|
|
_math_stats_quantiles
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
return ret
|
|
}
|
|
|
|
_math_stats_average() {
|
|
integer ret=1
|
|
local -a args
|
|
args+=(
|
|
'--kind[The kind of average to provide.]:kind:(mean median mode)'
|
|
':values:'
|
|
'--version[Show the version.]'
|
|
'(-h --help)'{-h,--help}'[Show help information.]'
|
|
)
|
|
_arguments -w -s -S $args[@] && ret=0
|
|
|
|
return ret
|
|
}
|
|
|
|
_math_stats_stdev() {
|
|
integer ret=1
|
|
local -a args
|
|
args+=(
|
|
':values:'
|
|
'--version[Show the version.]'
|
|
'(-h --help)'{-h,--help}'[Show help information.]'
|
|
)
|
|
_arguments -w -s -S $args[@] && ret=0
|
|
|
|
return ret
|
|
}
|
|
|
|
_math_stats_quantiles() {
|
|
integer ret=1
|
|
local -a args
|
|
args+=(
|
|
':one-of-four:(alphabet alligator branch braggart)'
|
|
':custom-arg:{_custom_completion $_math_commandname ---completion stats quantiles -- customArg $words}'
|
|
':values:'
|
|
'--file:file:_files -g '"'"'*.txt *.md'"'"''
|
|
'--directory:directory:_files -/'
|
|
'--shell:shell:{local -a list; list=(${(f)"$(head -100 /usr/share/dict/words | tail -50)"}); _describe '''' list}'
|
|
'--custom:custom:{_custom_completion $_math_commandname ---completion stats quantiles -- --custom $words}'
|
|
'--version[Show the version.]'
|
|
'(-h --help)'{-h,--help}'[Show help information.]'
|
|
)
|
|
_arguments -w -s -S $args[@] && ret=0
|
|
|
|
return ret
|
|
}
|
|
|
|
_math_help() {
|
|
integer ret=1
|
|
local -a args
|
|
args+=(
|
|
':subcommands:'
|
|
'--version[Show the version.]'
|
|
)
|
|
_arguments -w -s -S $args[@] && ret=0
|
|
|
|
return ret
|
|
}
|
|
|
|
|
|
_custom_completion() {
|
|
local completions=("${(@f)$($*)}")
|
|
_describe '' completions
|
|
}
|
|
|
|
_math
|
|
"""
|
|
|
|
private let fishCompletionScriptText = """
|
|
# A function which filters options which starts with \"-\" from $argv.
|
|
function _swift_math_preprocessor
|
|
set -l results
|
|
for i in (seq (count $argv))
|
|
switch (echo $argv[$i] | string sub -l 1)
|
|
case '-'
|
|
case '*'
|
|
echo $argv[$i]
|
|
end
|
|
end
|
|
end
|
|
|
|
function _swift_math_using_command
|
|
set -l currentCommands (_swift_math_preprocessor (commandline -opc))
|
|
set -l expectedCommands (string split \" \" $argv[1])
|
|
set -l subcommands (string split \" \" $argv[2])
|
|
if [ (count $currentCommands) -ge (count $expectedCommands) ]
|
|
for i in (seq (count $expectedCommands))
|
|
if [ $currentCommands[$i] != $expectedCommands[$i] ]
|
|
return 1
|
|
end
|
|
end
|
|
if [ (count $currentCommands) -eq (count $expectedCommands) ]
|
|
return 0
|
|
end
|
|
if [ (count $subcommands) -gt 1 ]
|
|
for i in (seq (count $subcommands))
|
|
if [ $currentCommands[(math (count $expectedCommands) + 1)] = $subcommands[$i] ]
|
|
return 1
|
|
end
|
|
end
|
|
end
|
|
return 0
|
|
end
|
|
return 1
|
|
end
|
|
|
|
complete -c math -n \'_swift_math_using_command \"math add\"\' -l hex-output -s x -d \'Use hexadecimal notation for the result.\'
|
|
complete -c math -n \'_swift_math_using_command \"math add\"\' -s h -l help -d \'Show help information.\'
|
|
complete -c math -n \'_swift_math_using_command \"math multiply\"\' -l hex-output -s x -d \'Use hexadecimal notation for the result.\'
|
|
complete -c math -n \'_swift_math_using_command \"math multiply\"\' -s h -l help -d \'Show help information.\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats average\"\' -l kind -d \'The kind of average to provide.\' -r -f -k -a \'mean median mode\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats average\"\' -l version -d \'Show the version.\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats average\"\' -s h -l help -d \'Show help information.\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats stdev\"\' -s h -l help -d \'Show help information.\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats quantiles\"\' -l file -r -f -a \'(for i in *.{txt,md}; echo $i;end)\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats quantiles\"\' -l directory -r -f -a \'(__fish_complete_directories)\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats quantiles\"\' -l shell -r -f -a \'(head -100 /usr/share/dict/words | tail -50)\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats quantiles\"\' -l custom -r -f -a \'(command math ---completion stats quantiles -- --custom (commandline -opc)[1..-1])\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats quantiles\"\' -s h -l help -d \'Show help information.\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats\" \"average stdev quantiles help\"\' -s h -l help -d \'Show help information.\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats\" \"average stdev quantiles help\"\' -f -a \'average\' -d \'Print the average of the values.\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats\" \"average stdev quantiles help\"\' -f -a \'stdev\' -d \'Print the standard deviation of the values.\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats\" \"average stdev quantiles help\"\' -f -a \'quantiles\' -d \'Print the quantiles of the values (TBD).\'
|
|
complete -c math -n \'_swift_math_using_command \"math stats\" \"average stdev quantiles help\"\' -f -a \'help\' -d \'Show subcommand help information.\'
|
|
complete -c math -n \'_swift_math_using_command \"math\" \"add multiply stats help\"\' -l version -d \'Show the version.\'
|
|
complete -c math -n \'_swift_math_using_command \"math\" \"add multiply stats help\"\' -s h -l help -d \'Show help information.\'
|
|
complete -c math -n \'_swift_math_using_command \"math\" \"add multiply stats help\"\' -f -a \'add\' -d \'Print the sum of the values.\'
|
|
complete -c math -n \'_swift_math_using_command \"math\" \"add multiply stats help\"\' -f -a \'multiply\' -d \'Print the product of the values.\'
|
|
complete -c math -n \'_swift_math_using_command \"math\" \"add multiply stats help\"\' -f -a \'stats\' -d \'Calculate descriptive statistics.\'
|
|
complete -c math -n \'_swift_math_using_command \"math\" \"add multiply stats help\"\' -f -a \'help\' -d \'Show subcommand help information.\'
|
|
"""
|