rusty-pdfgrep 0.1.0

Grep through PDF files — a Rust port of Hans-Peter Deifel's `pdfgrep(1)` with lopdf-backed text extraction, regex + fancy-regex pluggable engines, --password retry for encrypted PDFs, GNU-grep-compatible color output, recursive walking with fnmatch include/exclude, and a typed library API.
Documentation
//! US3 (Strict-compat) integration tests.

mod common;

#[test]
fn strict_excluded_short_flag_w_rejected() {
    // FR-035 + Clarifications Q10: -w is upstream-grep-only, excluded from v0.1.0.
    let assert = common::rusty_pdfgrep_cmd()
        .arg("--strict")
        .arg("-w")
        .arg("term")
        .assert()
        .code(2);
    let stderr = String::from_utf8_lossy(&assert.get_output().stderr);
    assert!(
        stderr.contains("invalid option") && stderr.contains("'w'"),
        "got: {stderr:?}"
    );
}

#[test]
fn strict_excluded_short_flag_a_rejected() {
    // -A is page-context, excluded from v0.1.0.
    let assert = common::rusty_pdfgrep_cmd()
        .arg("--strict")
        .arg("-A")
        .assert()
        .code(2);
    let stderr = String::from_utf8_lossy(&assert.get_output().stderr);
    assert!(stderr.contains("invalid option"), "got: {stderr:?}");
}

#[test]
fn strict_excluded_long_flag_cache_rejected() {
    // FR-035 long-flag form: "unrecognized option '--<name>'" per Clarifications Q10.
    let assert = common::rusty_pdfgrep_cmd()
        .arg("--strict")
        .arg("--cache")
        .arg("term")
        .assert()
        .code(2);
    let stderr = String::from_utf8_lossy(&assert.get_output().stderr);
    assert!(
        stderr.contains("unrecognized option") && stderr.contains("--cache"),
        "got: {stderr:?}"
    );
}

#[test]
fn strict_excluded_long_flag_password_list_rejected() {
    let assert = common::rusty_pdfgrep_cmd()
        .arg("--strict")
        .arg("--password-list")
        .arg("/tmp/list.txt")
        .arg("term")
        .assert()
        .code(2);
    let stderr = String::from_utf8_lossy(&assert.get_output().stderr);
    assert!(
        stderr.contains("unrecognized option") && stderr.contains("--password-list"),
        "got: {stderr:?}"
    );
}

#[test]
fn strict_activates_via_env_var() {
    // Strict mode activates without the --strict flag when env var set.
    let assert = common::rusty_pdfgrep_cmd()
        .env("RUSTY_PDFGREP_STRICT", "1")
        .arg("-w")
        .arg("term")
        .assert()
        .code(2);
    let stderr = String::from_utf8_lossy(&assert.get_output().stderr);
    assert!(
        stderr.contains("invalid option") && stderr.contains("'w'"),
        "env-var strict should reject -w; got: {stderr:?}"
    );
}

#[test]
fn no_strict_overrides_env_var() {
    // --no-strict beats env var; -w should be a clap-style error, not the strict format.
    let assert = common::rusty_pdfgrep_cmd()
        .env("RUSTY_PDFGREP_STRICT", "1")
        .arg("--no-strict")
        .arg("-w")
        .arg("term")
        .assert()
        .failure();
    let stderr = String::from_utf8_lossy(&assert.get_output().stderr);
    // Default mode rejects unknown short via clap; the error message differs.
    assert!(
        !stderr.contains("invalid option -- 'w'") || stderr.contains("Usage"),
        "default-mode rejection should NOT use the upstream getopt format verbatim; got: {stderr:?}"
    );
}