mirror of
https://github.com/Llewellynvdm/zoxide.git
synced 2025-02-05 04:38:25 +00:00
Add tests for completions (#204)
This commit is contained in:
parent
efe11ec924
commit
d33bfd111f
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -20,7 +20,5 @@ jobs:
|
||||
- uses: cachix/install-nix-action@v12
|
||||
if: ${{ matrix.os != 'windows-latest' }}
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-stable
|
||||
- run: mkdir -p /tmp/home && make test
|
||||
env:
|
||||
HOME: /tmp/home
|
||||
nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz
|
||||
- run: make test
|
||||
|
14
Makefile
14
Makefile
@ -11,7 +11,7 @@ endif
|
||||
.PHONY: build clean install test uninstall
|
||||
|
||||
build:
|
||||
cargo build --release $(ci_color_always)
|
||||
cargo build $(ci_color_always)
|
||||
|
||||
clean:
|
||||
cargo clean $(ci_color_always)
|
||||
@ -22,16 +22,16 @@ install:
|
||||
ifeq ($(NIX), true)
|
||||
test:
|
||||
nix-shell --pure --run 'cargo fmt -- --check --files-with-diff $(ci_color_always)'
|
||||
nix-shell --pure --run 'cargo check --all-features --release $(ci_color_always)'
|
||||
nix-shell --pure --run 'cargo clippy --all-features --release $(ci_color_always) -- --deny warnings --deny clippy::all'
|
||||
nix-shell --pure --run 'cargo test --all-features --no-fail-fast --release $(ci_color_always)'
|
||||
nix-shell --pure --run 'cargo check --all-features $(ci_color_always)'
|
||||
nix-shell --pure --run 'cargo clippy --all-features $(ci_color_always) -- --deny warnings --deny clippy::all'
|
||||
nix-shell --pure --run 'cargo test --all-features --no-fail-fast $(ci_color_always)'
|
||||
nix-shell --pure --run 'cargo audit --deny warnings $(ci_color_always) --ignore=RUSTSEC-2020-0095'
|
||||
else
|
||||
test:
|
||||
cargo fmt -- --check --files-with-diff $(ci_color_always)
|
||||
cargo check --all-features --release $(ci_color_always)
|
||||
cargo clippy --all-features --release $(ci_color_always) -- --deny warnings --deny clippy::all
|
||||
cargo test --no-fail-fast --release $(ci_color_always)
|
||||
cargo check --all-features $(ci_color_always)
|
||||
cargo clippy --all-features $(ci_color_always) -- --deny warnings --deny clippy::all
|
||||
cargo test --no-fail-fast $(ci_color_always)
|
||||
cargo audit --deny warnings $(ci_color_always) --ignore=RUSTSEC-2020-0095
|
||||
endif
|
||||
|
||||
|
5
build.rs
5
build.rs
@ -19,9 +19,8 @@ fn crate_version() -> String {
|
||||
}
|
||||
|
||||
fn generate_completions() {
|
||||
mod app {
|
||||
include!("src/app.rs");
|
||||
}
|
||||
#[path = "src/app/_app.rs"]
|
||||
mod app;
|
||||
|
||||
use app::App;
|
||||
use clap::IntoApp;
|
||||
|
@ -38,6 +38,6 @@ impl Run for Init {
|
||||
InitShell::Zsh => shell::Zsh(opts).render(),
|
||||
}
|
||||
.context("could not render template")?;
|
||||
writeln!(io::stdout(), "{}", source).wrap_write("stdout")
|
||||
writeln!(io::stdout(), "{}", source).pipe_exit("stdout")
|
||||
}
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
mod _app;
|
||||
mod add;
|
||||
mod import;
|
||||
mod init;
|
||||
mod query;
|
||||
mod remove;
|
||||
|
||||
use crate::app::App;
|
||||
pub use crate::app::_app::*;
|
||||
|
||||
use anyhow::Result;
|
||||
|
@ -27,7 +27,7 @@ impl Run for Query {
|
||||
if self.interactive {
|
||||
let mut fzf = Fzf::new(false)?;
|
||||
for dir in matches {
|
||||
writeln!(fzf.stdin(), "{}", dir.display_score(now)).wrap_write("fzf")?;
|
||||
writeln!(fzf.stdin(), "{}", dir.display_score(now)).pipe_exit("fzf")?;
|
||||
}
|
||||
|
||||
let selection = fzf.wait_select()?;
|
||||
@ -53,9 +53,9 @@ impl Run for Query {
|
||||
} else {
|
||||
writeln!(handle, "{}", dir.display())
|
||||
}
|
||||
.wrap_write("stdout")?;
|
||||
.pipe_exit("stdout")?;
|
||||
}
|
||||
handle.flush().wrap_write("stdout")?;
|
||||
handle.flush().pipe_exit("stdout")?;
|
||||
} else {
|
||||
let dir = matches.next().context("no match found")?;
|
||||
if self.score {
|
||||
@ -63,7 +63,7 @@ impl Run for Query {
|
||||
} else {
|
||||
writeln!(io::stdout(), "{}", dir.display())
|
||||
}
|
||||
.wrap_write("stdout")?;
|
||||
.pipe_exit("stdout")?;
|
||||
}
|
||||
|
||||
Ok(())
|
@ -25,7 +25,7 @@ impl Run for Remove {
|
||||
|
||||
let mut fzf = Fzf::new(true)?;
|
||||
for dir in db.iter_matches(&query, now, resolve_symlinks) {
|
||||
writeln!(fzf.stdin(), "{}", dir.display_score(now)).wrap_write("fzf")?;
|
||||
writeln!(fzf.stdin(), "{}", dir.display_score(now)).pipe_exit("fzf")?;
|
||||
}
|
||||
|
||||
selection = fzf.wait_select()?;
|
@ -16,11 +16,11 @@ impl Display for SilentExit {
|
||||
}
|
||||
|
||||
pub trait WriteErrorHandler {
|
||||
fn wrap_write(self, device: &str) -> Result<()>;
|
||||
fn pipe_exit(self, device: &str) -> Result<()>;
|
||||
}
|
||||
|
||||
impl WriteErrorHandler for io::Result<()> {
|
||||
fn wrap_write(self, device: &str) -> Result<()> {
|
||||
fn pipe_exit(self, device: &str) -> Result<()> {
|
||||
match self {
|
||||
Err(e) if e.kind() == io::ErrorKind::BrokenPipe => bail!(SilentExit { code: 0 }),
|
||||
result => result.with_context(|| format!("could not write to {}", device)),
|
||||
|
13
src/fzf.rs
13
src/fzf.rs
@ -3,6 +3,7 @@ use crate::error::SilentExit;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use std::io;
|
||||
use std::process::{Child, ChildStdin, Command, Stdio};
|
||||
|
||||
pub struct Fzf {
|
||||
@ -23,9 +24,15 @@ impl Fzf {
|
||||
command.env("FZF_DEFAULT_OPTS", fzf_opts);
|
||||
}
|
||||
|
||||
Ok(Fzf {
|
||||
child: command.spawn().context("could not launch fzf")?,
|
||||
})
|
||||
let child = match command.spawn() {
|
||||
Ok(child) => child,
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => {
|
||||
bail!("could not find fzf, is it installed?")
|
||||
}
|
||||
Err(e) => Err(e).context("could not launch fzf")?,
|
||||
};
|
||||
|
||||
Ok(Fzf { child })
|
||||
}
|
||||
|
||||
pub fn stdin(&mut self) -> &mut ChildStdin {
|
||||
|
@ -1,5 +1,4 @@
|
||||
mod app;
|
||||
mod cmd;
|
||||
mod config;
|
||||
mod db;
|
||||
mod error;
|
||||
@ -7,8 +6,7 @@ mod fzf;
|
||||
mod shell;
|
||||
mod util;
|
||||
|
||||
use crate::app::App;
|
||||
use crate::cmd::Run;
|
||||
use crate::app::{App, Run};
|
||||
use crate::error::SilentExit;
|
||||
|
||||
use clap::Clap;
|
||||
|
29
src/shell.rs
29
src/shell.rs
@ -60,13 +60,12 @@ mod tests {
|
||||
for &resolve_symlinks in BOOLS {
|
||||
for &hook in HOOKS {
|
||||
for &cmd in CMDS {
|
||||
let opt = Opts {
|
||||
opts.push(Opts {
|
||||
cmd,
|
||||
hook,
|
||||
echo,
|
||||
resolve_symlinks,
|
||||
};
|
||||
opts.push(opt);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,7 +83,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
macro_rules! generate_tests {
|
||||
macro_rules! make_tests {
|
||||
($N:literal) => {
|
||||
seq!(i in 0..$N {
|
||||
#[test]
|
||||
@ -92,7 +91,7 @@ mod tests {
|
||||
let opts = dbg!(&opts()[i]);
|
||||
let source = Bash(opts).render().unwrap();
|
||||
Command::new("bash")
|
||||
.args(&["-c", &source, "--noediting", "--noprofile", "--norc"])
|
||||
.args(&["--noprofile", "--norc", "-c", &source])
|
||||
.assert()
|
||||
.success()
|
||||
.stdout("")
|
||||
@ -213,7 +212,7 @@ mod tests {
|
||||
let opts = dbg!(&opts()[i]);
|
||||
let source = Posix(opts).render().unwrap();
|
||||
let assert = Command::new("bash")
|
||||
.args(&["--posix", "-c", &source, "--noediting", "--noprofile", "--norc"])
|
||||
.args(&["--posix", "--noprofile", "--norc", "-c", &source])
|
||||
.assert()
|
||||
.success()
|
||||
.stderr("");
|
||||
@ -256,7 +255,6 @@ mod tests {
|
||||
let opts = dbg!(&opts()[i]);
|
||||
let mut source = Posix(opts).render().unwrap();
|
||||
source.push('\n');
|
||||
|
||||
Command::new("shfmt")
|
||||
.args(&["-d", "-s", "-ln", "posix", "-i", "4", "-ci", "-"])
|
||||
.write_stdin(source)
|
||||
@ -271,7 +269,7 @@ mod tests {
|
||||
let opts = dbg!(&opts()[i]);
|
||||
let source = Powershell(opts).render().unwrap();
|
||||
Command::new("pwsh")
|
||||
.args(&["-Command", &source, "-NoLogo", "-NonInteractive", "-NoProfile"])
|
||||
.args(&["-NoLogo", "-NonInteractive", "-NoProfile", "-Command", &source])
|
||||
.assert()
|
||||
.success()
|
||||
.stdout("")
|
||||
@ -316,14 +314,19 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Xonsh complains about type-hinting here, although it works fine in practice.
|
||||
// <https://github.com/xonsh/xonsh/issues/3959>
|
||||
#[ignore]
|
||||
fn xonsh_xonsh_#i() {
|
||||
let opts = dbg!(&opts()[i]);
|
||||
let source = Xonsh(opts).render().unwrap();
|
||||
|
||||
// We can't pass the source directly to `xonsh -c` due to
|
||||
// a bug: <https://github.com/xonsh/xonsh/issues/3959>
|
||||
Command::new("xonsh")
|
||||
.args(&["-c", &source, "--no-rc"])
|
||||
.args(&[
|
||||
"-c",
|
||||
"import sys; execx(sys.stdin.read(), 'exec', __xonsh__.ctx, filename='zoxide')",
|
||||
"--no-rc"
|
||||
])
|
||||
.write_stdin(source.as_bytes())
|
||||
.assert()
|
||||
.success()
|
||||
.stdout("")
|
||||
@ -360,5 +363,5 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
with_opts_size!(generate_tests);
|
||||
with_opts_size!(make_tests);
|
||||
}
|
||||
|
71
tests/completion.rs
Normal file
71
tests/completion.rs
Normal file
@ -0,0 +1,71 @@
|
||||
//! Syntax checking for auto-generated shell completions.
|
||||
|
||||
#![cfg(feature = "shell_tests")]
|
||||
use assert_cmd::Command;
|
||||
|
||||
#[test]
|
||||
fn completions_bash() {
|
||||
let source = include_str!("../contrib/completions/zoxide.bash");
|
||||
Command::new("bash")
|
||||
.args(&["--noprofile", "--norc", "-c", source])
|
||||
.assert()
|
||||
.success()
|
||||
.stdout("")
|
||||
.stderr("");
|
||||
}
|
||||
|
||||
// Elvish: the completions file uses editor commands to add completions to the
|
||||
// shell. However, Elvish does not support running editor commands from a
|
||||
// script, so we can't create a test for this.
|
||||
// <https://github.com/elves/elvish/issues/1299>
|
||||
|
||||
#[test]
|
||||
fn completions_fish() {
|
||||
let source = include_str!("../contrib/completions/zoxide.fish");
|
||||
let tempdir = tempfile::tempdir().unwrap();
|
||||
let tempdir = tempdir.path().to_str().unwrap();
|
||||
|
||||
Command::new("fish")
|
||||
.env("HOME", tempdir)
|
||||
.args(&["--command", source, "--private"])
|
||||
.assert()
|
||||
.success()
|
||||
.stdout("")
|
||||
.stderr("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completions_powershell() {
|
||||
let source = include_str!("../contrib/completions/_zoxide.ps1");
|
||||
Command::new("pwsh")
|
||||
.args(&[
|
||||
"-NoLogo",
|
||||
"-NonInteractive",
|
||||
"-NoProfile",
|
||||
"-Command",
|
||||
source,
|
||||
])
|
||||
.assert()
|
||||
.success()
|
||||
.stdout("")
|
||||
.stderr("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completions_zsh() {
|
||||
let source = r#"
|
||||
set -eu
|
||||
completions='./contrib/completions'
|
||||
test -d "$completions"
|
||||
fpath=("$completions" $fpath)
|
||||
autoload -Uz compinit
|
||||
compinit -u
|
||||
"#;
|
||||
|
||||
Command::new("zsh")
|
||||
.args(&["-c", source, "--no-rcs"])
|
||||
.assert()
|
||||
.success()
|
||||
.stdout("")
|
||||
.stderr("");
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user