aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock103
-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
22 files changed, 801 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index dd0a65e..7ddc94a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -83,6 +83,21 @@ dependencies = [
]
[[package]]
+name = "assert_cmd"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c5bcfa8749ac45dd12cb11055aeeb6b27a3895560d60d71e3c23bf979e60514"
+dependencies = [
+ "anstyle",
+ "bstr",
+ "libc",
+ "predicates",
+ "predicates-core",
+ "predicates-tree",
+ "wait-timeout",
+]
+
+[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -138,6 +153,17 @@ dependencies = [
]
[[package]]
+name = "bstr"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
+dependencies = [
+ "memchr",
+ "regex-automata",
+ "serde",
+]
+
+[[package]]
name = "bumpalo"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -369,6 +395,12 @@ dependencies = [
]
[[package]]
+name = "difflib"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
+
+[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -460,6 +492,15 @@ dependencies = [
]
[[package]]
+name = "float-cmp"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -977,6 +1018,7 @@ name = "mozart"
version = "0.1.0"
dependencies = [
"anyhow",
+ "assert_cmd",
"bzip2",
"clap",
"colored",
@@ -984,6 +1026,7 @@ dependencies = [
"filetime",
"flate2",
"md5",
+ "predicates",
"pubgrub",
"regex",
"reqwest",
@@ -998,6 +1041,21 @@ dependencies = [
]
[[package]]
+name = "normalize-line-endings"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1081,6 +1139,36 @@ dependencies = [
]
[[package]]
+name = "predicates"
+version = "3.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe"
+dependencies = [
+ "anstyle",
+ "difflib",
+ "float-cmp",
+ "normalize-line-endings",
+ "predicates-core",
+ "regex",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2"
+dependencies = [
+ "predicates-core",
+ "termtree",
+]
+
+[[package]]
name = "priority-queue"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1673,6 +1761,12 @@ dependencies = [
]
[[package]]
+name = "termtree"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
+
+[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1922,6 +2016,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
+name = "wait-timeout"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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.