use common::binary;
use core::sync::atomic::{AtomicU32, Ordering};
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{self, Command, Output};
#[macro_use]
mod fixture_macros;
mod command_behavior;
mod corpus;
mod csharp_reorder;
mod directory_processing;
mod fences;
mod language_selection;
mod rust_reorder;
#[path = "../common/mod.rs"]
mod common;
static TEST_COUNTER: AtomicU32 = AtomicU32::new(0);
fn manifest_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
}
fn reorder_in_place(path: &Path, ext: &str) -> String {
let tmp = temp_file_ext(ext);
fs::copy(path, &tmp).unwrap();
let output = run_command(&["--include", "reorder"], &tmp);
assert!(
output.status.success(),
"in-place reorder failed on {}: {}",
path.display(),
String::from_utf8_lossy(&output.stderr)
);
let result = fs::read_to_string(&tmp).unwrap();
let _ = fs::remove_file(&tmp);
result
}
fn run(content: &str, args: &[&str]) -> (String, String, i32) {
let dir = std::env::temp_dir();
let pid = process::id();
let seq = TEST_COUNTER.fetch_add(1, Ordering::Relaxed);
let file = dir.join(format!("rust-llm-tidy-test-{}-{}.rs", pid, seq));
fs::write(&file, content).unwrap();
let mut full_args = vec!["--include", "reorder"];
full_args.extend(args);
let output = run_command(&full_args, &file);
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let exit = output.status.code().unwrap_or(-1);
let _ = fs::remove_file(&file);
(stdout, stderr, exit)
}
fn run_and_read(content: &str) -> String {
let dir = std::env::temp_dir();
let pid = process::id();
let seq = TEST_COUNTER.fetch_add(1, Ordering::Relaxed);
let file = dir.join(format!("rust-llm-tidy-test-{}-{}.rs", pid, seq));
fs::write(&file, content).unwrap();
let output = run_command(&["--include", "reorder"], &file);
assert!(
output.status.success(),
"rust-llm-tidy failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let result = fs::read_to_string(&file).unwrap();
let _ = fs::remove_file(&file);
result
}
fn run_dir(dir: &Path, args: &[&str]) -> (String, String, i32) {
let mut full_args = vec!["--include", "reorder"];
full_args.extend(args);
let output = run_command(&full_args, dir);
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let exit = output.status.code().unwrap_or(-1);
(stdout, stderr, exit)
}
fn run_dry_run(path: &Path) -> (String, String, i32) {
let output = run_command(&["--include", "reorder", "--dry-run"], path);
(
String::from_utf8_lossy(&output.stdout).to_string(),
String::from_utf8_lossy(&output.stderr).to_string(),
output.status.code().unwrap_or(-1),
)
}
fn strip_path_prefix(stderr: &str, path: &Path) -> String {
let prefix = format!("{}:", path.display());
stderr
.lines()
.map(|line| line.strip_prefix(&prefix).unwrap_or(line))
.collect::<Vec<_>>()
.join("\n")
}
fn temp_dir() -> PathBuf {
let seq = TEST_COUNTER.fetch_add(1, Ordering::Relaxed);
let pid = process::id();
std::env::temp_dir().join(format!("rust-llm-tidy-dir-{}-{}", pid, seq))
}
fn temp_file() -> PathBuf {
let seq = TEST_COUNTER.fetch_add(1, Ordering::Relaxed);
let pid = process::id();
std::env::temp_dir().join(format!("rust-llm-tidy-file-{}-{}.rs", pid, seq))
}
fn run_command(args: &[&str], path: &Path) -> Output {
let mut cmd = Command::new(binary());
cmd.env("RUST_LIB_BACKTRACE", "0");
cmd.args(["--no-config"]).args(args).arg(path);
cmd.output()
.unwrap_or_else(|e| panic!("failed to spawn rust-llm-tidy on {}: {e}", path.display()))
}
fn temp_file_ext(ext: &str) -> PathBuf {
let seq = TEST_COUNTER.fetch_add(1, Ordering::Relaxed);
let pid = process::id();
std::env::temp_dir().join(format!("rust-llm-tidy-ext-{}-{}.{}", pid, seq, ext))
}