mirror of
https://github.com/Llewellynvdm/starship.git
synced 2024-11-24 13:47:38 +00:00
test: introduce env variable mocking (#1490)
This commit is contained in:
parent
8b0f589486
commit
88b603be38
6
.github/workflows/workflow.yml
vendored
6
.github/workflows/workflow.yml
vendored
@ -125,12 +125,6 @@ jobs:
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
# Install dotnet at a fixed version
|
||||
- name: Setup | DotNet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: "2.2.402"
|
||||
|
||||
# Install Mercurial (pre-installed on Linux and windows)
|
||||
- name: Setup | Mercurial (macos)
|
||||
if: matrix.os == 'macOS-latest'
|
||||
|
137
CONTRIBUTING.md
137
CONTRIBUTING.md
@ -24,6 +24,52 @@ The project begins in [`main.rs`](src/main.rs), where the appropriate `print::`
|
||||
|
||||
Any styling that is applied to a module is inherited by its segments. Module prefixes and suffixes by default don't have any styling applied to them.
|
||||
|
||||
## Environment Variables and external commands
|
||||
|
||||
We have custom functions to be able to test our modules better. Here we show you how.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
To get an environment variable we have special function to allow for mocking of vars. Here's a quick example:
|
||||
|
||||
```rust
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
|
||||
use crate::configs::php::PhpConfig;
|
||||
use crate::formatter::StringFormatter;
|
||||
use crate::utils;
|
||||
|
||||
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
// Here `my_env_var` will be either the contents of the var or the function
|
||||
// will exit if the variable is not set.
|
||||
let my_env_var = context.get_env("MY_VAR")?;
|
||||
|
||||
// Then you can happily use the value
|
||||
}
|
||||
```
|
||||
|
||||
## External commands
|
||||
|
||||
To run a external command (e.g. to get the version of a tool) and to allow for mocking use the `utils::exec_cmd` function. Here's a quick example:
|
||||
|
||||
```rust
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
|
||||
use crate::configs::php::PhpConfig;
|
||||
use crate::formatter::StringFormatter;
|
||||
use crate::utils;
|
||||
|
||||
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
// Here `my_env_var` will be either the stdout of the called command or the function
|
||||
// will exit if the called program was not installed or could not be run.
|
||||
let output = utils::exec_cmd("my_command", &["first_arg", "second_arg"])?.stdout;
|
||||
|
||||
// Then you can happily use the output
|
||||
}
|
||||
```
|
||||
|
||||
## Logging
|
||||
|
||||
Debug logging in starship is done with [pretty_env_logger](https://crates.io/crates/pretty_env_logger).
|
||||
@ -56,37 +102,81 @@ rustup component add rustfmt
|
||||
cargo fmt
|
||||
```
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
Testing is critical to making sure starship works as intended on systems big and small. Starship interfaces with many applications and system APIs when generating the prompt, so there's a lot of room for bugs to slip in.
|
||||
|
||||
Unit tests and a subset of integration tests can be run with `cargo test`.
|
||||
The full integration test suite is run on GitHub as part of our GitHub Actions continuous integration.
|
||||
Unit tests are written using the built-in Rust testing library in the same file as the implementation, as is traditionally done in Rust codebases. These tests can be run with `cargo test` and are run on GitHub as part of our GitHub Actions continuous integration to ensure consistend behavior.
|
||||
|
||||
### Unit Testing
|
||||
All tests that test the rendered output of a module should use `ModuleRenderer`. For Example:
|
||||
|
||||
Unit tests are written using the built-in Rust testing library in the same file as the implementation, as is traditionally done in Rust codebases. These tests can be run with `cargo test`.
|
||||
```rust
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
|
||||
use crate::configs::php::PhpConfig;
|
||||
use crate::formatter::StringFormatter;
|
||||
use crate::utils;
|
||||
|
||||
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
/* This is where your module code goes */
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
|
||||
|
||||
#[test]
|
||||
fn should_render() -> io::Result<()> {
|
||||
// Here you setup the testing environment
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
// Create some file needed to render the module
|
||||
File::create(dir.path().join("YOUR_FILE"))?.sync_all()?;
|
||||
|
||||
// The output of the module
|
||||
let actual = ModuleRenderer::new("YOUR_MODULE_NAME")
|
||||
// For a custom path
|
||||
.path(&tempdir.path())
|
||||
// For a custom config
|
||||
.config(toml::toml!{
|
||||
[YOUR_MODULE_NAME]
|
||||
val = 1
|
||||
})
|
||||
// For env mocking
|
||||
.env("KEY","VALUE")
|
||||
// Run the module and collect the output
|
||||
.collect();
|
||||
|
||||
// The value that should be rendered by the module.
|
||||
let expected = Some(format!("{} ",Color::Black.paint("THIS SHOULD BE RENDERED")));
|
||||
|
||||
// Assert that the actual and expected values are the same
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
// Close the tempdir
|
||||
tempdir.close()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If a module depends on output of another program, then that output should be added to the match statement in [`utils.rs`](src/utils.rs). The match has to be exactly the same as the call to `utils::exec_cmd()`, including positional arguments and flags. The array of arguments are joined by a `" "`, so `utils::exec_cmd("program", &["arg", "more_args"])` would match with the `program arg more_args` match statement.
|
||||
|
||||
If the program cannot be mocked (e.g. It performs some filesystem operations, either writing or reading files) then it has to added to the project's GitHub Actions workflow file([`.github/workflows/workflow.yml`](.github/workflows/workflow.yml)) and the test has to be marked with an `#[ignored]`. This ensures that anyone can run the test suite locally without needing to pre-configure their environment. The `#[ignored]` attribute is bypassed during CI runs in GitHub Actions.
|
||||
|
||||
Unit tests should be fully isolated, only testing a given function's expected output given a specific input, and should be reproducible on any machine. Unit tests should not expect the computer running them to be in any particular state. This includes having any applications pre-installed, having any environment variables set, etc.
|
||||
|
||||
The previous point should be emphasized: even seemingly innocuous ideas like "if we can see the directory, we can read it" or "nobody will have their home directory be a git repo" have bitten us in the past. Having even a single test fail can completely break installation on some platforms, so be careful with tests!
|
||||
|
||||
### Integration Testing
|
||||
|
||||
Integration tests are located in the [`tests/`](tests) directory and are also written using the built-in Rust testing library.
|
||||
|
||||
Integration tests should test full modules or the entire prompt. All integration tests that expect the testing environment to have pre-existing state or tests that make permanent changes to the filesystem should have the `#[ignore]` attribute added to them. All tests that don't depend on any preexisting state will be run alongside the unit tests with `cargo test`.
|
||||
|
||||
For tests that depend on having preexisting state, whatever needed state will have to be added to the project's GitHub Actions workflow file([`.github/workflows/workflow.yml`](.github/workflows/workflow.yml)).
|
||||
|
||||
### Test Programming Guidelines
|
||||
|
||||
Any tests that depend on File I/O should use [`sync_all()`](https://doc.rust-lang.org/std/fs/struct.File.html#method.sync_all) when creating files or after writing to files.
|
||||
|
||||
Any tests that use `tempfile::tempdir` should take care to call `dir.close()` after usage to ensure the lifecycle of the directory can be reasoned about.
|
||||
|
||||
Any tests that use `create_fixture_repo()` should remove the returned directory after usage with `remove_dir_all::remove_dir_all()`.
|
||||
Any tests that use `tempfile::tempdir` should take care to call `dir.close()` after usage to ensure the lifecycle of the directory can be reasoned about. This includes `fixture_repo()` as it returns a TempDir that should be closed.
|
||||
|
||||
## Running the Documentation Website Locally
|
||||
|
||||
@ -98,17 +188,20 @@ After cloning the project, you can do the following to run the VuePress website
|
||||
|
||||
1. `cd` into the `/docs` directory.
|
||||
2. Install the project dependencies:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
$ npm install
|
||||
```
|
||||
|
||||
3. Start the project in development mode:
|
||||
```
|
||||
$ npm run dev
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Once setup is complete, you can refer to VuePress documentation on the actual implementation here: https://vuepress.vuejs.org/guide/.
|
||||
Once setup is complete, you can refer to VuePress documentation on the actual implementation here: <https://vuepress.vuejs.org/guide/>.
|
||||
|
||||
### Git/GitHub workflow
|
||||
## Git/GitHub workflow
|
||||
|
||||
This is our preferred process for opening a PR on GitHub:
|
||||
|
||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1104,7 +1104,6 @@ dependencies = [
|
||||
"quick-xml",
|
||||
"rayon",
|
||||
"regex",
|
||||
"remove_dir_all",
|
||||
"serde_json",
|
||||
"starship_module_config_derive",
|
||||
"sysinfo",
|
||||
|
14
Cargo.toml
14
Cargo.toml
@ -31,7 +31,7 @@ tls-vendored = ["native-tls/vendored"]
|
||||
clap = "2.33.1"
|
||||
ansi_term = "0.12.1"
|
||||
dirs-next = "1.0.1"
|
||||
git2 = { version = "0.13.8", default-features = false, features = [] }
|
||||
git2 = { version = "0.13.8", default-features = false }
|
||||
toml = { version = "0.5.6", features = ["preserve_order"] }
|
||||
serde_json = "1.0.57"
|
||||
rayon = "1.3.1"
|
||||
@ -64,17 +64,19 @@ attohttpc = { version = "0.15.0", optional = true, default-features = false, fea
|
||||
native-tls = { version = "0.2", optional = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3", features = ["winuser", "securitybaseapi", "processthreadsapi", "handleapi", "impl-default"]}
|
||||
winapi = { version = "0.3", features = [
|
||||
"winuser",
|
||||
"securitybaseapi",
|
||||
"processthreadsapi",
|
||||
"handleapi",
|
||||
"impl-default",
|
||||
] }
|
||||
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
nix = "0.18.0"
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.1.0"
|
||||
# More realiable than std::fs version on Windows
|
||||
# For removing temporary directories manually when needed
|
||||
# This is what tempfile uses to delete temporary directories
|
||||
remove_dir_all = "0.5.3"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::utils::exec_cmd;
|
||||
|
||||
use clap::crate_version;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
@ -254,5 +255,6 @@ mod tests {
|
||||
|
||||
let config_path = get_config_path("bash");
|
||||
assert_eq!("/test/home/.bashrc", config_path.unwrap().to_str().unwrap());
|
||||
env::remove_var("HOME");
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use git2::{ErrorCode::UnbornBranch, Repository, RepositoryState};
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::string::String;
|
||||
@ -33,6 +34,9 @@ pub struct Context<'a> {
|
||||
|
||||
/// The shell the user is assumed to be running
|
||||
pub shell: Shell,
|
||||
|
||||
/// A HashMap of environment variable mocks
|
||||
pub env: HashMap<&'a str, String>,
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
@ -82,11 +86,30 @@ impl<'a> Context<'a> {
|
||||
dir_contents: OnceCell::new(),
|
||||
repo: OnceCell::new(),
|
||||
shell,
|
||||
env: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// Retrives a environment variable from the os or from a table if in testing mode
|
||||
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())
|
||||
} else {
|
||||
env::var(key.as_ref()).ok()
|
||||
}
|
||||
}
|
||||
|
||||
// Retrives a environment variable from the os or from a table if in testing mode (os version)
|
||||
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)
|
||||
} else {
|
||||
env::var_os(key.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a `~` in a path to the home directory
|
||||
fn expand_tilde(dir: PathBuf) -> PathBuf {
|
||||
pub fn expand_tilde(dir: PathBuf) -> PathBuf {
|
||||
if dir.starts_with("~") {
|
||||
let without_home = dir.strip_prefix("~").unwrap();
|
||||
return dirs_next::home_dir().unwrap().join(without_home);
|
||||
@ -165,7 +188,7 @@ impl<'a> Context<'a> {
|
||||
}
|
||||
|
||||
fn get_shell() -> Shell {
|
||||
let shell = std::env::var("STARSHIP_SHELL").unwrap_or_default();
|
||||
let shell = env::var("STARSHIP_SHELL").unwrap_or_default();
|
||||
match shell.as_str() {
|
||||
"bash" => Shell::Bash,
|
||||
"fish" => Shell::Fish,
|
||||
@ -310,7 +333,7 @@ impl<'a> ScanDir<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
/// based on the current Pathbuf check to see
|
||||
/// based on the current PathBuf check to see
|
||||
/// if any of this criteria match or exist and returning a boolean
|
||||
pub fn is_match(&self) -> bool {
|
||||
self.dir_contents.has_any_extension(self.extensions)
|
||||
|
@ -1,4 +1,5 @@
|
||||
use pest::{error::Error, iterators::Pair, Parser};
|
||||
use pest_derive::*;
|
||||
|
||||
use super::model::*;
|
||||
|
||||
|
@ -1,6 +1,3 @@
|
||||
#[macro_use]
|
||||
extern crate pest_derive;
|
||||
|
||||
// Lib is present to allow for benchmarking
|
||||
pub mod config;
|
||||
pub mod configs;
|
||||
@ -11,3 +8,6 @@ pub mod modules;
|
||||
pub mod print;
|
||||
pub mod segment;
|
||||
mod utils;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
@ -1,11 +1,7 @@
|
||||
use clap::{crate_authors, crate_version};
|
||||
use std::io;
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
#[macro_use]
|
||||
extern crate pest_derive;
|
||||
|
||||
mod bug_report;
|
||||
mod config;
|
||||
mod configs;
|
||||
@ -19,6 +15,9 @@ mod print;
|
||||
mod segment;
|
||||
mod utils;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
use crate::module::ALL_MODULES;
|
||||
use clap::{App, AppSettings, Arg, Shell, SubCommand};
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::PathBuf;
|
||||
@ -13,9 +12,9 @@ use crate::formatter::StringFormatter;
|
||||
type Profile = String;
|
||||
type Region = String;
|
||||
|
||||
fn get_aws_region_from_config(aws_profile: Option<&str>) -> Option<Region> {
|
||||
let config_location = env::var("AWS_CONFIG_FILE")
|
||||
.ok()
|
||||
fn get_aws_region_from_config(context: &Context, aws_profile: Option<&str>) -> Option<Region> {
|
||||
let config_location = context
|
||||
.get_env("AWS_CONFIG_FILE")
|
||||
.and_then(|path| PathBuf::from_str(&path).ok())
|
||||
.or_else(|| {
|
||||
let mut home = dirs_next::home_dir()?;
|
||||
@ -47,19 +46,22 @@ fn get_aws_region_from_config(aws_profile: Option<&str>) -> Option<Region> {
|
||||
Some(region.to_string())
|
||||
}
|
||||
|
||||
fn get_aws_profile_and_region() -> (Option<Profile>, Option<Region>) {
|
||||
fn get_aws_profile_and_region(context: &Context) -> (Option<Profile>, Option<Region>) {
|
||||
match (
|
||||
env::var("AWS_VAULT")
|
||||
.or_else(|_| env::var("AWS_PROFILE"))
|
||||
.ok(),
|
||||
env::var("AWS_DEFAULT_REGION")
|
||||
.or_else(|_| env::var("AWS_REGION"))
|
||||
.ok(),
|
||||
context
|
||||
.get_env("AWS_VAULT")
|
||||
.or_else(|| context.get_env("AWS_PROFILE")),
|
||||
context
|
||||
.get_env("AWS_DEFAULT_REGION")
|
||||
.or_else(|| context.get_env("AWS_REGION")),
|
||||
) {
|
||||
(Some(p), Some(r)) => (Some(p), Some(r)),
|
||||
(None, Some(r)) => (None, Some(r)),
|
||||
(Some(ref p), None) => (Some(p.to_owned()), get_aws_region_from_config(Some(p))),
|
||||
(None, None) => (None, get_aws_region_from_config(None)),
|
||||
(Some(ref p), None) => (
|
||||
Some(p.to_owned()),
|
||||
get_aws_region_from_config(context, Some(p)),
|
||||
),
|
||||
(None, None) => (None, get_aws_region_from_config(context, None)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +76,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let mut module = context.new_module("aws");
|
||||
let config: AwsConfig = AwsConfig::try_load(module.config);
|
||||
|
||||
let (aws_profile, aws_region) = get_aws_profile_and_region();
|
||||
let (aws_profile, aws_region) = get_aws_profile_and_region(context);
|
||||
if aws_profile.is_none() && aws_region.is_none() {
|
||||
return None;
|
||||
}
|
||||
@ -113,3 +115,278 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
|
||||
#[test]
|
||||
fn no_region_set() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws").collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_set() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_REGION", "ap-northeast-2")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ (ap-northeast-2)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_set_with_alias() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_REGION", "ap-southeast-2")
|
||||
.config(toml::toml! {
|
||||
[aws.region_aliases]
|
||||
ap-southeast-2 = "au"
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("on {} ", Color::Yellow.bold().paint("☁️ (au)")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_region_set() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_REGION", "ap-northeast-2")
|
||||
.env("AWS_DEFAULT_REGION", "ap-northeast-1")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ (ap-northeast-1)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_set() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_set_from_aws_vault() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_VAULT", "astronauts-vault")
|
||||
.env("AWS_PROFILE", "astronauts-profile")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts-vault")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_region_set() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.env("AWS_REGION", "ap-northeast-2")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts(ap-northeast-2)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_profile_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let config_path = dir.path().join("config");
|
||||
let mut file = File::create(&config_path)?;
|
||||
|
||||
file.write_all(
|
||||
"[default]
|
||||
region = us-east-1
|
||||
|
||||
[profile astronauts]
|
||||
region = us-east-2
|
||||
"
|
||||
.as_bytes(),
|
||||
)?;
|
||||
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_CONFIG_FILE", config_path.to_string_lossy().as_ref())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ (us-east-1)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_config_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let config_path = dir.path().join("config");
|
||||
let mut file = File::create(&config_path)?;
|
||||
|
||||
file.write_all(
|
||||
"[default]
|
||||
region = us-east-1
|
||||
|
||||
[profile astronauts]
|
||||
region = us-east-2
|
||||
"
|
||||
.as_bytes(),
|
||||
)?;
|
||||
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_CONFIG_FILE", config_path.to_string_lossy().as_ref())
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.config(toml::toml! {
|
||||
[aws]
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts(us-east-2)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_region_set_with_display_all() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.env("AWS_REGION", "ap-northeast-1")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts(ap-northeast-1)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_set_with_display_all() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_set_with_display_all() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_REGION", "ap-northeast-1")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ (ap-northeast-1)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_region_set_with_display_region() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.env("AWS_DEFAULT_REGION", "ap-northeast-1")
|
||||
.config(toml::toml! {
|
||||
[aws]
|
||||
format = "on [$symbol$region]($style) "
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ ap-northeast-1")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_region_set_with_display_profile() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.env("AWS_REGION", "ap-northeast-1")
|
||||
.config(toml::toml! {
|
||||
[aws]
|
||||
format = "on [$symbol$profile]($style) "
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_set_with_display_profile() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_REGION", "ap-northeast-1")
|
||||
.config(toml::toml! {
|
||||
[aws]
|
||||
format = "on [$symbol$profile]($style) "
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("on {} ", Color::Yellow.bold().paint("☁️ ")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_not_set_with_display_region() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.config(toml::toml! {
|
||||
[aws]
|
||||
format = "on [$symbol$region]($style) "
|
||||
})
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -68,3 +68,142 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::context::Shell;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
#[test]
|
||||
fn success_status() -> io::Result<()> {
|
||||
let expected = Some(format!("{} ", Color::Green.bold().paint("❯")));
|
||||
|
||||
// Status code 0
|
||||
let actual = ModuleRenderer::new("character").status(0).collect();
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
// No status code
|
||||
let actual = ModuleRenderer::new("character").collect();
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failure_status() -> io::Result<()> {
|
||||
let expected = Some(format!("{} ", Color::Red.bold().paint("❯")));
|
||||
|
||||
let exit_values = [1, 54321, -5000];
|
||||
|
||||
for status in &exit_values {
|
||||
let actual = ModuleRenderer::new("character").status(*status).collect();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_symbol() -> io::Result<()> {
|
||||
let expected_fail = Some(format!("{} ", Color::Red.bold().paint("✖")));
|
||||
let expected_success = Some(format!("{} ", Color::Green.bold().paint("➜")));
|
||||
|
||||
let exit_values = [1, 54321, -5000];
|
||||
|
||||
// Test failure values
|
||||
for status in &exit_values {
|
||||
let actual = ModuleRenderer::new("character")
|
||||
.config(toml::toml! {
|
||||
[character]
|
||||
success_symbol = "[➜](bold green)"
|
||||
error_symbol = "[✖](bold red)"
|
||||
})
|
||||
.status(*status)
|
||||
.collect();
|
||||
assert_eq!(expected_fail, actual);
|
||||
}
|
||||
|
||||
// Test success
|
||||
let actual = ModuleRenderer::new("character")
|
||||
.config(toml::toml! {
|
||||
[character]
|
||||
success_symbol = "[➜](bold green)"
|
||||
error_symbol = "[✖](bold red)"
|
||||
})
|
||||
.status(0)
|
||||
.collect();
|
||||
assert_eq!(expected_success, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zsh_keymap() -> io::Result<()> {
|
||||
let expected_vicmd = Some(format!("{} ", Color::Green.bold().paint("❮")));
|
||||
let expected_specified = Some(format!("{} ", Color::Green.bold().paint("V")));
|
||||
let expected_other = Some(format!("{} ", Color::Green.bold().paint("❯")));
|
||||
|
||||
// zle keymap is vicmd
|
||||
let actual = ModuleRenderer::new("character")
|
||||
.shell(Shell::Zsh)
|
||||
.keymap("vicmd")
|
||||
.collect();
|
||||
assert_eq!(expected_vicmd, actual);
|
||||
|
||||
// specified vicmd character
|
||||
let actual = ModuleRenderer::new("character")
|
||||
.config(toml::toml! {
|
||||
[character]
|
||||
vicmd_symbol = "[V](bold green)"
|
||||
})
|
||||
.shell(Shell::Zsh)
|
||||
.keymap("vicmd")
|
||||
.collect();
|
||||
assert_eq!(expected_specified, actual);
|
||||
|
||||
// zle keymap is other
|
||||
let actual = ModuleRenderer::new("character")
|
||||
.shell(Shell::Zsh)
|
||||
.keymap("visual")
|
||||
.collect();
|
||||
assert_eq!(expected_other, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fish_keymap() -> io::Result<()> {
|
||||
let expected_vicmd = Some(format!("{} ", Color::Green.bold().paint("❮")));
|
||||
let expected_specified = Some(format!("{} ", Color::Green.bold().paint("V")));
|
||||
let expected_other = Some(format!("{} ", Color::Green.bold().paint("❯")));
|
||||
|
||||
// fish keymap is default
|
||||
let actual = ModuleRenderer::new("character")
|
||||
.shell(Shell::Fish)
|
||||
.keymap("default")
|
||||
.collect();
|
||||
assert_eq!(expected_vicmd, actual);
|
||||
|
||||
// specified vicmd character
|
||||
let actual = ModuleRenderer::new("character")
|
||||
.config(toml::toml! {
|
||||
[character]
|
||||
vicmd_symbol = "[V](bold green)"
|
||||
})
|
||||
.shell(Shell::Fish)
|
||||
.keymap("default")
|
||||
.collect();
|
||||
assert_eq!(expected_specified, actual);
|
||||
|
||||
// fish keymap is other
|
||||
let actual = ModuleRenderer::new("character")
|
||||
.shell(Shell::Fish)
|
||||
.keymap("visual")
|
||||
.collect();
|
||||
assert_eq!(expected_other, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ fn format_cmake_version(cmake_version: &str) -> Option<String> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -66,7 +66,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_cmake_lists() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("cmake", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("cmake").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -76,7 +76,7 @@ mod tests {
|
||||
fn folder_with_cmake_lists() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("CMakeLists.txt"))?.sync_all()?;
|
||||
let actual = render_module("cmake", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("cmake").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Blue.bold().paint("🛆 v3.17.3")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -89,6 +89,9 @@ fn render_time_component((component, suffix): (&u128, &&str)) -> String {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
#[test]
|
||||
fn test_500ms() {
|
||||
@ -110,4 +113,86 @@ mod tests {
|
||||
fn test_1d() {
|
||||
assert_eq!(render_time(86_400_000 as u128, true), "1d")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank_duration_1s() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("cmd_duration")
|
||||
.cmd_duration(1000)
|
||||
.collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank_duration_5s() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("cmd_duration")
|
||||
.cmd_duration(5000)
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!("took {} ", Color::Yellow.bold().paint("5s")));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_5s_duration_3s() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("cmd_duration")
|
||||
.config(toml::toml! {
|
||||
[cmd_duration]
|
||||
min_time = 5000
|
||||
})
|
||||
.cmd_duration(3000)
|
||||
.collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_5s_duration_10s() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("cmd_duration")
|
||||
.config(toml::toml! {
|
||||
[cmd_duration]
|
||||
min_time = 5000
|
||||
})
|
||||
.cmd_duration(10000)
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!("took {} ", Color::Yellow.bold().paint("10s")));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_1s_duration_prefix_underwent() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("cmd_duration")
|
||||
.config(toml::toml! {
|
||||
[cmd_duration]
|
||||
format = "underwent [$duration]($style) "
|
||||
})
|
||||
.cmd_duration(1000)
|
||||
.collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_5s_duration_prefix_underwent() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("cmd_duration")
|
||||
.config(toml::toml! {
|
||||
[cmd_duration]
|
||||
format = "underwent [$duration]($style) "
|
||||
})
|
||||
.cmd_duration(5000)
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!("underwent {} ", Color::Yellow.bold().paint("5s")));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::env;
|
||||
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
|
||||
use super::utils::directory::truncate;
|
||||
@ -11,7 +9,9 @@ use crate::formatter::StringFormatter;
|
||||
/// Will display the Conda environment iff `$CONDA_DEFAULT_ENV` is set.
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
// Reference implementation: https://github.com/denysdovhan/spaceship-prompt/blob/master/sections/conda.zsh
|
||||
let conda_env = env::var("CONDA_DEFAULT_ENV").unwrap_or_else(|_| "".into());
|
||||
let conda_env = context
|
||||
.get_env("CONDA_DEFAULT_ENV")
|
||||
.unwrap_or_else(|| "".into());
|
||||
if conda_env.trim().is_empty() {
|
||||
return None;
|
||||
}
|
||||
@ -52,3 +52,63 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
#[test]
|
||||
fn not_in_env() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("conda").collect();
|
||||
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_base() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("conda")
|
||||
.env("CONDA_DEFAULT_ENV", "base")
|
||||
.config(toml::toml! {
|
||||
[conda]
|
||||
ignore_base = true
|
||||
})
|
||||
.collect();
|
||||
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn env_set() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("conda")
|
||||
.env("CONDA_DEFAULT_ENV", "astronauts")
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Green.bold().paint("🅒 astronauts")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("conda")
|
||||
.env("CONDA_DEFAULT_ENV", "/some/really/long/and/really/annoying/path/that/shouldnt/be/displayed/fully/conda/my_env")
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Green.bold().paint("🅒 my_env")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ fn format_crystal_version(crystal_version: &str) -> Option<String> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -76,7 +76,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_crystal_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("crystal", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("crystal").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
@ -88,7 +88,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("shard.yml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("crystal", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("crystal").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.bold().paint("🔮 v0.35.1")));
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
@ -100,7 +100,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.cr"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("crystal", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("crystal").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.bold().paint("🔮 v0.35.1")));
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
|
@ -68,7 +68,7 @@ fn parse_dart_version(dart_version: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::parse_dart_version;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
@ -82,7 +82,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_dart_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("dart", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("dart").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -93,7 +93,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.dart"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("dart", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("dart").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Blue.bold().paint("🎯 v2.8.4")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -104,7 +104,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
fs::create_dir_all(dir.path().join(".dart_tool"))?;
|
||||
|
||||
let actual = render_module("dart", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("dart").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Blue.bold().paint("🎯 v2.8.4")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -115,7 +115,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("pubspec.yaml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("dart", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("dart").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Blue.bold().paint("🎯 v2.8.4")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -126,7 +126,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("pubspec.yml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("dart", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("dart").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Blue.bold().paint("🎯 v2.8.4")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -137,7 +137,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("pubspec.lock"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("dart", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("dart").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Blue.bold().paint("🎯 v2.8.4")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -18,9 +18,11 @@ use crate::formatter::StringFormatter;
|
||||
/// Creates a module with the current directory
|
||||
///
|
||||
/// Will perform path contraction, substitution, and truncation.
|
||||
///
|
||||
/// **Contraction**
|
||||
/// - Paths beginning with the home directory or with a git repo right
|
||||
/// inside the home directory will be contracted to `~`
|
||||
///
|
||||
/// - Paths beginning with the home directory or with a git repo right inside
|
||||
/// the home directory will be contracted to `~`
|
||||
/// - Paths containing a git repo will contract to begin at the repo root
|
||||
///
|
||||
/// **Substitution**
|
||||
@ -37,10 +39,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
// Using environment PWD is the standard approach for determining logical path
|
||||
// If this is None for any reason, we fall back to reading the os-provided path
|
||||
let physical_current_dir = if config.use_logical_path {
|
||||
match std::env::var("PWD") {
|
||||
Ok(x) => Some(PathBuf::from(x)),
|
||||
Err(e) => {
|
||||
log::debug!("Error getting PWD environment variable: {}", e);
|
||||
match context.get_env("PWD") {
|
||||
Some(x) => Some(PathBuf::from(x)),
|
||||
None => {
|
||||
log::debug!("Error getting PWD environment variable!");
|
||||
None
|
||||
}
|
||||
}
|
||||
@ -269,6 +271,17 @@ fn to_fish_style(pwd_dir_length: usize, dir_string: String, truncated_dir_string
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use dirs_next::home_dir;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use std::os::unix::fs::symlink;
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::os::windows::fs::symlink_dir as symlink;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::{fs, io};
|
||||
use tempfile::TempDir;
|
||||
|
||||
#[test]
|
||||
fn contract_home_directory() {
|
||||
@ -355,7 +368,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn fish_style_with_no_contracted_path() {
|
||||
// `truncatation_length = 2`
|
||||
// `truncation_length = 2`
|
||||
let path = "/absolute/Path/not/in_a/repo/but_nested";
|
||||
let output = to_fish_style(1, path.to_string(), "repo/but_nested");
|
||||
assert_eq!(output, "/a/P/n/i/");
|
||||
@ -363,7 +376,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn fish_style_with_pwd_dir_len_no_contracted_path() {
|
||||
// `truncatation_length = 2`
|
||||
// `truncation_length = 2`
|
||||
let path = "/absolute/Path/not/in_a/repo/but_nested";
|
||||
let output = to_fish_style(2, path.to_string(), "repo/but_nested");
|
||||
assert_eq!(output, "/ab/Pa/no/in/");
|
||||
@ -382,4 +395,777 @@ mod tests {
|
||||
let output = to_fish_style(1, path.to_string(), "目录");
|
||||
assert_eq!(output, "~/s/t/目/a̐/");
|
||||
}
|
||||
|
||||
fn init_repo(path: &Path) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["init"])
|
||||
.current_dir(path)
|
||||
.output()
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
fn make_known_tempdir(root: &Path) -> io::Result<(TempDir, String)> {
|
||||
fs::create_dir_all(root)?;
|
||||
let dir = TempDir::new_in(root)?;
|
||||
let path = dir
|
||||
.path()
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
Ok((dir, path))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
mod linux {
|
||||
use super::*;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
// As tests are run in parallel we have to keep a lock on which of the
|
||||
// two tests are currently running as they both modify `HOME` which can
|
||||
// override the other value resulting in inconsistent runs which is why
|
||||
// we only run one of these tests at once.
|
||||
static LOCK: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn symlinked_subdirectory_git_repo_out_of_tree() -> io::Result<()> {
|
||||
while LOCK.load(Ordering::Relaxed) {}
|
||||
LOCK.store(true, Ordering::Relaxed);
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap().as_path())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir.path().join("fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
init_repo(&repo_dir)?;
|
||||
symlink(&src_dir, &symlink_dir)?;
|
||||
|
||||
// We can't mock `HOME` since dirs-next uses it which does not care about our mocking
|
||||
let previous_home = home_dir().unwrap();
|
||||
|
||||
std::env::set_var("HOME", tmp_dir.path());
|
||||
|
||||
let actual = ModuleRenderer::new("directory").path(symlink_dir).collect();
|
||||
let expected = Some(format!("{} ", Color::Cyan.bold().paint("~/fuel-gauge")));
|
||||
|
||||
std::env::set_var("HOME", previous_home.as_path());
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
LOCK.store(false, Ordering::Relaxed);
|
||||
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn git_repo_in_home_directory_truncate_to_repo_true() -> io::Result<()> {
|
||||
while LOCK.load(Ordering::Relaxed) {}
|
||||
LOCK.store(true, Ordering::Relaxed);
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap().as_path())?;
|
||||
let dir = tmp_dir.path().join("src/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
init_repo(&tmp_dir.path())?;
|
||||
|
||||
// We can't mock `HOME` since dirs-next uses it which does not care about our mocking
|
||||
let previous_home = home_dir().unwrap();
|
||||
|
||||
std::env::set_var("HOME", tmp_dir.path());
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should attempt to display the truncated path
|
||||
truncate_to_repo = true
|
||||
truncation_length = 5
|
||||
})
|
||||
.path(dir)
|
||||
.collect();
|
||||
let expected = Some(format!("{} ", Color::Cyan.bold().paint("~/src/fuel-gauge")));
|
||||
|
||||
std::env::set_var("HOME", previous_home.as_path());
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
LOCK.store(false, Ordering::Relaxed);
|
||||
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn directory_in_root() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("directory").path("/etc").collect();
|
||||
let expected = Some(format!(
|
||||
"{}{} ",
|
||||
Color::Cyan.bold().paint("/etc"),
|
||||
Color::Red.normal().paint("🔒")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn home_directory() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.path(home_dir().unwrap())
|
||||
.config(toml::toml! { // Necessary if homedir is a git repo
|
||||
[directory]
|
||||
truncate_to_repo = false
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("{} ", Color::Cyan.bold().paint("~")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn substituted_truncated_path() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.path("/some/long/network/path/workspace/a/b/c/dev")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 4
|
||||
[directory.substitutions]
|
||||
"/some/long/network/path" = "/some/net"
|
||||
"a/b/c" = "d"
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("net/workspace/d/dev")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn strange_substitution() -> io::Result<()> {
|
||||
let strange_sub = "/\\/;,!";
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.path("/foo/bar/regular/path")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 0
|
||||
fish_style_pwd_dir_length = 2 // Overridden by substitutions
|
||||
[directory.substitutions]
|
||||
"regular" = strange_sub
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint(format!("/foo/bar/{}/path", strange_sub))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn directory_in_home() -> io::Result<()> {
|
||||
let (tmp_dir, name) = make_known_tempdir(home_dir().unwrap().as_path())?;
|
||||
let dir = tmp_dir.path().join("starship");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory").path(dir).collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint(format!("~/{}/starship", name))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncated_directory_in_home() -> io::Result<()> {
|
||||
let (tmp_dir, name) = make_known_tempdir(home_dir().unwrap().as_path())?;
|
||||
let dir = tmp_dir.path().join("engine/schematics");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory").path(dir).collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint(format!("{}/engine/schematics", name))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fish_directory_in_home() -> io::Result<()> {
|
||||
let (tmp_dir, name) = make_known_tempdir(home_dir().unwrap().as_path())?;
|
||||
let dir = tmp_dir.path().join("starship/schematics");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 1
|
||||
fish_style_pwd_dir_length = 2
|
||||
})
|
||||
.path(&dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint(format!("~/{}/st/schematics", name.split_at(3).0))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn root_directory() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("directory").path("/").collect();
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let expected = Some(format!(
|
||||
"{}{} ",
|
||||
Color::Cyan.bold().paint("/"),
|
||||
Color::Red.normal().paint("🔒")
|
||||
));
|
||||
#[cfg(target_os = "windows")]
|
||||
let expected = Some(format!("{} ", Color::Cyan.bold().paint("/")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncated_directory_in_root() -> io::Result<()> {
|
||||
let (tmp_dir, name) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let dir = tmp_dir.path().join("thrusters/rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory").path(dir).collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint(format!("{}/thrusters/rocket", name))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncated_directory_config_large() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let dir = tmp_dir.path().join("thrusters/rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 100
|
||||
})
|
||||
.path(&dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint(truncate(dir.to_slash_lossy(), 100))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fish_style_directory_config_large() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let dir = tmp_dir.path().join("thrusters/rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 1
|
||||
fish_style_pwd_dir_length = 100
|
||||
})
|
||||
.path(&dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint(to_fish_style(100, dir.to_slash_lossy(), ""))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncated_directory_config_small() -> io::Result<()> {
|
||||
let (tmp_dir, name) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let dir = tmp_dir.path().join("rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 2
|
||||
})
|
||||
.path(dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint(format!("{}/rocket", name))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fish_directory_config_small() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let dir = tmp_dir.path().join("thrusters/rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 2
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.path(&dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint(format!(
|
||||
"{}/thrusters/rocket",
|
||||
to_fish_style(1, dir.to_slash_lossy(), "/thrusters/rocket")
|
||||
))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn git_repo_root() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let repo_dir = tmp_dir.path().join("rocket-controls");
|
||||
fs::create_dir(&repo_dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("directory").path(repo_dir).collect();
|
||||
let expected = Some(format!("{} ", Color::Cyan.bold().paint("rocket-controls")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn 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");
|
||||
fs::create_dir_all(&dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("directory").path(dir).collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("rocket-controls/src")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[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)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("directory").path(dir).collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("src/meters/fuel-gauge")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_git_repo_truncate_to_repo_false() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// Don't truncate the path at all.
|
||||
truncation_length = 5
|
||||
truncate_to_repo = false
|
||||
})
|
||||
.path(dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("above-repo/rocket-controls/src/meters/fuel-gauge")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_path_directory_in_git_repo_truncate_to_repo_false() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// Don't truncate the path at all.
|
||||
truncation_length = 5
|
||||
truncate_to_repo = false
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.path(dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint(format!(
|
||||
"{}/above-repo/rocket-controls/src/meters/fuel-gauge",
|
||||
to_fish_style(1, tmp_dir.path().to_slash_lossy(), "")
|
||||
))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_path_directory_in_git_repo_truncate_to_repo_true() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.path(dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint(format!(
|
||||
"{}/rocket-controls/src/meters/fuel-gauge",
|
||||
to_fish_style(1, tmp_dir.path().join("above-repo").to_slash_lossy(), "")
|
||||
))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_git_repo_truncate_to_repo_true() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
})
|
||||
.path(dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("rocket-controls/src/meters/fuel-gauge")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn symlinked_git_repo_root() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("rocket-controls");
|
||||
let symlink_dir = tmp_dir.path().join("rocket-controls-symlink");
|
||||
fs::create_dir(&repo_dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory").path(symlink_dir).collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("rocket-controls-symlink")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_symlinked_git_repo() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src");
|
||||
let symlink_dir = tmp_dir.path().join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.path(symlink_src_dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("rocket-controls-symlink/src")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn truncated_directory_in_symlinked_git_repo() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir.path().join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.path(symlink_src_dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("src/meters/fuel-gauge")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_symlinked_git_repo_truncate_to_repo_false() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir
|
||||
.path()
|
||||
.join("above-repo")
|
||||
.join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// Don't truncate the path at all.
|
||||
truncation_length = 5
|
||||
truncate_to_repo = false
|
||||
})
|
||||
.path(symlink_src_dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("above-repo/rocket-controls-symlink/src/meters/fuel-gauge")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_path_directory_in_symlinked_git_repo_truncate_to_repo_false() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir
|
||||
.path()
|
||||
.join("above-repo")
|
||||
.join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// Don't truncate the path at all.
|
||||
truncation_length = 5
|
||||
truncate_to_repo = false
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.path(symlink_src_dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint(format!(
|
||||
"{}/above-repo/rocket-controls-symlink/src/meters/fuel-gauge",
|
||||
to_fish_style(1, tmp_dir.path().to_slash_lossy(), "")
|
||||
))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_path_directory_in_symlinked_git_repo_truncate_to_repo_true() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir
|
||||
.path()
|
||||
.join("above-repo")
|
||||
.join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.path(symlink_src_dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint(format!(
|
||||
"{}/rocket-controls-symlink/src/meters/fuel-gauge",
|
||||
to_fish_style(1, tmp_dir.path().join("above-repo").to_slash_lossy(), "")
|
||||
))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_symlinked_git_repo_truncate_to_repo_true() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir
|
||||
.path()
|
||||
.join("above-repo")
|
||||
.join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
})
|
||||
.path(symlink_src_dir)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("rocket-controls-symlink/src/meters/fuel-gauge")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn symlinked_directory_in_git_repo() -> io::Result<()> {
|
||||
let (tmp_dir, _) = make_known_tempdir(Path::new("/tmp"))?;
|
||||
let repo_dir = tmp_dir.path().join("rocket-controls");
|
||||
let dir = repo_dir.join("src");
|
||||
fs::create_dir_all(&dir)?;
|
||||
init_repo(&repo_dir).unwrap();
|
||||
symlink(&dir, repo_dir.join("src/loop"))?;
|
||||
|
||||
let actual = ModuleRenderer::new("directory")
|
||||
.config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
})
|
||||
.path(repo_dir.join("src/loop/loop"))
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("rocket-controls/src/loop/loop")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
@ -27,7 +26,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
return None;
|
||||
}
|
||||
let docker_config = PathBuf::from(
|
||||
&env::var_os("DOCKER_CONFIG")
|
||||
&context
|
||||
.get_env_os("DOCKER_CONFIG")
|
||||
.unwrap_or(dirs_next::home_dir()?.join(".docker").into_os_string()),
|
||||
)
|
||||
.join("config.json");
|
||||
|
@ -3,7 +3,7 @@ use quick_xml::Reader;
|
||||
use std::ffi::OsStr;
|
||||
use std::iter::Iterator;
|
||||
use std::ops::Deref;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str;
|
||||
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
@ -89,12 +89,12 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
Some(module)
|
||||
}
|
||||
|
||||
fn find_current_tfm<'a>(files: &[DotNetFile<'a>]) -> Option<String> {
|
||||
fn find_current_tfm(files: &[DotNetFile]) -> Option<String> {
|
||||
let get_file_of_type = |t: FileType| files.iter().find(|f| f.file_type == t);
|
||||
|
||||
let relevant_file = get_file_of_type(FileType::ProjectFile)?;
|
||||
|
||||
get_tfm_from_project_file(relevant_file.path)
|
||||
get_tfm_from_project_file(relevant_file.path.as_path())
|
||||
}
|
||||
|
||||
fn get_tfm_from_project_file(path: &Path) -> Option<String> {
|
||||
@ -135,8 +135,8 @@ fn get_tfm_from_project_file(path: &Path) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
fn estimate_dotnet_version<'a>(
|
||||
files: &[DotNetFile<'a>],
|
||||
fn estimate_dotnet_version(
|
||||
files: &[DotNetFile],
|
||||
current_dir: &Path,
|
||||
repo_root: Option<&Path>,
|
||||
) -> Option<Version> {
|
||||
@ -149,9 +149,8 @@ fn estimate_dotnet_version<'a>(
|
||||
.or_else(|| files.iter().next())?;
|
||||
|
||||
match relevant_file.file_type {
|
||||
FileType::GlobalJson => {
|
||||
get_pinned_sdk_version_from_file(relevant_file.path).or_else(get_latest_sdk_from_cli)
|
||||
}
|
||||
FileType::GlobalJson => get_pinned_sdk_version_from_file(relevant_file.path.as_path())
|
||||
.or_else(get_latest_sdk_from_cli),
|
||||
FileType::SolutionFile => {
|
||||
// With this heuristic, we'll assume that a "global.json" won't
|
||||
// be found in any directory above the solution file.
|
||||
@ -251,13 +250,13 @@ fn get_pinned_sdk_version(json: &str) -> Option<Version> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_local_dotnet_files<'a>(context: &'a Context) -> Result<Vec<DotNetFile<'a>>, std::io::Error> {
|
||||
fn get_local_dotnet_files<'a>(context: &'a Context) -> Result<Vec<DotNetFile>, std::io::Error> {
|
||||
Ok(context
|
||||
.dir_contents()?
|
||||
.files()
|
||||
.filter_map(|p| {
|
||||
get_dotnet_file_type(p).map(|t| DotNetFile {
|
||||
path: p.as_ref(),
|
||||
path: context.current_dir.join(p),
|
||||
file_type: t,
|
||||
})
|
||||
})
|
||||
@ -331,8 +330,8 @@ fn get_latest_sdk_from_cli() -> Option<Version> {
|
||||
}
|
||||
}
|
||||
|
||||
struct DotNetFile<'a> {
|
||||
path: &'a Path,
|
||||
struct DotNetFile {
|
||||
path: PathBuf,
|
||||
file_type: FileType,
|
||||
}
|
||||
|
||||
@ -354,6 +353,263 @@ impl Deref for Version {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, OpenOptions};
|
||||
use std::io::{self, Write};
|
||||
use std::process::Command;
|
||||
use tempfile::{self, TempDir};
|
||||
|
||||
#[test]
|
||||
fn shows_nothing_in_directory_with_zero_relevant_files() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
expect_output(&workspace.path(), None)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_latest_in_directory_with_directory_build_props_file() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "Directory.Build.props", None)?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!("{} ", Color::Blue.bold().paint("•NET v3.1.103"))),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_latest_in_directory_with_directory_build_targets_file() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "Directory.Build.targets", None)?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!("{} ", Color::Blue.bold().paint("•NET v3.1.103"))),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_latest_in_directory_with_packages_props_file() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "Packages.props", None)?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!("{} ", Color::Blue.bold().paint("•NET v3.1.103"))),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_latest_in_directory_with_solution() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "solution.sln", None)?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!("{} ", Color::Blue.bold().paint("•NET v3.1.103"))),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_latest_in_directory_with_csproj() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let csproj = make_csproj_with_tfm("TargetFramework", "netstandard2.0");
|
||||
touch_path(&workspace, "project.csproj", Some(&csproj))?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!(
|
||||
"{} ",
|
||||
Color::Blue.bold().paint("•NET v3.1.103 🎯 netstandard2.0")
|
||||
)),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_latest_in_directory_with_fsproj() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "project.fsproj", None)?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!("{} ", Color::Blue.bold().paint("•NET v3.1.103"))),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_latest_in_directory_with_xproj() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "project.xproj", None)?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!("{} ", Color::Blue.bold().paint("•NET v3.1.103"))),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_latest_in_directory_with_project_json() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "project.json", None)?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!("{} ", Color::Blue.bold().paint("•NET v3.1.103"))),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_pinned_in_directory_with_global_json() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let global_json = make_pinned_sdk_json("1.2.3");
|
||||
touch_path(&workspace, "global.json", Some(&global_json))?;
|
||||
expect_output(
|
||||
&workspace.path(),
|
||||
Some(format!("{} ", Color::Blue.bold().paint("•NET v1.2.3"))),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_pinned_in_project_below_root_with_global_json() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let global_json = make_pinned_sdk_json("1.2.3");
|
||||
let csproj = make_csproj_with_tfm("TargetFramework", "netstandard2.0");
|
||||
touch_path(&workspace, "global.json", Some(&global_json))?;
|
||||
touch_path(&workspace, "project/project.csproj", Some(&csproj))?;
|
||||
expect_output(
|
||||
&workspace.path().join("project"),
|
||||
Some(format!(
|
||||
"{} ",
|
||||
Color::Blue.bold().paint("•NET v1.2.3 🎯 netstandard2.0")
|
||||
)),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_pinned_in_deeply_nested_project_within_repository() -> io::Result<()> {
|
||||
let workspace = create_workspace(true)?;
|
||||
let global_json = make_pinned_sdk_json("1.2.3");
|
||||
let csproj = make_csproj_with_tfm("TargetFramework", "netstandard2.0");
|
||||
touch_path(&workspace, "global.json", Some(&global_json))?;
|
||||
touch_path(
|
||||
&workspace,
|
||||
"deep/path/to/project/project.csproj",
|
||||
Some(&csproj),
|
||||
)?;
|
||||
expect_output(
|
||||
&workspace.path().join("deep/path/to/project"),
|
||||
Some(format!(
|
||||
"{} ",
|
||||
Color::Blue.bold().paint("•NET v1.2.3 🎯 netstandard2.0")
|
||||
)),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_single_tfm() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let csproj = make_csproj_with_tfm("TargetFramework", "netstandard2.0");
|
||||
touch_path(&workspace, "project.csproj", Some(&csproj))?;
|
||||
expect_output(
|
||||
workspace.path(),
|
||||
Some(format!(
|
||||
"{} ",
|
||||
Color::Blue.bold().paint("•NET v3.1.103 🎯 netstandard2.0")
|
||||
)),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_multiple_tfms() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let csproj = make_csproj_with_tfm("TargetFrameworks", "netstandard2.0;net461");
|
||||
touch_path(&workspace, "project.csproj", Some(&csproj))?;
|
||||
expect_output(
|
||||
workspace.path(),
|
||||
Some(format!(
|
||||
"{} ",
|
||||
Color::Blue
|
||||
.bold()
|
||||
.paint("•NET v3.1.103 🎯 netstandard2.0;net461")
|
||||
)),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
fn create_workspace(is_repo: bool) -> io::Result<TempDir> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
if is_repo {
|
||||
Command::new("git")
|
||||
.args(&["init", "--quiet"])
|
||||
.current_dir(repo_dir.path())
|
||||
.output()?;
|
||||
}
|
||||
|
||||
Ok(repo_dir)
|
||||
}
|
||||
|
||||
fn touch_path(
|
||||
workspace: &TempDir,
|
||||
relative_path: &str,
|
||||
contents: Option<&str>,
|
||||
) -> io::Result<()> {
|
||||
let path = workspace.path().join(relative_path);
|
||||
|
||||
fs::create_dir_all(
|
||||
path.parent()
|
||||
.expect("Expected relative_path to be a file in a directory"),
|
||||
)?;
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(&path)?;
|
||||
write!(file, "{}", contents.unwrap_or(""))?;
|
||||
file.sync_data()
|
||||
}
|
||||
|
||||
fn make_pinned_sdk_json(version: &str) -> String {
|
||||
let json_text = r#"
|
||||
{
|
||||
"sdk": {
|
||||
"version": "INSERT_VERSION"
|
||||
}
|
||||
}
|
||||
"#;
|
||||
json_text.replace("INSERT_VERSION", version)
|
||||
}
|
||||
|
||||
fn make_csproj_with_tfm(tfm_element: &str, tfm: &str) -> String {
|
||||
let json_text = r#"
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TFM_ELEMENT>TFM_VALUE</TFM_ELEMENT>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
"#;
|
||||
json_text
|
||||
.replace("TFM_ELEMENT", tfm_element)
|
||||
.replace("TFM_VALUE", tfm)
|
||||
}
|
||||
|
||||
fn expect_output(dir: &Path, expected: Option<String>) -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("dotnet").path(dir).collect();
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_parse_version_from_global_json() {
|
||||
let json_text = r#"
|
||||
@ -375,3 +631,4 @@ fn should_ignore_empty_global_json() {
|
||||
let version = get_pinned_sdk_version(json_text);
|
||||
assert!(version.is_none());
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ fn parse_elixir_version(version: &str) -> Option<(String, String)> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -97,7 +97,7 @@ Elixir 1.10 (compiled with Erlang/OTP 22)
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let expected = None;
|
||||
let output = render_module("elixir", dir.path(), None);
|
||||
let output = ModuleRenderer::new("elixir").path(dir.path()).collect();
|
||||
|
||||
assert_eq!(output, expected);
|
||||
|
||||
@ -113,7 +113,7 @@ Elixir 1.10 (compiled with Erlang/OTP 22)
|
||||
"via {} ",
|
||||
Color::Purple.bold().paint("💧 1.10 (OTP 22)")
|
||||
));
|
||||
let output = render_module("elixir", dir.path(), None);
|
||||
let output = ModuleRenderer::new("elixir").path(dir.path()).collect();
|
||||
|
||||
assert_eq!(output, expected);
|
||||
|
||||
|
@ -60,7 +60,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
@ -68,7 +68,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_elm() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("elm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("elm").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -78,7 +78,7 @@ mod tests {
|
||||
fn folder_with_elm_json() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("elm.json"))?.sync_all()?;
|
||||
let actual = render_module("elm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("elm").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -88,7 +88,7 @@ mod tests {
|
||||
fn folder_with_elm_package_json() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("elm-package.json"))?.sync_all()?;
|
||||
let actual = render_module("elm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("elm").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -98,7 +98,7 @@ mod tests {
|
||||
fn folder_with_elm_version() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join(".elm-version"))?.sync_all()?;
|
||||
let actual = render_module("elm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("elm").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -109,7 +109,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let elmstuff = dir.path().join("elm-stuff");
|
||||
fs::create_dir_all(&elmstuff)?;
|
||||
let actual = render_module("elm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("elm").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -119,7 +119,7 @@ mod tests {
|
||||
fn folder_with_elm_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.elm"))?.sync_all()?;
|
||||
let actual = render_module("elm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("elm").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::env;
|
||||
|
||||
use super::{Context, Module};
|
||||
|
||||
use crate::config::RootModuleConfig;
|
||||
@ -16,7 +14,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let mut module = context.new_module("env_var");
|
||||
let config: EnvVarConfig = EnvVarConfig::try_load(module.config);
|
||||
|
||||
let env_value = get_env_value(config.variable?, config.default)?;
|
||||
let env_value = get_env_value(context, config.variable?, config.default)?;
|
||||
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
|
||||
formatter
|
||||
.map_meta(|var, _| match var {
|
||||
@ -45,12 +43,153 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
Some(module)
|
||||
}
|
||||
|
||||
fn get_env_value(name: &str, default: Option<&str>) -> Option<String> {
|
||||
match env::var_os(name) {
|
||||
Some(os_value) => match os_value.into_string() {
|
||||
Ok(value) => Some(value),
|
||||
Err(_error) => None,
|
||||
},
|
||||
fn get_env_value(context: &Context, name: &str, default: Option<&str>) -> Option<String> {
|
||||
match context.get_env(name) {
|
||||
Some(value) => Some(value),
|
||||
None => default.map(|value| value.to_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::{Color, Style};
|
||||
use std::io;
|
||||
|
||||
const TEST_VAR_VALUE: &str = "astronauts";
|
||||
|
||||
#[test]
|
||||
fn empty_config() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("env_var")
|
||||
.config(toml::toml! {
|
||||
[env_var]
|
||||
})
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defined_variable() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("env_var")
|
||||
.config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.collect();
|
||||
let expected = Some(format!("with {} ", style().paint(TEST_VAR_VALUE)));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn undefined_variable() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("env_var")
|
||||
.config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
})
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_has_no_effect() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("env_var")
|
||||
.config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
default = "N/A"
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.collect();
|
||||
let expected = Some(format!("with {} ", style().paint(TEST_VAR_VALUE)));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_takes_effect() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("env_var")
|
||||
.config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "UNDEFINED_TEST_VAR"
|
||||
default = "N/A"
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("with {} ", style().paint("N/A")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn symbol() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("env_var")
|
||||
.config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
format = "with [■ $env_value](black bold dimmed) "
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"with {} ",
|
||||
style().paint(format!("■ {}", TEST_VAR_VALUE))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prefix() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("env_var")
|
||||
.config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
format = "with [_$env_value](black bold dimmed) "
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"with {} ",
|
||||
style().paint(format!("_{}", TEST_VAR_VALUE))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suffix() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("env_var")
|
||||
.config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
format = "with [${env_value}_](black bold dimmed) "
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"with {} ",
|
||||
style().paint(format!("{}_", TEST_VAR_VALUE))
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn style() -> Style {
|
||||
// default style
|
||||
Color::Black.bold().dimmed()
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ fn get_erlang_version() -> Option<String> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -77,7 +77,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let expected = None;
|
||||
let output = render_module("erlang", dir.path(), None);
|
||||
let output = ModuleRenderer::new("erlang").path(dir.path()).collect();
|
||||
|
||||
assert_eq!(output, expected);
|
||||
|
||||
@ -90,7 +90,7 @@ mod tests {
|
||||
File::create(dir.path().join("rebar.config"))?.sync_all()?;
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Red.bold().paint("🖧 22.1.3")));
|
||||
let output = render_module("erlang", dir.path(), None);
|
||||
let output = ModuleRenderer::new("erlang").path(dir.path()).collect();
|
||||
|
||||
assert_eq!(output, expected);
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, Error, ErrorKind};
|
||||
use std::path::PathBuf;
|
||||
@ -68,16 +67,16 @@ fn get_active_config(config_root: &PathBuf) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_current_config_path() -> Option<PathBuf> {
|
||||
let config_dir = get_config_dir()?;
|
||||
fn get_current_config_path(context: &Context) -> Option<PathBuf> {
|
||||
let config_dir = get_config_dir(context)?;
|
||||
let active_config = get_active_config(&config_dir)?;
|
||||
let current_config = config_dir.join(format!("configurations/config_{}", active_config));
|
||||
Some(current_config)
|
||||
}
|
||||
|
||||
fn get_config_dir() -> Option<PathBuf> {
|
||||
let config_dir = env::var("CLOUDSDK_CONFIG")
|
||||
.ok()
|
||||
fn get_config_dir(context: &Context) -> Option<PathBuf> {
|
||||
let config_dir = context
|
||||
.get_env("CLOUDSDK_CONFIG")
|
||||
.and_then(|path| PathBuf::from_str(&path).ok())
|
||||
.or_else(|| {
|
||||
let mut home = dirs_next::home_dir()?;
|
||||
@ -98,11 +97,11 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let mut module = context.new_module("gcloud");
|
||||
let config: GcloudConfig = GcloudConfig::try_load(module.config);
|
||||
|
||||
let config_path = get_current_config_path()?;
|
||||
let config_path = get_current_config_path(context)?;
|
||||
let gcloud_account = get_gcloud_account_from_config(&config_path);
|
||||
let gcloud_project = get_gcloud_project_from_config(&config_path);
|
||||
let gcloud_region = get_gcloud_region_from_config(&config_path);
|
||||
let config_dir = get_config_dir()?;
|
||||
let config_dir = get_config_dir(context)?;
|
||||
let gcloud_active: Option<Active> = get_active_config(&config_dir);
|
||||
|
||||
if gcloud_account.is_none()
|
||||
@ -149,3 +148,172 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::{create_dir, File};
|
||||
use std::io::{self, Write};
|
||||
|
||||
use ansi_term::Color;
|
||||
|
||||
use crate::test::ModuleRenderer;
|
||||
|
||||
#[test]
|
||||
fn account_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default")?;
|
||||
|
||||
create_dir(dir.path().join("configurations"))?;
|
||||
let config_default_path = dir.path().join("configurations/config_default");
|
||||
let mut config_default_file = File::create(&config_default_path)?;
|
||||
config_default_file.write_all(
|
||||
b"[core]
|
||||
account = foo@example.com
|
||||
",
|
||||
)?;
|
||||
|
||||
let actual = ModuleRenderer::new("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Blue.bold().paint("☁️ foo@example.com")
|
||||
));
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_and_region_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default")?;
|
||||
|
||||
create_dir(dir.path().join("configurations"))?;
|
||||
let config_default_path = dir.path().join("configurations/config_default");
|
||||
let mut config_default_file = File::create(&config_default_path)?;
|
||||
config_default_file.write_all(
|
||||
b"[core]
|
||||
account = foo@example.com
|
||||
|
||||
[compute]
|
||||
region = us-central1
|
||||
",
|
||||
)?;
|
||||
|
||||
let actual = ModuleRenderer::new("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Blue.bold().paint("☁️ foo@example.com(us-central1)")
|
||||
));
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_and_region_set_with_alias() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default")?;
|
||||
|
||||
create_dir(dir.path().join("configurations"))?;
|
||||
let config_default_path = dir.path().join("configurations/config_default");
|
||||
let mut config_default_file = File::create(&config_default_path)?;
|
||||
config_default_file.write_all(
|
||||
b"[core]
|
||||
account = foo@example.com
|
||||
|
||||
[compute]
|
||||
region = us-central1
|
||||
",
|
||||
)?;
|
||||
|
||||
let actual = ModuleRenderer::new("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy())
|
||||
.config(toml::toml! {
|
||||
[gcloud.region_aliases]
|
||||
us-central1 = "uc1"
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Blue.bold().paint("☁️ foo@example.com(uc1)")
|
||||
));
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn active_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default1")?;
|
||||
|
||||
let actual = ModuleRenderer::new("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy())
|
||||
.config(toml::toml! {
|
||||
[gcloud]
|
||||
format = "on [$symbol$active]($style) "
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("on {} ", Color::Blue.bold().paint("☁️ default1")));
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn project_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default")?;
|
||||
|
||||
create_dir(dir.path().join("configurations"))?;
|
||||
let config_default_path = dir.path().join("configurations/config_default");
|
||||
let mut config_default_file = File::create(&config_default_path)?;
|
||||
config_default_file.write_all(
|
||||
b"[core]
|
||||
project = abc
|
||||
",
|
||||
)?;
|
||||
|
||||
let actual = ModuleRenderer::new("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy())
|
||||
.config(toml::toml! {
|
||||
[gcloud]
|
||||
format = "on [$symbol$project]($style) "
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("on {} ", Color::Blue.bold().paint("☁️ abc")));
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_not_set_with_display_region() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = ModuleRenderer::new("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy())
|
||||
.config(toml::toml! {
|
||||
[gcloud]
|
||||
format = "on [$symbol$region]($style) "
|
||||
})
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let repo = context.get_repo().ok()?;
|
||||
let branch_name = repo.branch.as_ref()?;
|
||||
|
||||
let mut graphemes = get_graphemes(&branch_name);
|
||||
let mut graphemes: Vec<&str> = branch_name.graphemes(true).collect();
|
||||
let trunc_len = len.min(graphemes.len());
|
||||
|
||||
if trunc_len < graphemes.len() {
|
||||
@ -72,6 +72,295 @@ fn get_first_grapheme(text: &str) -> &str {
|
||||
.unwrap_or("")
|
||||
}
|
||||
|
||||
fn get_graphemes(text: &str) -> Vec<&str> {
|
||||
UnicodeSegmentation::graphemes(text, true).collect()
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::test::{fixture_repo, FixtureProvider, ModuleRenderer};
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_branch")
|
||||
.path(repo_dir.path())
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_changed_truncation_symbol() -> io::Result<()> {
|
||||
test_truncate_length_with_config(
|
||||
"1337_hello_world",
|
||||
15,
|
||||
"1337_hello_worl",
|
||||
"%",
|
||||
"truncation_symbol = \"%\"",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_truncation_symbol() -> io::Result<()> {
|
||||
test_truncate_length_with_config(
|
||||
"1337_hello_world",
|
||||
15,
|
||||
"1337_hello_worl",
|
||||
"",
|
||||
"truncation_symbol = \"\"",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_char_truncation_symbol() -> io::Result<()> {
|
||||
test_truncate_length_with_config(
|
||||
"1337_hello_world",
|
||||
15,
|
||||
"1337_hello_worl",
|
||||
"a",
|
||||
"truncation_symbol = \"apple\"",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_boundary_below() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 15, "1337_hello_worl", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_boundary_on() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 16, "1337_hello_world", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_boundary_above() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 17, "1337_hello_world", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_one() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 1, "1", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 0, "1337_hello_world", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_negative() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", -1, "1337_hello_world", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hindi_truncation() -> io::Result<()> {
|
||||
test_truncate_length("नमस्ते", 3, "नमस्", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hindi_truncation2() -> io::Result<()> {
|
||||
test_truncate_length("नमस्त", 3, "नमस्", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_japanese_truncation() -> io::Result<()> {
|
||||
test_truncate_length("がんばってね", 4, "がんばっ", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_no_branch() -> io::Result<()> {
|
||||
test_format("1337_hello_world", "no_branch", "", "no_branch")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_just_branch_name() -> io::Result<()> {
|
||||
test_format("1337_hello_world", "$branch", "", "1337_hello_world")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_just_branch_name_color() -> io::Result<()> {
|
||||
test_format(
|
||||
"1337_hello_world",
|
||||
"[$branch](bold blue)",
|
||||
"",
|
||||
Color::Blue.bold().paint("1337_hello_world").to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_mixed_colors() -> io::Result<()> {
|
||||
test_format(
|
||||
"1337_hello_world",
|
||||
"branch: [$branch](bold blue) [THE COLORS](red) ",
|
||||
"",
|
||||
format!(
|
||||
"branch: {} {} ",
|
||||
Color::Blue.bold().paint("1337_hello_world").to_string(),
|
||||
Color::Red.paint("THE COLORS").to_string()
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_symbol_style() -> io::Result<()> {
|
||||
test_format(
|
||||
"1337_hello_world",
|
||||
"$symbol[$branch]($style)",
|
||||
r#"
|
||||
symbol = "git: "
|
||||
style = "green"
|
||||
"#,
|
||||
format!(
|
||||
"git: {}",
|
||||
Color::Green.paint("1337_hello_world").to_string(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_works_with_unborn_default_branch() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["init"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["symbolic-ref", "HEAD", "refs/heads/main"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_branch")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Purple.bold().paint(format!("\u{e0a0} {}", "main")),
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
// This test is not possible until we switch to `git status --porcelain`
|
||||
// where we can mock the env for the specific git process. This is because
|
||||
// git2 does not care about our mocking and when we set the real `GIT_DIR`
|
||||
// variable it will interfere with the other tests.
|
||||
// #[test]
|
||||
// fn test_git_dir_env_variable() -> io::Result<()> {let repo_dir =
|
||||
// tempfile::tempdir()?;
|
||||
|
||||
// Command::new("git")
|
||||
// .args(&["init"])
|
||||
// .current_dir(&repo_dir)
|
||||
// .output()?;
|
||||
|
||||
// // git2 does not care about our mocking
|
||||
// std::env::set_var("GIT_DIR", repo_dir.path().join(".git"));
|
||||
|
||||
// let actual = ModuleRenderer::new("git_branch").collect();
|
||||
|
||||
// std::env::remove_var("GIT_DIR");
|
||||
|
||||
// let expected = Some(format!(
|
||||
// "on {} ",
|
||||
// Color::Purple.bold().paint(format!("\u{e0a0} {}", "master")),
|
||||
// ));
|
||||
|
||||
// assert_eq!(expected, actual);
|
||||
// repo_dir.close()
|
||||
// }
|
||||
|
||||
fn test_truncate_length(
|
||||
branch_name: &str,
|
||||
truncate_length: i64,
|
||||
expected_name: &str,
|
||||
truncation_symbol: &str,
|
||||
) -> io::Result<()> {
|
||||
test_truncate_length_with_config(
|
||||
branch_name,
|
||||
truncate_length,
|
||||
expected_name,
|
||||
truncation_symbol,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
fn test_truncate_length_with_config(
|
||||
branch_name: &str,
|
||||
truncate_length: i64,
|
||||
expected_name: &str,
|
||||
truncation_symbol: &str,
|
||||
config_options: &str,
|
||||
) -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["checkout", "-b", branch_name])
|
||||
.current_dir(repo_dir.path())
|
||||
.output()?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_branch")
|
||||
.config(
|
||||
toml::from_str(&format!(
|
||||
"
|
||||
[git_branch]
|
||||
truncation_length = {}
|
||||
{}
|
||||
",
|
||||
truncate_length, config_options
|
||||
))
|
||||
.unwrap(),
|
||||
)
|
||||
.path(repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
Color::Purple
|
||||
.bold()
|
||||
.paint(format!("\u{e0a0} {}{}", expected_name, truncation_symbol)),
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
fn test_format<T: Into<String>>(
|
||||
branch_name: &str,
|
||||
format: &str,
|
||||
config_options: &str,
|
||||
expected: T,
|
||||
) -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["checkout", "-b", branch_name])
|
||||
.current_dir(repo_dir.path())
|
||||
.output()?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_branch")
|
||||
.config(
|
||||
toml::from_str(&format!(
|
||||
r#"
|
||||
[git_branch]
|
||||
format = "{}"
|
||||
{}
|
||||
"#,
|
||||
format, config_options
|
||||
))
|
||||
.unwrap(),
|
||||
)
|
||||
.path(repo_dir.path())
|
||||
.collect();
|
||||
|
||||
assert_eq!(Some(expected.into()), actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
}
|
||||
|
@ -62,3 +62,138 @@ pub fn id_to_hex_abbrev(bytes: &[u8], len: usize) -> String {
|
||||
.take(len)
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::process::Command;
|
||||
use std::{io, str};
|
||||
|
||||
use crate::test::{fixture_repo, FixtureProvider, ModuleRenderer};
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_commit")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
let mut git_output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?
|
||||
.stdout;
|
||||
git_output.truncate(7);
|
||||
let expected_hash = str::from_utf8(&git_output).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("git_commit")
|
||||
.config(toml::toml! {
|
||||
[git_commit]
|
||||
only_detached = false
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Green
|
||||
.bold()
|
||||
.paint(format!("({})", expected_hash))
|
||||
.to_string()
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash_len_override() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
let mut git_output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?
|
||||
.stdout;
|
||||
git_output.truncate(14);
|
||||
let expected_hash = str::from_utf8(&git_output).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("git_commit")
|
||||
.config(toml::toml! {
|
||||
[git_commit]
|
||||
only_detached = false
|
||||
commit_hash_length = 14
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Green
|
||||
.bold()
|
||||
.paint(format!("({})", expected_hash))
|
||||
.to_string()
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash_only_detached_on_branch() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_commit")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash_only_detached_on_detached() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["checkout", "@~1"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?;
|
||||
|
||||
let mut git_output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?
|
||||
.stdout;
|
||||
git_output.truncate(7);
|
||||
let expected_hash = str::from_utf8(&git_output).unwrap();
|
||||
|
||||
let actual = ModuleRenderer::new("git_commit")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Green
|
||||
.bold()
|
||||
.paint(format!("({})", expected_hash))
|
||||
.to_string()
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
}
|
||||
|
@ -153,3 +153,195 @@ struct StateDescription<'a> {
|
||||
current: Option<String>,
|
||||
total: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{self, Error, ErrorKind, Write};
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
use crate::test::ModuleRenderer;
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_state")
|
||||
.path(repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_rebasing() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = repo_dir.path();
|
||||
|
||||
run_git_cmd(&["rebase", "other-branch"], Some(path), false)?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_state").path(path).collect();
|
||||
|
||||
let expected = Some(format!("{} ", Color::Yellow.bold().paint("(REBASING 1/1)")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_merging() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = repo_dir.path();
|
||||
|
||||
run_git_cmd(&["merge", "other-branch"], Some(path), false)?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_state").path(path).collect();
|
||||
|
||||
let expected = Some(format!("{} ", Color::Yellow.bold().paint("(MERGING)")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_cherry_picking() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = repo_dir.path();
|
||||
|
||||
run_git_cmd(&["cherry-pick", "other-branch"], Some(path), false)?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_state").path(path).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Yellow.bold().paint("(CHERRY-PICKING)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_bisecting() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = repo_dir.path();
|
||||
|
||||
run_git_cmd(&["bisect", "start"], Some(path), false)?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_state").path(path).collect();
|
||||
|
||||
let expected = Some(format!("{} ", Color::Yellow.bold().paint("(BISECTING)")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_reverting() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = repo_dir.path();
|
||||
|
||||
run_git_cmd(&["revert", "--no-commit", "HEAD~1"], Some(path), false)?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_state").path(path).collect();
|
||||
|
||||
let expected = Some(format!("{} ", Color::Yellow.bold().paint("(REVERTING)")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
fn run_git_cmd<A, S>(args: A, dir: Option<&Path>, should_succeed: bool) -> io::Result<()>
|
||||
where
|
||||
A: IntoIterator<Item = S>,
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
let mut command = Command::new("git");
|
||||
command
|
||||
.args(args)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.stdin(Stdio::null());
|
||||
|
||||
if let Some(dir) = dir {
|
||||
command.current_dir(dir);
|
||||
}
|
||||
|
||||
let status = command.status()?;
|
||||
|
||||
if should_succeed && !status.success() {
|
||||
Err(Error::from(ErrorKind::Other))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn create_repo_with_conflict() -> io::Result<tempfile::TempDir> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
let path = repo_dir.path();
|
||||
let conflicted_file = repo_dir.path().join("the_file");
|
||||
|
||||
let write_file = |text: &str| {
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(&conflicted_file)?;
|
||||
write!(file, "{}", text)
|
||||
};
|
||||
|
||||
// Initialize a new git repo
|
||||
run_git_cmd(
|
||||
&[
|
||||
"init",
|
||||
"--quiet",
|
||||
path.to_str().expect("Path was not UTF-8"),
|
||||
],
|
||||
None,
|
||||
true,
|
||||
)?;
|
||||
|
||||
// Set local author info
|
||||
run_git_cmd(
|
||||
&["config", "--local", "user.email", "starship@example.com"],
|
||||
Some(path),
|
||||
true,
|
||||
)?;
|
||||
run_git_cmd(
|
||||
&["config", "--local", "user.name", "starship"],
|
||||
Some(path),
|
||||
true,
|
||||
)?;
|
||||
|
||||
// Write a file on master and commit it
|
||||
write_file("Version A")?;
|
||||
run_git_cmd(&["add", "the_file"], Some(path), true)?;
|
||||
run_git_cmd(&["commit", "--message", "Commit A"], Some(path), true)?;
|
||||
|
||||
// Switch to another branch, and commit a change to the file
|
||||
run_git_cmd(&["checkout", "-b", "other-branch"], Some(path), true)?;
|
||||
write_file("Version B")?;
|
||||
run_git_cmd(
|
||||
&["commit", "--all", "--message", "Commit B"],
|
||||
Some(path),
|
||||
true,
|
||||
)?;
|
||||
|
||||
// Switch back to master, and commit a third change to the file
|
||||
run_git_cmd(&["checkout", "master"], Some(path), true)?;
|
||||
write_file("Version C")?;
|
||||
run_git_cmd(
|
||||
&["commit", "--all", "--message", "Commit C"],
|
||||
Some(path),
|
||||
true,
|
||||
)?;
|
||||
|
||||
Ok(repo_dir)
|
||||
}
|
||||
}
|
||||
|
@ -371,3 +371,599 @@ fn format_count(format_str: &str, config_path: &str, count: usize) -> Option<Vec
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ansi_term::{ANSIStrings, Color};
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::test::{fixture_repo, FixtureProvider, ModuleRenderer};
|
||||
|
||||
/// Right after the calls to git the filesystem state may not have finished
|
||||
/// updating yet causing some of the tests to fail. These barriers are placed
|
||||
/// after each call to git.
|
||||
/// This barrier is windows-specific though other operating systems may need it
|
||||
/// in the future.
|
||||
#[cfg(not(windows))]
|
||||
fn barrier() {}
|
||||
#[cfg(windows)]
|
||||
fn barrier() {
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
}
|
||||
|
||||
fn format_output(symbols: &str) -> Option<String> {
|
||||
Some(format!(
|
||||
"{} ",
|
||||
Color::Red.bold().paint(format!("[{}]", symbols))
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(repo_dir.path())
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_behind() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
behind(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("⇣");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_behind_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
behind(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
behind = "⇣$count"
|
||||
})
|
||||
.path(repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("⇣1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_ahead() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
File::create(repo_dir.path().join("readme.md"))?.sync_all()?;
|
||||
ahead(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("⇡");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_ahead_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
File::create(repo_dir.path().join("readme.md"))?.sync_all()?;
|
||||
ahead(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
ahead="⇡$count"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("⇡1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_diverged() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
diverge(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("⇕");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_diverged_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
diverge(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
diverged=r"⇕⇡$ahead_count⇣$behind_count"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("⇕⇡1⇣1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_conflicted() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_conflict(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("=");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_conflicted_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_conflict(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
conflicted = "=$count"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("=1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_untracked_file() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_untracked(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("?");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_untracked_file_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_untracked(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
untracked = "?$count"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("?1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doesnt_show_untracked_file_if_disabled() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_untracked(&repo_dir.path())?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["config", "status.showUntrackedFiles", "no"])
|
||||
.current_dir(repo_dir.path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_stashed() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
barrier();
|
||||
|
||||
create_stash(&repo_dir.path())?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD"])
|
||||
.current_dir(repo_dir.path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("$");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_stashed_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
barrier();
|
||||
|
||||
create_stash(&repo_dir.path())?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD"])
|
||||
.current_dir(repo_dir.path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
stashed = r"\$$count"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("$1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_modified() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_modified(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("!");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_modified_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_modified(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
modified = "!$count"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("!1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_staged_file() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_staged(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("+");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_staged_file_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_staged(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
staged = "+[$count](green)"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
ANSIStrings(&[
|
||||
Color::Red.bold().paint("[+"),
|
||||
Color::Green.paint("1"),
|
||||
Color::Red.bold().paint("]"),
|
||||
])
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_renamed_file() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_renamed(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("»");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_renamed_file_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_renamed(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
renamed = "»$count"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("»1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_deleted_file() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_deleted(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("✘");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_deleted_file_with_count() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
create_deleted(&repo_dir.path())?;
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
deleted = "✘$count"
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
let expected = format_output("✘1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
// Whenever a file is manually renamed, git itself ('git status') does not treat such file as renamed,
|
||||
// but as untracked instead. The following test checks if manually deleted and manually renamed
|
||||
// files are tracked by git_status module in the same way 'git status' does.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn ignore_manually_renamed() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
File::create(repo_dir.path().join("a"))?.sync_all()?;
|
||||
File::create(repo_dir.path().join("b"))?.sync_all()?;
|
||||
Command::new("git")
|
||||
.args(&["add", "--all"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?;
|
||||
Command::new("git")
|
||||
.args(&["commit", "-m", "add new files"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?;
|
||||
|
||||
fs::remove_file(repo_dir.path().join("a"))?;
|
||||
fs::rename(repo_dir.path().join("b"), repo_dir.path().join("c"))?;
|
||||
barrier();
|
||||
|
||||
let actual = ModuleRenderer::new("git_status")
|
||||
.path(&repo_dir.path())
|
||||
.config(toml::toml! {
|
||||
[git_status]
|
||||
ahead = "A"
|
||||
deleted = "D"
|
||||
untracked = "U"
|
||||
renamed = "R"
|
||||
})
|
||||
.collect();
|
||||
let expected = format_output("DUA");
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
fn ahead(repo_dir: &Path) -> io::Result<()> {
|
||||
File::create(repo_dir.join("readme.md"))?.sync_all()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["commit", "-am", "Update readme"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn behind(repo_dir: &Path) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD^"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn diverge(repo_dir: &Path) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD^"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
fs::write(repo_dir.join("Cargo.toml"), " ")?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["commit", "-am", "Update readme"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_conflict(repo_dir: &Path) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD^"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
fs::write(repo_dir.join("readme.md"), "# goodbye")?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["add", "."])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["commit", "-m", "Change readme"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["pull", "--rebase"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_stash(repo_dir: &Path) -> io::Result<()> {
|
||||
File::create(repo_dir.join("readme.md"))?.sync_all()?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["stash", "--all"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_untracked(repo_dir: &Path) -> io::Result<()> {
|
||||
File::create(repo_dir.join("license"))?.sync_all()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_modified(repo_dir: &Path) -> io::Result<()> {
|
||||
File::create(repo_dir.join("readme.md"))?.sync_all()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_staged(repo_dir: &Path) -> io::Result<()> {
|
||||
File::create(repo_dir.join("license"))?.sync_all()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["add", "."])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_renamed(repo_dir: &Path) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["mv", "readme.md", "readme.md.bak"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["add", "-A"])
|
||||
.current_dir(repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_deleted(repo_dir: &Path) -> io::Result<()> {
|
||||
fs::remove_file(repo_dir.join("readme.md"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ fn format_go_version(go_stdout: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
@ -95,7 +95,7 @@ mod tests {
|
||||
fn folder_without_go_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
@ -107,7 +107,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.go"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🐹 v1.12.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -119,7 +119,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("go.mod"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🐹 v1.12.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -131,7 +131,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("go.sum"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🐹 v1.12.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -144,7 +144,7 @@ mod tests {
|
||||
let godeps = dir.path().join("Godeps");
|
||||
fs::create_dir_all(&godeps)?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🐹 v1.12.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -156,7 +156,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("glide.yaml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🐹 v1.12.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -168,7 +168,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Gopkg.yml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🐹 v1.12.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -179,7 +179,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Gopkg.lock"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🐹 v1.12.1")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -189,7 +189,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join(".go-version"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("golang", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("golang").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🐹 v1.12.1")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -77,7 +77,7 @@ fn format_helm_version(helm_stdout: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -86,7 +86,7 @@ mod tests {
|
||||
fn folder_without_helm_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = render_module("helm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("helm").path(dir.path()).collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
@ -98,7 +98,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("helmfile.yaml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("helm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("helm").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::White.bold().paint("⎈ v3.1.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -110,7 +110,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Chart.yaml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("helm", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("helm").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::White.bold().paint("⎈ v3.1.1")));
|
||||
assert_eq!(expected, actual);
|
||||
|
@ -92,3 +92,228 @@ fn get_graphemes(text: &str, length: usize) -> String {
|
||||
fn graphemes_len(text: &str) -> usize {
|
||||
UnicodeSegmentation::graphemes(&text[..], true).count()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ansi_term::{Color, Style};
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::test::{fixture_repo, FixtureProvider, ModuleRenderer};
|
||||
|
||||
enum Expect<'a> {
|
||||
BranchName(&'a str),
|
||||
Empty,
|
||||
NoTruncation,
|
||||
Symbol(&'a str),
|
||||
Style(Style),
|
||||
TruncationSymbol(&'a str),
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = ModuleRenderer::new("hg_branch")
|
||||
.path(repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_hg_get_branch_fails() -> io::Result<()> {
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
|
||||
// Create a fake corrupted mercurial repo.
|
||||
let hgdir = tempdir.path().join(".hg");
|
||||
fs::create_dir(&hgdir)?;
|
||||
fs::write(&hgdir.join("requires"), "fake-corrupted-repo")?;
|
||||
|
||||
expect_hg_branch_with_config(
|
||||
tempdir.path(),
|
||||
None,
|
||||
&[Expect::BranchName(&"default"), Expect::NoTruncation],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_hg_get_branch_autodisabled() -> io::Result<()> {
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
expect_hg_branch_with_config(tempdir.path(), None, &[Expect::Empty])?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_hg_bookmark() -> io::Result<()> {
|
||||
let tempdir = fixture_repo(FixtureProvider::HG)?;
|
||||
let repo_dir = tempdir.path();
|
||||
run_hg(&["bookmark", "bookmark-101"], &repo_dir)?;
|
||||
expect_hg_branch_with_config(
|
||||
&repo_dir,
|
||||
None,
|
||||
&[Expect::BranchName(&"bookmark-101"), Expect::NoTruncation],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_default_truncation_symbol() -> io::Result<()> {
|
||||
let tempdir = fixture_repo(FixtureProvider::HG)?;
|
||||
let repo_dir = tempdir.path();
|
||||
run_hg(&["branch", "-f", "branch-name-101"], &repo_dir)?;
|
||||
run_hg(
|
||||
&[
|
||||
"commit",
|
||||
"-m",
|
||||
"empty commit 101",
|
||||
"-u",
|
||||
"fake user <fake@user>",
|
||||
],
|
||||
&repo_dir,
|
||||
)?;
|
||||
expect_hg_branch_with_config(
|
||||
&repo_dir,
|
||||
Some(toml::toml! {
|
||||
[hg_branch]
|
||||
truncation_length = 14
|
||||
}),
|
||||
&[Expect::BranchName(&"branch-name-10")],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_configured_symbols() -> io::Result<()> {
|
||||
let tempdir = fixture_repo(FixtureProvider::HG)?;
|
||||
let repo_dir = tempdir.path();
|
||||
run_hg(&["branch", "-f", "branch-name-121"], &repo_dir)?;
|
||||
run_hg(
|
||||
&[
|
||||
"commit",
|
||||
"-m",
|
||||
"empty commit 121",
|
||||
"-u",
|
||||
"fake user <fake@user>",
|
||||
],
|
||||
&repo_dir,
|
||||
)?;
|
||||
expect_hg_branch_with_config(
|
||||
&repo_dir,
|
||||
Some(toml::toml! {
|
||||
[hg_branch]
|
||||
symbol = "B "
|
||||
truncation_length = 14
|
||||
truncation_symbol = "%"
|
||||
}),
|
||||
&[
|
||||
Expect::BranchName(&"branch-name-12"),
|
||||
Expect::Symbol(&"B"),
|
||||
Expect::TruncationSymbol(&"%"),
|
||||
],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_configured_style() -> io::Result<()> {
|
||||
let tempdir = fixture_repo(FixtureProvider::HG)?;
|
||||
let repo_dir = tempdir.path();
|
||||
run_hg(&["branch", "-f", "branch-name-131"], &repo_dir)?;
|
||||
run_hg(
|
||||
&[
|
||||
"commit",
|
||||
"-m",
|
||||
"empty commit 131",
|
||||
"-u",
|
||||
"fake user <fake@user>",
|
||||
],
|
||||
&repo_dir,
|
||||
)?;
|
||||
|
||||
expect_hg_branch_with_config(
|
||||
&repo_dir,
|
||||
Some(toml::toml! {
|
||||
[hg_branch]
|
||||
style = "underline blue"
|
||||
}),
|
||||
&[
|
||||
Expect::BranchName(&"branch-name-131"),
|
||||
Expect::Style(Color::Blue.underline()),
|
||||
Expect::TruncationSymbol(&""),
|
||||
],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
fn expect_hg_branch_with_config(
|
||||
repo_dir: &Path,
|
||||
config: Option<toml::Value>,
|
||||
expectations: &[Expect],
|
||||
) -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("hg_branch")
|
||||
.path(repo_dir.to_str().unwrap())
|
||||
.config(config.unwrap_or_else(|| {
|
||||
toml::toml! {
|
||||
[hg_branch]
|
||||
}
|
||||
}))
|
||||
.collect();
|
||||
|
||||
let mut expect_branch_name = "default";
|
||||
let mut expect_style = Color::Purple.bold();
|
||||
let mut expect_symbol = "\u{e0a0}";
|
||||
let mut expect_truncation_symbol = "…";
|
||||
|
||||
for expect in expectations {
|
||||
match expect {
|
||||
Expect::Empty => {
|
||||
assert_eq!(None, actual);
|
||||
return Ok(());
|
||||
}
|
||||
Expect::Symbol(symbol) => {
|
||||
expect_symbol = symbol;
|
||||
}
|
||||
Expect::TruncationSymbol(truncation_symbol) => {
|
||||
expect_truncation_symbol = truncation_symbol;
|
||||
}
|
||||
Expect::NoTruncation => {
|
||||
expect_truncation_symbol = "";
|
||||
}
|
||||
Expect::BranchName(branch_name) => {
|
||||
expect_branch_name = branch_name;
|
||||
}
|
||||
Expect::Style(style) => expect_style = *style,
|
||||
}
|
||||
}
|
||||
|
||||
let expected = Some(format!(
|
||||
"on {} ",
|
||||
expect_style.paint(format!(
|
||||
"{} {}{}",
|
||||
expect_symbol, expect_branch_name, expect_truncation_symbol
|
||||
)),
|
||||
));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_hg(args: &[&str], repo_dir: &Path) -> io::Result<()> {
|
||||
Command::new("hg")
|
||||
.args(args)
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::env;
|
||||
|
||||
use super::{Context, Module};
|
||||
use std::ffi::OsString;
|
||||
|
||||
@ -16,7 +14,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let mut module = context.new_module("hostname");
|
||||
let config: HostnameConfig = HostnameConfig::try_load(module.config);
|
||||
|
||||
let ssh_connection = env::var("SSH_CONNECTION").ok();
|
||||
let ssh_connection = context.get_env("SSH_CONNECTION");
|
||||
if config.ssh_only && ssh_connection.is_none() {
|
||||
return None;
|
||||
}
|
||||
@ -66,3 +64,108 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::{Color, Style};
|
||||
use std::io;
|
||||
|
||||
macro_rules! get_hostname {
|
||||
() => {
|
||||
if let Some(hostname) = gethostname::gethostname().into_string().ok() {
|
||||
hostname
|
||||
} else {
|
||||
println!(
|
||||
"hostname was not tested because gethostname failed! \
|
||||
This could be caused by your hostname containing invalid UTF."
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh_only_false() -> io::Result<()> {
|
||||
let hostname = get_hostname!();
|
||||
let actual = ModuleRenderer::new("hostname")
|
||||
.config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = false
|
||||
trim_at = ""
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("on {} ", style().paint(hostname)));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ssh() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("hostname")
|
||||
.config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = true
|
||||
})
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh() -> io::Result<()> {
|
||||
let hostname = get_hostname!();
|
||||
let actual = ModuleRenderer::new("hostname")
|
||||
.config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = true
|
||||
trim_at = ""
|
||||
})
|
||||
.env("SSH_CONNECTION", "something")
|
||||
.collect();
|
||||
let expected = Some(format!("on {} ", style().paint(hostname)));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_trim_at() -> io::Result<()> {
|
||||
let hostname = get_hostname!();
|
||||
let actual = ModuleRenderer::new("hostname")
|
||||
.config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = false
|
||||
trim_at = ""
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("on {} ", style().paint(hostname)));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trim_at() -> io::Result<()> {
|
||||
let hostname = get_hostname!();
|
||||
let (remainder, trim_at) = hostname.split_at(1);
|
||||
let actual = ModuleRenderer::new("hostname")
|
||||
.config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = false
|
||||
trim_at = trim_at
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("on {} ", style().paint(remainder)));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn style() -> Style {
|
||||
Color::Green.bold().dimmed()
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
return None;
|
||||
}
|
||||
|
||||
let java_version = get_java_version()?;
|
||||
let java_version = get_java_version(context)?;
|
||||
|
||||
let mut module = context.new_module("java");
|
||||
let config: JavaConfig = JavaConfig::try_load(module.config);
|
||||
@ -57,10 +57,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
Some(module)
|
||||
}
|
||||
|
||||
fn get_java_version() -> Option<String> {
|
||||
let java_command = match std::env::var("JAVA_HOME") {
|
||||
Ok(java_home) => format!("{}/bin/java", java_home),
|
||||
Err(_) => String::from("java"),
|
||||
fn get_java_version(context: &Context) -> Option<String> {
|
||||
let java_command = match context.get_env("JAVA_HOME") {
|
||||
Some(java_home) => format!("{}/bin/java", java_home),
|
||||
None => String::from("java"),
|
||||
};
|
||||
|
||||
let output = utils::exec_cmd(&java_command.as_str(), &["-Xinternalversion"])?;
|
||||
@ -84,7 +84,7 @@ fn parse_java_version(java_version: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -156,7 +156,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_java_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -166,7 +166,7 @@ mod tests {
|
||||
fn folder_with_java_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Main.java"))?.sync_all()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.dimmed().paint("☕ v13.0.2")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -176,7 +176,7 @@ mod tests {
|
||||
fn folder_with_class_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Main.class"))?.sync_all()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.dimmed().paint("☕ v13.0.2")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -186,7 +186,7 @@ mod tests {
|
||||
fn folder_with_gradle_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("build.gradle"))?.sync_all()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.dimmed().paint("☕ v13.0.2")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -196,7 +196,7 @@ mod tests {
|
||||
fn folder_with_jar_archive() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("test.jar"))?.sync_all()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.dimmed().paint("☕ v13.0.2")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -206,7 +206,7 @@ mod tests {
|
||||
fn folder_with_pom_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("pom.xml"))?.sync_all()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.dimmed().paint("☕ v13.0.2")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -216,7 +216,7 @@ mod tests {
|
||||
fn folder_with_gradle_kotlin_build_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("build.gradle.kts"))?.sync_all()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.dimmed().paint("☕ v13.0.2")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -226,7 +226,7 @@ mod tests {
|
||||
fn folder_with_sbt_build_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("build.gradle.kts"))?.sync_all()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.dimmed().paint("☕ v13.0.2")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -236,7 +236,7 @@ mod tests {
|
||||
fn folder_with_java_version_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join(".java-version"))?.sync_all()?;
|
||||
let actual = render_module("java", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("java").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Red.dimmed().paint("☕ v13.0.2")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -52,3 +52,67 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
#[test]
|
||||
fn config_blank_job_0() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("jobs").jobs(0).collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank_job_1() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("jobs").jobs(1).collect();
|
||||
|
||||
let expected = Some(format!("{} ", Color::Blue.bold().paint("✦")));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank_job_2() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("jobs").jobs(2).collect();
|
||||
|
||||
let expected = Some(format!("{} ", Color::Blue.bold().paint("✦2")));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_2_job_2() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("jobs")
|
||||
.config(toml::toml! {
|
||||
[jobs]
|
||||
threshold = 2
|
||||
})
|
||||
.jobs(2)
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!("{} ", Color::Blue.bold().paint("✦")));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_2_job_3() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("jobs")
|
||||
.config(toml::toml! {
|
||||
[jobs]
|
||||
threshold = 2
|
||||
})
|
||||
.jobs(3)
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!("{} ", Color::Blue.bold().paint("✦3")));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ fn format_julia_version(julia_stdout: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -81,7 +81,7 @@ mod tests {
|
||||
fn folder_without_julia_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = render_module("julia", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("julia").path(dir.path()).collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
@ -93,7 +93,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("hello.jl"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("julia", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("julia").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Purple.bold().paint("ஃ v1.4.0")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -105,7 +105,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Project.toml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("julia", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("julia").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Purple.bold().paint("ஃ v1.4.0")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -117,7 +117,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Manifest.toml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("julia", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("julia").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Purple.bold().paint("ஃ v1.4.0")));
|
||||
assert_eq!(expected, actual);
|
||||
|
@ -42,11 +42,11 @@ fn parse_kubectl_file(filename: &path::PathBuf) -> Option<(String, String)> {
|
||||
}
|
||||
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let kube_cfg = match env::var("KUBECONFIG") {
|
||||
Ok(paths) => env::split_paths(&paths)
|
||||
let kube_cfg = match context.get_env("KUBECONFIG") {
|
||||
Some(paths) => env::split_paths(&paths)
|
||||
.filter_map(|filename| parse_kubectl_file(&filename))
|
||||
.next(),
|
||||
Err(_) => {
|
||||
None => {
|
||||
let filename = dirs_next::home_dir()?.join(".kube").join("config");
|
||||
parse_kubectl_file(&filename)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ fn parse_nim_version(version_cmd_output: &str) -> Option<&str> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::parse_nim_version;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -100,7 +100,7 @@ mod tests {
|
||||
fn folder_without_nim() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("nim.txt"))?.sync_all()?;
|
||||
let actual = render_module("nim", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nim").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -110,7 +110,7 @@ mod tests {
|
||||
fn folder_with_nimble_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.nimble"))?.sync_all()?;
|
||||
let actual = render_module("nim", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nim").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("👑 v1.2.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -120,7 +120,7 @@ mod tests {
|
||||
fn folder_with_nim_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.nim"))?.sync_all()?;
|
||||
let actual = render_module("nim", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nim").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("👑 v1.2.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -130,7 +130,7 @@ mod tests {
|
||||
fn folder_with_nims_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.nims"))?.sync_all()?;
|
||||
let actual = render_module("nim", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nim").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("👑 v1.2.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -140,7 +140,7 @@ mod tests {
|
||||
fn folder_with_cfg_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("cfg.nim"))?.sync_all()?;
|
||||
let actual = render_module("nim", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nim").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("👑 v1.2.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::env;
|
||||
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
|
||||
use crate::configs::nix_shell::NixShellConfig;
|
||||
@ -23,8 +21,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let mut module = context.new_module("nix_shell");
|
||||
let config: NixShellConfig = NixShellConfig::try_load(module.config);
|
||||
|
||||
let shell_name = env::var("name").ok();
|
||||
let shell_type = env::var("IN_NIX_SHELL").ok()?;
|
||||
let shell_name = context.get_env("name");
|
||||
let shell_type = context.get_env("IN_NIX_SHELL")?;
|
||||
let shell_type_format = match shell_type.as_ref() {
|
||||
"impure" => config.impure_msg,
|
||||
"pure" => config.pure_msg,
|
||||
@ -61,3 +59,82 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
#[test]
|
||||
fn no_env_variables() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("nix_shell").collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_env_variables() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("nix_shell")
|
||||
.env("IN_NIX_SHELL", "something_wrong")
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pure_shell() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("nix_shell")
|
||||
.env("IN_NIX_SHELL", "pure")
|
||||
.collect();
|
||||
let expected = Some(format!("via {} ", Color::Blue.bold().paint("❄️ pure")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn impure_shell() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("nix_shell")
|
||||
.env("IN_NIX_SHELL", "impure")
|
||||
.collect();
|
||||
let expected = Some(format!("via {} ", Color::Blue.bold().paint("❄️ impure")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pure_shell_name() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("nix_shell")
|
||||
.env("IN_NIX_SHELL", "pure")
|
||||
.env("name", "starship")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Blue.bold().paint("❄️ pure (starship)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn impure_shell_name() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("nix_shell")
|
||||
.env("IN_NIX_SHELL", "impure")
|
||||
.env("name", "starship")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Blue.bold().paint("❄️ impure (starship)")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
@ -69,7 +69,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_node_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -80,7 +80,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("package.json"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Green.bold().paint("⬢ v12.0.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -93,7 +93,7 @@ mod tests {
|
||||
let esy_lock = dir.path().join("esy.lock");
|
||||
fs::create_dir_all(&esy_lock)?;
|
||||
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -104,7 +104,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join(".node-version"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Green.bold().paint("⬢ v12.0.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -115,7 +115,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("index.js"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Green.bold().paint("⬢ v12.0.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -126,7 +126,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("index.mjs"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Green.bold().paint("⬢ v12.0.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -137,7 +137,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("index.cjs"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Green.bold().paint("⬢ v12.0.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -148,7 +148,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("index.ts"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Green.bold().paint("⬢ v12.0.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -160,7 +160,7 @@ mod tests {
|
||||
let node_modules = dir.path().join("node_modules");
|
||||
fs::create_dir_all(&node_modules)?;
|
||||
|
||||
let actual = render_module("nodejs", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("nodejs").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Green.bold().paint("⬢ v12.0.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -69,7 +69,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
@ -77,7 +77,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_ocaml_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -88,7 +88,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.opam"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -99,7 +99,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
fs::create_dir_all(dir.path().join("_opam"))?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -114,7 +114,7 @@ mod tests {
|
||||
dir.path().join("package.lock"),
|
||||
"{\"dependencies\": {\"ocaml\": \"4.8.1000\"}}",
|
||||
)?;
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.08.1")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -125,7 +125,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("dune"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -136,7 +136,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("dune-project"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -147,7 +147,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("jbuild"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -158,7 +158,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("jbuild-ignore"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -169,7 +169,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join(".merlin"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -180,7 +180,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.ml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -191,7 +191,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.mli"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -202,7 +202,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.re"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -213,7 +213,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.rei"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ocaml", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ocaml").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐫 v4.10.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -198,7 +198,7 @@ fn format_version(version: &str) -> String {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -741,12 +741,15 @@ end";
|
||||
contains: Option<&str>,
|
||||
config: Option<toml::Value>,
|
||||
) -> io::Result<()> {
|
||||
let starship_config = Some(config.unwrap_or(toml::toml! {
|
||||
let starship_config = config.unwrap_or(toml::toml! {
|
||||
[package]
|
||||
disabled = false
|
||||
}));
|
||||
});
|
||||
|
||||
let actual = render_module("package", project_dir.path(), starship_config);
|
||||
let actual = ModuleRenderer::new("package")
|
||||
.path(project_dir.path())
|
||||
.config(starship_config)
|
||||
.collect();
|
||||
let text = String::from(contains.unwrap_or(""));
|
||||
let expected = Some(format!(
|
||||
"is {} ",
|
||||
|
@ -64,7 +64,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -73,7 +73,7 @@ mod tests {
|
||||
fn folder_without_perl_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
@ -85,7 +85,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Makefile.PL"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -100,7 +100,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Build.PL"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -115,7 +115,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("cpanfile"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -130,7 +130,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("cpanfile.snapshot"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -145,7 +145,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("META.json"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -160,7 +160,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("META.yml"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -175,7 +175,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join(".perl-version"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -190,7 +190,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.pl"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -205,7 +205,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.pm"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -220,7 +220,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.pod"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("perl", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("perl").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
|
@ -72,7 +72,7 @@ fn format_php_version(php_version: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -87,7 +87,7 @@ mod tests {
|
||||
fn folder_without_php_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = render_module("php", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("php").path(dir.path()).collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
@ -99,7 +99,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("composer.json"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("php", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("php").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -114,7 +114,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join(".php-version"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("php", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("php").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
@ -129,7 +129,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.php"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("php", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("php").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
|
@ -55,7 +55,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -63,7 +63,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_purescript_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("purescript", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("purescript").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -74,7 +74,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Main.purs"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("purescript", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("purescript").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::White.bold().paint("<=> v0.13.5")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -85,7 +85,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("spago.dhall"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("purescript", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("purescript").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::White.bold().paint("<=> v0.13.5")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
@ -1,4 +1,3 @@
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
@ -36,7 +35,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
}
|
||||
};
|
||||
|
||||
let is_venv = env::var("VIRTUAL_ENV").ok().is_some();
|
||||
let is_venv = context.get_env("VIRTUAL_ENV").is_some();
|
||||
|
||||
if !is_py_project && !is_venv {
|
||||
return None;
|
||||
@ -48,7 +47,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let version = get_python_version(&config.python_binary)?;
|
||||
format_python_version(&version)
|
||||
};
|
||||
let virtual_env = get_python_virtual_env();
|
||||
let virtual_env = get_python_virtual_env(context);
|
||||
|
||||
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
|
||||
formatter
|
||||
@ -102,8 +101,8 @@ fn format_python_version(python_stdout: &str) -> String {
|
||||
)
|
||||
}
|
||||
|
||||
fn get_python_virtual_env() -> Option<String> {
|
||||
env::var("VIRTUAL_ENV").ok().and_then(|venv| {
|
||||
fn get_python_virtual_env(context: &Context) -> Option<String> {
|
||||
context.get_env("VIRTUAL_ENV").and_then(|venv| {
|
||||
Path::new(&venv)
|
||||
.file_name()
|
||||
.map(|filename| String::from(filename.to_str().unwrap_or("")))
|
||||
@ -113,7 +112,7 @@ fn get_python_virtual_env() -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -133,7 +132,7 @@ mod tests {
|
||||
#[test]
|
||||
fn folder_without_python_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let actual = render_module("python", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("python").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
@ -230,7 +229,10 @@ mod tests {
|
||||
[python]
|
||||
scan_for_pyfiles = false
|
||||
};
|
||||
let actual = render_module("python", dir.path(), Some(config));
|
||||
let actual = ModuleRenderer::new("python")
|
||||
.path(dir.path())
|
||||
.config(config)
|
||||
.collect();
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
@ -258,19 +260,68 @@ mod tests {
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_virtual_env() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.py"))?.sync_all()?;
|
||||
let actual = ModuleRenderer::new("python")
|
||||
.path(dir.path())
|
||||
.env("VIRTUAL_ENV", "/foo/bar/my_venv")
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Yellow.bold().paint("🐍 v2.7.17 (my_venv)")
|
||||
));
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_active_venv() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = ModuleRenderer::new("python")
|
||||
.path(dir.path())
|
||||
.env("VIRTUAL_ENV", "/foo/bar/my_venv")
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Yellow.bold().paint("🐍 v2.7.17 (my_venv)")
|
||||
));
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
fn check_python2_renders(dir: &tempfile::TempDir, starship_config: Option<toml::Value>) {
|
||||
let actual = render_module("python", dir.path(), starship_config);
|
||||
let config = starship_config.unwrap_or(toml::toml! {
|
||||
[python]
|
||||
python_binary = "python"
|
||||
});
|
||||
|
||||
let actual = ModuleRenderer::new("python")
|
||||
.path(dir.path())
|
||||
.config(config)
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐍 v2.7.17")));
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
fn check_python3_renders(dir: &tempfile::TempDir, starship_config: Option<toml::Value>) {
|
||||
let config = Some(starship_config.unwrap_or(toml::toml! {
|
||||
let config = starship_config.unwrap_or(toml::toml! {
|
||||
[python]
|
||||
python_binary = "python3"
|
||||
}));
|
||||
});
|
||||
|
||||
let actual = ModuleRenderer::new("python")
|
||||
.path(dir.path())
|
||||
.config(config)
|
||||
.collect();
|
||||
|
||||
let actual = render_module("python", dir.path(), config);
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("🐍 v3.8.0")));
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ fn format_ruby_version(ruby_version: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -81,7 +81,7 @@ mod tests {
|
||||
fn folder_without_ruby_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = render_module("ruby", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ruby").path(dir.path()).collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
@ -93,7 +93,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Gemfile"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ruby", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ruby").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Red.bold().paint("💎 v2.5.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -105,7 +105,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join(".ruby-version"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ruby", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ruby").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Red.bold().paint("💎 v2.5.1")));
|
||||
assert_eq!(expected, actual);
|
||||
@ -117,7 +117,7 @@ mod tests {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("any.rb"))?.sync_all()?;
|
||||
|
||||
let actual = render_module("ruby", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("ruby").path(dir.path()).collect();
|
||||
|
||||
let expected = Some(format!("via {} ", Color::Red.bold().paint("💎 v2.5.1")));
|
||||
assert_eq!(expected, actual);
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Output};
|
||||
use std::{env, fs};
|
||||
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
|
||||
@ -72,7 +72,7 @@ fn get_module_version(context: &Context) -> Option<String> {
|
||||
// - `rustup show`
|
||||
// - `rustup show active-toolchain`
|
||||
// - `rustup which`
|
||||
let module_version = if let Some(toolchain) = env_rustup_toolchain()
|
||||
let module_version = if let Some(toolchain) = env_rustup_toolchain(context)
|
||||
.or_else(|| execute_rustup_override_list(&context.current_dir))
|
||||
.or_else(|| find_rust_toolchain_file(&context))
|
||||
{
|
||||
@ -93,8 +93,8 @@ fn get_module_version(context: &Context) -> Option<String> {
|
||||
Some(module_version)
|
||||
}
|
||||
|
||||
fn env_rustup_toolchain() -> Option<String> {
|
||||
let val = env::var("RUSTUP_TOOLCHAIN").ok()?;
|
||||
fn env_rustup_toolchain(context: &Context) -> Option<String> {
|
||||
let val = context.get_env("RUSTUP_TOOLCHAIN")?;
|
||||
Some(val.trim().to_owned())
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::env;
|
||||
|
||||
use super::{Context, Module};
|
||||
|
||||
use crate::config::RootModuleConfig;
|
||||
@ -9,7 +7,7 @@ use crate::formatter::StringFormatter;
|
||||
const SHLVL_ENV_VAR: &str = "SHLVL";
|
||||
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let shlvl = get_shlvl_value()?;
|
||||
let shlvl = context.get_env(SHLVL_ENV_VAR)?.parse::<i64>().ok()?;
|
||||
|
||||
let mut module = context.new_module("shlvl");
|
||||
let config: ShLvlConfig = ShLvlConfig::try_load(module.config);
|
||||
@ -47,7 +45,155 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ansi_term::{Color, Style};
|
||||
use std::io;
|
||||
|
||||
fn get_shlvl_value() -> Option<i64> {
|
||||
env::var(SHLVL_ENV_VAR).ok()?.parse::<i64>().ok()
|
||||
use crate::test::ModuleRenderer;
|
||||
|
||||
use super::SHLVL_ENV_VAR;
|
||||
|
||||
fn style() -> Style {
|
||||
// default style
|
||||
Color::Yellow.bold()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_config() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enabled() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.collect();
|
||||
let expected = Some(format!("{} ", style().paint("↕️ 2")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_level() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
disabled = false
|
||||
})
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enabled_config_level_1() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "1")
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lower_threshold() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
threshold = 1
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "1")
|
||||
.collect();
|
||||
let expected = Some(format!("{} ", style().paint("↕️ 1")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn higher_threshold() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
threshold = 3
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "1")
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_style() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
style = "Red Underline"
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.collect();
|
||||
let expected = Some(format!("{} ", Color::Red.underline().paint("↕️ 2")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_symbol() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
symbol = "shlvl is "
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.collect();
|
||||
let expected = Some(format!("{} ", style().paint("shlvl is 2")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formatting() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("shlvl")
|
||||
.config(toml::toml! {
|
||||
[shlvl]
|
||||
format = "$symbol going down [$shlvl]($style) GOING UP "
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.collect();
|
||||
let expected = Some(format!("↕️ going down {} GOING UP ", style().paint("2")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::env;
|
||||
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
|
||||
use crate::configs::singularity::SingularityConfig;
|
||||
@ -9,7 +7,7 @@ use crate::formatter::StringFormatter;
|
||||
///
|
||||
/// Will display the Singularity image if `$SINGULARITY_NAME` is set.
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let singularity_env = env::var("SINGULARITY_NAME").ok();
|
||||
let singularity_env = context.get_env("SINGULARITY_NAME");
|
||||
singularity_env.as_ref()?;
|
||||
|
||||
let mut module = context.new_module("singularity");
|
||||
@ -42,3 +40,33 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
#[test]
|
||||
fn no_env_set() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("singularity").collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
#[test]
|
||||
fn env_set() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("singularity")
|
||||
.env("SINGULARITY_NAME", "centos.img")
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Blue.bold().dimmed().paint("[centos.img]")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ fn parse_swift_version(swift_version: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::parse_swift_version;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -80,7 +80,7 @@ mod tests {
|
||||
fn folder_without_swift_files() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("swift.txt"))?.sync_all()?;
|
||||
let actual = render_module("swift", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("swift").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -90,7 +90,7 @@ mod tests {
|
||||
fn folder_with_package_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("Package.swift"))?.sync_all()?;
|
||||
let actual = render_module("swift", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("swift").path(dir.path()).collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(202).bold().paint("🐦 v5.2.2")
|
||||
@ -103,7 +103,7 @@ mod tests {
|
||||
fn folder_with_swift_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.swift"))?.sync_all()?;
|
||||
let actual = render_module("swift", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("swift").path(dir.path()).collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(202).bold().paint("🐦 v5.2.2")
|
||||
|
@ -4,7 +4,6 @@ use crate::configs::terraform::TerraformConfig;
|
||||
use crate::formatter::StringFormatter;
|
||||
use crate::utils;
|
||||
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
@ -42,7 +41,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
&utils::exec_cmd("terraform", &["version"])?.stdout.as_str(),
|
||||
)
|
||||
.map(Ok),
|
||||
"workspace" => get_terraform_workspace(&context.current_dir).map(Ok),
|
||||
"workspace" => get_terraform_workspace(context).map(Ok),
|
||||
_ => None,
|
||||
})
|
||||
.parse(None)
|
||||
@ -60,17 +59,17 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
}
|
||||
|
||||
// Determines the currently selected workspace (see https://github.com/hashicorp/terraform/blob/master/command/meta.go for the original implementation)
|
||||
fn get_terraform_workspace(cwd: &PathBuf) -> Option<String> {
|
||||
fn get_terraform_workspace(context: &Context) -> Option<String> {
|
||||
// Workspace can be explicitly overwritten by an env var
|
||||
let workspace_override = env::var("TF_WORKSPACE");
|
||||
if workspace_override.is_ok() {
|
||||
return workspace_override.ok();
|
||||
let workspace_override = context.get_env("TF_WORKSPACE");
|
||||
if workspace_override.is_some() {
|
||||
return workspace_override;
|
||||
}
|
||||
|
||||
// Data directory containing current workspace can be overwritten by an env var
|
||||
let datadir = match env::var("TF_DATA_DIR") {
|
||||
Ok(s) => PathBuf::from(s),
|
||||
Err(_) => cwd.join(".terraform"),
|
||||
let datadir = match context.get_env("TF_DATA_DIR") {
|
||||
Some(s) => PathBuf::from(s),
|
||||
None => context.current_dir.join(".terraform"),
|
||||
};
|
||||
match utils::read_file(datadir.join("environment")) {
|
||||
Err(ref e) if e.kind() == io::ErrorKind::NotFound => Some("default".to_string()),
|
||||
@ -97,10 +96,10 @@ fn format_terraform_version(version: &str) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::io::{self, Write};
|
||||
|
||||
#[test]
|
||||
fn test_format_terraform_version_release() {
|
||||
@ -149,21 +148,20 @@ is 0.12.14. You can update by downloading from www.terraform.io/downloads.html
|
||||
let tf_dir = dir.path().join(".terraform");
|
||||
fs::create_dir(&tf_dir)?;
|
||||
|
||||
let actual = render_module(
|
||||
"terraform",
|
||||
dir.path(),
|
||||
Some(toml::toml! {
|
||||
let actual = ModuleRenderer::new("terraform")
|
||||
.path(dir.path())
|
||||
.config(toml::toml! {
|
||||
[terraform]
|
||||
format = "via [$symbol$version$workspace]($style) "
|
||||
}),
|
||||
);
|
||||
})
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(105).bold().paint("💠 v0.12.14 default")
|
||||
));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -175,20 +173,122 @@ is 0.12.14. You can update by downloading from www.terraform.io/downloads.html
|
||||
file.write_all(b"development")?;
|
||||
file.sync_all()?;
|
||||
|
||||
let actual = render_module(
|
||||
"terraform",
|
||||
dir.path(),
|
||||
Some(toml::toml! {
|
||||
let actual = ModuleRenderer::new("terraform")
|
||||
.path(dir.path())
|
||||
.config(toml::toml! {
|
||||
[terraform]
|
||||
format = "via [$symbol$version$workspace]($style) "
|
||||
}),
|
||||
);
|
||||
})
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(105).bold().paint("💠 v0.12.14 development")
|
||||
));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn folder_without_dotterraform() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let actual = ModuleRenderer::new("terraform").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn folder_with_tf_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.tf"))?;
|
||||
|
||||
let actual = ModuleRenderer::new("terraform").path(dir.path()).collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(105).bold().paint("💠 default")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn folder_with_workspace_override() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.tf"))?;
|
||||
|
||||
let actual = ModuleRenderer::new("terraform")
|
||||
.path(dir.path())
|
||||
.env("TF_WORKSPACE", "development")
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(105).bold().paint("💠 development")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn folder_with_datadir_override() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.tf"))?;
|
||||
|
||||
let datadir = tempfile::tempdir()?;
|
||||
let mut file = File::create(datadir.path().join("environment"))?;
|
||||
file.write_all(b"development")?;
|
||||
file.sync_all()?;
|
||||
|
||||
let actual = ModuleRenderer::new("terraform")
|
||||
.path(dir.path())
|
||||
.env("TF_DATA_DIR", datadir.path().to_str().unwrap())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(105).bold().paint("💠 development")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()?;
|
||||
datadir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn folder_with_dotterraform_no_environment() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let tf_dir = dir.path().join(".terraform");
|
||||
fs::create_dir(&tf_dir)?;
|
||||
|
||||
let actual = ModuleRenderer::new("terraform").path(dir.path()).collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(105).bold().paint("💠 default")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn folder_with_dotterraform_with_environment() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let tf_dir = dir.path().join(".terraform");
|
||||
fs::create_dir(&tf_dir)?;
|
||||
let mut file = File::create(tf_dir.join("environment"))?;
|
||||
file.write_all(b"development")?;
|
||||
file.sync_all()?;
|
||||
|
||||
let actual = ModuleRenderer::new("terraform").path(dir.path()).collect();
|
||||
let expected = Some(format!(
|
||||
"via {} ",
|
||||
Color::Fixed(105).bold().paint("💠 development")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +151,9 @@ tests become extra important */
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::ModuleRenderer;
|
||||
use chrono::offset::TimeZone;
|
||||
use std::io;
|
||||
|
||||
const FMT_12: &str = "%r";
|
||||
const FMT_24: &str = "%T";
|
||||
@ -464,4 +466,50 @@ mod tests {
|
||||
assert_eq!(is_inside_time_range(time_now2, time_start, time_end), false);
|
||||
assert_eq!(is_inside_time_range(time_now3, time_start, time_end), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_enabled() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("time")
|
||||
.config(toml::toml! {
|
||||
[time]
|
||||
disabled = false
|
||||
})
|
||||
.collect();
|
||||
|
||||
// We can't test what it actually is...but we can assert that it is something
|
||||
assert!(actual.is_some());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("time").collect();
|
||||
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_check_prefix_and_suffix() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("time")
|
||||
.config(toml::toml! {
|
||||
[time]
|
||||
disabled = false
|
||||
format = "at [\\[$time\\]]($style) "
|
||||
time_format = "%T"
|
||||
})
|
||||
.collect()
|
||||
.unwrap();
|
||||
|
||||
// This is the prefix with "at ", the color code, then the prefix char [
|
||||
let col_prefix = format!("at {}{}[", '\u{1b}', "[1;33m");
|
||||
|
||||
// This is the suffix with suffix char ']', then color codes, then a space
|
||||
let col_suffix = format!("]{}{} ", '\u{1b}', "[0m");
|
||||
|
||||
assert!(actual.starts_with(&col_prefix));
|
||||
assert!(actual.ends_with(&col_suffix));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::env;
|
||||
|
||||
use super::{Context, Module, RootModuleConfig};
|
||||
|
||||
use crate::configs::username::UsernameConfig;
|
||||
@ -13,9 +11,9 @@ use crate::utils;
|
||||
/// - The current user is root (UID = 0)
|
||||
/// - The user is currently connected as an SSH session (`$SSH_CONNECTION`)
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let user = env::var("USER").ok();
|
||||
let logname = env::var("LOGNAME").ok();
|
||||
let ssh_connection = env::var("SSH_CONNECTION").ok();
|
||||
let user = context.get_env("USER");
|
||||
let logname = context.get_env("LOGNAME");
|
||||
let ssh_connection = context.get_env("SSH_CONNECTION");
|
||||
|
||||
const ROOT_UID: Option<u32> = Some(0);
|
||||
let user_uid = get_uid();
|
||||
@ -64,3 +62,85 @@ fn get_uid() -> Option<u32> {
|
||||
.parse::<u32>()
|
||||
.ok()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
// TODO: Add tests for if root user (UID == 0)
|
||||
// Requires mocking
|
||||
|
||||
#[test]
|
||||
fn no_env_variables() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("username").collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn logname_equals_user() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("username")
|
||||
.env("LOGNAME", "astronaut")
|
||||
.env("USER", "astronaut")
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh_wo_username() -> io::Result<()> {
|
||||
// SSH connection w/o username
|
||||
let actual = ModuleRenderer::new("username")
|
||||
.env("SSH_CONNECTION", "192.168.223.17 36673 192.168.223.229 22")
|
||||
.collect();
|
||||
let expected = None;
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn current_user_not_logname() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("username")
|
||||
.env("LOGNAME", "astronaut")
|
||||
.env("USER", "cosmonaut")
|
||||
.collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("cosmonaut")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh_connection() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("username")
|
||||
.env("USER", "astronaut")
|
||||
.env("SSH_CONNECTION", "192.168.223.17 36673 192.168.223.229 22")
|
||||
.collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("astronaut")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_always() -> io::Result<()> {
|
||||
let actual = ModuleRenderer::new("username")
|
||||
.env("USER", "astronaut")
|
||||
.config(toml::toml! {
|
||||
[username]
|
||||
show_always = true
|
||||
})
|
||||
.collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("astronaut")));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,3 @@ pub mod directory_win;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub mod directory_nix;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test;
|
||||
|
@ -1,16 +0,0 @@
|
||||
use crate::config::StarshipConfig;
|
||||
use crate::context::{Context, Shell};
|
||||
use std::path::Path;
|
||||
|
||||
/// Render a specific starship module by name
|
||||
pub fn render_module(
|
||||
module_name: &str,
|
||||
path: &Path,
|
||||
config: Option<toml::Value>,
|
||||
) -> Option<String> {
|
||||
let mut context = Context::new_with_dir(clap::ArgMatches::default(), path);
|
||||
context.config = StarshipConfig { config };
|
||||
context.shell = Shell::Unknown;
|
||||
|
||||
crate::print::get_module(module_name, context)
|
||||
}
|
@ -57,7 +57,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::utils::test::render_module;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -66,7 +66,7 @@ mod tests {
|
||||
fn folder_without_zig() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("zig.txt"))?.sync_all()?;
|
||||
let actual = render_module("zig", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("zig").path(dir.path()).collect();
|
||||
let expected = None;
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
@ -76,7 +76,7 @@ mod tests {
|
||||
fn folder_with_zig_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.zig"))?.sync_all()?;
|
||||
let actual = render_module("zig", dir.path(), None);
|
||||
let actual = ModuleRenderer::new("zig").path(dir.path()).collect();
|
||||
let expected = Some(format!("via {} ", Color::Yellow.bold().paint("↯ v0.6.0")));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
|
138
src/test/mod.rs
Normal file
138
src/test/mod.rs
Normal file
@ -0,0 +1,138 @@
|
||||
use crate::config::StarshipConfig;
|
||||
use crate::context::{Context, Shell};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use tempfile::TempDir;
|
||||
|
||||
static FIXTURE_DIR: Lazy<PathBuf> =
|
||||
Lazy::new(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/test/fixtures/"));
|
||||
|
||||
static GIT_FIXTURE: Lazy<PathBuf> = Lazy::new(|| FIXTURE_DIR.join("git-repo.bundle"));
|
||||
static HG_FIXTURE: Lazy<PathBuf> = Lazy::new(|| FIXTURE_DIR.join("hg-repo.bundle"));
|
||||
|
||||
/// Render a specific starship module by name
|
||||
pub struct ModuleRenderer<'a> {
|
||||
name: &'a str,
|
||||
context: Context<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ModuleRenderer<'a> {
|
||||
/// Creates a new ModuleRenderer
|
||||
pub fn new(name: &'a str) -> Self {
|
||||
let mut context = Context::new_with_dir(clap::ArgMatches::default(), PathBuf::new());
|
||||
context.shell = Shell::Unknown;
|
||||
context.config = StarshipConfig { config: None };
|
||||
|
||||
Self { name, context }
|
||||
}
|
||||
|
||||
pub fn path<T>(mut self, path: T) -> Self
|
||||
where
|
||||
T: Into<PathBuf>,
|
||||
{
|
||||
self.context.current_dir = path.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the config of the underlying context
|
||||
pub fn config(mut self, config: toml::Value) -> Self {
|
||||
self.context.config = StarshipConfig {
|
||||
config: Some(config),
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds the variable to the env_mocks of the underlying context
|
||||
pub fn env<V: Into<String>>(mut self, key: &'a str, val: V) -> Self {
|
||||
self.context.env.insert(key, val.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn shell(mut self, shell: Shell) -> Self {
|
||||
self.context.shell = shell;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn jobs(mut self, jobs: u64) -> Self {
|
||||
self.context.properties.insert("jobs", jobs.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn cmd_duration(mut self, duration: u64) -> Self {
|
||||
self.context
|
||||
.properties
|
||||
.insert("cmd_duration", duration.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn keymap<T>(mut self, keymap: T) -> Self
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
self.context.properties.insert("keymap", keymap.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn status(mut self, status: i32) -> Self {
|
||||
self.context
|
||||
.properties
|
||||
.insert("status_code", status.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Renders the module returning its output
|
||||
pub fn collect(self) -> Option<String> {
|
||||
crate::print::get_module(self.name, self.context)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum FixtureProvider {
|
||||
GIT,
|
||||
HG,
|
||||
}
|
||||
|
||||
pub fn fixture_repo(provider: FixtureProvider) -> io::Result<TempDir> {
|
||||
match provider {
|
||||
FixtureProvider::GIT => {
|
||||
let path = tempfile::tempdir()?;
|
||||
|
||||
Command::new("git")
|
||||
.current_dir(path.path())
|
||||
.args(&["clone", "-b", "master"])
|
||||
.arg(GIT_FIXTURE.as_os_str())
|
||||
.arg(&path.path())
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["config", "--local", "user.email", "starship@example.com"])
|
||||
.current_dir(&path.path())
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["config", "--local", "user.name", "starship"])
|
||||
.current_dir(&path.path())
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD"])
|
||||
.current_dir(&path.path())
|
||||
.output()?;
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
FixtureProvider::HG => {
|
||||
let path = tempfile::tempdir()?;
|
||||
|
||||
Command::new("hg")
|
||||
.current_dir(path.path())
|
||||
.arg("clone")
|
||||
.arg(HG_FIXTURE.as_os_str())
|
||||
.arg(&path.path())
|
||||
.output()?;
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
}
|
||||
}
|
10
src/utils.rs
10
src/utils.rs
@ -26,7 +26,7 @@ impl PartialEq for CommandOutput {
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute a command and return the output on stdout and stderr if sucessful
|
||||
/// Execute a command and return the output on stdout and stderr if successful
|
||||
#[cfg(not(test))]
|
||||
pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> {
|
||||
internal_exec_cmd(&cmd, &args)
|
||||
@ -158,6 +158,14 @@ CMake suite maintained and supported by Kitware (kitware.com/cmake).\n",
|
||||
),
|
||||
stderr: String::default(),
|
||||
}),
|
||||
"dotnet --version" => Some(CommandOutput {
|
||||
stdout: String::from("3.1.103"),
|
||||
stderr: String::default(),
|
||||
}),
|
||||
"dotnet --list-sdks" => Some(CommandOutput {
|
||||
stdout: String::from("3.1.103 [/usr/share/dotnet/sdk]"),
|
||||
stderr: String::default(),
|
||||
}),
|
||||
"terraform version" => Some(CommandOutput {
|
||||
stdout: String::from("Terraform v0.12.14\n"),
|
||||
stderr: String::default(),
|
||||
|
0
tests/fixtures/empty_config.toml
vendored
0
tests/fixtures/empty_config.toml
vendored
@ -1,250 +0,0 @@
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use ansi_term::Color;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn no_region_set() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("PATH", env!("PATH"))
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_set() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_REGION", "ap-northeast-2")
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ (ap-northeast-2)"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_set_with_alias() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_REGION", "ap-southeast-2")
|
||||
.use_config(toml::toml! {
|
||||
[aws.region_aliases]
|
||||
ap-southeast-2 = "au"
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ (au)"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_region_set() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_REGION", "ap-northeast-2")
|
||||
.env("AWS_DEFAULT_REGION", "ap-northeast-1")
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ (ap-northeast-1)"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_set() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ astronauts"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_set_from_aws_vault() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_VAULT", "astronauts-vault")
|
||||
.env("AWS_PROFILE", "astronauts-profile")
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ astronauts-vault"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_region_set() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.env("AWS_REGION", "ap-northeast-2")
|
||||
.output()?;
|
||||
let expected = format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts(ap-northeast-2)")
|
||||
);
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_profile_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let config_path = dir.path().join("config");
|
||||
let mut file = File::create(&config_path)?;
|
||||
|
||||
file.write_all(
|
||||
"[default]
|
||||
region = us-east-1
|
||||
|
||||
[profile astronauts]
|
||||
region = us-east-2
|
||||
"
|
||||
.as_bytes(),
|
||||
)?;
|
||||
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_CONFIG_FILE", config_path.to_string_lossy().as_ref())
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ (us-east-1)"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_config_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let config_path = dir.path().join("config");
|
||||
let mut file = File::create(&config_path)?;
|
||||
|
||||
file.write_all(
|
||||
"[default]
|
||||
region = us-east-1
|
||||
|
||||
[profile astronauts]
|
||||
region = us-east-2
|
||||
"
|
||||
.as_bytes(),
|
||||
)?;
|
||||
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_CONFIG_FILE", config_path.to_string_lossy().as_ref())
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.use_config(toml::toml! {
|
||||
[aws]
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts(us-east-2)")
|
||||
);
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_region_set_with_display_all() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.env("AWS_REGION", "ap-northeast-1")
|
||||
.output()?;
|
||||
let expected = format!(
|
||||
"on {} ",
|
||||
Color::Yellow.bold().paint("☁️ astronauts(ap-northeast-1)")
|
||||
);
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_set_with_display_all() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ astronauts"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_set_with_display_all() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_REGION", "ap-northeast-1")
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ (ap-northeast-1)"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_region_set_with_display_region() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.env("AWS_DEFAULT_REGION", "ap-northeast-1")
|
||||
.use_config(toml::toml! {
|
||||
[aws]
|
||||
format = "on [$symbol$region]($style) "
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ ap-northeast-1"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_and_region_set_with_display_profile() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_PROFILE", "astronauts")
|
||||
.env("AWS_REGION", "ap-northeast-1")
|
||||
.use_config(toml::toml! {
|
||||
[aws]
|
||||
format = "on [$symbol$profile]($style) "
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ astronauts"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_set_with_display_profile() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.env("AWS_REGION", "ap-northeast-1")
|
||||
.use_config(toml::toml! {
|
||||
[aws]
|
||||
format = "on [$symbol$profile]($style) "
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ "));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn region_not_set_with_display_region() -> io::Result<()> {
|
||||
let output = common::render_module("aws")
|
||||
.use_config(toml::toml! {
|
||||
[aws]
|
||||
format = "on [$symbol$region]($style) "
|
||||
})
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn success_status() -> io::Result<()> {
|
||||
let expected = format!("{} ", Color::Green.bold().paint("❯"));
|
||||
|
||||
// Status code 0
|
||||
let output = common::render_module("character")
|
||||
.arg("--status=0")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
// No status code
|
||||
let output = common::render_module("character").output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failure_status() -> io::Result<()> {
|
||||
let expected = format!("{} ", Color::Red.bold().paint("❯"));
|
||||
|
||||
let exit_values = ["1", "54321", "-5000"];
|
||||
|
||||
for status in exit_values.iter() {
|
||||
let arg = format!("--status={}", status);
|
||||
let output = common::render_module("character").arg(arg).output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_symbol() -> io::Result<()> {
|
||||
let expected_fail = format!("{} ", Color::Red.bold().paint("✖"));
|
||||
let expected_success = format!("{} ", Color::Green.bold().paint("➜"));
|
||||
|
||||
let exit_values = ["1", "54321", "-5000"];
|
||||
|
||||
// Test failure values
|
||||
for status in exit_values.iter() {
|
||||
let arg = format!("--status={}", status);
|
||||
let output = common::render_module("character")
|
||||
.use_config(toml::toml! {
|
||||
[character]
|
||||
success_symbol = "[➜](bold green)"
|
||||
error_symbol = "[✖](bold red)"
|
||||
|
||||
})
|
||||
.arg(arg)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected_fail, actual);
|
||||
}
|
||||
|
||||
// Test success
|
||||
let output = common::render_module("character")
|
||||
.use_config(toml::toml! {
|
||||
[character]
|
||||
success_symbol = "[➜](bold green)"
|
||||
error_symbol = "[✖](bold red)"
|
||||
})
|
||||
.arg("--status=0")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected_success, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zsh_keymap() -> io::Result<()> {
|
||||
let expected_vicmd = format!("{} ", Color::Green.bold().paint("❮"));
|
||||
let expected_specified = format!("{} ", Color::Green.bold().paint("V"));
|
||||
let expected_other = format!("{} ", Color::Green.bold().paint("❯"));
|
||||
|
||||
// zle keymap is vicmd
|
||||
let output = common::render_module("character")
|
||||
.env("STARSHIP_SHELL", "zsh")
|
||||
.arg("--keymap=vicmd")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected_vicmd, actual);
|
||||
|
||||
// specified vicmd character
|
||||
let output = common::render_module("character")
|
||||
.use_config(toml::toml! {
|
||||
[character]
|
||||
vicmd_symbol = "[V](bold green)"
|
||||
})
|
||||
.env("STARSHIP_SHELL", "zsh")
|
||||
.arg("--keymap=vicmd")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected_specified, actual);
|
||||
|
||||
// zle keymap is other
|
||||
let output = common::render_module("character")
|
||||
.env("STARSHIP_SHELL", "zsh")
|
||||
.arg("--keymap=visual")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected_other, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fish_keymap() -> io::Result<()> {
|
||||
let expected_vicmd = format!("{} ", Color::Green.bold().paint("❮"));
|
||||
let expected_specified = format!("{} ", Color::Green.bold().paint("V"));
|
||||
let expected_other = format!("{} ", Color::Green.bold().paint("❯"));
|
||||
|
||||
// fish keymap is default
|
||||
let output = common::render_module("character")
|
||||
.env("STARSHIP_SHELL", "fish")
|
||||
.arg("--keymap=default")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected_vicmd, actual);
|
||||
|
||||
// specified vicmd character
|
||||
let output = common::render_module("character")
|
||||
.use_config(toml::toml! {
|
||||
[character]
|
||||
vicmd_symbol = "[V](bold green)"
|
||||
})
|
||||
.env("STARSHIP_SHELL", "fish")
|
||||
.arg("--keymap=default")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected_specified, actual);
|
||||
|
||||
// fish keymap is other
|
||||
let output = common::render_module("character")
|
||||
.env("STARSHIP_SHELL", "fish")
|
||||
.arg("--keymap=visual")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected_other, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn config_blank_duration_1s() -> io::Result<()> {
|
||||
let output = common::render_module("cmd_duration")
|
||||
.arg("--cmd-duration=1000")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank_duration_5s() -> io::Result<()> {
|
||||
let output = common::render_module("cmd_duration")
|
||||
.arg("--cmd-duration=5000")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("took {} ", Color::Yellow.bold().paint("5s"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_5s_duration_3s() -> io::Result<()> {
|
||||
let output = common::render_module("cmd_duration")
|
||||
.use_config(toml::toml! {
|
||||
[cmd_duration]
|
||||
min_time = 5000
|
||||
})
|
||||
.arg("--cmd-duration=3000")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_5s_duration_10s() -> io::Result<()> {
|
||||
let output = common::render_module("cmd_duration")
|
||||
.use_config(toml::toml! {
|
||||
[cmd_duration]
|
||||
min_time = 5000
|
||||
})
|
||||
.arg("--cmd-duration=10000")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("took {} ", Color::Yellow.bold().paint("10s"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_1s_duration_prefix_underwent() -> io::Result<()> {
|
||||
let output = common::render_module("cmd_duration")
|
||||
.use_config(toml::toml! {
|
||||
[cmd_duration]
|
||||
format = "underwent [$duration]($style) "
|
||||
})
|
||||
.arg("--cmd-duration=1000")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_5s_duration_prefix_underwent() -> io::Result<()> {
|
||||
let output = common::render_module("cmd_duration")
|
||||
.use_config(toml::toml! {
|
||||
[cmd_duration]
|
||||
format = "underwent [$duration]($style) "
|
||||
})
|
||||
.arg("--cmd-duration=5000")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("underwent {} ", Color::Yellow.bold().paint("5s"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use remove_dir_all::remove_dir_all;
|
||||
use std::io::prelude::*;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::{env, fs, io, process};
|
||||
|
||||
static MANIFEST_DIR: Lazy<&'static Path> = Lazy::new(|| Path::new(env!("CARGO_MANIFEST_DIR")));
|
||||
static EMPTY_CONFIG: Lazy<PathBuf> = Lazy::new(|| MANIFEST_DIR.join("empty_config.toml"));
|
||||
|
||||
#[cfg(windows)]
|
||||
const EXE_PATH: &str = "./target/debug/starship.exe";
|
||||
|
||||
#[cfg(not(windows))]
|
||||
const EXE_PATH: &str = "./target/debug/starship";
|
||||
|
||||
/// Render the full starship prompt
|
||||
pub fn _render_prompt() -> process::Command {
|
||||
let mut command = process::Command::new(EXE_PATH);
|
||||
|
||||
command
|
||||
.arg("prompt")
|
||||
.env_clear()
|
||||
.env("PATH", env!("PATH")) // Provide the $PATH variable so that external programs are runnable
|
||||
.env("STARSHIP_CONFIG", EMPTY_CONFIG.as_os_str());
|
||||
|
||||
command
|
||||
}
|
||||
|
||||
/// Render a specific starship module by name
|
||||
pub fn render_module(module_name: &str) -> process::Command {
|
||||
let binary = fs::canonicalize(EXE_PATH).unwrap();
|
||||
let mut command = process::Command::new(binary);
|
||||
|
||||
command
|
||||
.arg("module")
|
||||
.arg(module_name)
|
||||
.env_clear()
|
||||
.env("PATH", env!("PATH")) // Provide the $PATH variable so that external programs are runnable
|
||||
.env("STARSHIP_CONFIG", EMPTY_CONFIG.as_os_str());
|
||||
|
||||
command
|
||||
}
|
||||
|
||||
/// Create a repo from the fixture to be used in git module tests
|
||||
/// Please delete the returned directory manually after usage with `remove_dir_all::remove_dir_all`
|
||||
pub fn create_fixture_repo() -> io::Result<PathBuf> {
|
||||
let fixture_repo_path = tempfile::tempdir()?.into_path();
|
||||
let repo_path = tempfile::tempdir()?.into_path();
|
||||
let fixture_path = env::current_dir()?.join("tests/fixtures/rocket.bundle");
|
||||
|
||||
let fixture_repo_dir = path_str(&fixture_repo_path)?;
|
||||
let repo_dir = path_str(&repo_path)?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["clone", "-b", "master"])
|
||||
.args(&[&fixture_path, &repo_path])
|
||||
.output()?;
|
||||
|
||||
git2::Repository::clone(&fixture_repo_dir, &repo_dir).ok();
|
||||
remove_dir_all(fixture_repo_path)?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["config", "--local", "user.email", "starship@example.com"])
|
||||
.current_dir(&repo_path)
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["config", "--local", "user.name", "starship"])
|
||||
.current_dir(&repo_path)
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD"])
|
||||
.current_dir(&repo_path)
|
||||
.output()?;
|
||||
|
||||
Ok(repo_path)
|
||||
}
|
||||
|
||||
fn path_str(repo_dir: &PathBuf) -> io::Result<String> {
|
||||
repo_dir
|
||||
.to_str()
|
||||
.ok_or_else(|| Error::from(ErrorKind::Other))
|
||||
.map(|i| i.replace("\\", "/"))
|
||||
}
|
||||
|
||||
/// Extends `std::process::Command` with methods for testing
|
||||
pub trait TestCommand {
|
||||
fn use_config(&mut self, toml: toml::value::Value) -> &mut process::Command;
|
||||
}
|
||||
|
||||
impl TestCommand for process::Command {
|
||||
/// Create a configuration file with the provided TOML and use it
|
||||
fn use_config(&mut self, toml: toml::value::Value) -> &mut process::Command {
|
||||
// Create a persistent config file in a tempdir
|
||||
let (mut config_file, config_path) =
|
||||
tempfile::NamedTempFile::new().unwrap().keep().unwrap();
|
||||
write!(config_file, "{}", toml.to_string()).unwrap();
|
||||
|
||||
// Set that newly-created file as the config for the prompt instance
|
||||
self.env("STARSHIP_CONFIG", config_path)
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn not_in_env() -> io::Result<()> {
|
||||
let output = common::render_module("conda").output()?;
|
||||
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_base() -> io::Result<()> {
|
||||
let output = common::render_module("conda")
|
||||
.env("CONDA_DEFAULT_ENV", "base")
|
||||
.use_config(toml::toml! {
|
||||
[conda]
|
||||
ignore_base = true
|
||||
})
|
||||
.output()?;
|
||||
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn env_set() -> io::Result<()> {
|
||||
let output = common::render_module("conda")
|
||||
.env("CONDA_DEFAULT_ENV", "astronauts")
|
||||
.output()?;
|
||||
|
||||
let expected = format!("via {} ", Color::Green.bold().paint("🅒 astronauts"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate() -> io::Result<()> {
|
||||
let output = common::render_module("conda")
|
||||
.env("CONDA_DEFAULT_ENV", "/some/really/long/and/really/annoying/path/that/shouldnt/be/displayed/fully/conda/my_env")
|
||||
.output()?;
|
||||
|
||||
let expected = format!("via {} ", Color::Green.bold().paint("🅒 my_env"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn char_symbol_configuration() -> io::Result<()> {
|
||||
let expected = format!("{} ", Color::Green.bold().paint("❯"));
|
||||
|
||||
let output = common::render_module("character")
|
||||
.use_config(toml::toml! {
|
||||
[character]
|
||||
symbol = "❯"
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,781 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use dirs_next::home_dir;
|
||||
use git2::Repository;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use std::os::unix::fs::symlink;
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::os::windows::fs::symlink_dir as symlink;
|
||||
use std::path::Path;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn home_directory() -> io::Result<()> {
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path=~")
|
||||
.use_config(toml::toml! { // Necessary if homedir is a git repo
|
||||
[directory]
|
||||
truncate_to_repo = false
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("~"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn substituted_truncated_path() -> io::Result<()> {
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path=/some/long/network/path/workspace/a/b/c/dev")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 4
|
||||
[directory.substitutions]
|
||||
"/some/long/network/path" = "/some/net"
|
||||
"a/b/c" = "d"
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("net/workspace/d/dev"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn strange_substitution() -> io::Result<()> {
|
||||
let strange_sub = "/\\/;,!";
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path=/foo/bar/regular/path")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 0
|
||||
fish_style_pwd_dir_length = 2 // Overridden by substitutions
|
||||
[directory.substitutions]
|
||||
"regular" = strange_sub
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint(format!("/foo/bar/{}/path", strange_sub))
|
||||
);
|
||||
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("directory")
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", 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("directory")
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("starship/engine/schematics")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_directory_in_home() -> io::Result<()> {
|
||||
let dir = home_dir().unwrap().join("starship/engine/schematics");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 1
|
||||
fish_style_pwd_dir_length = 2
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("~/st/en/schematics"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn root_directory() -> io::Result<()> {
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path=/")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let expected = format!(
|
||||
"{}{} ",
|
||||
Color::Cyan.bold().paint("/"),
|
||||
Color::Red.normal().paint("🔒")
|
||||
);
|
||||
#[cfg(target_os = "windows")]
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("/"),);
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn directory_in_root() -> io::Result<()> {
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path=/etc")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{}{} ",
|
||||
Color::Cyan.bold().paint("/etc"),
|
||||
Color::Red.normal().paint("🔒")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "windows")]
|
||||
fn directory_in_root() -> io::Result<()> {
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path=C:\\")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("C:"));
|
||||
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 output = common::render_module("directory")
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("starship/thrusters/rocket"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn truncated_directory_config_large() -> io::Result<()> {
|
||||
let dir = Path::new("/tmp/starship/thrusters/rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 100
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("/tmp/starship/thrusters/rocket")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_style_directory_config_large() -> io::Result<()> {
|
||||
let dir = Path::new("/tmp/starship/thrusters/rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 1
|
||||
fish_style_pwd_dir_length = 100
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("/tmp/starship/thrusters/rocket")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn truncated_directory_config_small() -> io::Result<()> {
|
||||
let dir = Path::new("/tmp/starship/thrusters/rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 2
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("thrusters/rocket"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_directory_config_small() -> io::Result<()> {
|
||||
let dir = Path::new("/tmp/starship/thrusters/rocket");
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
truncation_length = 2
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("/t/s/thrusters/rocket"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn git_repo_root() -> io::Result<()> {
|
||||
// TODO: Investigate why git repo related tests fail when the tempdir is within /tmp/...
|
||||
// Temporarily making the tempdir within $HOME
|
||||
// #[ignore] can be removed after this TODO is addressed
|
||||
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 output = common::render_module("directory")
|
||||
.arg("--path")
|
||||
.arg(repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("rocket-controls"));
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[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 output = common::render_module("directory")
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("rocket-controls/src"));
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn truncated_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/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("src/meters/fuel-gauge"));
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_git_repo_truncate_to_repo_false() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// Don't truncate the path at all.
|
||||
truncation_length = 5
|
||||
truncate_to_repo = false
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("above-repo/rocket-controls/src/meters/fuel-gauge")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_path_directory_in_git_repo_truncate_to_repo_false() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// Don't truncate the path at all.
|
||||
truncation_length = 5
|
||||
truncate_to_repo = false
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("~/.t/above-repo/rocket-controls/src/meters/fuel-gauge")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_path_directory_in_git_repo_truncate_to_repo_true() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("~/.t/a/rocket-controls/src/meters/fuel-gauge")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_git_repo_truncate_to_repo_true() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("rocket-controls/src/meters/fuel-gauge")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn git_repo_in_home_directory_truncate_to_repo_true() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let dir = tmp_dir.path().join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&dir)?;
|
||||
Repository::init(&tmp_dir).unwrap();
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should attmpt to display the truncated path
|
||||
truncate_to_repo = true
|
||||
truncation_length = 5
|
||||
})
|
||||
// Set home directory to the temp repository
|
||||
.env("HOME", tmp_dir.path())
|
||||
.arg("--path")
|
||||
.arg(dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("~/src/meters/fuel-gauge"));
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn symlinked_git_repo_root() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("rocket-controls");
|
||||
let symlink_dir = tmp_dir.path().join("rocket-controls-symlink");
|
||||
fs::create_dir(&repo_dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path")
|
||||
.arg(symlink_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("rocket-controls-symlink"));
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_symlinked_git_repo() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src");
|
||||
let symlink_dir = tmp_dir.path().join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path")
|
||||
.arg(symlink_src_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("rocket-controls-symlink/src")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn truncated_directory_in_symlinked_git_repo() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir.path().join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.arg("--path")
|
||||
.arg(symlink_src_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("src/meters/fuel-gauge"));
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_symlinked_git_repo_truncate_to_repo_false() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir
|
||||
.path()
|
||||
.join("above-repo")
|
||||
.join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// Don't truncate the path at all.
|
||||
truncation_length = 5
|
||||
truncate_to_repo = false
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(symlink_src_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("above-repo/rocket-controls-symlink/src/meters/fuel-gauge")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_path_directory_in_symlinked_git_repo_truncate_to_repo_false() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir
|
||||
.path()
|
||||
.join("above-repo")
|
||||
.join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// Don't truncate the path at all.
|
||||
truncation_length = 5
|
||||
truncate_to_repo = false
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(symlink_src_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("~/.t/above-repo/rocket-controls-symlink/src/meters/fuel-gauge")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fish_path_directory_in_symlinked_git_repo_truncate_to_repo_true() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir
|
||||
.path()
|
||||
.join("above-repo")
|
||||
.join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
fish_style_pwd_dir_length = 1
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(symlink_src_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("~/.t/a/rocket-controls-symlink/src/meters/fuel-gauge")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn directory_in_symlinked_git_repo_truncate_to_repo_true() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir
|
||||
.path()
|
||||
.join("above-repo")
|
||||
.join("rocket-controls-symlink");
|
||||
let symlink_src_dir = symlink_dir.join("src/meters/fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
symlink(&repo_dir, &symlink_dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(symlink_src_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan
|
||||
.bold()
|
||||
.paint("rocket-controls-symlink/src/meters/fuel-gauge")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn symlinked_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();
|
||||
symlink(&dir, repo_dir.join("src/loop"))?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
.use_config(toml::toml! {
|
||||
[directory]
|
||||
// `truncate_to_repo = true` should display the truncated path
|
||||
truncation_length = 5
|
||||
truncate_to_repo = true
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(repo_dir.join("src/loop/loop"))
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
Color::Cyan.bold().paint("rocket-controls/src/loop/loop")
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn symlinked_subdirectory_git_repo_out_of_tree() -> io::Result<()> {
|
||||
let tmp_dir = TempDir::new_in(home_dir().unwrap())?;
|
||||
let repo_dir = tmp_dir.path().join("above-repo").join("rocket-controls");
|
||||
let src_dir = repo_dir.join("src/meters/fuel-gauge");
|
||||
let symlink_dir = tmp_dir.path().join("fuel-gauge");
|
||||
fs::create_dir_all(&src_dir)?;
|
||||
Repository::init(&repo_dir).unwrap();
|
||||
symlink(&src_dir, &symlink_dir)?;
|
||||
|
||||
let output = common::render_module("directory")
|
||||
// Set home directory to the temp repository
|
||||
.env("HOME", tmp_dir.path())
|
||||
.arg("--path")
|
||||
.arg(symlink_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Cyan.bold().paint("~/fuel-gauge"));
|
||||
assert_eq!(expected, actual);
|
||||
tmp_dir.close()
|
||||
}
|
@ -1,244 +0,0 @@
|
||||
use super::common;
|
||||
use regex::Regex;
|
||||
use std::fs::{DirBuilder, OpenOptions};
|
||||
use std::io::{self, Error, ErrorKind, Write};
|
||||
use std::process::{Command, Stdio};
|
||||
use tempfile::{self, TempDir};
|
||||
|
||||
const DOTNET_OUTPUT_PATTERN: &str = "•NET v\\d+?\\.\\d+?\\.\\d?";
|
||||
const DOTNET_PINNED_VERSION: &str = "1.2.3";
|
||||
const DOTNET_PINNED_VERSION_OUTPUT_PATTERN: &str = "•NET v1\\.2\\.3";
|
||||
const DOTNET_TFM_PATTERN: &str = r"🎯 .+";
|
||||
const DOTNET_TFM_PINNED_VERSION: &str = r"netstandard2.0";
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_nothing_in_directory_with_zero_relevant_files() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
expect_output(&workspace, ".", None)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_latest_in_directory_with_directory_build_props_file() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "Directory.Build.props", None)?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_OUTPUT_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_latest_in_directory_with_directory_build_targets_file() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "Directory.Build.targets", None)?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_OUTPUT_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_latest_in_directory_with_packages_props_file() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "Packages.props", None)?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_OUTPUT_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_latest_in_directory_with_solution() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "solution.sln", None)?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_OUTPUT_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_latest_in_directory_with_csproj() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let csproj = make_csproj_with_tfm("TargetFramework", "netstandard2.0");
|
||||
touch_path(&workspace, "project.csproj", Some(&csproj))?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_OUTPUT_PATTERN))?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_TFM_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_latest_in_directory_with_fsproj() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "project.fsproj", None)?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_OUTPUT_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_latest_in_directory_with_xproj() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "project.xproj", None)?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_OUTPUT_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_latest_in_directory_with_project_json() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
touch_path(&workspace, "project.json", None)?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_OUTPUT_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_pinned_in_directory_with_global_json() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let global_json = make_pinned_sdk_json(DOTNET_PINNED_VERSION);
|
||||
touch_path(&workspace, "global.json", Some(&global_json))?;
|
||||
expect_output(&workspace, ".", Some(DOTNET_PINNED_VERSION_OUTPUT_PATTERN))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_pinned_in_project_below_root_with_global_json() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let global_json = make_pinned_sdk_json(DOTNET_PINNED_VERSION);
|
||||
let csproj = make_csproj_with_tfm("TargetFramework", DOTNET_TFM_PINNED_VERSION);
|
||||
touch_path(&workspace, "global.json", Some(&global_json))?;
|
||||
touch_path(&workspace, "project/project.csproj", Some(&csproj))?;
|
||||
expect_output(
|
||||
&workspace,
|
||||
"project",
|
||||
Some(DOTNET_PINNED_VERSION_OUTPUT_PATTERN),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_pinned_in_deeply_nested_project_within_repository() -> io::Result<()> {
|
||||
let workspace = create_workspace(true)?;
|
||||
let global_json = make_pinned_sdk_json("1.2.3");
|
||||
let csproj = make_csproj_with_tfm("TargetFramework", DOTNET_TFM_PINNED_VERSION);
|
||||
touch_path(&workspace, "global.json", Some(&global_json))?;
|
||||
touch_path(
|
||||
&workspace,
|
||||
"deep/path/to/project/project.csproj",
|
||||
Some(&csproj),
|
||||
)?;
|
||||
expect_output(
|
||||
&workspace,
|
||||
"deep/path/to/project",
|
||||
Some(DOTNET_PINNED_VERSION_OUTPUT_PATTERN),
|
||||
)?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_single_tfm() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let csproj = make_csproj_with_tfm("TargetFramework", "netstandard2.0");
|
||||
touch_path(&workspace, "project.csproj", Some(&csproj))?;
|
||||
expect_output(&workspace, ".", Some("•NET v2.2.402"))?;
|
||||
expect_output(&workspace, ".", Some("🎯 netstandard2.0"))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_multiple_tfms() -> io::Result<()> {
|
||||
let workspace = create_workspace(false)?;
|
||||
let csproj = make_csproj_with_tfm("TargetFrameworks", "netstandard2.0;net461");
|
||||
touch_path(&workspace, "project.csproj", Some(&csproj))?;
|
||||
expect_output(&workspace, ".", Some("•NET v2.2.402"))?;
|
||||
expect_output(&workspace, ".", Some("🎯 netstandard2.0;net461"))?;
|
||||
workspace.close()
|
||||
}
|
||||
|
||||
fn create_workspace(is_repo: bool) -> io::Result<TempDir> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
if is_repo {
|
||||
let mut command = Command::new("git");
|
||||
command
|
||||
.args(&["init", "--quiet"])
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.stdin(Stdio::null())
|
||||
.current_dir(repo_dir.path());
|
||||
|
||||
if !command.status()?.success() {
|
||||
return Err(Error::from(ErrorKind::Other));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(repo_dir)
|
||||
}
|
||||
|
||||
fn touch_path(workspace: &TempDir, relative_path: &str, contents: Option<&str>) -> io::Result<()> {
|
||||
let path = workspace.path().join(relative_path);
|
||||
|
||||
DirBuilder::new().recursive(true).create(
|
||||
path.parent()
|
||||
.expect("Expected relative_path to be a file in a directory"),
|
||||
)?;
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(&path)?;
|
||||
write!(file, "{}", contents.unwrap_or(""))?;
|
||||
file.sync_data()
|
||||
}
|
||||
|
||||
fn make_pinned_sdk_json(version: &str) -> String {
|
||||
let json_text = r#"
|
||||
{
|
||||
"sdk": {
|
||||
"version": "INSERT_VERSION"
|
||||
}
|
||||
}
|
||||
"#;
|
||||
json_text.replace("INSERT_VERSION", version)
|
||||
}
|
||||
|
||||
fn make_csproj_with_tfm(tfm_element: &str, tfm: &str) -> String {
|
||||
let json_text = r#"
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TFM_ELEMENT>TFM_VALUE</TFM_ELEMENT>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
"#;
|
||||
json_text
|
||||
.replace("TFM_ELEMENT", tfm_element)
|
||||
.replace("TFM_VALUE", tfm)
|
||||
}
|
||||
|
||||
fn expect_output(workspace: &TempDir, run_from: &str, pattern: Option<&str>) -> io::Result<()> {
|
||||
let run_path = workspace.path().join(run_from);
|
||||
let output = common::render_module("dotnet")
|
||||
.current_dir(run_path)
|
||||
.output()?;
|
||||
let text = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
// This can be helpful for debugging
|
||||
eprintln!("The dotnet module showed: {}", text);
|
||||
|
||||
match pattern {
|
||||
Some(pattern) => {
|
||||
let re = Regex::new(pattern).unwrap();
|
||||
assert!(re.is_match(&text));
|
||||
}
|
||||
None => assert!(text.is_empty()),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
use ansi_term::{Color, Style};
|
||||
use std::io;
|
||||
|
||||
use crate::common;
|
||||
use crate::common::TestCommand;
|
||||
|
||||
const TEST_VAR_VALUE: &str = "astronauts";
|
||||
|
||||
#[test]
|
||||
fn empty_config() -> io::Result<()> {
|
||||
let output = common::render_module("env_var")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[env_var]
|
||||
})
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defined_variable() -> io::Result<()> {
|
||||
let output = common::render_module("env_var")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.output()?;
|
||||
let expected = format!("with {} ", style().paint(TEST_VAR_VALUE));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn undefined_variable() -> io::Result<()> {
|
||||
let output = common::render_module("env_var")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
})
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_has_no_effect() -> io::Result<()> {
|
||||
let output = common::render_module("env_var")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
default = "N/A"
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.output()?;
|
||||
let expected = format!("with {} ", style().paint(TEST_VAR_VALUE));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_takes_effect() -> io::Result<()> {
|
||||
let output = common::render_module("env_var")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "UNDEFINED_TEST_VAR"
|
||||
default = "N/A"
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!("with {} ", style().paint("N/A"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn symbol() -> io::Result<()> {
|
||||
let output = common::render_module("env_var")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
format = "with [■ $env_value](black bold dimmed) "
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.output()?;
|
||||
let expected = format!("with {} ", style().paint(format!("■ {}", TEST_VAR_VALUE)));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prefix() -> io::Result<()> {
|
||||
let output = common::render_module("env_var")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
format = "with [_$env_value](black bold dimmed) "
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.output()?;
|
||||
let expected = format!("with {} ", style().paint(format!("_{}", TEST_VAR_VALUE)));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suffix() -> io::Result<()> {
|
||||
let output = common::render_module("env_var")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[env_var]
|
||||
variable = "TEST_VAR"
|
||||
format = "with [${env_value}_](black bold dimmed) "
|
||||
})
|
||||
.env("TEST_VAR", TEST_VAR_VALUE)
|
||||
.output()?;
|
||||
let expected = format!("with {} ", style().paint(format!("{}_", TEST_VAR_VALUE)));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn style() -> Style {
|
||||
// default style
|
||||
Color::Black.bold().dimmed()
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
use std::fs::{create_dir, File};
|
||||
use std::io::{self, Write};
|
||||
|
||||
use ansi_term::Color;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn account_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default")?;
|
||||
|
||||
create_dir(dir.path().join("configurations"))?;
|
||||
let config_default_path = dir.path().join("configurations/config_default");
|
||||
let mut config_default_file = File::create(&config_default_path)?;
|
||||
config_default_file.write_all(
|
||||
b"[core]
|
||||
account = foo@example.com
|
||||
",
|
||||
)?;
|
||||
|
||||
let output = common::render_module("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy().as_ref())
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Blue.bold().paint("☁️ foo@example.com"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_and_region_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default")?;
|
||||
|
||||
create_dir(dir.path().join("configurations"))?;
|
||||
let config_default_path = dir.path().join("configurations/config_default");
|
||||
let mut config_default_file = File::create(&config_default_path)?;
|
||||
config_default_file.write_all(
|
||||
b"[core]
|
||||
account = foo@example.com
|
||||
|
||||
[compute]
|
||||
region = us-central1
|
||||
",
|
||||
)?;
|
||||
|
||||
let output = common::render_module("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy().as_ref())
|
||||
.output()?;
|
||||
let expected = format!(
|
||||
"on {} ",
|
||||
Color::Blue.bold().paint("☁️ foo@example.com(us-central1)")
|
||||
);
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_and_region_set_with_alias() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default")?;
|
||||
|
||||
create_dir(dir.path().join("configurations"))?;
|
||||
let config_default_path = dir.path().join("configurations/config_default");
|
||||
let mut config_default_file = File::create(&config_default_path)?;
|
||||
config_default_file.write_all(
|
||||
b"[core]
|
||||
account = foo@example.com
|
||||
|
||||
[compute]
|
||||
region = us-central1
|
||||
",
|
||||
)?;
|
||||
|
||||
let output = common::render_module("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy().as_ref())
|
||||
.use_config(toml::toml! {
|
||||
[gcloud.region_aliases]
|
||||
us-central1 = "uc1"
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Blue.bold().paint("☁️ foo@example.com(uc1)"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn active_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default1")?;
|
||||
|
||||
let output = common::render_module("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy().as_ref())
|
||||
.use_config(toml::toml! {
|
||||
[gcloud]
|
||||
format = "on [$symbol$active]($style) "
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Blue.bold().paint("☁️ default1"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn project_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let active_config_path = dir.path().join("active_config");
|
||||
let mut active_config_file = File::create(&active_config_path)?;
|
||||
active_config_file.write_all(b"default")?;
|
||||
|
||||
create_dir(dir.path().join("configurations"))?;
|
||||
let config_default_path = dir.path().join("configurations/config_default");
|
||||
let mut config_default_file = File::create(&config_default_path)?;
|
||||
config_default_file.write_all(
|
||||
b"[core]
|
||||
project = abc
|
||||
",
|
||||
)?;
|
||||
|
||||
let output = common::render_module("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy().as_ref())
|
||||
.use_config(toml::toml! {
|
||||
[gcloud]
|
||||
format = "on [$symbol$project]($style) "
|
||||
})
|
||||
.output()?;
|
||||
let expected = format!("on {} ", Color::Blue.bold().paint("☁️ abc"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn region_not_set_with_display_region() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let output = common::render_module("gcloud")
|
||||
.env("CLOUDSDK_CONFIG", dir.path().to_string_lossy().as_ref())
|
||||
.use_config(toml::toml! {
|
||||
[gcloud]
|
||||
format = "on [$symbol$region]($style) "
|
||||
})
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
@ -1,292 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use remove_dir_all::remove_dir_all;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let output = common::render_module("git_branch")
|
||||
.arg("--path")
|
||||
.arg(repo_dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_changed_truncation_symbol() -> io::Result<()> {
|
||||
test_truncate_length_with_config(
|
||||
"1337_hello_world",
|
||||
15,
|
||||
"1337_hello_worl",
|
||||
"%",
|
||||
"truncation_symbol = \"%\"",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_truncation_symbol() -> io::Result<()> {
|
||||
test_truncate_length_with_config(
|
||||
"1337_hello_world",
|
||||
15,
|
||||
"1337_hello_worl",
|
||||
"",
|
||||
"truncation_symbol = \"\"",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_char_truncation_symbol() -> io::Result<()> {
|
||||
test_truncate_length_with_config(
|
||||
"1337_hello_world",
|
||||
15,
|
||||
"1337_hello_worl",
|
||||
"a",
|
||||
"truncation_symbol = \"apple\"",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_boundary_below() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 15, "1337_hello_worl", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_boundary_on() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 16, "1337_hello_world", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_boundary_above() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 17, "1337_hello_world", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_one() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 1, "1", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", 0, "1337_hello_world", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_negative() -> io::Result<()> {
|
||||
test_truncate_length("1337_hello_world", -1, "1337_hello_world", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hindi_truncation() -> io::Result<()> {
|
||||
test_truncate_length("नमस्ते", 3, "नमस्", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hindi_truncation2() -> io::Result<()> {
|
||||
test_truncate_length("नमस्त", 3, "नमस्", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_japanese_truncation() -> io::Result<()> {
|
||||
test_truncate_length("がんばってね", 4, "がんばっ", "…")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_no_branch() -> io::Result<()> {
|
||||
test_format("1337_hello_world", "no_branch", "", "no_branch")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_just_branch_name() -> io::Result<()> {
|
||||
test_format("1337_hello_world", "$branch", "", "1337_hello_world")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_just_branch_name_color() -> io::Result<()> {
|
||||
test_format(
|
||||
"1337_hello_world",
|
||||
"[$branch](bold blue)",
|
||||
"",
|
||||
Color::Blue.bold().paint("1337_hello_world").to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_mixed_colors() -> io::Result<()> {
|
||||
test_format(
|
||||
"1337_hello_world",
|
||||
"branch: [$branch](bold blue) [THE COLORS](red) ",
|
||||
"",
|
||||
format!(
|
||||
"branch: {} {} ",
|
||||
Color::Blue.bold().paint("1337_hello_world").to_string(),
|
||||
Color::Red.paint("THE COLORS").to_string()
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_symbol_style() -> io::Result<()> {
|
||||
test_format(
|
||||
"1337_hello_world",
|
||||
"$symbol[$branch]($style)",
|
||||
r#"
|
||||
symbol = "git: "
|
||||
style = "green"
|
||||
"#,
|
||||
format!(
|
||||
"git: {}",
|
||||
Color::Green.paint("1337_hello_world").to_string(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_works_with_unborn_default_branch() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?.into_path();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["init"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["symbolic-ref", "HEAD", "refs/heads/main"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
let output = common::render_module("git_branch")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()
|
||||
.unwrap();
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"on {} ",
|
||||
Color::Purple.bold().paint(format!("\u{e0a0} {}", "main")),
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_dir_env_variable() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?.into_path();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["init"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
let output = common::render_module("git_branch")
|
||||
.env("GIT_DIR", Path::new(&repo_dir).join(".git"))
|
||||
.output()
|
||||
.unwrap();
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"on {} ",
|
||||
Color::Purple.bold().paint(format!("\u{e0a0} {}", "master")),
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
fn test_truncate_length(
|
||||
branch_name: &str,
|
||||
truncate_length: i64,
|
||||
expected_name: &str,
|
||||
truncation_symbol: &str,
|
||||
) -> io::Result<()> {
|
||||
test_truncate_length_with_config(
|
||||
branch_name,
|
||||
truncate_length,
|
||||
expected_name,
|
||||
truncation_symbol,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
fn test_truncate_length_with_config(
|
||||
branch_name: &str,
|
||||
truncate_length: i64,
|
||||
expected_name: &str,
|
||||
truncation_symbol: &str,
|
||||
config_options: &str,
|
||||
) -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["checkout", "-b", branch_name])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
|
||||
let output = common::render_module("git_branch")
|
||||
.use_config(
|
||||
toml::from_str(&format!(
|
||||
"
|
||||
[git_branch]
|
||||
truncation_length = {}
|
||||
{}
|
||||
",
|
||||
truncate_length, config_options
|
||||
))
|
||||
.unwrap(),
|
||||
)
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!(
|
||||
"on {} ",
|
||||
Color::Purple
|
||||
.bold()
|
||||
.paint(format!("\u{e0a0} {}{}", expected_name, truncation_symbol)),
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
fn test_format<T: AsRef<str>>(
|
||||
branch_name: &str,
|
||||
format: &str,
|
||||
config_options: &str,
|
||||
expected: T,
|
||||
) -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["checkout", "-b", branch_name])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
|
||||
let output = common::render_module("git_branch")
|
||||
.use_config(
|
||||
toml::from_str(&format!(
|
||||
r#"
|
||||
[git_branch]
|
||||
format = "{}"
|
||||
{}
|
||||
"#,
|
||||
format, config_options
|
||||
))
|
||||
.unwrap(),
|
||||
)
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert_eq!(expected.as_ref(), actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use remove_dir_all::remove_dir_all;
|
||||
use std::process::Command;
|
||||
use std::{io, str};
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let output = common::render_module("git_commit")
|
||||
.arg("--path")
|
||||
.arg(repo_dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
let mut git_output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?
|
||||
.stdout;
|
||||
git_output.truncate(7);
|
||||
let expected_hash = str::from_utf8(&git_output).unwrap();
|
||||
|
||||
let output = common::render_module("git_commit")
|
||||
.use_config(toml::toml! {
|
||||
[git_commit]
|
||||
only_detached = false
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let mut expected = Color::Green
|
||||
.bold()
|
||||
.paint(format!("({})", expected_hash))
|
||||
.to_string();
|
||||
expected.push(' ');
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash_len_override() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
let mut git_output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?
|
||||
.stdout;
|
||||
git_output.truncate(14);
|
||||
let expected_hash = str::from_utf8(&git_output).unwrap();
|
||||
|
||||
let output = common::render_module("git_commit")
|
||||
.use_config(toml::toml! {
|
||||
[git_commit]
|
||||
only_detached = false
|
||||
commit_hash_length = 14
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let mut expected = Color::Green
|
||||
.bold()
|
||||
.paint(format!("({})", expected_hash))
|
||||
.to_string();
|
||||
expected.push(' ');
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash_only_detached_on_branch() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
let output = common::render_module("git_commit")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert_eq!("", actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash_only_detached_on_detached() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["checkout", "@~1"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
|
||||
let mut git_output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?
|
||||
.stdout;
|
||||
git_output.truncate(7);
|
||||
let expected_hash = str::from_utf8(&git_output).unwrap();
|
||||
|
||||
let output = common::render_module("git_commit")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let mut expected = Color::Green
|
||||
.bold()
|
||||
.paint(format!("({})", expected_hash))
|
||||
.to_string();
|
||||
expected.push(' ');
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
use super::common;
|
||||
use ansi_term::Color;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{self, Error, ErrorKind, Write};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let output = common::render_module("git_state")
|
||||
.arg("--path")
|
||||
.arg(repo_dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_rebasing() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = path_str(&repo_dir)?;
|
||||
|
||||
run_git_cmd(&["rebase", "other-branch"], Some(path), false)?;
|
||||
|
||||
let output = common::render_module("git_state")
|
||||
.arg("--path")
|
||||
.arg(&path)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let mut expected = Color::Yellow.bold().paint("(REBASING 1/1)").to_string();
|
||||
expected.push(' ');
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_merging() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = path_str(&repo_dir)?;
|
||||
|
||||
run_git_cmd(&["merge", "other-branch"], Some(path), false)?;
|
||||
|
||||
let output = common::render_module("git_state")
|
||||
.arg("--path")
|
||||
.arg(&path)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let mut expected = Color::Yellow.bold().paint("(MERGING)").to_string();
|
||||
expected.push(' ');
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_cherry_picking() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = path_str(&repo_dir)?;
|
||||
|
||||
run_git_cmd(&["cherry-pick", "other-branch"], Some(path), false)?;
|
||||
|
||||
let output = common::render_module("git_state")
|
||||
.arg("--path")
|
||||
.arg(&path)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let mut expected = Color::Yellow.bold().paint("(CHERRY-PICKING)").to_string();
|
||||
expected.push(' ');
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_bisecting() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = path_str(&repo_dir)?;
|
||||
|
||||
run_git_cmd(&["bisect", "start"], Some(path), false)?;
|
||||
|
||||
let output = common::render_module("git_state")
|
||||
.arg("--path")
|
||||
.arg(&path)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let mut expected = Color::Yellow.bold().paint("(BISECTING)").to_string();
|
||||
expected.push(' ');
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_reverting() -> io::Result<()> {
|
||||
let repo_dir = create_repo_with_conflict()?;
|
||||
let path = path_str(&repo_dir)?;
|
||||
|
||||
run_git_cmd(&["revert", "--no-commit", "HEAD~1"], Some(path), false)?;
|
||||
|
||||
let output = common::render_module("git_state")
|
||||
.arg("--path")
|
||||
.arg(&path)
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let mut expected = Color::Yellow.bold().paint("(REVERTING)").to_string();
|
||||
expected.push(' ');
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_git_cmd<A, S>(args: A, dir: Option<&str>, expect_ok: bool) -> io::Result<()>
|
||||
where
|
||||
A: IntoIterator<Item = S>,
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
let mut command = Command::new("git");
|
||||
command
|
||||
.args(args)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.stdin(Stdio::null());
|
||||
|
||||
if let Some(dir) = dir {
|
||||
command.current_dir(dir);
|
||||
}
|
||||
|
||||
let status = command.status()?;
|
||||
|
||||
if expect_ok && !status.success() {
|
||||
Err(Error::from(ErrorKind::Other))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn create_repo_with_conflict() -> io::Result<tempfile::TempDir> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
let path = path_str(&repo_dir)?;
|
||||
let conflicted_file = repo_dir.path().join("the_file");
|
||||
|
||||
let write_file = |text: &str| {
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(&conflicted_file)?;
|
||||
write!(file, "{}", text)
|
||||
};
|
||||
|
||||
// Initialize a new git repo
|
||||
run_git_cmd(&["init", "--quiet", path], None, true)?;
|
||||
|
||||
// Set local author info
|
||||
run_git_cmd(
|
||||
&["config", "--local", "user.email", "starship@example.com"],
|
||||
Some(path),
|
||||
true,
|
||||
)?;
|
||||
run_git_cmd(
|
||||
&["config", "--local", "user.name", "starship"],
|
||||
Some(path),
|
||||
true,
|
||||
)?;
|
||||
|
||||
// Write a file on master and commit it
|
||||
write_file("Version A")?;
|
||||
run_git_cmd(&["add", "the_file"], Some(path), true)?;
|
||||
run_git_cmd(&["commit", "--message", "Commit A"], Some(path), true)?;
|
||||
|
||||
// Switch to another branch, and commit a change to the file
|
||||
run_git_cmd(&["checkout", "-b", "other-branch"], Some(path), true)?;
|
||||
write_file("Version B")?;
|
||||
run_git_cmd(
|
||||
&["commit", "--all", "--message", "Commit B"],
|
||||
Some(path),
|
||||
true,
|
||||
)?;
|
||||
|
||||
// Switch back to master, and commit a third change to the file
|
||||
run_git_cmd(&["checkout", "master"], Some(path), true)?;
|
||||
write_file("Version C")?;
|
||||
run_git_cmd(
|
||||
&["commit", "--all", "--message", "Commit C"],
|
||||
Some(path),
|
||||
true,
|
||||
)?;
|
||||
|
||||
Ok(repo_dir)
|
||||
}
|
||||
|
||||
fn path_str(repo_dir: &tempfile::TempDir) -> io::Result<&str> {
|
||||
repo_dir
|
||||
.path()
|
||||
.to_str()
|
||||
.ok_or_else(|| Error::from(ErrorKind::Other))
|
||||
}
|
@ -1,680 +0,0 @@
|
||||
use ansi_term::{ANSIStrings, Color};
|
||||
use remove_dir_all::remove_dir_all;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
/// Right after the calls to git the filesystem state may not have finished
|
||||
/// updating yet causing some of the tests to fail. These barriers are placed
|
||||
/// after each call to git.
|
||||
/// This barrier is windows-specific though other operating systems may need it
|
||||
/// in the future.
|
||||
#[cfg(not(windows))]
|
||||
fn barrier() {}
|
||||
#[cfg(windows)]
|
||||
fn barrier() {
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
}
|
||||
|
||||
fn format_output(symbols: &str) -> String {
|
||||
format!("{} ", Color::Red.bold().paint(format!("[{}]", symbols)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(repo_dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_behind() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
behind(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("⇣");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_behind_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
behind(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
behind = "⇣$count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("⇣1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_ahead() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
File::create(repo_dir.join("readme.md"))?.sync_all()?;
|
||||
ahead(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("⇡");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_ahead_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
File::create(repo_dir.join("readme.md"))?.sync_all()?;
|
||||
ahead(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
ahead="⇡$count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("⇡1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_diverged() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
diverge(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("⇕");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_diverged_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
diverge(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
diverged=r"⇕⇡$ahead_count⇣$behind_count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("⇕⇡1⇣1");
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_conflicted() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_conflict(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("=");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_conflicted_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_conflict(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
conflicted = "=$count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("=1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_untracked_file() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_untracked(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("?");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_untracked_file_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_untracked(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
untracked = "?$count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("?1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn doesnt_show_untracked_file_if_disabled() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_untracked(&repo_dir)?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["config", "status.showUntrackedFiles", "no"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = "";
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_stashed() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
barrier();
|
||||
|
||||
create_stash(&repo_dir)?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("$");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shows_stashed_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
barrier();
|
||||
|
||||
create_stash(&repo_dir)?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
stashed = r"\$$count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("$1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_modified() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_modified(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("!");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_modified_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_modified(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
modified = "!$count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("!1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_staged_file() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_staged(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("+");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_staged_file_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_staged(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
staged = "+[$count](green)"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format!(
|
||||
"{} ",
|
||||
ANSIStrings(&[
|
||||
Color::Red.bold().paint("[+"),
|
||||
Color::Green.paint("1"),
|
||||
Color::Red.bold().paint("]"),
|
||||
])
|
||||
);
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_renamed_file() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_renamed(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("»");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_renamed_file_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_renamed(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
renamed = "»$count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("»1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_deleted_file() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_deleted(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("✘");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn shows_deleted_file_with_count() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
|
||||
create_deleted(&repo_dir)?;
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
deleted = "✘$count"
|
||||
})
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format_output("✘1");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
// Whenever a file is manually renamed, git itself ('git status') does not treat such file as renamed,
|
||||
// but as untracked instead. The following test checks if manually deleted and manually renamed
|
||||
// files are tracked by git_status module in the same way 'git status' does.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn ignore_manually_renamed() -> io::Result<()> {
|
||||
let repo_dir = common::create_fixture_repo()?;
|
||||
File::create(repo_dir.join("a"))?.sync_all()?;
|
||||
File::create(repo_dir.join("b"))?.sync_all()?;
|
||||
Command::new("git")
|
||||
.args(&["add", "--all"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
Command::new("git")
|
||||
.args(&["commit", "-m", "add new files"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
|
||||
fs::remove_file(repo_dir.join("a"))?;
|
||||
fs::rename(repo_dir.join("b"), repo_dir.join("c"))?;
|
||||
barrier();
|
||||
|
||||
let output = common::render_module("git_status")
|
||||
.arg("--path")
|
||||
.arg(&repo_dir)
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[git_status]
|
||||
prefix = ""
|
||||
suffix = ""
|
||||
style = ""
|
||||
ahead = "A"
|
||||
deleted = "D"
|
||||
untracked = "U"
|
||||
renamed = "R"
|
||||
})
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert!(actual.contains('A'));
|
||||
assert!(actual.contains('D'));
|
||||
assert!(actual.contains('U'));
|
||||
assert!(!actual.contains('R'));
|
||||
|
||||
remove_dir_all(repo_dir)
|
||||
}
|
||||
|
||||
fn ahead(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
File::create(repo_dir.join("readme.md"))?.sync_all()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["commit", "-am", "Update readme"])
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn behind(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD^"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn diverge(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD^"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
fs::write(repo_dir.join("Cargo.toml"), " ")?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["commit", "-am", "Update readme"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_conflict(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["reset", "--hard", "HEAD^"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
fs::write(repo_dir.join("readme.md"), "# goodbye")?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["add", "."])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["commit", "-m", "Change readme"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["pull", "--rebase"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_stash(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
File::create(repo_dir.join("readme.md"))?.sync_all()?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["stash", "--all"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_untracked(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
File::create(repo_dir.join("license"))?.sync_all()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_modified(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
File::create(repo_dir.join("readme.md"))?.sync_all()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_staged(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
File::create(repo_dir.join("license"))?.sync_all()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["add", "."])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_renamed(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
Command::new("git")
|
||||
.args(&["mv", "readme.md", "readme.md.bak"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Command::new("git")
|
||||
.args(&["add", "-A"])
|
||||
.current_dir(repo_dir.as_path())
|
||||
.output()?;
|
||||
barrier();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_deleted(repo_dir: &PathBuf) -> io::Result<()> {
|
||||
fs::remove_file(repo_dir.join("readme.md"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
use ansi_term::{Color, Style};
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::{env, io};
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
enum Expect<'a> {
|
||||
BranchName(&'a str),
|
||||
Empty,
|
||||
NoTruncation,
|
||||
Symbol(&'a str),
|
||||
Style(Style),
|
||||
TruncationSymbol(&'a str),
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
let repo_dir = tempfile::tempdir()?;
|
||||
|
||||
let output = common::render_module("hg_branch")
|
||||
.arg("--path")
|
||||
.arg(repo_dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_hg_get_branch_fails() -> io::Result<()> {
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
|
||||
// Create a fake corrupted mercurial repo.
|
||||
let hgdir = tempdir.path().join(".hg");
|
||||
fs::create_dir(&hgdir)?;
|
||||
fs::write(&hgdir.join("requires"), "fake-corrupted-repo")?;
|
||||
|
||||
expect_hg_branch_with_config(
|
||||
tempdir.path(),
|
||||
"",
|
||||
&[Expect::BranchName(&"default"), Expect::NoTruncation],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_hg_get_branch_autodisabled() -> io::Result<()> {
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
expect_hg_branch_with_config(tempdir.path(), "", &[Expect::Empty])?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_hg_bookmark() -> io::Result<()> {
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
let repo_dir = create_fixture_hgrepo(&tempdir)?;
|
||||
run_hg(&["bookmark", "bookmark-101"], &repo_dir)?;
|
||||
expect_hg_branch_with_config(
|
||||
&repo_dir,
|
||||
"",
|
||||
&[Expect::BranchName(&"bookmark-101"), Expect::NoTruncation],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_default_truncation_symbol() -> io::Result<()> {
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
let repo_dir = create_fixture_hgrepo(&tempdir)?;
|
||||
run_hg(&["branch", "-f", "branch-name-101"], &repo_dir)?;
|
||||
run_hg(
|
||||
&[
|
||||
"commit",
|
||||
"-m",
|
||||
"empty commit 101",
|
||||
"-u",
|
||||
"fake user <fake@user>",
|
||||
],
|
||||
&repo_dir,
|
||||
)?;
|
||||
expect_hg_branch_with_config(
|
||||
&repo_dir,
|
||||
"truncation_length = 14",
|
||||
&[Expect::BranchName(&"branch-name-10")],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_configured_symbols() -> io::Result<()> {
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
let repo_dir = create_fixture_hgrepo(&tempdir)?;
|
||||
run_hg(&["branch", "-f", "branch-name-121"], &repo_dir)?;
|
||||
run_hg(
|
||||
&[
|
||||
"commit",
|
||||
"-m",
|
||||
"empty commit 121",
|
||||
"-u",
|
||||
"fake user <fake@user>",
|
||||
],
|
||||
&repo_dir,
|
||||
)?;
|
||||
expect_hg_branch_with_config(
|
||||
&repo_dir,
|
||||
r#"
|
||||
symbol = "B "
|
||||
truncation_length = 14
|
||||
truncation_symbol = "%"
|
||||
"#,
|
||||
&[
|
||||
Expect::BranchName(&"branch-name-12"),
|
||||
Expect::Symbol(&"B"),
|
||||
Expect::TruncationSymbol(&"%"),
|
||||
],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_configured_style() -> io::Result<()> {
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
let repo_dir = create_fixture_hgrepo(&tempdir)?;
|
||||
run_hg(&["branch", "-f", "branch-name-131"], &repo_dir)?;
|
||||
run_hg(
|
||||
&[
|
||||
"commit",
|
||||
"-m",
|
||||
"empty commit 131",
|
||||
"-u",
|
||||
"fake user <fake@user>",
|
||||
],
|
||||
&repo_dir,
|
||||
)?;
|
||||
|
||||
expect_hg_branch_with_config(
|
||||
&repo_dir,
|
||||
r#"
|
||||
style = "underline blue"
|
||||
"#,
|
||||
&[
|
||||
Expect::BranchName(&"branch-name-131"),
|
||||
Expect::Style(Color::Blue.underline()),
|
||||
Expect::TruncationSymbol(&""),
|
||||
],
|
||||
)?;
|
||||
tempdir.close()
|
||||
}
|
||||
|
||||
fn expect_hg_branch_with_config(
|
||||
repo_dir: &Path,
|
||||
config_options: &str,
|
||||
expectations: &[Expect],
|
||||
) -> io::Result<()> {
|
||||
let output = common::render_module("hg_branch")
|
||||
.use_config(toml::from_str(&format!(
|
||||
r#"
|
||||
[hg_branch]
|
||||
{}
|
||||
"#,
|
||||
config_options
|
||||
))?)
|
||||
.arg("--path")
|
||||
.arg(repo_dir.to_str().unwrap())
|
||||
.output()?;
|
||||
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let mut expect_branch_name = "default";
|
||||
let mut expect_style = Color::Purple.bold();
|
||||
let mut expect_symbol = "\u{e0a0}";
|
||||
let mut expect_truncation_symbol = "…";
|
||||
|
||||
for expect in expectations {
|
||||
match expect {
|
||||
Expect::Empty => {
|
||||
assert_eq!("", actual);
|
||||
return Ok(());
|
||||
}
|
||||
Expect::Symbol(symbol) => {
|
||||
expect_symbol = symbol;
|
||||
}
|
||||
Expect::TruncationSymbol(truncation_symbol) => {
|
||||
expect_truncation_symbol = truncation_symbol;
|
||||
}
|
||||
Expect::NoTruncation => {
|
||||
expect_truncation_symbol = "";
|
||||
}
|
||||
Expect::BranchName(branch_name) => {
|
||||
expect_branch_name = branch_name;
|
||||
}
|
||||
Expect::Style(style) => expect_style = *style,
|
||||
}
|
||||
}
|
||||
|
||||
let expected = format!(
|
||||
"on {} ",
|
||||
expect_style.paint(format!(
|
||||
"{} {}{}",
|
||||
expect_symbol, expect_branch_name, expect_truncation_symbol
|
||||
)),
|
||||
);
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn create_fixture_hgrepo(tempdir: &tempfile::TempDir) -> io::Result<PathBuf> {
|
||||
let repo_path = tempdir.path().join("hg-repo");
|
||||
let fixture_path = env::current_dir()?.join("tests/fixtures/hg-repo.bundle");
|
||||
|
||||
run_hg(
|
||||
&[
|
||||
"clone",
|
||||
fixture_path.to_str().unwrap(),
|
||||
repo_path.to_str().unwrap(),
|
||||
],
|
||||
&tempdir.path(),
|
||||
)?;
|
||||
|
||||
Ok(repo_path)
|
||||
}
|
||||
|
||||
fn run_hg(args: &[&str], repo_dir: &Path) -> io::Result<()> {
|
||||
Command::new("hg")
|
||||
.args(args)
|
||||
.current_dir(&repo_dir)
|
||||
.output()?;
|
||||
Ok(())
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
use ansi_term::{Color, Style};
|
||||
use std::io;
|
||||
|
||||
use crate::common;
|
||||
use crate::common::TestCommand;
|
||||
|
||||
#[test]
|
||||
fn ssh_only_false() -> io::Result<()> {
|
||||
let hostname = match get_hostname() {
|
||||
Some(h) => h,
|
||||
None => return hostname_not_tested(),
|
||||
};
|
||||
let output = common::render_module("hostname")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = false
|
||||
trim_at = ""
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format!("on {} ", style().paint(hostname));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ssh() -> io::Result<()> {
|
||||
let output = common::render_module("hostname")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = true
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!("", actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh() -> io::Result<()> {
|
||||
let hostname = match get_hostname() {
|
||||
Some(h) => h,
|
||||
None => return hostname_not_tested(),
|
||||
};
|
||||
let output = common::render_module("hostname")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = true
|
||||
trim_at = ""
|
||||
})
|
||||
.env("SSH_CONNECTION", "something")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format!("on {} ", style().paint(hostname));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_trim_at() -> io::Result<()> {
|
||||
let hostname = match get_hostname() {
|
||||
Some(h) => h,
|
||||
None => return hostname_not_tested(),
|
||||
};
|
||||
let output = common::render_module("hostname")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = false
|
||||
trim_at = ""
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format!("on {} ", style().paint(hostname));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trim_at() -> io::Result<()> {
|
||||
let hostname = match get_hostname() {
|
||||
Some(h) => h,
|
||||
None => return hostname_not_tested(),
|
||||
};
|
||||
let (remainder, trim_at) = hostname.split_at(1);
|
||||
let output = common::render_module("hostname")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[hostname]
|
||||
ssh_only = false
|
||||
trim_at = trim_at
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
let expected = format!("on {} ", style().paint(remainder));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_hostname() -> Option<String> {
|
||||
match gethostname::gethostname().into_string() {
|
||||
Ok(hostname) => Some(hostname),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn style() -> Style {
|
||||
Color::Green.bold().dimmed()
|
||||
}
|
||||
|
||||
fn hostname_not_tested() -> io::Result<()> {
|
||||
println!(
|
||||
"hostname was not tested because gethostname failed! \
|
||||
This could be caused by your hostname containing invalid UTF."
|
||||
);
|
||||
Ok(())
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
#[test]
|
||||
fn config_blank_job_0() -> io::Result<()> {
|
||||
let output = common::render_module("jobs").arg("--jobs=0").output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank_job_1() -> io::Result<()> {
|
||||
let output = common::render_module("jobs").arg("--jobs=1").output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Blue.bold().paint("✦"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank_job_2() -> io::Result<()> {
|
||||
let output = common::render_module("jobs").arg("--jobs=2").output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Blue.bold().paint("✦2"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_2_job_2() -> io::Result<()> {
|
||||
let output = common::render_module("jobs")
|
||||
.use_config(toml::toml! {
|
||||
[jobs]
|
||||
threshold = 2
|
||||
})
|
||||
.arg("--jobs=2")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Blue.bold().paint("✦"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_2_job_3() -> io::Result<()> {
|
||||
let output = common::render_module("jobs")
|
||||
.use_config(toml::toml! {
|
||||
[jobs]
|
||||
threshold = 2
|
||||
})
|
||||
.arg("--jobs=3")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("{} ", Color::Blue.bold().paint("✦3"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
mod aws;
|
||||
mod character;
|
||||
mod cmd_duration;
|
||||
mod common;
|
||||
mod conda;
|
||||
mod configuration;
|
||||
mod directory;
|
||||
mod dotnet;
|
||||
mod env_var;
|
||||
mod gcloud;
|
||||
mod git_branch;
|
||||
mod git_commit;
|
||||
mod git_state;
|
||||
mod git_status;
|
||||
mod hg_branch;
|
||||
mod hostname;
|
||||
mod jobs;
|
||||
mod modules;
|
||||
mod nix_shell;
|
||||
mod python;
|
||||
mod shlvl;
|
||||
mod singularity;
|
||||
mod terraform;
|
||||
mod time;
|
||||
mod username;
|
@ -1,31 +0,0 @@
|
||||
use std::io;
|
||||
|
||||
use crate::common;
|
||||
|
||||
#[test]
|
||||
fn unknown_module_name() -> io::Result<()> {
|
||||
let unknown_module_name = "some_random_name";
|
||||
let output = common::render_module(unknown_module_name).output()?;
|
||||
let actual_stdout = String::from_utf8(output.stdout).unwrap();
|
||||
let actual_stderr = String::from_utf8(output.stderr).unwrap();
|
||||
let expected_stdout = "";
|
||||
let expected_stderr = format!(
|
||||
"Error: Unknown module {}. Use starship module --list to list out all supported modules.\n",
|
||||
unknown_module_name
|
||||
);
|
||||
assert_eq!(expected_stdout, actual_stdout);
|
||||
assert_eq!(expected_stderr, actual_stderr);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn known_module_name() -> io::Result<()> {
|
||||
let output = common::render_module("line_break").output()?;
|
||||
let actual_stdout = String::from_utf8(output.stdout).unwrap();
|
||||
let actual_stderr = String::from_utf8(output.stderr).unwrap();
|
||||
let expected_stdout = "\n";
|
||||
let expected_stderr = "";
|
||||
assert_eq!(expected_stdout, actual_stdout);
|
||||
assert_eq!(expected_stderr, actual_stderr);
|
||||
Ok(())
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
use crate::common;
|
||||
|
||||
#[test]
|
||||
fn no_env_variables() -> io::Result<()> {
|
||||
let output = common::render_module("nix_shell").output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!("", actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_env_variables() -> io::Result<()> {
|
||||
let output = common::render_module("nix_shell")
|
||||
.env("IN_NIX_SHELL", "something_wrong")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!("", actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pure_shell() -> io::Result<()> {
|
||||
let output = common::render_module("nix_shell")
|
||||
.env("IN_NIX_SHELL", "pure")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Blue.bold().paint("❄️ pure"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn impure_shell() -> io::Result<()> {
|
||||
let output = common::render_module("nix_shell")
|
||||
.env("IN_NIX_SHELL", "impure")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Blue.bold().paint("❄️ impure"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pure_shell_name() -> io::Result<()> {
|
||||
let output = common::render_module("nix_shell")
|
||||
.env("IN_NIX_SHELL", "pure")
|
||||
.env("name", "starship")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Blue.bold().paint("❄️ pure (starship)"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn impure_shell_name() -> io::Result<()> {
|
||||
let output = common::render_module("nix_shell")
|
||||
.env("IN_NIX_SHELL", "impure")
|
||||
.env("name", "starship")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Blue.bold().paint("❄️ impure (starship)"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
|
||||
use crate::common;
|
||||
|
||||
// TODO - These tests should be moved into the python module when we have sorted out mocking of env
|
||||
// vars.
|
||||
|
||||
#[test]
|
||||
fn with_virtual_env() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.py"))?.sync_all()?;
|
||||
let output = common::render_module("python")
|
||||
.env("VIRTUAL_ENV", "/foo/bar/my_venv")
|
||||
.arg("--path")
|
||||
.arg(dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert!(actual.contains("my_venv"));
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_active_venv() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let output = common::render_module("python")
|
||||
.env("VIRTUAL_ENV", "/foo/bar/my_venv")
|
||||
.arg("--path")
|
||||
.arg(dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert!(actual.contains("my_venv"));
|
||||
dir.close()
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
use ansi_term::{Color, Style};
|
||||
use std::io;
|
||||
|
||||
use crate::common;
|
||||
use crate::common::TestCommand;
|
||||
|
||||
const SHLVL_ENV_VAR: &str = "SHLVL";
|
||||
|
||||
fn style() -> Style {
|
||||
// default style
|
||||
Color::Yellow.bold()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_config() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enabled() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.output()?;
|
||||
let expected = format!("{} ", style().paint("↕️ 2"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_level() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
disabled = false
|
||||
})
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enabled_config_level_1() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "1")
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lower_threshold() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
threshold = 1
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "1")
|
||||
.output()?;
|
||||
let expected = format!("{} ", style().paint("↕️ 1"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn higher_threshold() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
threshold = 3
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "1")
|
||||
.output()?;
|
||||
let expected = "";
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_style() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
style = "Red Underline"
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.output()?;
|
||||
let expected = format!("{} ", Color::Red.underline().paint("↕️ 2"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_symbol() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
symbol = "shlvl is "
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.output()?;
|
||||
let expected = format!("{} ", style().paint("shlvl is 2"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formatting() -> io::Result<()> {
|
||||
let output = common::render_module("shlvl")
|
||||
.env_clear()
|
||||
.use_config(toml::toml! {
|
||||
[shlvl]
|
||||
format = "$symbol going down [$shlvl]($style) GOING UP "
|
||||
disabled = false
|
||||
})
|
||||
.env(SHLVL_ENV_VAR, "2")
|
||||
.output()?;
|
||||
let expected = format!("↕️ going down {} GOING UP ", style().paint("2"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
use crate::common;
|
||||
|
||||
#[test]
|
||||
fn no_env_set() -> io::Result<()> {
|
||||
let output = common::render_module("singularity").output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
#[test]
|
||||
fn env_set() -> io::Result<()> {
|
||||
let output = common::render_module("singularity")
|
||||
.env_clear()
|
||||
.env("SINGULARITY_NAME", "centos.img")
|
||||
.output()?;
|
||||
|
||||
let expected = format!("{} ", Color::Blue.bold().dimmed().paint("[centos.img]"));
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Write};
|
||||
|
||||
use crate::common;
|
||||
|
||||
#[test]
|
||||
fn folder_without_dotterraform() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let output = common::render_module("terraform")
|
||||
.arg("--path")
|
||||
.arg(dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn folder_with_tf_file() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.tf"))?;
|
||||
|
||||
let output = common::render_module("terraform")
|
||||
.arg("--path")
|
||||
.arg(dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Fixed(105).bold().paint("💠 default"));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn folder_with_workspace_override() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.tf"))?;
|
||||
|
||||
let output = common::render_module("terraform")
|
||||
.arg("--path")
|
||||
.arg(dir.path())
|
||||
.env("TF_WORKSPACE", "development")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Fixed(105).bold().paint("💠 development"));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn folder_with_datadir_override() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
File::create(dir.path().join("main.tf"))?;
|
||||
|
||||
let datadir = tempfile::tempdir()?;
|
||||
let mut file = File::create(datadir.path().join("environment"))?;
|
||||
file.write_all(b"development")?;
|
||||
file.sync_all()?;
|
||||
|
||||
let output = common::render_module("terraform")
|
||||
.arg("--path")
|
||||
.arg(dir.path())
|
||||
.env("TF_DATA_DIR", datadir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Fixed(105).bold().paint("💠 development"));
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()?;
|
||||
datadir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn folder_with_dotterraform_no_environment() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let tf_dir = dir.path().join(".terraform");
|
||||
fs::create_dir(&tf_dir)?;
|
||||
|
||||
let output = common::render_module("terraform")
|
||||
.arg("--path")
|
||||
.arg(dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Fixed(105).bold().paint("💠 default"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn folder_with_dotterraform_with_environment() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let tf_dir = dir.path().join(".terraform");
|
||||
fs::create_dir(&tf_dir)?;
|
||||
let mut file = File::create(tf_dir.join("environment"))?;
|
||||
file.write_all(b"development")?;
|
||||
file.sync_all()?;
|
||||
|
||||
let output = common::render_module("terraform")
|
||||
.arg("--path")
|
||||
.arg(dir.path())
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Fixed(105).bold().paint("💠 development"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
use std::io;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
/* Note: tests in this crate cannot rely on the actual time displayed by
|
||||
the module, since that is dependent on the time inside the test environment,
|
||||
which we cannot control.
|
||||
|
||||
However, we *can* test certain things here, such as the fact that the module
|
||||
should not display when disabled, should display *something* when enabled,
|
||||
and should have the correct prefixes and suffixes in a given config */
|
||||
|
||||
#[test]
|
||||
fn config_enabled() -> io::Result<()> {
|
||||
let output = common::render_module("time")
|
||||
.use_config(toml::toml! {
|
||||
[time]
|
||||
disabled = false
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
// We can't test what it actually is...but we can assert it's not blank
|
||||
assert!(!actual.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_blank() -> io::Result<()> {
|
||||
let output = common::render_module("time").output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = "";
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_check_prefix_and_suffix() -> io::Result<()> {
|
||||
let output = common::render_module("time")
|
||||
.use_config(toml::toml! {
|
||||
[time]
|
||||
disabled = false
|
||||
format = "at [\\[$time\\]]($style) "
|
||||
time_format = "%T"
|
||||
})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
// This is the prefix with "at ", the color code, then the prefix char [
|
||||
let col_prefix = format!("at {}{}[", '\u{1b}', "[1;33m");
|
||||
|
||||
// This is the suffix with suffix char ']', then color codes, then a space
|
||||
let col_suffix = format!("]{}{} ", '\u{1b}', "[0m");
|
||||
|
||||
assert!(actual.starts_with(&col_prefix));
|
||||
assert!(actual.ends_with(&col_suffix));
|
||||
Ok(())
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
use ansi_term::Color;
|
||||
use std::io;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
// TODO: Add tests for if root user (UID == 0)
|
||||
// Requires mocking
|
||||
|
||||
#[test]
|
||||
fn no_env_variables() -> io::Result<()> {
|
||||
let output = common::render_module("username").output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!("", actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn logname_equals_user() -> io::Result<()> {
|
||||
let output = common::render_module("username")
|
||||
.env("LOGNAME", "astronaut")
|
||||
.env("USER", "astronaut")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!("", actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh_wo_username() -> io::Result<()> {
|
||||
// SSH connection w/o username
|
||||
let output = common::render_module("username")
|
||||
.env("SSH_CONNECTION", "192.168.223.17 36673 192.168.223.229 22")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!("", actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn current_user_not_logname() -> io::Result<()> {
|
||||
let output = common::render_module("username")
|
||||
.env("LOGNAME", "astronaut")
|
||||
.env("USER", "cosmonaut")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Yellow.bold().paint("cosmonaut"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh_connection() -> io::Result<()> {
|
||||
let output = common::render_module("username")
|
||||
.env("USER", "astronaut")
|
||||
.env("SSH_CONNECTION", "192.168.223.17 36673 192.168.223.229 22")
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Yellow.bold().paint("astronaut"));
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_always() -> io::Result<()> {
|
||||
let output = common::render_module("username")
|
||||
.env("USER", "astronaut")
|
||||
.use_config(toml::toml! {
|
||||
[username]
|
||||
show_always = true})
|
||||
.output()?;
|
||||
let actual = String::from_utf8(output.stdout).unwrap();
|
||||
|
||||
let expected = format!("via {} ", Color::Yellow.bold().paint("astronaut"));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user