//! Integration tests for the `snip` command. use std::fs; use std::path::PathBuf; use assert_cmd::Command; use predicates::prelude::*; use tempfile::{TempDir, tempdir}; const SAMPLE_RS: &str = "reading/sample.rs"; fn cargo_command() -> Command { Command::cargo_bin("snip").expect("binary") } fn fixture(path: &str) -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("..") .join("..") .join("fixtures") .join(path) } fn temp_file(name: &str, contents: impl AsRef<[u8]>) -> (TempDir, PathBuf) { let dir = tempdir().expect("tempdir"); let path = dir.path().join(name); fs::write(&path, contents).expect("fixture"); (dir, path) } fn pwsh_command(script: impl AsRef) -> Command { let mut command = Command::new("pwsh"); command .arg("-NoProfile") .arg("-Command") .arg(script.as_ref()); command } fn ps_quote(value: impl std::fmt::Display) -> String { format!("'{}'", value.to_string().replace('\'', "''")) } #[test] fn extracts_requested_line_ranges() { let mut command = cargo_command(); command .arg("--lines") .arg("18:31") .arg(fixture(SAMPLE_RS)) .assert() .success() .stdout(predicate::str::contains("reason=lines")) .stdout(predicate::str::contains("18: pub fn run")) .stdout(predicate::str::contains("31: }")); } #[test] fn extracts_symbol_blocks() { let mut command = cargo_command(); command .arg("--symbol") .arg("ComputeScore") .arg(fixture("reading/sample.cs")) .assert() .success() .stdout(predicate::str::contains("reason=symbol:ComputeScore")) .stdout(predicate::str::contains( "9: private int ComputeScore", )) .stdout(predicate::str::contains("15: }")); } #[test] fn extracts_regex_matches_with_context_as_json() { let mut command = cargo_command(); command .arg("--around") .arg("Mode::Fast") .arg("--context") .arg("1") .arg("--json") .arg(fixture("reading/sample.rs")) .assert() .success() .stdout(predicate::str::contains("\"reason\":\"around:Mode::Fast\"")) .stdout(predicate::str::contains("\"start_line\":21")) .stdout(predicate::str::contains("\"end_line\":23")); } #[test] fn supports_stdin_content_snipping() { let binary = assert_cmd::cargo::cargo_bin("snip"); let input = fixture(SAMPLE_RS); let script = format!( "[System.IO.File]::ReadLines({}) | & {} --around 'helper' --context 0", ps_quote(input.display()), ps_quote(binary.display()) ); let mut command = pwsh_command(script); command .assert() .success() .stdout(predicate::str::contains("")) .stdout(predicate::str::contains("fn helper")); } #[test] fn utf8_bom_stdin_does_not_pollute_first_snippet_line() { let mut command = cargo_command(); command .args(["--lines", "1:1"]) .write_stdin("\u{feff}fn main() {}\n") .assert() .success() .stdout(predicate::str::contains("1: fn main() {}")); } #[test] fn utf8_bom_file_does_not_pollute_first_snippet_line() { let (_dir, path) = temp_file("bom.rs", "\u{feff}fn main() {}\n"); let mut command = cargo_command(); command .arg("--lines") .arg("1:1") .arg(&path) .assert() .success() .stdout(predicate::str::contains("1: fn main() {}")); } #[test] fn invalid_utf8_file_reports_read_error() { let (_dir, path) = temp_file("invalid-utf8.rs", [0x66, 0x6E, 0x80, 0x0A]); let mut command = cargo_command(); command .arg("--lines") .arg("1:1") .arg(&path) .assert() .failure() .stderr(predicate::str::contains("failed to read")) .stderr(predicate::str::contains("invalid-utf8.rs")); } #[test] fn help_includes_selector_examples() { let mut command = cargo_command(); command .arg("--help") .assert() .success() .stdout(predicate::str::contains("--lines")) .stdout(predicate::str::contains("--symbol")) .stdout(predicate::str::contains("ConvertFrom-Json")); }