1
0
mirror of https://github.com/Llewellynvdm/starship.git synced 2024-10-31 18:52:29 +00:00

feat(test): allow dynamic mocking of commands (#2307)

This commit is contained in:
David Knaack 2021-02-13 19:32:35 +01:00 committed by GitHub
parent 5ee09aa4dd
commit cdb999447a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 13 deletions

View File

@ -43,8 +43,13 @@ pub struct Context<'a> {
pub shell: Shell, pub shell: Shell,
/// A HashMap of environment variable mocks /// A HashMap of environment variable mocks
#[cfg(test)]
pub env: HashMap<&'a str, String>, pub env: HashMap<&'a str, String>,
/// A HashMap of command mocks
#[cfg(test)]
pub cmd: HashMap<&'a str, Option<CommandOutput>>,
/// Timeout for the execution of commands /// Timeout for the execution of commands
cmd_timeout: Duration, cmd_timeout: Duration,
} }
@ -114,7 +119,10 @@ impl<'a> Context<'a> {
dir_contents: OnceCell::new(), dir_contents: OnceCell::new(),
repo: OnceCell::new(), repo: OnceCell::new(),
shell, shell,
#[cfg(test)]
env: HashMap::new(), env: HashMap::new(),
#[cfg(test)]
cmd: HashMap::new(),
cmd_timeout, cmd_timeout,
} }
} }
@ -129,21 +137,27 @@ impl<'a> Context<'a> {
} }
// Retrives a environment variable from the os or from a table if in testing mode // Retrives a environment variable from the os or from a table if in testing mode
#[cfg(test)]
pub fn get_env<K: AsRef<str>>(&self, key: K) -> Option<String> { pub fn get_env<K: AsRef<str>>(&self, key: K) -> Option<String> {
if cfg!(test) { self.env.get(key.as_ref()).map(|val| val.to_string())
self.env.get(key.as_ref()).map(|val| val.to_string()) }
} else {
env::var(key.as_ref()).ok() #[cfg(not(test))]
} #[inline]
pub fn get_env<K: AsRef<str>>(&self, key: K) -> Option<String> {
env::var(key.as_ref()).ok()
} }
// Retrives a environment variable from the os or from a table if in testing mode (os version) // Retrives a environment variable from the os or from a table if in testing mode (os version)
#[cfg(test)]
pub fn get_env_os<K: AsRef<str>>(&self, key: K) -> Option<OsString> { pub fn get_env_os<K: AsRef<str>>(&self, key: K) -> Option<OsString> {
if cfg!(test) { self.env.get(key.as_ref()).map(OsString::from)
self.env.get(key.as_ref()).map(OsString::from) }
} else {
env::var_os(key.as_ref()) #[cfg(not(test))]
} #[inline]
pub fn get_env_os<K: AsRef<str>>(&self, key: K) -> Option<OsString> {
env::var_os(key.as_ref())
} }
/// Convert a `~` in a path to the home directory /// Convert a `~` in a path to the home directory
@ -246,7 +260,18 @@ impl<'a> Context<'a> {
} }
/// Execute a command and return the output on stdout and stderr if successful /// Execute a command and return the output on stdout and stderr if successful
#[inline]
pub fn exec_cmd(&self, cmd: &str, args: &[&str]) -> Option<CommandOutput> { pub fn exec_cmd(&self, cmd: &str, args: &[&str]) -> Option<CommandOutput> {
#[cfg(test)]
{
let command = match args.len() {
0 => cmd.to_owned(),
_ => format!("{} {}", cmd, args.join(" ")),
};
if let Some(output) = self.cmd.get(command.as_str()) {
return output.clone();
}
}
exec_cmd(cmd, args, self.cmd_timeout) exec_cmd(cmd, args, self.cmd_timeout)
} }
} }

View File

@ -91,7 +91,7 @@ fn parse_java_version(java_version: &str) -> Option<String> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::test::ModuleRenderer; use crate::{test::ModuleRenderer, utils::CommandOutput};
use ansi_term::Color; use ansi_term::Color;
use std::fs::File; use std::fs::File;
use std::io; use std::io;
@ -179,6 +179,32 @@ mod tests {
dir.close() dir.close()
} }
#[test]
fn folder_with_java_file_preview() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("Main.java"))?.sync_all()?;
let actual = ModuleRenderer::new("java").cmd("java -Xinternalversion", Some(CommandOutput {
stdout: "OpenJDK 64-Bit Server VM (16+14) for bsd-aarch64 JRE (16+14), built on Jan 17 2021 07:19:47 by \"brew\" with clang Apple LLVM 12.0.0 (clang-1200.0.32.28)\n".to_owned(),
stderr: "".to_owned()
})).path(dir.path()).collect();
let expected = Some(format!("via {}", Color::Red.dimmed().paint("☕ v16 ")));
assert_eq!(expected, actual);
dir.close()
}
#[test]
fn folder_with_java_file_no_java_installed() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("Main.java"))?.sync_all()?;
let actual = ModuleRenderer::new("java")
.cmd("java -Xinternalversion", None)
.path(dir.path())
.collect();
let expected = Some(format!("via {}", Color::Red.dimmed().paint("")));
assert_eq!(expected, actual);
dir.close()
}
#[test] #[test]
fn folder_with_class_file() -> io::Result<()> { fn folder_with_class_file() -> io::Result<()> {
let dir = tempfile::tempdir()?; let dir = tempfile::tempdir()?;

View File

@ -1,6 +1,6 @@
use crate::config::StarshipConfig;
use crate::context::{Context, Shell}; use crate::context::{Context, Shell};
use crate::logger::StarshipLogger; use crate::logger::StarshipLogger;
use crate::{config::StarshipConfig, utils::CommandOutput};
use log::{Level, LevelFilter}; use log::{Level, LevelFilter};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::io; use std::io;
@ -83,6 +83,12 @@ impl<'a> ModuleRenderer<'a> {
self self
} }
/// Adds the command to the commandv_mocks of the underlying context
pub fn cmd(mut self, key: &'a str, val: Option<CommandOutput>) -> Self {
self.context.cmd.insert(key, val);
self
}
pub fn shell(mut self, shell: Shell) -> Self { pub fn shell(mut self, shell: Shell) -> Self {
self.context.shell = shell; self.context.shell = shell;
self self

View File

@ -16,7 +16,7 @@ pub fn read_file<P: AsRef<Path>>(file_name: P) -> Result<String> {
Ok(data) Ok(data)
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct CommandOutput { pub struct CommandOutput {
pub stdout: String, pub stdout: String,
pub stderr: String, pub stderr: String,