refactor(complete): Make test code reusable

This commit is contained in:
Ed Page 2023-07-20 14:42:58 -05:00
parent 28be38b3a7
commit 1d0fa2c6ce
4 changed files with 94 additions and 80 deletions

4
Cargo.lock generated
View file

@ -646,9 +646,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "completest"
version = "0.0.3"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6feacc4465b103a9c3ee1ca2de3fc8336822145bed52ede7cd80f9b32a1ab329"
checksum = "e6b57d79ef15ead5db9b7168af5a3008a4499d8048005ea3b3868748f12b27ad"
dependencies = [
"ptyprocess",
"vt100",

View file

@ -43,7 +43,7 @@ unicode-xid = { version = "0.2.2", optional = true }
snapbox = { version = "0.4.11", features = ["diff", "examples"] }
# Cutting out `filesystem` feature
trycmd = { version = "0.14.16", default-features = false, features = ["color-auto", "diff", "examples"] }
completest = "0.0.3"
completest = "0.0.4"
clap = { path = "../", version = "4.0.0", default-features = false, features = ["std", "derive", "help"] }
[[example]]

View file

@ -139,46 +139,22 @@ fn subcommand_last() {
#[test]
#[cfg(unix)]
fn register_completion() {
if !has_command("bash") {
if !common::has_command("bash") {
return;
}
let shell = "bash";
let home = std::path::Path::new("tests/snapshots/home/test/bash").to_owned();
let bin_path = snapbox::cmd::compile_example("test", []).unwrap();
let bin_root = bin_path.parent().unwrap().to_owned();
let registration = std::process::Command::new(&bin_path)
.arg(format!("--generate={shell}"))
.output()
.unwrap();
assert!(
registration.status.success(),
"{}",
String::from_utf8_lossy(&registration.stderr)
);
let registration = std::str::from_utf8(&registration.stdout).unwrap();
assert!(!registration.is_empty());
let runtime = completest::BashRuntime::new(bin_root, home).unwrap();
runtime.register("test", registration).unwrap();
common::register_example("test", completest::Shell::Bash);
}
#[test]
#[cfg(unix)]
fn complete() {
if !has_command("bash") {
if !common::has_command("bash") {
return;
}
let shell = "bash";
let home = std::path::PathBuf::from(format!("tests/snapshots/home/test/{shell}"));
let bin_path = snapbox::cmd::compile_example("test", []).unwrap();
let bin_root = bin_path.parent().unwrap().to_owned();
let term = completest::Term::new();
let runtime = completest::BashRuntime::with_home(bin_root, home);
let runtime = common::load_runtime("test", completest::Shell::Bash);
let input = "test \t\t";
let expected = r#"%
@ -187,52 +163,3 @@ fn complete() {
let actual = runtime.complete(input, &term).unwrap();
snapbox::assert_eq(expected, actual);
}
fn has_command(command: &str) -> bool {
let output = match std::process::Command::new(command)
.arg("--version")
.output()
{
Ok(output) => output,
Err(e) => {
// CI is expected to support all of the commands
if is_ci() && cfg!(linux) {
panic!(
"expected command `{}` to be somewhere in PATH: {}",
command, e
);
}
return false;
}
};
if !output.status.success() {
panic!(
"expected command `{}` to be runnable, got error {}:\n\
stderr:{}\n\
stdout:{}\n",
command,
output.status,
String::from_utf8_lossy(&output.stderr),
String::from_utf8_lossy(&output.stdout)
);
}
let stdout = String::from_utf8_lossy(&output.stdout);
println!(
"$ bash --version
{}",
stdout
);
if cfg!(target_os = "macos") && stdout.starts_with("GNU bash, version 3") {
return false;
}
true
}
/// Whether or not this running in a Continuous Integration environment.
fn is_ci() -> bool {
// Consider using `tracked_env` instead of option_env! when it is stabilized.
// `tracked_env` will handle changes, but not require rebuilding the macro
// itself like option_env does.
option_env!("CI").is_some() || option_env!("TF_BUILD").is_some()
}

View file

@ -295,3 +295,90 @@ pub fn assert_matches_path(
.normalize_paths(false)
.matches_path(expected_path, buf);
}
pub fn has_command(command: &str) -> bool {
let output = match std::process::Command::new(command)
.arg("--version")
.output()
{
Ok(output) => output,
Err(e) => {
// CI is expected to support all of the commands
if is_ci() && cfg!(linux) {
panic!(
"expected command `{}` to be somewhere in PATH: {}",
command, e
);
}
return false;
}
};
if !output.status.success() {
panic!(
"expected command `{}` to be runnable, got error {}:\n\
stderr:{}\n\
stdout:{}\n",
command,
output.status,
String::from_utf8_lossy(&output.stderr),
String::from_utf8_lossy(&output.stdout)
);
}
let stdout = String::from_utf8_lossy(&output.stdout);
println!(
"$ {command} --version
{}",
stdout
);
if cfg!(target_os = "macos") && stdout.starts_with("GNU bash, version 3") {
return false;
}
true
}
#[cfg(unix)]
pub fn register_example(name: &str, shell: completest::Shell) {
let shell_name = shell.name();
let home = std::path::Path::new("tests/snapshots/home")
.join(name)
.join(shell_name);
let bin_path = snapbox::cmd::compile_example(name, []).unwrap();
let bin_root = bin_path.parent().unwrap().to_owned();
let registration = std::process::Command::new(&bin_path)
.arg(format!("--generate={shell_name}"))
.output()
.unwrap();
assert!(
registration.status.success(),
"{}",
String::from_utf8_lossy(&registration.stderr)
);
let registration = std::str::from_utf8(&registration.stdout).unwrap();
assert!(!registration.is_empty());
let runtime = shell.init(bin_root, home).unwrap();
runtime.register(name, registration).unwrap();
}
#[cfg(unix)]
pub fn load_runtime(name: &str, shell: completest::Shell) -> Box<dyn completest::Runtime> {
let shell_name = shell.name();
let home = std::path::Path::new("tests/snapshots/home")
.join(name)
.join(shell_name);
let bin_path = snapbox::cmd::compile_example(name, []).unwrap();
let bin_root = bin_path.parent().unwrap().to_owned();
shell.with_home(bin_root, home)
}
/// Whether or not this running in a Continuous Integration environment.
fn is_ci() -> bool {
// Consider using `tracked_env` instead of option_env! when it is stabilized.
// `tracked_env` will handle changes, but not require rebuilding the macro
// itself like option_env does.
option_env!("CI").is_some() || option_env!("TF_BUILD").is_some()
}