Skip to content

Commit

Permalink
test: run completion tests using bash-completion 2.14.0 (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
reubeno authored Oct 25, 2024
1 parent 252e794 commit 41e6284
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ jobs:
${BASH_PATH} --version
echo "BASH_PATH=${BASH_PATH}">>$GITHUB_ENV
- name: "Download recent bash-completion sources for tests"
uses: actions/checkout@v4
with:
repository: "scop/bash-completion"
ref: "2.14.0"
path: "bash-completion"

- name: "Setup bash-completion"
run: |
echo "BASH_COMPLETION_PATH=${GITHUB_WORKSPACE}/bash-completion/bash_completion">>$GITHUB_ENV
- name: Test
run: |
set -euxo pipefail
Expand Down
4 changes: 4 additions & 0 deletions brush-shell/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ harness = false
name = "brush-interactive-tests"
path = "tests/interactive_tests.rs"

[[test]]
name = "brush-completion-tests"
path = "tests/completion_tests.rs"

[features]
default = ["basic", "reedline"]
basic = []
Expand Down
44 changes: 40 additions & 4 deletions brush-shell/tests/completion_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

use anyhow::Result;
use assert_fs::prelude::*;
use std::path::Path;
use std::path::PathBuf;

struct TestShellWithBashCompletion {
shell: brush_core::Shell,
temp_dir: assert_fs::TempDir,
}

const BASH_COMPLETION_SCRIPT: &str = "/usr/share/bash-completion/bash_completion";
const DEFAULT_BASH_COMPLETION_SCRIPT: &str = "/usr/share/bash-completion/bash_completion";

impl TestShellWithBashCompletion {
async fn new() -> Result<Self> {
Expand All @@ -23,11 +23,12 @@ impl TestShellWithBashCompletion {
..Default::default()
};

let mut shell = brush_core::Shell::new(&create_options).await?;
let bash_completion_script_path = Self::find_bash_completion_script()?;

let mut shell = brush_core::Shell::new(&create_options).await?;
let exec_params = shell.default_exec_params();
let source_result = shell
.source::<String>(Path::new(BASH_COMPLETION_SCRIPT), &[], &exec_params)
.source::<String>(bash_completion_script_path.as_path(), &[], &exec_params)
.await?;

if source_result.exit_code != 0 {
Expand All @@ -39,6 +40,22 @@ impl TestShellWithBashCompletion {
Ok(Self { shell, temp_dir })
}

fn find_bash_completion_script() -> Result<PathBuf> {
// See if an environmental override was provided.
let script_path = std::env::var("BASH_COMPLETION_PATH")
.map(PathBuf::from)
.unwrap_or(PathBuf::from(DEFAULT_BASH_COMPLETION_SCRIPT));

if script_path.exists() {
Ok(script_path)
} else {
Err(anyhow::anyhow!(
"bash completion script not found: {}",
script_path.display()
))
}
}

pub async fn complete(&mut self, line: &str, pos: usize) -> Result<Vec<String>> {
let completions = self.shell.get_completions(line, pos).await?;
Ok(completions.candidates.into_iter().collect())
Expand Down Expand Up @@ -280,3 +297,22 @@ async fn complete_command_option() -> Result<()> {

Ok(())
}

/// Tests completion with some well-known programs that have been good manual test cases
/// for us in the past.
#[tokio::test]
async fn complete_path_args_to_well_known_programs() -> Result<()> {
let mut test_shell = TestShellWithBashCompletion::new().await?;

// Create file and dir.
test_shell.temp_dir.child("item1").touch()?;
test_shell.temp_dir.child("item2").create_dir_all()?;

// Complete.
let input = "tar tvf ./item";
let results = test_shell.complete(input, input.len()).await?;

assert_eq!(results, ["./item1", "./item2"]);

Ok(())
}

0 comments on commit 41e6284

Please sign in to comment.