Skip to content

Commit

Permalink
chore: E2E tests for dynamic completions
Browse files Browse the repository at this point in the history
  • Loading branch information
ModProg committed Jul 28, 2023
1 parent 48c8f1e commit aabe822
Show file tree
Hide file tree
Showing 13 changed files with 371 additions and 69 deletions.
4 changes: 4 additions & 0 deletions clap_complete/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ clap = { path = "../", version = "4.0.0", default-features = false, features = [
name = "dynamic"
required-features = ["unstable-dynamic"]

[[example]]
name = "test-dynamic"
required-features = ["unstable-dynamic"]

[features]
default = []
unstable-dynamic = ["dep:clap_lex", "dep:shlex", "dep:unicode-xid", "clap/derive", "dep:is_executable", "dep:pathdiff"]
Expand Down
168 changes: 168 additions & 0 deletions clap_complete/examples/test-dynamic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
use clap::{FromArgMatches, Subcommand};

fn main() {
let matches = cli().get_matches();
if let Ok(completions) =
clap_complete::dynamic::shells::CompleteCommand::from_arg_matches(&matches)
{
completions.complete(&mut cli());
} else {
println!("{matches:#?}");
}
}

fn cli() -> clap::Command {
let cmd = clap::Command::new("test-dynamic")
.version("3.0")
.propagate_version(true)
.args([clap::Arg::new("global")
.long("global")
.global(true)
.action(clap::ArgAction::SetTrue)
.help("everywhere")])
.subcommands([
clap::Command::new("action").args([
clap::Arg::new("set-true")
.long("set-true")
.action(clap::ArgAction::SetTrue)
.help("bool"),
clap::Arg::new("set")
.long("set")
.action(clap::ArgAction::Set)
.help("value"),
clap::Arg::new("count")
.long("count")
.action(clap::ArgAction::Count)
.help("number"),
clap::Arg::new("choice")
.long("choice")
.value_parser(["first", "second"])
.help("enum"),
]),
clap::Command::new("quote")
.args([
clap::Arg::new("single-quotes")
.long("single-quotes")
.action(clap::ArgAction::SetTrue)
.help("Can be 'always', 'auto', or 'never'"),
clap::Arg::new("double-quotes")
.long("double-quotes")
.action(clap::ArgAction::SetTrue)
.help("Can be \"always\", \"auto\", or \"never\""),
clap::Arg::new("backticks")
.long("backticks")
.action(clap::ArgAction::SetTrue)
.help("For more information see `echo test`"),
clap::Arg::new("backslash")
.long("backslash")
.action(clap::ArgAction::SetTrue)
.help("Avoid '\\n'"),
clap::Arg::new("brackets")
.long("brackets")
.action(clap::ArgAction::SetTrue)
.help("List packages [filter]"),
clap::Arg::new("expansions")
.long("expansions")
.action(clap::ArgAction::SetTrue)
.help("Execute the shell command with $SHELL"),
])
.subcommands([
clap::Command::new("cmd-single-quotes")
.about("Can be 'always', 'auto', or 'never'"),
clap::Command::new("cmd-double-quotes")
.about("Can be \"always\", \"auto\", or \"never\""),
clap::Command::new("cmd-backticks")
.about("For more information see `echo test`"),
clap::Command::new("cmd-backslash").about("Avoid '\\n'"),
clap::Command::new("cmd-brackets").about("List packages [filter]"),
clap::Command::new("cmd-expansions")
.about("Execute the shell command with $SHELL"),
]),
clap::Command::new("value").args([
clap::Arg::new("delim").long("delim").value_delimiter(','),
clap::Arg::new("tuple").long("tuple").num_args(2),
clap::Arg::new("require-eq")
.long("require-eq")
.require_equals(true),
clap::Arg::new("term").num_args(1..).value_terminator(";"),
]),
clap::Command::new("pacman").subcommands([
clap::Command::new("one").long_flag("one").short_flag('o'),
clap::Command::new("two").long_flag("two").short_flag('t'),
]),
clap::Command::new("last")
.args([clap::Arg::new("first"), clap::Arg::new("free").last(true)]),
clap::Command::new("alias").args([
clap::Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.action(clap::ArgAction::SetTrue)
.visible_alias("flg")
.help("cmd flag"),
clap::Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.action(clap::ArgAction::Set),
clap::Arg::new("positional"),
]),
clap::Command::new("hint").args([
clap::Arg::new("choice")
.long("choice")
.action(clap::ArgAction::Set)
.value_parser(["bash", "fish", "zsh"]),
clap::Arg::new("unknown")
.long("unknown")
.value_hint(clap::ValueHint::Unknown),
clap::Arg::new("other")
.long("other")
.value_hint(clap::ValueHint::Other),
clap::Arg::new("path")
.long("path")
.short('p')
.value_hint(clap::ValueHint::AnyPath),
clap::Arg::new("file")
.long("file")
.short('f')
.value_hint(clap::ValueHint::FilePath),
clap::Arg::new("dir")
.long("dir")
.short('d')
.value_hint(clap::ValueHint::DirPath),
clap::Arg::new("exe")
.long("exe")
.short('e')
.value_hint(clap::ValueHint::ExecutablePath),
clap::Arg::new("cmd_name")
.long("cmd-name")
.value_hint(clap::ValueHint::CommandName),
clap::Arg::new("cmd")
.long("cmd")
.short('c')
.value_hint(clap::ValueHint::CommandString),
clap::Arg::new("command_with_args")
.action(clap::ArgAction::Set)
.num_args(1..)
.trailing_var_arg(true)
.value_hint(clap::ValueHint::CommandWithArguments),
clap::Arg::new("user")
.short('u')
.long("user")
.value_hint(clap::ValueHint::Username),
clap::Arg::new("host")
.short('H')
.long("host")
.value_hint(clap::ValueHint::Hostname),
clap::Arg::new("url")
.long("url")
.value_hint(clap::ValueHint::Url),
clap::Arg::new("email")
.long("email")
.value_hint(clap::ValueHint::EmailAddress),
]),
]);
clap_complete::dynamic::shells::CompleteCommand::augment_subcommands(cmd)
}
33 changes: 19 additions & 14 deletions clap_complete/examples/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ use clap_complete::{generate, Generator, Shell};

fn main() {
let matches = cli().get_matches();
if let Some(generator) = matches.get_one::<Shell>("generate") {
// Interface compatible with `test-dynamic`
if let Some(complete) = matches.subcommand_matches("complete") {
let shell: Shell = *complete.get_one("shell").unwrap();
// Compatibility with `test-dynamic`
assert_eq!(complete.get_one::<String>("register").unwrap(), "-");
let mut cmd = cli();
eprintln!("Generating completion file for {generator}...");
print_completions(*generator, &mut cmd);
eprintln!("Generating completion file for {shell}...");
print_completions(shell, &mut cmd);
} else {
println!("{:?}", matches);
}
Expand All @@ -19,18 +23,19 @@ fn cli() -> clap::Command {
clap::Command::new("test")
.version("3.0")
.propagate_version(true)
.args([
clap::Arg::new("global")
.long("global")
.global(true)
.action(clap::ArgAction::SetTrue)
.help("everywhere"),
clap::Arg::new("generate")
.long("generate")
.value_parser(clap::value_parser!(Shell))
.help("generate"),
])
.args([clap::Arg::new("global")
.long("global")
.global(true)
.action(clap::ArgAction::SetTrue)
.help("everywhere")])
.subcommands([
clap::Command::new("complete").hide(true).args([
clap::Arg::new("shell")
.value_parser(clap::value_parser!(Shell))
.long("shell")
.required(true),
clap::Arg::new("register").long("register").required(true),
]),
clap::Command::new("action").args([
clap::Arg::new("set-true")
.long("set-true")
Expand Down
22 changes: 22 additions & 0 deletions clap_complete/tests/snapshots/home/test-dynamic/bash/.bashrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
PS1='% '
. /etc/bash_completion

_clap_complete_test_dynamic() {
export _CLAP_COMPLETE_INDEX=${COMP_CWORD}
export _CLAP_COMPLETE_COMP_TYPE=${COMP_TYPE}
if compopt +o nospace 2> /dev/null; then
export _CLAP_COMPLETE_SPACE=false
else
export _CLAP_COMPLETE_SPACE=true
fi
export _CLAP_COMPLETE_IFS=$'\013'
COMPREPLY=( $("test-dynamic" complete --shell bash -- "${COMP_WORDS[@]}") )
if [[ $? != 0 ]]; then
unset COMPREPLY
elif [[ $SUPPRESS_SPACE == 1 ]] && [[ "${COMPREPLY-}" =~ [=/:]$ ]]; then
compopt -o nospace
fi
}
complete -o nospace -o bashdefault -F _clap_complete_test_dynamic test-dynamic


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
complete -x -c test-dynamic -a "("'test-dynamic'" complete --shell fish -- (commandline --current-process --tokenize --cut-at-cursor) (commandline --current-token))"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
set -U fish_greeting ""
set -U fish_autosuggestion_enabled 0
function fish_title
end
function fish_prompt
printf '%% '
end;
50 changes: 44 additions & 6 deletions clap_complete/tests/snapshots/home/test/bash/.bashrc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ _test() {
test,alias)
cmd="test__alias"
;;
test,complete)
cmd="test__complete"
;;
test,help)
cmd="test__help"
;;
Expand All @@ -44,6 +47,9 @@ _test() {
test__help,alias)
cmd="test__help__alias"
;;
test__help,complete)
cmd="test__help__complete"
;;
test__help,help)
cmd="test__help__help"
;;
Expand Down Expand Up @@ -153,16 +159,12 @@ _test() {

case "${cmd}" in
test)
opts="-h -V --global --generate --help --version action quote value pacman last alias hint help"
opts="-h -V --global --help --version complete action quote value pacman last alias hint help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--generate)
COMPREPLY=($(compgen -W "bash elvish fish powershell zsh" -- "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
Expand Down Expand Up @@ -222,8 +224,30 @@ _test() {
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
test__complete)
opts="-h -V --shell --register --global --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--shell)
COMPREPLY=($(compgen -W "bash elvish fish powershell zsh" -- "${cur}"))
return 0
;;
--register)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
test__help)
opts="action quote value pacman last alias hint help"
opts="complete action quote value pacman last alias hint help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
Expand Down Expand Up @@ -264,6 +288,20 @@ _test() {
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
test__help__complete)
opts=""
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
test__help__help)
opts=""
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
Expand Down
Loading

0 comments on commit aabe822

Please sign in to comment.