src/cli/shell_completion.rs

//! Generate shell completion scripts.
//!
//! Backed by `clap_complete`. Writing to an arbitrary `io::Write` makes the
//! integration tests easier.

use std::io::Write;

use clap::CommandFactory;
use clap_complete::{generate, shells};

use super::args::{Cli, Shell};

pub fn print<W: Write>(shell: Shell, out: &mut W) {
    let mut cmd = Cli::command();
    match shell {
        Shell::Bash => generate(shells::Bash, &mut cmd, "ripgrab", out),
        Shell::Zsh => generate(shells::Zsh, &mut cmd, "ripgrab", out),
        Shell::Fish => generate(shells::Fish, &mut cmd, "ripgrab", out),
        Shell::Powershell => generate(shells::PowerShell, &mut cmd, "ripgrab", out),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn render(shell: Shell) -> String {
        let mut buf = Vec::new();
        print(shell, &mut buf);
        String::from_utf8(buf).unwrap()
    }

    #[test]
    fn bash_script_mentions_program_name() {
        let script = render(Shell::Bash);
        assert!(script.contains("ripgrab"));
    }

    #[test]
    fn zsh_script_is_not_empty() {
        assert!(!render(Shell::Zsh).is_empty());
    }

    #[test]
    fn fish_script_mentions_subcommand() {
        let script = render(Shell::Fish);
        assert!(script.contains("tail"));
    }
}