diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-01 19:24:28 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-01 19:24:28 +0900 |
| commit | 7d36d8e5cf8c6f7c21a6b4c713217bc92c37d328 (patch) | |
| tree | d8fdbdbc3abb6acf41095c013f281fdabc880372 /crates/mozart-test-harness/src/runner.rs | |
| parent | 64ed53cf184fb05cbfe9f0336bc8695ff0e800f8 (diff) | |
| download | php-mozart-7d36d8e5cf8c6f7c21a6b4c713217bc92c37d328.tar.gz php-mozart-7d36d8e5cf8c6f7c21a6b4c713217bc92c37d328.tar.zst php-mozart-7d36d8e5cf8c6f7c21a6b4c713217bc92c37d328.zip | |
feat(test-harness): add Composer .test fixture parser and runner
Foundation for porting Composer's installer integration fixtures.
Parser covers the 13 sections of InstallerTest.php; runner sets up a
tempdir from COMPOSER/LOCK/INSTALLED and invokes the mozart binary.
No fixtures are migrated in this commit.
Diffstat (limited to 'crates/mozart-test-harness/src/runner.rs')
| -rw-r--r-- | crates/mozart-test-harness/src/runner.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/crates/mozart-test-harness/src/runner.rs b/crates/mozart-test-harness/src/runner.rs new file mode 100644 index 0000000..e041cd7 --- /dev/null +++ b/crates/mozart-test-harness/src/runner.rs @@ -0,0 +1,62 @@ +use anyhow::{Context, Result}; +use std::path::Path; +use std::process::Command; +use tempfile::TempDir; + +use crate::parser::ParsedTest; + +/// Outcome of running a parsed `.test` against the `mozart` binary. +/// +/// The temp directory is kept alive in this struct so callers can inspect +/// files written by the run; it is removed when `RunResult` is dropped. +pub struct RunResult { + pub working_dir: TempDir, + pub stdout: String, + pub stderr: String, + pub exit_code: i32, + pub final_lock: Option<String>, + pub final_installed: Option<String>, +} + +/// Set up a temp project from the parsed test, invoke `mozart` with the +/// `--RUN--` command, and capture the result. +pub fn run_test(test: &ParsedTest, mozart_bin: &Path) -> Result<RunResult> { + let working_dir = TempDir::new().context("failed to create tempdir")?; + let root = working_dir.path(); + + std::fs::write(root.join("composer.json"), &test.composer) + .context("failed to write composer.json")?; + + if let Some(lock) = &test.lock { + std::fs::write(root.join("composer.lock"), lock) + .context("failed to write composer.lock")?; + } + + if let Some(installed) = &test.installed { + let vendor_composer = root.join("vendor").join("composer"); + std::fs::create_dir_all(&vendor_composer) + .context("failed to create vendor/composer dir")?; + std::fs::write(vendor_composer.join("installed.json"), installed) + .context("failed to write installed.json")?; + } + + let args: Vec<&str> = test.run.split_whitespace().collect(); + let output = Command::new(mozart_bin) + .args(&args) + .current_dir(root) + .output() + .with_context(|| format!("failed to invoke {}", mozart_bin.display()))?; + + let final_lock = std::fs::read_to_string(root.join("composer.lock")).ok(); + let final_installed = + std::fs::read_to_string(root.join("vendor").join("composer").join("installed.json")).ok(); + + Ok(RunResult { + working_dir, + stdout: String::from_utf8_lossy(&output.stdout).into_owned(), + stderr: String::from_utf8_lossy(&output.stderr).into_owned(), + exit_code: output.status.code().unwrap_or(-1), + final_lock, + final_installed, + }) +} |
