summaryrefslogtreecommitdiff
path: root/tests/cli.rs
diff options
context:
space:
mode:
authorStefan Kreutz <mail@skreutz.com>2024-03-24 15:04:09 +0100
committerStefan Kreutz <mail@skreutz.com>2024-03-24 15:04:09 +0100
commitc1fa48e9bd617d70e823efef5d6dcea41b1d2087 (patch)
tree421e69c512ac54bf65495ef23fd7d9ec5a5e67d5 /tests/cli.rs
downloadbrck-a7f062939ead1e0cb89b9a2c211108cd42b8e15d.tar
Add initial implementationbrck-0.1.0
Diffstat (limited to 'tests/cli.rs')
-rw-r--r--tests/cli.rs299
1 files changed, 299 insertions, 0 deletions
diff --git a/tests/cli.rs b/tests/cli.rs
new file mode 100644
index 0000000..2846a62
--- /dev/null
+++ b/tests/cli.rs
@@ -0,0 +1,299 @@
+use std::{fs::File, path::Path, process::Command};
+
+use assert_cmd::prelude::*;
+use assert_fs::fixture::{FileWriteStr, PathChild};
+use filetime::FileTime;
+use predicates::prelude::*;
+use serde_json::Value;
+use sha2::{Digest, Sha256};
+use testresult::TestResult;
+
+#[test]
+fn corrupted() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+ dir.child("a").write_str("apple")?;
+ dir.child("b").write_str("banana")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::is_empty());
+
+ let db = dir.child(".brck");
+ assert!(db.exists());
+ let db_time = db.metadata()?.modified()?;
+ let db_hash = sha256(db.path())?;
+
+ let b = dir.child("b");
+ let b_time = FileTime::from_last_modification_time(&b.metadata()?);
+ b.write_str("cheese")?;
+ filetime::set_file_mtime(b.path(), b_time)?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .assert()
+ .failure()
+ .stdout(predicate::str::contains("corrupted"))
+ .stderr(predicate::str::contains("Error"));
+
+ assert_eq!(db_time, db.metadata()?.modified()?);
+ assert_eq!(db_hash, sha256(db.path())?);
+
+ Ok(())
+}
+
+#[test]
+fn quiet_by_default() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+ dir.child("a").write_str("apple")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::is_empty());
+
+ Ok(())
+}
+
+#[test]
+fn verbose() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+ dir.child("a").write_str("apple")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .arg("--verbose")
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("added"))
+ .stderr(predicate::str::is_empty());
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .arg("--verbose")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::is_empty());
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .arg("--verbose")
+ .arg("--verbose")
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("unchanged"))
+ .stderr(predicate::str::is_empty());
+
+ Ok(())
+}
+
+#[test]
+fn json() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+ dir.child("a").write_str("apple")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ let assert = cmd
+ .current_dir(&dir)
+ .arg("--verbose")
+ .arg("--verbose")
+ .arg("--json")
+ .assert()
+ .success()
+ .stderr(predicate::str::is_empty());
+
+ let out = &assert.get_output().stdout;
+ let mut iter = serde_json::Deserializer::from_slice(out).into_iter::<Value>();
+ let added = iter.next().unwrap()?;
+ assert_eq!(
+ added.get("type"),
+ Some(Value::String("added".into())).as_ref()
+ );
+ assert_eq!(
+ added.get("new").unwrap().get("sha256"),
+ Some(Value::String(
+ "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b".into()
+ ))
+ .as_ref()
+ );
+ assert!(iter.next().is_none());
+
+ Ok(())
+}
+
+#[test]
+fn summary() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+ dir.child("a").write_str("apple")?;
+ dir.child("b").write_str("banana")?;
+ dir.child("c").write_str("cherry")?;
+ dir.child("d").write_str("date")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::is_empty());
+
+ std::fs::remove_file(dir.child("b"))?;
+ dir.child("c").write_str("cashew")?;
+ dir.child("d").write_str("date")?;
+ dir.child("e").write_str("elderberry")?;
+ dir.child("f").write_str("fig")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ // Matching ^ and $ doesn't really work.
+ let pred = predicate::str::is_match("Removed: *1")?
+ .and(predicate::str::is_match("Added: *2")?) // e, f
+ .and(predicate::str::is_match("Unchanged: *1")?) // a
+ .and(predicate::str::is_match("Corrupted: *0")?) // -
+ .and(predicate::str::is_match("Touched: *1")?) // d
+ .and(predicate::str::is_match("Changed: *1")?) // c
+ .and(predicate::str::is_match("Total: *6")?); // a-f
+ cmd.current_dir(&dir)
+ .arg("--summary")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(pred);
+
+ Ok(())
+}
+
+#[test]
+fn dry_run_init() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+ dir.child("a").write_str("apple")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .arg("--dry-run")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("dry run"));
+ assert!(!dir.child(".brck").exists());
+
+ Ok(())
+}
+
+#[test]
+fn dry_run_update() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+ dir.child("a").write_str("apple")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::is_empty());
+
+ let db = dir.child(".brck");
+ assert!(db.exists());
+ let db_time = db.metadata()?.modified()?;
+ let db_hash = sha256(db.path())?;
+
+ dir.child("b").write_str("banana")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .arg("--dry-run")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("dry run"));
+
+ assert_eq!(db_time, db.metadata()?.modified()?);
+ assert_eq!(db_hash, sha256(db.path())?);
+
+ Ok(())
+}
+
+#[test]
+fn deny() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+ dir.child("a").write_str("apple")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::is_empty());
+
+ let db = dir.child(".brck");
+ assert!(db.exists());
+ let db_time = db.metadata()?.modified()?;
+ let db_hash = sha256(db.path())?;
+
+ dir.child("b").write_str("banana")?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .arg("--deny")
+ .arg("added")
+ .assert()
+ .failure()
+ .stdout(predicate::str::contains("added"))
+ .stderr(predicate::str::contains("Error"));
+
+ assert_eq!(db_time, db.metadata()?.modified()?);
+ assert_eq!(db_hash, sha256(db.path())?);
+
+ Ok(())
+}
+
+#[test]
+fn empty_dir() -> TestResult {
+ let dir = assert_fs::TempDir::new()?;
+
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.current_dir(&dir)
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::is_empty());
+
+ assert!(dir.child(".brck").exists());
+
+ Ok(())
+}
+
+#[test]
+fn short_help() -> TestResult {
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.arg("-h")
+ .assert()
+ .failure()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("--help"));
+
+ Ok(())
+}
+
+#[test]
+fn long_help() -> TestResult {
+ let mut cmd = Command::cargo_bin("brck")?;
+ cmd.arg("--help")
+ .assert()
+ .failure()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("Usage"));
+
+ Ok(())
+}
+
+fn sha256<P: AsRef<Path>>(path: P) -> Result<Vec<u8>, std::io::Error> {
+ let mut file = File::open(path)?;
+ let mut hasher = Sha256::new();
+ std::io::copy(&mut file, &mut hasher)?;
+ let hash = hasher.finalize();
+ Ok(hash.as_slice().into())
+}
Generated by cgit. See skreutz.com for my tech blog and contact information.