From 7736ec2744e264267af267021d59ba12c2087e7a Mon Sep 17 00:00:00 2001 From: Austin Gill Date: Sun, 16 Jun 2024 13:35:15 -0500 Subject: [PATCH] Break apart integration tests for "add" and "check" subcommands --- Cargo.lock | 1 + Cargo.toml | 1 + tests/add.rs | 38 ++++++++++++++++ tests/check.rs | 41 +++++++++++++++++ tests/common/mod.rs | 49 ++++++++++++++++++++ tests/test_simple.rs | 105 ------------------------------------------- 6 files changed, 130 insertions(+), 105 deletions(-) create mode 100644 tests/add.rs create mode 100644 tests/check.rs create mode 100644 tests/common/mod.rs delete mode 100644 tests/test_simple.rs diff --git a/Cargo.lock b/Cargo.lock index 0fb70d6..f6911fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,6 +355,7 @@ dependencies = [ "directories", "eyre", "git2", + "lazy_static", "predicates", "tempfile", "tracing", diff --git a/Cargo.toml b/Cargo.toml index a57c6b9..7d1c519 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,5 +18,6 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } [dev-dependencies] assert_cmd = { version = "2.0.14", features = ["color"] } ctor = "0.2.7" +lazy_static = "1.4.0" predicates = "3.1.0" tempfile = "3.10.1" diff --git a/tests/add.rs b/tests/add.rs new file mode 100644 index 0000000..1fa0004 --- /dev/null +++ b/tests/add.rs @@ -0,0 +1,38 @@ +mod common; + +use common::CommandExt; + +#[test] +#[ignore = "Slow; performs git clone"] +fn clone_herostratus() { + let (mut cmd, temp) = common::herostratus(None); + let data_dir = temp.as_ref().unwrap().path(); + + let expected_bare_repo = data_dir + .join("git") + .join("Notgnoshi") + .join("herostratus.git"); + + let url = "https://github.com/Notgnoshi/herostratus.git"; + cmd.arg("add").arg(url); + + assert!(!data_dir.join("git").exists()); + + let output = cmd.captured_output().unwrap(); + assert!(output.status.success()); + assert!(expected_bare_repo.exists()); + + // Adding the same URL again in the same data_dir fails ... + let (mut cmd, _temp) = common::herostratus(Some(data_dir)); + cmd.arg("add").arg(url); + + let output = cmd.captured_output().unwrap(); + assert!(!output.status.success()); + + // ... unless the --force flag is given + let (mut cmd, _temp) = common::herostratus(Some(data_dir)); + cmd.arg("add").arg("--force").arg(url); + + let output = cmd.captured_output().unwrap(); + assert!(output.status.success()); +} diff --git a/tests/check.rs b/tests/check.rs new file mode 100644 index 0000000..ca648b6 --- /dev/null +++ b/tests/check.rs @@ -0,0 +1,41 @@ +mod common; + +use common::CommandExt; +use predicates::prelude::*; +use predicates::str; + +#[test] +fn search_current_repo_for_test_simple_branch() { + let (mut cmd, _temp) = common::herostratus(None); + cmd.arg("check").arg(".").arg("origin/test/simple"); + + let output = cmd.captured_output().unwrap(); + assert!(output.status.success()); +} + +#[test] +fn search_current_repo_for_branch_that_does_not_exist() { + let (mut cmd, _temp) = common::herostratus(None); + cmd.arg("check") + .arg(".") + .arg("origin/test/this-branch-will-never-exist"); + + let output = cmd.captured_output().unwrap(); + assert!(!output.status.success()); +} + +#[test] +fn search_current_repo_for_fixup_commits() { + let (mut cmd, _temp) = common::herostratus(None); + cmd.arg("check").arg(".").arg("origin/test/fixup"); + + let output = cmd.captured_output().unwrap(); + assert!(output.status.success()); + + // These are the three fixup! commits in the test/fixup branch + let assertion = str::contains("60b480b554dbd5266eec0f2378f72df5170a6702") + .and(str::contains("a987013884fc7dafbe9eb080d7cbc8625408a85f")) + .and(str::contains("2721748d8fa0b0cc3302b41733d37e30161eabfd")); + let stdout = String::from_utf8_lossy(&output.stdout); + assert!(assertion.eval(&stdout)); +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs new file mode 100644 index 0000000..075d84a --- /dev/null +++ b/tests/common/mod.rs @@ -0,0 +1,49 @@ +use std::path::{Path, PathBuf}; +use std::process::Output; + +use assert_cmd::Command; +use tempfile::{tempdir, TempDir}; + +// Cache the path to the binary as suggested by https://github.com/assert-rs/assert_cmd/issues/6 to +// avoid expensive repeated lookups. +lazy_static::lazy_static! { + static ref HEROSTRATUS: PathBuf = assert_cmd::cargo::cargo_bin("herostratus"); +} + +/// Get a [`Command`] for the herostratus binary and the [`TempDir`] data dir used in the test +pub fn herostratus(data_dir: Option<&Path>) -> (Command, Option) { + let (tempdir, path) = if let Some(data_dir) = data_dir { + (None, data_dir.to_path_buf()) + } else { + let temp = tempdir().unwrap(); + let data_dir = temp.path().to_path_buf(); + (Some(temp), data_dir) + }; + + let mut cmd = Command::new(&*HEROSTRATUS); + cmd.arg("--log-level=DEBUG").arg("--data-dir").arg(path); + + (cmd, tempdir) +} + +fn capture_output(output: &Output) { + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + + // Test output capture relies on magic in the print! and println! macros + print!("{stdout}"); + print!("{stderr}"); +} + +pub trait CommandExt { + /// Same as [Command::output], except with hooks to print stdout and stderr for failed tests + fn captured_output(&mut self) -> std::io::Result; +} + +impl CommandExt for Command { + fn captured_output(&mut self) -> std::io::Result { + let output = self.output()?; + capture_output(&output); + Ok(output) + } +} diff --git a/tests/test_simple.rs b/tests/test_simple.rs deleted file mode 100644 index 8ef1469..0000000 --- a/tests/test_simple.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::process::Output; - -use predicate::str; -use predicates::prelude::*; - -fn capture_output(output: &Output) { - let stdout = String::from_utf8_lossy(&output.stdout); - let stderr = String::from_utf8_lossy(&output.stderr); - - // Test output capture relies on magic in the print! and println! macros - print!("{stdout}"); - print!("{stderr}"); -} - -#[test] -fn search_current_repo_for_test_simple_branch() { - // TODO: Consider caching this, so it doesn't get so expensive as - // https://github.com/assert-rs/assert_cmd/issues/6 suggests. - let mut cmd = assert_cmd::Command::cargo_bin("herostratus").unwrap(); - cmd.arg("check").arg(".").arg("origin/test/simple"); - - let output = cmd.output().unwrap(); - capture_output(&output); - assert!(output.status.success()); -} - -#[test] -fn search_current_repo_for_branch_that_does_not_exist() { - let mut cmd = assert_cmd::Command::cargo_bin("herostratus").unwrap(); - cmd.arg("check") - .arg(".") - .arg("origin/test/this-branch-will-never-exist"); - - let output = cmd.output().unwrap(); - capture_output(&output); - assert!(!output.status.success()); -} - -#[test] -fn search_current_repo_for_fixup_commits() { - let mut cmd = assert_cmd::Command::cargo_bin("herostratus").unwrap(); - cmd.arg("check").arg(".").arg("origin/test/fixup"); - - let output = cmd.output().unwrap(); - capture_output(&output); - assert!(output.status.success()); - - let assertion = str::contains("60b480b554dbd5266eec0f2378f72df5170a6702") - .and(str::contains("a987013884fc7dafbe9eb080d7cbc8625408a85f")) - .and(str::contains("2721748d8fa0b0cc3302b41733d37e30161eabfd")); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(assertion.eval(&stdout)); -} - -#[test] -#[ignore = "Slow; performs git clone"] -fn clone_herostratus() { - let temp = tempfile::tempdir().unwrap(); - let data_dir = temp.path(); - // let data_dir = PathBuf::from("/tmp/herostratus"); - - let mut cmd = assert_cmd::Command::cargo_bin("herostratus").unwrap(); - let expected_bare_repo = data_dir - .join("git") - .join("Notgnoshi") - .join("herostratus.git"); - let url = "https://github.com/Notgnoshi/herostratus.git"; - cmd.arg("--data-dir") - .arg(data_dir) - .arg("--log-level=DEBUG") - .arg("add") - .arg(url); - - assert!(!data_dir.join("git").exists()); - - let output = cmd.output().unwrap(); - capture_output(&output); - assert!(output.status.success()); - assert!(expected_bare_repo.exists()); - - // Adding the same URL again fails ... - let mut cmd = assert_cmd::Command::cargo_bin("herostratus").unwrap(); - cmd.arg("--data-dir") - .arg(data_dir) - .arg("--log-level=DEBUG") - .arg("add") - .arg(url); - - let output = cmd.output().unwrap(); - capture_output(&output); - assert!(!output.status.success()); - - // ... unless the --force flag is given - let mut cmd = assert_cmd::Command::cargo_bin("herostratus").unwrap(); - cmd.arg("--data-dir") - .arg(data_dir) - .arg("--log-level=DEBUG") - .arg("add") - .arg("--force") - .arg(url); - - let output = cmd.output().unwrap(); - capture_output(&output); - assert!(output.status.success()); -}