aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-21 20:54:29 +0900
committernsfisis <nsfisis@gmail.com>2026-02-21 20:54:29 +0900
commite40ae3649d62a933211e81d8ac773fdd86ff1dfb (patch)
tree22713882537531c2b0f0a55248045d9f280ce3fe /crates
parent3c8ce2b72daccccc88278b8dfbff1a1acc39096c (diff)
downloadphp-mozart-e40ae3649d62a933211e81d8ac773fdd86ff1dfb.tar.gz
php-mozart-e40ae3649d62a933211e81d8ac773fdd86ff1dfb.tar.zst
php-mozart-e40ae3649d62a933211e81d8ac773fdd86ff1dfb.zip
test(cli): add end-to-end integration tests for CLI commands
Add 23 integration tests using assert_cmd and predicates covering about, validate, show, licenses, install, config, init, and dump-autoload commands with shared test helpers and fixture projects. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates')
-rw-r--r--crates/mozart/Cargo.toml2
-rw-r--r--crates/mozart/tests/cli_about.rs12
-rw-r--r--crates/mozart/tests/cli_config.rs40
-rw-r--r--crates/mozart/tests/cli_dump_autoload.rs34
-rw-r--r--crates/mozart/tests/cli_init.rs25
-rw-r--r--crates/mozart/tests/cli_install.rs52
-rw-r--r--crates/mozart/tests/cli_licenses.rs50
-rw-r--r--crates/mozart/tests/cli_show.rs65
-rw-r--r--crates/mozart/tests/cli_validate.rs60
-rw-r--r--crates/mozart/tests/common/mod.rs74
-rw-r--r--crates/mozart/tests/fixtures/invalid_json/composer.json1
-rw-r--r--crates/mozart/tests/fixtures/minimal/composer.json8
-rw-r--r--crates/mozart/tests/fixtures/with_dev_deps/composer.json12
-rw-r--r--crates/mozart/tests/fixtures/with_dev_deps/composer.lock80
-rw-r--r--crates/mozart/tests/fixtures/with_dev_deps/vendor/composer/installed.json32
-rw-r--r--crates/mozart/tests/fixtures/with_installed/composer.json9
-rw-r--r--crates/mozart/tests/fixtures/with_installed/composer.lock56
-rw-r--r--crates/mozart/tests/fixtures/with_installed/vendor/composer/installed.json18
-rw-r--r--crates/mozart/tests/fixtures/with_lock/composer.json9
-rw-r--r--crates/mozart/tests/fixtures/with_lock/composer.lock56
-rw-r--r--crates/mozart/tests/hash_helper.rs3
21 files changed, 698 insertions, 0 deletions
diff --git a/crates/mozart/Cargo.toml b/crates/mozart/Cargo.toml
index 287f800..e219fff 100644
--- a/crates/mozart/Cargo.toml
+++ b/crates/mozart/Cargo.toml
@@ -25,3 +25,5 @@ tokio = { version = "1.49.0", features = ["full"] }
zip = { version = "2", default-features = false, features = ["deflate"] }
[dev-dependencies]
+assert_cmd = "2"
+predicates = "3"
diff --git a/crates/mozart/tests/cli_about.rs b/crates/mozart/tests/cli_about.rs
new file mode 100644
index 0000000..3819d90
--- /dev/null
+++ b/crates/mozart/tests/cli_about.rs
@@ -0,0 +1,12 @@
+mod common;
+
+use predicates::str::contains;
+
+#[test]
+fn test_about_prints_version() {
+ common::mozart_cmd()
+ .arg("about")
+ .assert()
+ .success()
+ .stdout(contains("Mozart"));
+}
diff --git a/crates/mozart/tests/cli_config.rs b/crates/mozart/tests/cli_config.rs
new file mode 100644
index 0000000..e433653
--- /dev/null
+++ b/crates/mozart/tests/cli_config.rs
@@ -0,0 +1,40 @@
+mod common;
+
+use predicates::str::contains;
+
+#[test]
+fn test_config_list() {
+ let project = common::copy_fixture_to_temp("minimal");
+ common::mozart_cmd()
+ .arg("config")
+ .arg("--list")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stdout(contains("vendor-dir"));
+}
+
+#[test]
+fn test_config_single_key() {
+ let project = common::copy_fixture_to_temp("minimal");
+ common::mozart_cmd()
+ .arg("config")
+ .arg("vendor-dir")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stdout(contains("vendor"));
+}
+
+#[test]
+fn test_config_no_key_fails() {
+ let project = common::copy_fixture_to_temp("minimal");
+ common::mozart_cmd()
+ .arg("config")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .failure();
+}
diff --git a/crates/mozart/tests/cli_dump_autoload.rs b/crates/mozart/tests/cli_dump_autoload.rs
new file mode 100644
index 0000000..ca592a3
--- /dev/null
+++ b/crates/mozart/tests/cli_dump_autoload.rs
@@ -0,0 +1,34 @@
+mod common;
+
+use predicates::str::contains;
+
+#[test]
+fn test_dump_autoload_dry_run() {
+ let project = common::copy_fixture_to_temp("minimal");
+ common::mozart_cmd()
+ .arg("dump-autoload")
+ .arg("--dry-run")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stderr(contains("Dry run"));
+}
+
+#[test]
+fn test_dump_autoload_does_not_write_in_dry_run() {
+ let project = common::copy_fixture_to_temp("minimal");
+ let vendor_dir = project.path().join("vendor");
+ common::mozart_cmd()
+ .arg("dump-autoload")
+ .arg("--dry-run")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success();
+ // In dry-run mode, no vendor directory should have been created
+ assert!(
+ !vendor_dir.exists(),
+ "vendor/ should not be created in dry-run mode"
+ );
+}
diff --git a/crates/mozart/tests/cli_init.rs b/crates/mozart/tests/cli_init.rs
new file mode 100644
index 0000000..11661fc
--- /dev/null
+++ b/crates/mozart/tests/cli_init.rs
@@ -0,0 +1,25 @@
+mod common;
+
+#[test]
+fn test_init_creates_composer_json() {
+ let dir = tempfile::TempDir::new().unwrap();
+ common::mozart_cmd()
+ .arg("init")
+ .arg("--name")
+ .arg("test/new-project")
+ .arg("--no-interaction")
+ .arg("--working-dir")
+ .arg(dir.path())
+ .assert()
+ .success();
+
+ assert!(
+ dir.path().join("composer.json").exists(),
+ "composer.json should have been created"
+ );
+
+ let content =
+ std::fs::read_to_string(dir.path().join("composer.json")).expect("Failed to read");
+ let json: serde_json::Value = serde_json::from_str(&content).expect("Should be valid JSON");
+ assert_eq!(json["name"], serde_json::json!("test/new-project"));
+}
diff --git a/crates/mozart/tests/cli_install.rs b/crates/mozart/tests/cli_install.rs
new file mode 100644
index 0000000..5312956
--- /dev/null
+++ b/crates/mozart/tests/cli_install.rs
@@ -0,0 +1,52 @@
+mod common;
+
+use predicates::str::contains;
+
+#[test]
+fn test_install_dry_run() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ common::mozart_cmd()
+ .arg("install")
+ .arg("--dry-run")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stderr(contains("Installing"));
+}
+
+#[test]
+fn test_install_no_lock_file() {
+ let project = common::copy_fixture_to_temp("minimal");
+ common::mozart_cmd()
+ .arg("install")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .failure()
+ .stderr(contains("mozart update"));
+}
+
+#[test]
+fn test_install_no_composer_json() {
+ let project = tempfile::TempDir::new().unwrap();
+ common::mozart_cmd()
+ .arg("install")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .failure();
+}
+
+#[test]
+fn test_install_dry_run_shows_package_names() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ common::mozart_cmd()
+ .arg("install")
+ .arg("--dry-run")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stderr(contains("psr/log"));
+}
diff --git a/crates/mozart/tests/cli_licenses.rs b/crates/mozart/tests/cli_licenses.rs
new file mode 100644
index 0000000..96d5c4e
--- /dev/null
+++ b/crates/mozart/tests/cli_licenses.rs
@@ -0,0 +1,50 @@
+mod common;
+
+use predicates::str::contains;
+
+#[test]
+fn test_licenses_locked() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ common::mozart_cmd()
+ .arg("licenses")
+ .arg("--locked")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stdout(contains("MIT"));
+}
+
+#[test]
+fn test_licenses_format_json() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ let output = common::mozart_cmd()
+ .arg("licenses")
+ .arg("--format=json")
+ .arg("--locked")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .get_output()
+ .stdout
+ .clone();
+
+ let stdout = String::from_utf8_lossy(&output);
+ serde_json::from_str::<serde_json::Value>(&stdout)
+ .expect("licenses --format=json output should be valid JSON");
+}
+
+#[test]
+fn test_licenses_format_summary() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ common::mozart_cmd()
+ .arg("licenses")
+ .arg("--format=summary")
+ .arg("--locked")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stdout(contains("MIT"));
+}
diff --git a/crates/mozart/tests/cli_show.rs b/crates/mozart/tests/cli_show.rs
new file mode 100644
index 0000000..0ecb588
--- /dev/null
+++ b/crates/mozart/tests/cli_show.rs
@@ -0,0 +1,65 @@
+mod common;
+
+use predicates::str::contains;
+
+#[test]
+fn test_show_locked_packages() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ common::mozart_cmd()
+ .arg("show")
+ .arg("--locked")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stdout(contains("psr/log"));
+}
+
+#[test]
+fn test_show_self() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ common::mozart_cmd()
+ .arg("show")
+ .arg("--self-info")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stdout(contains("test/locked-project"));
+}
+
+#[test]
+fn test_show_name_only() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ common::mozart_cmd()
+ .arg("show")
+ .arg("--name-only")
+ .arg("--locked")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .stdout(contains("psr/log"));
+}
+
+#[test]
+fn test_show_format_json() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ let output = common::mozart_cmd()
+ .arg("show")
+ .arg("--format=json")
+ .arg("--locked")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success()
+ .get_output()
+ .stdout
+ .clone();
+
+ let stdout = String::from_utf8_lossy(&output);
+ // Output should be parseable JSON
+ let parsed: serde_json::Value =
+ serde_json::from_str(&stdout).expect("show --format=json output should be valid JSON");
+ assert!(parsed.is_array() || parsed.is_object());
+}
diff --git a/crates/mozart/tests/cli_validate.rs b/crates/mozart/tests/cli_validate.rs
new file mode 100644
index 0000000..fe3c080
--- /dev/null
+++ b/crates/mozart/tests/cli_validate.rs
@@ -0,0 +1,60 @@
+mod common;
+
+#[test]
+fn test_validate_valid_project() {
+ let project = common::copy_fixture_to_temp("minimal");
+ common::mozart_cmd()
+ .arg("validate")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success();
+}
+
+#[test]
+fn test_validate_valid_with_lock() {
+ let project = common::copy_fixture_to_temp("with_lock");
+ common::mozart_cmd()
+ .arg("validate")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .success();
+}
+
+#[test]
+fn test_validate_invalid_json() {
+ let project = common::copy_fixture_to_temp("invalid_json");
+ common::mozart_cmd()
+ .arg("validate")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .code(2);
+}
+
+#[test]
+fn test_validate_missing_composer_json() {
+ let project = tempfile::TempDir::new().unwrap();
+ common::mozart_cmd()
+ .arg("validate")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .failure();
+}
+
+#[test]
+fn test_validate_strict_with_warnings() {
+ // A composer.json without a license generates a warning.
+ // With --strict, warnings become a non-zero exit code.
+ let project =
+ common::setup_temp_project(r#"{"name": "test/no-license", "require": {"php": ">=8.1"}}"#);
+ common::mozart_cmd()
+ .arg("validate")
+ .arg("--strict")
+ .arg("--working-dir")
+ .arg(project.path())
+ .assert()
+ .code(1);
+}
diff --git a/crates/mozart/tests/common/mod.rs b/crates/mozart/tests/common/mod.rs
new file mode 100644
index 0000000..bec4677
--- /dev/null
+++ b/crates/mozart/tests/common/mod.rs
@@ -0,0 +1,74 @@
+use std::fs;
+use std::path::{Path, PathBuf};
+use tempfile::TempDir;
+
+/// Returns a `Command` configured to run the `mozart` binary.
+pub fn mozart_cmd() -> assert_cmd::Command {
+ assert_cmd::cargo::cargo_bin_cmd!("mozart")
+}
+
+/// Returns the absolute path to `tests/fixtures/<name>`.
+pub fn fixture_dir(name: &str) -> PathBuf {
+ Path::new(env!("CARGO_MANIFEST_DIR"))
+ .join("tests")
+ .join("fixtures")
+ .join(name)
+}
+
+/// A temporary project directory that is cleaned up when dropped.
+pub struct TestProject {
+ #[allow(dead_code)]
+ pub dir: TempDir,
+}
+
+impl TestProject {
+ /// Returns the path to the temp directory root.
+ #[allow(dead_code)]
+ pub fn path(&self) -> &Path {
+ self.dir.path()
+ }
+}
+
+/// Create a temporary project with just a `composer.json`.
+#[allow(dead_code)]
+pub fn setup_temp_project(composer_json: &str) -> TestProject {
+ let dir = TempDir::new().expect("Failed to create temp dir");
+ fs::write(dir.path().join("composer.json"), composer_json)
+ .expect("Failed to write composer.json");
+ TestProject { dir }
+}
+
+/// Create a temporary project with both `composer.json` and `composer.lock`.
+#[allow(dead_code)]
+pub fn setup_temp_project_with_lock(composer_json: &str, composer_lock: &str) -> TestProject {
+ let dir = TempDir::new().expect("Failed to create temp dir");
+ fs::write(dir.path().join("composer.json"), composer_json)
+ .expect("Failed to write composer.json");
+ fs::write(dir.path().join("composer.lock"), composer_lock)
+ .expect("Failed to write composer.lock");
+ TestProject { dir }
+}
+
+/// Copy an entire fixture directory to a new temp directory.
+#[allow(dead_code)]
+pub fn copy_fixture_to_temp(fixture_name: &str) -> TestProject {
+ let src = fixture_dir(fixture_name);
+ let dir = TempDir::new().expect("Failed to create temp dir");
+ copy_dir_recursive(&src, dir.path()).expect("Failed to copy fixture");
+ TestProject { dir }
+}
+
+fn copy_dir_recursive(src: &Path, dst: &Path) -> anyhow::Result<()> {
+ for entry in fs::read_dir(src)? {
+ let entry = entry?;
+ let file_type = entry.file_type()?;
+ let dst_path = dst.join(entry.file_name());
+ if file_type.is_dir() {
+ fs::create_dir_all(&dst_path)?;
+ copy_dir_recursive(&entry.path(), &dst_path)?;
+ } else {
+ fs::copy(entry.path(), dst_path)?;
+ }
+ }
+ Ok(())
+}
diff --git a/crates/mozart/tests/fixtures/invalid_json/composer.json b/crates/mozart/tests/fixtures/invalid_json/composer.json
new file mode 100644
index 0000000..e367425
--- /dev/null
+++ b/crates/mozart/tests/fixtures/invalid_json/composer.json
@@ -0,0 +1 @@
+{this is not valid json
diff --git a/crates/mozart/tests/fixtures/minimal/composer.json b/crates/mozart/tests/fixtures/minimal/composer.json
new file mode 100644
index 0000000..a84ee9f
--- /dev/null
+++ b/crates/mozart/tests/fixtures/minimal/composer.json
@@ -0,0 +1,8 @@
+{
+ "name": "test/minimal-project",
+ "description": "A minimal test project",
+ "license": "MIT",
+ "require": {
+ "php": ">=8.1"
+ }
+}
diff --git a/crates/mozart/tests/fixtures/with_dev_deps/composer.json b/crates/mozart/tests/fixtures/with_dev_deps/composer.json
new file mode 100644
index 0000000..09126f2
--- /dev/null
+++ b/crates/mozart/tests/fixtures/with_dev_deps/composer.json
@@ -0,0 +1,12 @@
+{
+ "name": "test/dev-project",
+ "description": "A project with dev dependencies",
+ "license": "MIT",
+ "require": {
+ "php": ">=8.1",
+ "psr/log": "^3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ }
+}
diff --git a/crates/mozart/tests/fixtures/with_dev_deps/composer.lock b/crates/mozart/tests/fixtures/with_dev_deps/composer.lock
new file mode 100644
index 0000000..d01e341
--- /dev/null
+++ b/crates/mozart/tests/fixtures/with_dev_deps/composer.lock
@@ -0,0 +1,80 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "ed17fac2f30232d69c31587151006a2f",
+ "packages": [
+ {
+ "name": "psr/log",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ },
+ "license": [
+ "MIT"
+ ],
+ "description": "Common interface for logging libraries",
+ "time": "2024-09-11T13:17:53+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "phpunit/phpunit",
+ "version": "11.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "fake000000000000000000000000000000000001"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://fake.example.com/phpunit-11.0.0.zip",
+ "reference": "fake000000000000000000000000000000000001",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPUnit\\": "src/"
+ }
+ },
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "The PHP Unit Testing framework",
+ "time": "2024-02-02T06:38:00+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {},
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=8.1"
+ },
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
+}
diff --git a/crates/mozart/tests/fixtures/with_dev_deps/vendor/composer/installed.json b/crates/mozart/tests/fixtures/with_dev_deps/vendor/composer/installed.json
new file mode 100644
index 0000000..efa3905
--- /dev/null
+++ b/crates/mozart/tests/fixtures/with_dev_deps/vendor/composer/installed.json
@@ -0,0 +1,32 @@
+{
+ "packages": [
+ {
+ "name": "phpunit/phpunit",
+ "version": "11.0.0",
+ "version_normalized": "11.0.0.0",
+ "type": "library",
+ "install-path": "../phpunit/phpunit",
+ "autoload": {
+ "psr-4": {
+ "PHPUnit\\": "src/"
+ }
+ }
+ },
+ {
+ "name": "psr/log",
+ "version": "3.0.2",
+ "version_normalized": "3.0.2.0",
+ "type": "library",
+ "install-path": "../psr/log",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ }
+ }
+ ],
+ "dev-package-names": [
+ "phpunit/phpunit"
+ ],
+ "dev": true
+}
diff --git a/crates/mozart/tests/fixtures/with_installed/composer.json b/crates/mozart/tests/fixtures/with_installed/composer.json
new file mode 100644
index 0000000..1653318
--- /dev/null
+++ b/crates/mozart/tests/fixtures/with_installed/composer.json
@@ -0,0 +1,9 @@
+{
+ "name": "test/locked-project",
+ "description": "A project with a lock file",
+ "license": "MIT",
+ "require": {
+ "php": ">=8.1",
+ "psr/log": "^3.0"
+ }
+}
diff --git a/crates/mozart/tests/fixtures/with_installed/composer.lock b/crates/mozart/tests/fixtures/with_installed/composer.lock
new file mode 100644
index 0000000..0e4f7aa
--- /dev/null
+++ b/crates/mozart/tests/fixtures/with_installed/composer.lock
@@ -0,0 +1,56 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "ca27a8c1835db5af5fd5efe936f402b4",
+ "packages": [
+ {
+ "name": "psr/log",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ },
+ "license": [
+ "MIT"
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://www.php-fig.org/",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2024-09-11T13:17:53+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {},
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=8.1"
+ },
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
+}
diff --git a/crates/mozart/tests/fixtures/with_installed/vendor/composer/installed.json b/crates/mozart/tests/fixtures/with_installed/vendor/composer/installed.json
new file mode 100644
index 0000000..bbbe53c
--- /dev/null
+++ b/crates/mozart/tests/fixtures/with_installed/vendor/composer/installed.json
@@ -0,0 +1,18 @@
+{
+ "packages": [
+ {
+ "name": "psr/log",
+ "version": "3.0.2",
+ "version_normalized": "3.0.2.0",
+ "type": "library",
+ "install-path": "../psr/log",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ }
+ }
+ ],
+ "dev-package-names": [],
+ "dev": true
+}
diff --git a/crates/mozart/tests/fixtures/with_lock/composer.json b/crates/mozart/tests/fixtures/with_lock/composer.json
new file mode 100644
index 0000000..1653318
--- /dev/null
+++ b/crates/mozart/tests/fixtures/with_lock/composer.json
@@ -0,0 +1,9 @@
+{
+ "name": "test/locked-project",
+ "description": "A project with a lock file",
+ "license": "MIT",
+ "require": {
+ "php": ">=8.1",
+ "psr/log": "^3.0"
+ }
+}
diff --git a/crates/mozart/tests/fixtures/with_lock/composer.lock b/crates/mozart/tests/fixtures/with_lock/composer.lock
new file mode 100644
index 0000000..0e4f7aa
--- /dev/null
+++ b/crates/mozart/tests/fixtures/with_lock/composer.lock
@@ -0,0 +1,56 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "ca27a8c1835db5af5fd5efe936f402b4",
+ "packages": [
+ {
+ "name": "psr/log",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ },
+ "license": [
+ "MIT"
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://www.php-fig.org/",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2024-09-11T13:17:53+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {},
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=8.1"
+ },
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
+}
diff --git a/crates/mozart/tests/hash_helper.rs b/crates/mozart/tests/hash_helper.rs
new file mode 100644
index 0000000..301c72c
--- /dev/null
+++ b/crates/mozart/tests/hash_helper.rs
@@ -0,0 +1,3 @@
+// This file is intentionally empty.
+// It was a temporary helper used during development.
+// The actual integration tests are in cli_*.rs files.