//! Integration tests for the `outline` command. use std::path::PathBuf; use assert_cmd::Command; use predicates::prelude::*; fn cargo_command() -> Command { Command::cargo_bin("outline").expect("binary") } fn fixture(path: &str) -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("..") .join("..") .join("fixtures") .join(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 outlines_rust_source_in_text_mode() { let mut command = cargo_command(); command .arg(fixture("reading/sample.rs")) .assert() .success() .stdout(predicate::str::contains("family=rust")) .stdout(predicate::str::contains("18 depth=0 fn run")) .stdout(predicate::str::contains("2 depth=1 struct Client")); } #[test] fn outlines_csharp_source_as_json() { let mut command = cargo_command(); command .arg("--json") .arg(fixture("reading/sample.cs")) .assert() .success() .stdout(predicate::str::contains("\"family\":\"csharp\"")) .stdout(predicate::str::contains("\"kind\":\"class\"")) .stdout(predicate::str::contains("\"name\":\"PlayerController\"")) .stdout(predicate::str::contains("\"name\":\"ComputeScore\"")); } #[test] fn outlines_java_source_in_text_mode() { let mut command = cargo_command(); command .arg(fixture("reading/sample.java")) .assert() .success() .stdout(predicate::str::contains("family=java")) .stdout(predicate::str::contains("5 depth=0 class OutlineDemo")) .stdout(predicate::str::contains("11 depth=1 method run")) .stdout(predicate::str::contains("20 depth=1 record Result")) .stdout(predicate::str::contains("22 depth=1 interface Nested")); } #[test] fn outlines_go_source_in_text_mode() { let mut command = cargo_command(); command .arg(fixture("reading/sample.go")) .assert() .success() .stdout(predicate::str::contains("family=go")) .stdout(predicate::str::contains("9 depth=0 interface Runner")) .stdout(predicate::str::contains("13 depth=0 struct Service")) .stdout(predicate::str::contains("17 depth=0 fn NewService")) .stdout(predicate::str::contains("21 depth=1 method Run")); } #[test] fn outlines_python_source_in_text_mode() { let mut command = cargo_command(); command .arg(fixture("reading/sample.py")) .assert() .success() .stdout(predicate::str::contains("family=python")) .stdout(predicate::str::contains("1 depth=0 class Worker")) .stdout(predicate::str::contains("5 depth=1 method run")) .stdout(predicate::str::contains("12 depth=0 fn build_worker")); } #[test] fn outlines_javascript_source_in_text_mode() { let mut command = cargo_command(); command .arg(fixture("reading/sample.js")) .assert() .success() .stdout(predicate::str::contains("family=javascript")) .stdout(predicate::str::contains("1 depth=0 class Widget")) .stdout(predicate::str::contains("6 depth=1 method render")) .stdout(predicate::str::contains("15 depth=0 fn loadWidget")); } #[test] fn outlines_typescript_source_in_text_mode() { let mut command = cargo_command(); command .arg(fixture("reading/sample.ts")) .assert() .success() .stdout(predicate::str::contains("family=typescript")) .stdout(predicate::str::contains("1 depth=0 interface Runner")) .stdout(predicate::str::contains("5 depth=0 type WorkerOptions")) .stdout(predicate::str::contains("12 depth=1 method run")) .stdout(predicate::str::contains("21 depth=0 fn defaultWorker")); } #[test] fn outlines_powershell_source_in_text_mode() { let mut command = cargo_command(); command .arg(fixture("reading/sample.ps1")) .assert() .success() .stdout(predicate::str::contains("family=powershell")) .stdout(predicate::str::contains("fn Get-Widget")) .stdout(predicate::str::contains("class WidgetBuilder")) .stdout(predicate::str::contains("enum WidgetMode")); } #[test] fn outlines_config_files_with_depth_limit() { let mut command = cargo_command(); command .arg("--depth") .arg("1") .arg(fixture("reading/config.toml")) .assert() .success() .stdout(predicate::str::contains("family=toml")) .stdout(predicate::str::contains("1 depth=0 table workspace")) .stdout(predicate::str::contains("7 depth=1 table plugins.metrics")) .stdout(predicate::str::contains("enabled").not()); } #[test] fn supports_powershell_path_pipeline() { let binary = assert_cmd::cargo::cargo_bin("outline"); let input = fixture("reading/config.yaml"); let script = format!( "{} | & {} --json", ps_quote(input.display()), ps_quote(binary.display()) ); let mut command = pwsh_command(script); command .assert() .success() .stdout(predicate::str::contains("\"family\":\"yaml\"")) .stdout(predicate::str::contains("\"name\":\"logging\"")); } #[test] fn help_includes_outline_examples() { let mut command = cargo_command(); command .arg("--help") .assert() .success() .stdout(predicate::str::contains("--depth")) .stdout(predicate::str::contains("Supported code")) .stdout(predicate::str::contains("sample.go")) .stdout(predicate::str::contains("sample.java")) .stdout(predicate::str::contains("sample.ts")) .stdout(predicate::str::contains( "outline .\\fixtures\\reading\\sample.rs", )) .stdout(predicate::str::contains("ConvertFrom-Json")); }