dbgfmt 0.1.0

Pretty-print Rust Debug trait output with proper indentation
Documentation
use std::io::Write;
use std::process::{Command, Stdio};

fn cargo_bin() -> Command {
    Command::new(env!("CARGO_BIN_EXE_dbgfmt"))
}

// ========================================
// CLI E2E tests
// ========================================

#[test]
fn cli_argument_input() {
    let output = cargo_bin()
        .args(["Foo", "{", "bar:", "1,", "baz:", "2", "}"])
        .output()
        .expect("failed to execute");

    assert!(output.status.success());
    let stdout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(
        stdout.trim(),
        "\
Foo {
  bar: 1,
  baz: 2,
}"
    );
}

#[test]
fn cli_stdin_input() {
    let mut child = cargo_bin()
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .expect("failed to spawn");

    child
        .stdin
        .as_mut()
        .unwrap()
        .write_all(b"Foo { bar: 1, baz: 2 }")
        .expect("failed to write");
    drop(child.stdin.take());

    let output = child.wait_with_output().expect("failed to wait");
    assert!(output.status.success());
    let stdout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(
        stdout.trim(),
        "\
Foo {
  bar: 1,
  baz: 2,
}"
    );
}

#[test]
fn cli_help_flag() {
    let output = cargo_bin()
        .arg("--help")
        .output()
        .expect("failed to execute");

    assert!(output.status.success());
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("Usage:"));
}

#[test]
fn cli_version_flag() {
    let output = cargo_bin()
        .arg("--version")
        .output()
        .expect("failed to execute");

    assert!(output.status.success());
    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(stdout.contains("dbgfmt"));
}

#[test]
fn cli_complex_pipe() {
    let input = r#"Config { server: Server { host: "localhost", port: 8080 }, items: [1, 2, 3] }"#;

    let mut child = cargo_bin()
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .expect("failed to spawn");

    child
        .stdin
        .as_mut()
        .unwrap()
        .write_all(input.as_bytes())
        .expect("failed to write");
    drop(child.stdin.take());

    let output = child.wait_with_output().expect("failed to wait");
    assert!(output.status.success());
    let stdout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(
        stdout.trim(),
        r#"Config {
  server: Server {
    host: "localhost",
    port: 8080,
  },
  items: [
    1,
    2,
    3,
  ],
}"#
    );
}

#[test]
fn cli_no_input_shows_usage() {
    // stdin is not a pipe (default inherits terminal), and no args → should fail with usage
    let output = cargo_bin()
        .stdin(Stdio::null())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()
        .expect("failed to spawn")
        .wait_with_output()
        .expect("failed to wait");

    assert!(!output.status.success());
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("Usage:"));
}