test(man): Add snapshot tests

This commit is contained in:
Ed Page 2022-03-07 14:12:59 -06:00
parent 003b0052bb
commit 7c86eeb176
11 changed files with 546 additions and 30 deletions

View file

@ -39,7 +39,7 @@ roff = "0.2.1"
clap = { path = "../", version = "3.1", default-features = false, features = ["std", "env"] }
[dev-dependencies]
pretty_assertions = "1.0"
snapbox = { version = "0.2", features = ["diff"] }
clap = { path = "../", version = "3.1", default-features = false, features = ["std"] }
[features]

230
clap_mangen/tests/common.rs Normal file
View file

@ -0,0 +1,230 @@
pub fn basic_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.arg(clap::Arg::new("config").short('c').global(true))
.arg(clap::Arg::new("v").short('v').conflicts_with("config"))
.subcommand(
clap::Command::new("test")
.about("Subcommand")
.arg(clap::Arg::new("debug").short('d')),
)
}
pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
clap::Arg::new("file")
.value_hint(clap::ValueHint::FilePath)
.help("some input file"),
)
.arg(
clap::Arg::new("config")
.help("some config file")
.short('c')
.visible_short_alias('C')
.long("config")
.visible_alias("conf"),
)
.arg(clap::Arg::new("choice").possible_values(["first", "second"]))
.subcommand(
clap::Command::new("test").about("tests things").arg(
clap::Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
pub fn special_commands_command(name: &'static str) -> clap::Command<'static> {
feature_sample_command(name)
.subcommand(
clap::Command::new("some_cmd")
.about("tests other things")
.arg(
clap::Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
pub fn quoting_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.arg(
clap::Arg::new("single-quotes")
.long("single-quotes")
.help("Can be 'always', 'auto', or 'never'"),
)
.arg(
clap::Arg::new("double-quotes")
.long("double-quotes")
.help("Can be \"always\", \"auto\", or \"never\""),
)
.arg(
clap::Arg::new("backticks")
.long("backticks")
.help("For more information see `echo test`"),
)
.arg(
clap::Arg::new("backslash")
.long("backslash")
.help("Avoid '\\n'"),
)
.arg(
clap::Arg::new("brackets")
.long("brackets")
.help("List packages [filter]"),
)
.arg(
clap::Arg::new("expansions")
.long("expansions")
.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"),
])
}
pub fn aliases_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.about("testing bash completions")
.arg(
clap::Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
clap::Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(clap::Arg::new("positional"))
}
pub fn sub_subcommands_command(name: &'static str) -> clap::Command<'static> {
feature_sample_command(name).subcommand(
clap::Command::new("some_cmd")
.about("top level subcommand")
.subcommand(
clap::Command::new("sub_cmd").about("sub-subcommand").arg(
clap::Arg::new("config")
.long("--config")
.takes_value(true)
.possible_values([clap::PossibleValue::new("Lest quotes aren't escaped.")])
.help("the other case to test"),
),
),
)
}
pub fn value_hint_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.trailing_var_arg(true)
.arg(
clap::Arg::new("choice")
.long("choice")
.possible_values(["bash", "fish", "zsh"]),
)
.arg(
clap::Arg::new("unknown")
.long("unknown")
.value_hint(clap::ValueHint::Unknown),
)
.arg(
clap::Arg::new("other")
.long("other")
.value_hint(clap::ValueHint::Other),
)
.arg(
clap::Arg::new("path")
.long("path")
.short('p')
.value_hint(clap::ValueHint::AnyPath),
)
.arg(
clap::Arg::new("file")
.long("file")
.short('f')
.value_hint(clap::ValueHint::FilePath),
)
.arg(
clap::Arg::new("dir")
.long("dir")
.short('d')
.value_hint(clap::ValueHint::DirPath),
)
.arg(
clap::Arg::new("exe")
.long("exe")
.short('e')
.value_hint(clap::ValueHint::ExecutablePath),
)
.arg(
clap::Arg::new("cmd_name")
.long("cmd-name")
.value_hint(clap::ValueHint::CommandName),
)
.arg(
clap::Arg::new("cmd")
.long("cmd")
.short('c')
.value_hint(clap::ValueHint::CommandString),
)
.arg(
clap::Arg::new("command_with_args")
.takes_value(true)
.multiple_values(true)
.value_hint(clap::ValueHint::CommandWithArguments),
)
.arg(
clap::Arg::new("user")
.short('u')
.long("user")
.value_hint(clap::ValueHint::Username),
)
.arg(
clap::Arg::new("host")
.short('h')
.long("host")
.value_hint(clap::ValueHint::Hostname),
)
.arg(
clap::Arg::new("url")
.long("url")
.value_hint(clap::ValueHint::Url),
)
.arg(
clap::Arg::new("email")
.long("email")
.value_hint(clap::ValueHint::EmailAddress),
)
}
pub fn assert_matches_path(expected_path: impl AsRef<std::path::Path>, cmd: clap::Command) {
let mut buf = vec![];
clap_mangen::Man::new(cmd).render(&mut buf).unwrap();
snapbox::Assert::new()
.action_env("SNAPSHOTS")
.matches_path(expected_path, buf);
}

View file

@ -1,29 +0,0 @@
use clap::{arg, Command};
use clap_mangen::Man;
use std::io;
#[test]
fn render_manpage() {
let cmd = Command::new("myapp")
.version("1.0")
.author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things")
.long_about("With a longer description to help clarify some things.")
.after_help("This is an extra section added to the end of the manpage.")
.after_long_help("With even more text added.")
.arg(
arg!(-c --config <FILE> "Sets a custom config file")
.long_help("Some more text about how to set a custom config file")
.required(false)
.takes_value(true),
)
.arg(arg!([output] "Sets an optional output file").index(1))
.arg(arg!(-d --debug ... "Turn debugging information on"))
.subcommand(
Command::new("test")
.about("does testing things")
.arg(arg!(-l --list "Lists test values")),
);
Man::new(cmd).render(&mut io::sink()).unwrap();
}

50
clap_mangen/tests/roff.rs Normal file
View file

@ -0,0 +1,50 @@
mod common;
#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches_path("tests/snapshots/basic.bash.roff", cmd);
}
#[test]
fn feature_sample() {
let name = "my-app";
let cmd = common::feature_sample_command(name);
common::assert_matches_path("tests/snapshots/feature_sample.bash.roff", cmd);
}
#[test]
fn special_commands() {
let name = "my-app";
let cmd = common::special_commands_command(name);
common::assert_matches_path("tests/snapshots/special_commands.bash.roff", cmd);
}
#[test]
fn quoting() {
let name = "my-app";
let cmd = common::quoting_command(name);
common::assert_matches_path("tests/snapshots/quoting.bash.roff", cmd);
}
#[test]
fn aliases() {
let name = "my-app";
let cmd = common::aliases_command(name);
common::assert_matches_path("tests/snapshots/aliases.bash.roff", cmd);
}
#[test]
fn sub_subcommands() {
let name = "my-app";
let cmd = common::sub_subcommands_command(name);
common::assert_matches_path("tests/snapshots/sub_subcommands.bash.roff", cmd);
}
#[test]
fn value_hint() {
let name = "my-app";
let cmd = common::value_hint_command(name);
common::assert_matches_path("tests/snapshots/value_hint.bash.roff", cmd);
}

View file

@ -0,0 +1,26 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app /- testing bash completions
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-f/fR|/fB/-/-flag/fR] [/fB/-o/fR|/fB/-/-option/fR] [/fIpositional/fR]
.SH DESCRIPTION
testing bash completions
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-f/fR, /fB/-/-flag/fR
cmd flag
.TP
/fB/-o/fR, /fB/-/-option/fR
cmd option
.TP
.SH VERSION
v3.0

View file

@ -0,0 +1,25 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app "
.SH NAME
my/-app
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-c /fR] [/fB/-v /fR] [/fIsubcommands/fR]
.SH DESCRIPTION
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-c/fR
.TP
/fB/-v/fR
.SH SUBCOMMANDS
.TP
my/-app/-test(1)
Subcommand
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)

