diff options
author | Stefan Kreutz <mail@skreutz.com> | 2024-03-24 15:04:09 +0100 |
---|---|---|
committer | Stefan Kreutz <mail@skreutz.com> | 2024-03-24 15:04:09 +0100 |
commit | c1fa48e9bd617d70e823efef5d6dcea41b1d2087 (patch) | |
tree | 421e69c512ac54bf65495ef23fd7d9ec5a5e67d5 /tests/cli.rs | |
download | brck-0.1.0.tar |
Add initial implementationbrck-0.1.0
Diffstat (limited to 'tests/cli.rs')
-rw-r--r-- | tests/cli.rs | 299 |
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()) +} |