diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-06 16:59:11 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-06 16:59:11 -0800 |
commit | e78d0432b8db215cf76cb410de354287fc2da8ba (patch) | |
tree | 1c8e160868d7749b44f66e317848170947b28249 /nitrocli/src/tests/run.rs | |
parent | 6bb629b4d1035c3fd851244060f99da78a7bd929 (diff) | |
download | nitrocli-e78d0432b8db215cf76cb410de354287fc2da8ba.tar.gz nitrocli-e78d0432b8db215cf76cb410de354287fc2da8ba.tar.bz2 |
Introduce support for user-provided extensions
This change introduces support for discovering and executing
user-provided extensions to the program. Extensions are useful for
allowing users to provide additional functionality on top of the
nitrocli proper. Implementation wise we stick to an approach similar to
git or cargo subcommands in nature: we find executables in the PATH
environment variable whose file name starts with "nitrocli-" and allow
for them to be invoked as a nitrocli command.
Diffstat (limited to 'nitrocli/src/tests/run.rs')
-rw-r--r-- | nitrocli/src/tests/run.rs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/nitrocli/src/tests/run.rs b/nitrocli/src/tests/run.rs index c59c660..2212577 100644 --- a/nitrocli/src/tests/run.rs +++ b/nitrocli/src/tests/run.rs @@ -17,6 +17,11 @@ // * along with this program. If not, see <http://www.gnu.org/licenses/>. * // ************************************************************************* +use std::fs; +use std::io::Write; +use std::os::unix::fs::OpenOptionsExt; +use std::path; + use super::*; #[test] @@ -101,3 +106,110 @@ fn version_option() { test(&re, "--version"); test(&re, "-V"); } + +#[test] +fn extension() -> crate::Result<()> { + let ext_dir = tempfile::tempdir()?; + { + let mut ext = fs::OpenOptions::new() + .create(true) + .mode(0o755) + .write(true) + .open(ext_dir.path().join("nitrocli-ext"))?; + + ext.write_all( + br#"#!/usr/bin/env python +print("success") +"#, + )?; + } + + let path = ext_dir.path().as_os_str().to_os_string(); + let out = Nitrocli::make().path(path).build().handle(&["ext"])?; + assert_eq!(out, "success\n"); + Ok(()) +} + +#[test] +fn extension_failure() -> crate::Result<()> { + let ext_dir = tempfile::tempdir()?; + { + let mut ext = fs::OpenOptions::new() + .create(true) + .mode(0o755) + .write(true) + .open(ext_dir.path().join("nitrocli-ext"))?; + + ext.write_all( + br#"#!/usr/bin/env python +import sys +sys.exit(42); +"#, + )?; + } + + let path = ext_dir.path().as_os_str().to_os_string(); + let err = Nitrocli::make() + .path(path) + .build() + .handle(&["ext"]) + .unwrap_err(); + + match err { + crate::Error::ExtensionFailed(ext, rc) => { + assert_eq!(&ext, "ext"); + assert_eq!(rc, Some(42)); + } + _ => panic!("Unexpected error variant found: {:?}", err), + }; + Ok(()) +} + +#[test_device] +fn extension_arguments(model: nitrokey::Model) -> crate::Result<()> { + fn test<F>(model: nitrokey::Model, what: &str, args: &[&str], check: F) -> crate::Result<()> + where + F: FnOnce(&str) -> bool, + { + let ext_dir = tempfile::tempdir()?; + { + let mut ext = fs::OpenOptions::new() + .create(true) + .mode(0o755) + .write(true) + .open(ext_dir.path().join("nitrocli-ext"))?; + + ext.write_all(include_bytes!("extension_model_test.py"))?; + } + + let mut args = args.to_vec(); + args.append(&mut vec!["ext", what]); + + let path = ext_dir.path().as_os_str().to_os_string(); + let out = Nitrocli::make() + .model(model) + .path(path) + .build() + .handle(&args)?; + + assert!(check(&out), out); + Ok(()) + } + + test(model, "model", &[], |out| { + out == model.to_string().to_lowercase() + "\n" + })?; + test(model, "nitrocli", &[], |out| { + path::Path::new(out) + .file_stem() + .unwrap() + .to_str() + .unwrap() + .trim() + .contains("nitrocli") + })?; + test(model, "verbosity", &[], |out| out == "0\n")?; + test(model, "verbosity", &["-v"], |out| out == "1\n")?; + test(model, "verbosity", &["-v", "--verbose"], |out| out == "2\n")?; + Ok(()) +} |