View file

@ -0,0 +1,32 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app /- Tests completions
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
.SH DESCRIPTION
Tests completions
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-c/fR, /fB/-/-config/fR
some config file
.TP
some input file
.TP
.SH SUBCOMMANDS
.TP
my/-app/-test(1)
tests things
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
v3.0

View file

@ -0,0 +1,57 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-/-single/-quotes/fR] [/fB/-/-double/-quotes/fR] [/fB/-/-backticks/fR] [/fB/-/-backslash/fR] [/fB/-/-brackets/fR] [/fB/-/-expansions/fR] [/fIsubcommands/fR]
.SH DESCRIPTION
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-/-single/-quotes/fR
Can be /*(Aqalways/*(Aq, /*(Aqauto/*(Aq, or /*(Aqnever/*(Aq
.TP
/fB/-/-double/-quotes/fR
Can be "always", "auto", or "never"
.TP
/fB/-/-backticks/fR
For more information see `echo test`
.TP
/fB/-/-backslash/fR
Avoid /*(Aq//n/*(Aq
.TP
/fB/-/-brackets/fR
List packages [filter]
.TP
/fB/-/-expansions/fR
Execute the shell command with $SHELL
.SH SUBCOMMANDS
.TP
my/-app/-cmd/-single/-quotes(1)
Can be /*(Aqalways/*(Aq, /*(Aqauto/*(Aq, or /*(Aqnever/*(Aq
.TP
my/-app/-cmd/-double/-quotes(1)
Can be "always", "auto", or "never"
.TP
my/-app/-cmd/-backticks(1)
For more information see `echo test`
.TP
my/-app/-cmd/-backslash(1)
Avoid /*(Aq//n/*(Aq
.TP
my/-app/-cmd/-brackets(1)
List packages [filter]
.TP
my/-app/-cmd/-expansions(1)
Execute the shell command with $SHELL
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
v3.0

View file

@ -0,0 +1,37 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app /- Tests completions
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
.SH DESCRIPTION
Tests completions
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-c/fR, /fB/-/-config/fR
some config file
.TP
some input file
.TP
.SH SUBCOMMANDS
.TP
my/-app/-test(1)
tests things
.TP
my/-app/-some_cmd(1)
tests other things
.TP
my/-app/-some/-cmd/-with/-hyphens(1)
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
v3.0

View file

@ -0,0 +1,35 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app /- Tests completions
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
.SH DESCRIPTION
Tests completions
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-c/fR, /fB/-/-config/fR
some config file
.TP
some input file
.TP
.SH SUBCOMMANDS
.TP
my/-app/-test(1)
tests things
.TP
my/-app/-some_cmd(1)
top level subcommand
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
v3.0

View file

@ -0,0 +1,53 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app "
.SH NAME
my/-app
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-/-help/fR] [/fB/-/-choice/fR] [/fB/-/-unknown/fR] [/fB/-/-other/fR] [/fB/-p/fR|/fB/-/-path/fR] [/fB/-f/fR|/fB/-/-file/fR] [/fB/-d/fR|/fB/-/-dir/fR] [/fB/-e/fR|/fB/-/-exe/fR] [/fB/-/-cmd/-name/fR] [/fB/-c/fR|/fB/-/-cmd/fR] [/fB/-u/fR|/fB/-/-user/fR] [/fB/-h/fR|/fB/-/-host/fR] [/fB/-/-url/fR] [/fB/-/-email/fR] [/fIcommand_with_args/fR]
.SH DESCRIPTION
.SH OPTIONS
.TP
/fB/-/-help/fR
Print help information
.TP
/fB/-/-choice/fR
.TP
/fB/-/-unknown/fR
.TP
/fB/-/-other/fR
.TP
/fB/-p/fR, /fB/-/-path/fR
.TP
/fB/-f/fR, /fB/-/-file/fR
.TP
/fB/-d/fR, /fB/-/-dir/fR
.TP
/fB/-e/fR, /fB/-/-exe/fR
.TP
/fB/-/-cmd/-name/fR
.TP
/fB/-c/fR, /fB/-/-cmd/fR
.TP
/fB/-u/fR, /fB/-/-user/fR
.TP
/fB/-h/fR, /fB/-/-host/fR
.TP
/fB/-/-url/fR
.TP
/fB/-/-email/fR
.TP