summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatan Kushner <hello@matchai.me>2019-06-06 13:18:00 +0100
committerGitHub <noreply@github.com>2019-06-06 13:18:00 +0100
commit8239fbd12befad1126e677fa083ce73947d74d8c (patch)
treef2d7a82f92c5f696e77a70fea39c7b56ac6b3875
parentbb220bb5a056b28c6457d2f5c75c53184a2cbe77 (diff)
Refactor integration tests (#71)
- Create subcommands to be able to print modules independently - `starship prompt` will print the full prompt - `starship module <MODULE_NAME>` will print a specific module e.g. `starship module python` - Added `--path` flag to print the prompt or modules without being in a specific directory - Added `--status` flag to provide the status of the last command, instead of requiring it as an argument - Refactored integration tests to be end-to-end tests, since there was no way in integration tests to set the environment variables for a specific command, which was required for the `username` module - Moved e2e tests to `tests/testsuite` to allow for a single binary to be built - Tests will build/run faster - No more false positives for unused functions - Added tests for `username` - Removed codecov + tarpaulin 😢
-rw-r--r--.gitignore3
-rw-r--r--README.md1
-rw-r--r--adapters/fish_prompt.fish2
-rw-r--r--adapters/starship.zsh-theme2
-rw-r--r--ci/azure-test-docker.yml8
-rwxr-xr-xintegration_test7
-rw-r--r--src/context.rs10
-rw-r--r--src/main.rs67
-rw-r--r--src/modules/character.rs2
-rw-r--r--src/print.rs11
-rw-r--r--tests/Dockerfile7
-rw-r--r--tests/character.rs20
-rw-r--r--tests/common.rs27
-rw-r--r--tests/directory.rs158
-rw-r--r--tests/go.rs134
-rw-r--r--tests/nodejs.rs62
-rw-r--r--tests/python.rs79
-rw-r--r--tests/testsuite/character.rs47
-rw-r--r--tests/testsuite/common.rs22
-rw-r--r--tests/testsuite/directory.rs158
-rw-r--r--tests/testsuite/golang.rs140
-rw-r--r--tests/testsuite/line_break.rs13
-rw-r--r--tests/testsuite/main.rs8
-rw-r--r--tests/testsuite/nodejs.rs72
-rw-r--r--tests/testsuite/package.rs0
-rw-r--r--tests/testsuite/python.rs73
-rw-r--r--tests/testsuite/username.rs64
27 files changed, 678 insertions, 519 deletions
diff --git a/.gitignore b/.gitignore
index 958be4e10..963cff618 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,3 @@ Cargo.lock
# Intellij IDE configuration
.idea/
-
-# Cobertura coverage report
-cobertura.xml
diff --git a/README.md b/README.md
index 576f003bb..bae3808f9 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,6 @@
<p align="center">The cross-shell prompt for astronauts.</p>
<p align="center">
<a href="https://dev.azure.com/starship-control/starship/_build"><img src="https://badgen.net/azure-pipelines/starship-control/starship/Starship%20Test%20Suite" alt="Azure Pipelines Build Status"></a>
- <a href="https://codecov.io/gh/starship/starship"><img src="https://badgen.net/codecov/c/github/starship/starship" alt="Codecov Coverage"></a>
<a href="#contributors"><img src="https://badgen.net/badge/all%20contributors/7/orange" alt="All Contributors"></a>
<a href="https://discord.gg/8Jzqu3T"><img src="https://badgen.net/badge/chat/on%20discord/7289da" alt="Chat on Discord"></a>
</p>
diff --git a/adapters/fish_prompt.fish b/adapters/fish_prompt.fish
index 965398ea1..cd3d77120 100644
--- a/adapters/fish_prompt.fish
+++ b/adapters/fish_prompt.fish
@@ -1,3 +1,3 @@
function fish_prompt
- starship $status
+ starship prompt --status=$status
end
diff --git a/adapters/starship.zsh-theme b/adapters/starship.zsh-theme
index ded509824..0da0bd713 100644
--- a/adapters/starship.zsh-theme
+++ b/adapters/starship.zsh-theme
@@ -1 +1 @@
-PROMPT='$(starship $?)'
+PROMPT='$(starship prompt --status=$?)'
diff --git a/ci/azure-test-docker.yml b/ci/azure-test-docker.yml
index 93b8cfcbf..22df04cb5 100644
--- a/ci/azure-test-docker.yml
+++ b/ci/azure-test-docker.yml
@@ -5,11 +5,11 @@ jobs:
vmImage: ubuntu-16.04
steps:
- - script: ./integration_test
- displayName: Run integration test within Docker
+ - script: docker pull starshipcommand/starship-test
+ displayName: Pull docker image
- - script: bash <(curl -s https://codecov.io/bash) -t $(CODECOV_TOKEN)
- displayName: Report coverage to Codecov
+ - script: ./integration_test
+ displayName: Run integration test suite
- script: |
docker login -u $(dockerUsername) -p $(dockerPassword)
diff --git a/integration_test b/integration_test
index 81c7ba3b2..cf91a2134 100755
--- a/integration_test
+++ b/integration_test
@@ -6,9 +6,6 @@ if ! (docker --version); then
exit 1
fi
-printf 'Pulling latest docker image'
-docker pull starshipcommand/starship-test
-
printf 'Building test docker image:\n'
docker build -f tests/Dockerfile \
--tag starshipcommand/starship-test \
@@ -16,6 +13,4 @@ docker build -f tests/Dockerfile \
.
printf 'Running test suite:\n'
-# `seccomp=unconfined` is needed to allow tarpaulin to disable ASLR
-# Details found here: https://github.com/xd009642/tarpaulin/issues/146
-docker run --rm --security-opt seccomp=unconfined -v $(pwd):/starship starshipcommand/starship-test
+docker run --rm -v $(pwd):/starship starshipcommand/starship-test
diff --git a/src/context.rs b/src/context.rs
index b86bd0708..e0e7e286c 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -15,11 +15,15 @@ pub struct Context<'a> {
impl<'a> Context<'a> {
pub fn new(arguments: ArgMatches) -> Context {
- let current_dir = env::current_dir().expect("Unable to identify current directory.");
- Context::new_with_dir(arguments, current_dir)
+ // Retreive the "path" flag. If unavailable, use the current directory instead.
+ let path = arguments
+ .value_of("path")
+ .map(From::from)
+ .unwrap_or_else(|| env::current_dir().expect("Unable to identify current directory."));
+
+ Context::new_with_dir(arguments, path)
}
- #[allow(dead_code)]
pub fn new_with_dir<T>(arguments: ArgMatches, dir: T) -> Context
where
T: Into<PathBuf>,
diff --git a/src/main.rs b/src/main.rs
index 1f69d4ed9..4707cd816 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,36 +1,77 @@
#[macro_use]
extern crate clap;
-extern crate ansi_term;
-extern crate battery;
-extern crate dirs;
-extern crate git2;
-extern crate pretty_env_logger;
-
mod context;
mod module;
mod modules;
mod print;
mod segment;
-use clap::{App, Arg};
+use clap::{App, Arg, SubCommand};
fn main() {
pretty_env_logger::init();
- let args = App::new("Starship")
+ let matches = App::new("Starship")
.about("The cross-shell prompt for astronauts. ✨🚀")
// pull the version number from Cargo.toml
.version(crate_version!())
// pull the authors from Cargo.toml
.author(crate_authors!())
.after_help("https://github.com/matchai/starship")
- .arg(
- Arg::with_name("status_code")
- .help("The status code of the previously run command")
- .required(true),
+ .subcommand(
+ SubCommand::with_name("prompt")
+ .about("Prints the full starship prompt")
+ .arg(
+ Arg::with_name("status_code")
+ .short("s")
+ .long("status")
+ .value_name("STATUS_CODE")
+ .help("The status code of the previously run command")
+ .takes_value(true),
+ )
+ .arg(
+ Arg::with_name("path")
+ .short("p")
+ .long("path")
+ .value_name("PATH")
+ .help("The path that the prompt should render for ($PWD by default)")
+ .takes_value(true),
+ ),
+ )
+ .subcommand(
+ SubCommand::with_name("module")
+ .about("Prints a specific prompt module")
+ .arg(
+ Arg::with_name("name")
+ .help("The name of the module to be printed")
+ .required(true),
+ )
+ .arg(
+ Arg::with_name("status_code")
+ .short("s")
+ .long("status")
+ .value_name("STATUS_CODE")
+ .help("The status code of the previously run command")
+ .takes_value(true),
+ )
+ .arg(
+ Arg::with_name("path")
+ .short("p")
+ .long("path")
+ .value_name("PATH")
+ .help("The path the prompt should render for ($PWD by default)")
+ .takes_value(true),
+ ),
)
.get_matches();
- print::prompt(args);
+ match matches.subcommand() {
+ ("prompt", Some(sub_m)) => print::prompt(sub_m.clone()),
+ ("module", Some(sub_m)) => {
+ let module_name = sub_m.value_of("name").expect("Module name missing.");
+ print::module(module_name, sub_m.clone());
+ }
+ _ => {}
+ }
}
diff --git a/src/modules/character.rs b/src/modules/character.rs
index 2a9334894..1dfc27991 100644
--- a/src/modules/character.rs
+++ b/src/modules/character.rs
@@ -20,7 +20,7 @@ pub fn segment(context: &Context) -> Option<Module> {
let symbol = module.new_segment("symbol", PROMPT_CHAR);
let arguments = &context.arguments;
- if arguments.value_of("status_code").unwrap() == "0" {
+ if arguments.value_of("status_code").unwrap_or("0") == "0" {
symbol.set_style(color_success.bold());
} else {
symbol.set_style(color_failure.bold());
diff --git a/src/print.rs b/src/print.rs
index 53442f23f..71d453e34 100644
--- a/src/print.rs
+++ b/src/print.rs
@@ -46,3 +46,14 @@ pub fn prompt(args: ArgMatches) {
// Print all remaining modules
printable.for_each(|module| write!(handle, "{}", module).unwrap());
}
+
+pub fn module(module_name: &str, args: ArgMatches) {
+ let context = Context::new(args);
+
+ // If the module returns `None`, print an empty string
+ let module = modules::handle(module_name, &context)
+ .map(|m| m.to_string())
+ .unwrap_or_default();
+
+ print!("{}", module);
+}
diff --git a/tests/Dockerfile b/tests/Dockerfile
index 532b42dc5..4d1cd3217 100644
--- a/tests/Dockerfile
+++ b/tests/Dockerfile
@@ -1,9 +1,5 @@
FROM rust
-# Install Tarpaulin (code coverage tool)
-# https://github.com/xd009642/tarpaulin
-COPY --from=xd009642/tarpaulin /usr/local/cargo/bin/cargo-tarpaulin /usr/local/cargo/bin/cargo-tarpaulin
-
# Install Node.js
ENV NODE_VERSION 12.0.0
ENV PATH /root/.nvm/versions/node/v$NODE_VERSION/bin:$PATH
@@ -54,5 +50,4 @@ RUN rm -rf /starship
RUN mkdir starship
WORKDIR /starship
-# Instrument coverage tooling and run the full test suite
-CMD ["cargo", "tarpaulin", "--ignored", "--out", "Xml"]
+CMD ["cargo", "test", "--", "--ignored"]
diff --git a/tests/character.rs b/tests/character.rs
deleted file mode 100644
index be0b1a8e3..000000000
--- a/tests/character.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use ansi_term::Color;
-use std::path::Path;
-
-mod common;
-
-#[test]
-fn char_module_success_status() {
- let dir = Path::new("~");
- let expected = format!("{} ", Color::Green.bold().paint("➜"));
- let actual = common::render_module_with_status("char", &dir, "0");
- assert_eq!(expected, actual);
-}
-
-#[test]
-fn char_module_failure_status() {
- let dir = Path::new("~");
- let expected = format!("{} ", Color::Red.bold().paint("➜"));
- let actual = common::render_module_with_status("char", &dir, "1");
- assert_eq!(expected, actual);
-}
diff --git a/tests/common.rs b/tests/common.rs
deleted file mode 100644
index 2d2cd2a00..000000000
--- a/tests/common.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use clap::{App, Arg};
-use starship::context::Context;
-use starship::modules;
-use std::path::PathBuf;
-
-#[allow(dead_code)]
-pub fn render_module<T>(module: &str, path: T) -> String
-where
- T: Into<PathBuf>,
-{
- render_module_with_status(module, path.into(), "0")
-}
-
-pub fn render_module_with_status<T>(module: &str, path: T, status: &str) -> String
-where
- T: Into<PathBuf>,
-{
- // Create an `Arg` with status_code of "0"
- let args = App::new("starship")
- .arg(Arg::with_name("status_code"))
- .get_matches_from(vec!["starship", status]);
- let context = Context::new_with_dir(args, path.into());
-
- let module = modules::handle(module, &context);
-
- module.unwrap().to_string()
-}
diff --git a/tests/directory.rs b/tests/directory.rs
deleted file mode 100644
index 42d6398ad..000000000
--- a/tests/directory.rs
+++ /dev/null
@@ -1,158 +0,0 @@
-use ansi_term::Color;
-use dirs::home_dir;
-use git2::Repository;
-use std::fs;
-use std::io;
-use std::path::Path;
-use tempfile::TempDir;
-
-mod common;
-
-#[test]
-fn home_directory() -> io::Result<()> {
- let dir = Path::new("~");
-
- let expected = format!("in {} ", Color::Cyan.bold().paint("~").to_string());
- let actual = common::render_module("dir", &dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn directory_in_home() -> io::Result<()> {
- let dir = home_dir().unwrap().join("starship/engine");
- fs::create_dir_all(&dir)?;
-
- let expected = format!(
- "in {} ",
- Color::Cyan.bold().paint("~/starship/engine").to_string()
- );
- let actual = common::render_module("dir", &dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn truncated_directory_in_home() -> io::Result<()> {
- let dir = home_dir().unwrap().join("starship/engine/schematics");
- fs::create_dir_all(&dir)?;
-
- let expected = format!(
- "in {} ",
- Color::Cyan
- .bold()
- .paint("starship/engine/schematics")
- .to_string()
- );
- let actual = common::render_module("dir", &dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-fn root_directory() -> io::Result<()> {
- let dir = Path::new("/");
-
- let expected = format!("in {} ", Color::Cyan.bold().paint("/").to_string());
- let actual = common::render_module("dir", &dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-fn directory_in_root() -> io::Result<()> {
- let dir = Path::new("/tmp");
-
- let expected = format!("in {} ", Color::Cyan.bold().paint("/tmp").to_string());
- let actual = common::render_module("dir", &dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn truncated_directory_in_root() -> io::Result<()> {
- let dir = Path::new("/tmp/starship/thrusters/rocket");
- fs::create_dir_all(&dir)?;
-
- let expected = format!(
- "in {} ",
- Color::Cyan
- .bold()
- .paint("starship/thrusters/rocket")
- .to_string()
- );
- let actual = common::render_module("dir", &dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn git_repo_root() -> io::Result<()> {
- let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
- let repo_dir = tmp_dir.path().join("rocket-controls");
- fs::create_dir(&repo_dir)?;
-
- Repository::init(&repo_dir).unwrap();
-
- let expected = format!(
- "in {} ",
- Color::Cyan.bold().paint("rocket-controls").to_string()
- );
- let actual = common::render_module("dir", &repo_dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn directory_in_git_repo() -> io::Result<()> {
- let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
- let repo_dir = tmp_dir.path().join("rocket-controls");
- let dir = repo_dir.join("src");
- fs::create_dir_all(&dir)?;
-
- Repository::init(&repo_dir).unwrap();
-
- let expected = format!(
- "in {} ",
- Color::Cyan.bold().paint("rocket-controls/src").to_string()
- );
- let actual = common::render_module("dir", &dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn truncated_directory_in_git_repo() -> io::Result<()> {
- let tmp_dir = TempDir::new()?;
- let repo_dir = tmp_dir.path().join("rocket-controls");
- let dir = repo_dir.join("src/meters/fuel-gauge");
- fs::create_dir_all(&dir)?;
-
- Repository::init(&repo_dir).unwrap();
-
- let expected = format!(
- "in {} ",
- Color::Cyan
- .bold()
- .paint("src/meters/fuel-gauge")
- .to_string()
- );
- let actual = common::render_module("dir", &dir);
- assert_eq!(expected, actual);
-
- Ok(())
-}
diff --git a/tests/go.rs b/tests/go.rs
deleted file mode 100644
index 369530abc..000000000
--- a/tests/go.rs
+++ /dev/null
@@ -1,134 +0,0 @@
-use ansi_term::Color;
-use starship::segment::Segment;
-use std::fs::{self, File};
-use std::io;
-use tempfile::TempDir;
-
-mod common;
-
-#[test]
-#[ignore]
-fn folder_with_go_file() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("main.go"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("go")
- .set_value("🐹 v1.10")
- .set_style(Color::Cyan.bold())
- );
- let actual = common::render_module("go", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_go_mod() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("go.mod"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("go")
- .set_value("🐹 v1.10")
- .set_style(Color::Cyan.bold())
- );
- let actual = common::render_module("go", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_go_sum() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("go.sum"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("go")
- .set_value("🐹 v1.10")
- .set_style(Color::Cyan.bold())
- );
- let actual = common::render_module("go", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_godeps() -> io::Result<()> {
- let dir = TempDir::new()?;
- let godeps = dir.path().join("Godeps");
- fs::create_dir_all(&godeps)?;
-
- let expected = format!(
- "via {} ",
- Segment::new("go")
- .set_value("🐹 v1.10")
- .set_style(Color::Cyan.bold())
- );
- let actual = common::render_module("go", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_glide_yaml() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("glide.yaml"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("go")
- .set_value("🐹 v1.10")
- .set_style(Color::Cyan.bold())
- );
- let actual = common::render_module("go", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_gopkg_yml() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("Gopkg.yml"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("go")
- .set_value("🐹 v1.10")
- .set_style(Color::Cyan.bold())
- );
- let actual = common::render_module("go", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_gopkg_lock() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("Gopkg.lock"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("go")
- .set_value("🐹 v1.10")
- .set_style(Color::Cyan.bold())
- );
- let actual = common::render_module("go", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
diff --git a/tests/nodejs.rs b/tests/nodejs.rs
deleted file mode 100644
index 38bca73bf..000000000
--- a/tests/nodejs.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-use ansi_term::Color;
-use starship::segment::Segment;
-use std::fs::{self, File};
-use std::io;
-use tempfile::TempDir;
-
-mod common;
-
-#[test]
-#[ignore]
-fn folder_with_package_json() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("package.json"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("node")
- .set_value("⬢ v12.0.0")
- .set_style(Color::Green.bold())
- );
- let actual = common::render_module("nodejs", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_js_file() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("index.js"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("node")
- .set_value("⬢ v12.0.0")
- .set_style(Color::Green.bold())
- );
- let actual = common::render_module("nodejs", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_node_modules() -> io::Result<()> {
- let dir = TempDir::new()?;
- let node_modules = dir.path().join("node_modules");
- fs::create_dir_all(&node_modules)?;
-
- let expected = format!(
- "via {} ",
- Segment::new("node")
- .set_value("⬢ v12.0.0")
- .set_style(Color::Green.bold())
- );
- let actual = common::render_module("nodejs", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
diff --git a/tests/python.rs b/tests/python.rs
deleted file mode 100644
index 237c1f306..000000000
--- a/tests/python.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-use ansi_term::Color;
-use starship::segment::Segment;
-use std::fs::File;
-use std::io;
-use tempfile::TempDir;
-
-mod common;
-
-#[test]
-#[ignore]
-fn folder_with_python_version() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join(".python-version"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("python")
- .set_value("🐍 v3.6.8")
- .set_style(Color::Yellow.bold())
- );
- let actual = common::render_module("python", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_requirements_txt() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("requirements.txt"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("python")
- .set_value("🐍 v3.6.8")
- .set_style(Color::Yellow.bold())
- );
- let actual = common::render_module("python", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_pyproject_toml() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("pyproject.toml"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("python")
- .set_value("🐍 v3.6.8")
- .set_style(Color::Yellow.bold())
- );
- let actual = common::render_module("python", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
-
-#[test]
-#[ignore]
-fn folder_with_py_file() -> io::Result<()> {
- let dir = TempDir::new()?;
- File::create(dir.path().join("main.py"))?;
-
- let expected = format!(
- "via {} ",
- Segment::new("python")
- .set_value("🐍 v3.6.8")
- .set_style(Color::Yellow.bold())
- );
- let actual = common::render_module("python", &dir.path());
- assert_eq!(expected, actual);
-
- Ok(())
-}
diff --git a/tests/testsuite/character.rs b/tests/testsuite/character.rs
new file mode 100644
index 000000000..80a12bd32
--- /dev/null
+++ b/tests/testsuite/character.rs
@@ -0,0 +1,47 @@
+use ansi_term::Color;
+use std::io;
+
+use crate::common;
+
+#[test]
+fn char_module_success_status() -> io::Result<()> {
+ let expected = format!("{} ", Color::Green.bold().paint("➜"));
+
+ // Status code 0
+ let output = common::render_module("char").arg("--status=0").output()?;
+ let actual = String::from_utf8(output.stdout).unwrap();
+ assert_eq!(expected, actual);
+
+ // No status code
+ let output = common::render_module("char").output()?;
+ let actual = String::from_utf8(output.stdout).unwrap();
+ assert_eq!(expected, actual);
+
+ Ok(())
+}
+
+#[test]
+fn char_module_failure_status() -> io::Result<()> {
+ let expected = format!("{} ", Color::Red.bold().paint("➜"));
+
+ // Error status code 1
+ let output = common::render_module("char").arg("--status=1").output()?;
+ let actual = String::from_utf8(output.stdout).unwrap();
+ assert_eq!(expected, actual);
+
+ // Random non-zero status code
+ let output = common::render_module("char")
+ .arg("--status=54321")
+ .output()?;
+ let actual = String::from_utf8(output.stdout).unwrap();
+ assert_eq!(expected, actual);
+
+ // Negative status code!?
+ let output = common::render_module("char")
+ .arg("--status=-5000")
+ .output()?;
+ let actual = String::from_utf8(output.stdout).unwrap();
+ assert_eq!(expected, actual);
+
+ Ok(())
+}
diff --git a/tests/testsuite/common.rs b/tests/testsuite/common.rs
new file mode 100644
index 000000000..451880288
--- /dev/null
+++ b/tests/testsuite/common.rs
@@ -0,0 +1,22 @@
+use std::{io, process};
+
+pub fn render_prompt() -> process::Command {
+ let mut command = process::Command::new("./target/debug/starship");
+ command.arg("prompt");
+
+ command
+}
+
+pub fn render_module(module_name: &str) -> process::Command {
+ let mut command = process::Command::new("./target/debug/starship");
+ command.arg("module").arg(module_name);
+
+ command
+}
+
+/// Create a temporary directory with full access permissions (rwxrwxrwt).
+pub fn new_tempdir() -> io::Result<tempfile::TempDir> {
+ // Using `tempfile::TempDir` directly creates files on macOS within
+ // "/var/folders", which provides us with restricted permissions (rwxr-xr-x)
+ tempfile::tempdir_in("/tmp")
+}
diff --git a/tests/testsuite/directory.rs b/tests/testsuite/directory.rs
new file mode 100644
index 000000000..8835b8440
--- /dev/null
+++ b/tests/testsuite/directory.rs
@@ -0,0 +1,158 @@
+use ansi_term::Color;
+use dirs::home_dir;
+use git2::Repository;
+use std::fs;
+use std::io;
+use std::path::Path;
+use tempfile::TempDir;
+
+use crate::common;
+
+#[test]
+fn home_directory() -> io::Result<()> {
+ let output = common::render_module("dir").arg("--path=~").output()?;
+ let actual = String::from_utf8(output.stdout).unwrap();
+
+ let expected = format!("in {} ", Color::Cyan.bold().paint("~"));
+ assert_eq!(expected, actual);
+ Ok(())
+}
+
+#[test]
+#[ignore]
+fn directory_in_home() -> io::Result<()> {
+ let dir = home_dir().unwrap().join("starship/engine");
+ fs::create_dir_all(&dir)?;
+
+ let output = common::render_module("dir")
+ .arg("--path")
+ .arg(dir)
+ .output()?;
+ let actual = String::from_utf8(output.stdout).unwrap();
+
+ let expected = format!("in {} ", Color::Cyan.bold().paint("~/starship/engine"));
+ assert_eq!(expected, actual);
+ Ok(())
+}
+
+#[test]
+#[ignore]
+fn truncated_directory_in_home() -> io::Result<()> {
+ let dir = home_dir().unwrap().join("starship/engine/schematics");
+ fs::create_dir_all(&dir)?;
+
+ let output = common::render_module("dir")
+ .arg("--path")