obj-cli 1.0.0

Command-line tools (dump, check, stat, backup) for the obj embedded document database.
Documentation
//! `obj backup` acceptance tests (issue #99).

use assert_cmd::Command;
use obj::{Db, Document};
use predicates::str::contains;
use serde::{Deserialize, Serialize};
use tempfile::TempDir;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct Note {
    title: String,
    body: String,
}

impl Document for Note {
    const COLLECTION: &'static str = "notes";
    const VERSION: u32 = 1;
}

#[test]
fn backup_round_trips_via_cli() {
    let dir = TempDir::new().expect("tmp");
    let src = dir.path().join("src.obj");
    let dest = dir.path().join("dest.obj");
    {
        let db = Db::open(&src).expect("open source");
        for i in 0..6u32 {
            db.insert(Note {
                title: format!("note-{i}"),
                body: format!("body-{i}"),
            })
            .expect("insert");
        }
    }

    Command::cargo_bin("obj")
        .expect("binary")
        .arg("backup")
        .arg(&src)
        .arg(&dest)
        .assert()
        .success()
        .stdout(contains("ok: backup"));

    assert!(dest.exists(), "destination file should now exist");

    // The backup must itself pass `obj check`.
    Command::cargo_bin("obj")
        .expect("binary")
        .arg("check")
        .arg(&dest)
        .assert()
        .success()
        .stdout(contains("ok:"));
}

#[test]
fn backup_refuses_existing_destination() {
    let dir = TempDir::new().expect("tmp");
    let src = dir.path().join("src.obj");
    let dest = dir.path().join("already-here.obj");
    {
        let db = Db::open(&src).expect("open source");
        db.insert(Note {
            title: "t".into(),
            body: "b".into(),
        })
        .expect("insert");
    }
    std::fs::write(&dest, b"sentinel").expect("seed dest");

    Command::cargo_bin("obj")
        .expect("binary")
        .arg("backup")
        .arg(&src)
        .arg(&dest)
        .assert()
        .code(2)
        .stderr(contains("error:"));
}