aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands/install.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-11 02:36:42 +0900
committernsfisis <nsfisis@gmail.com>2026-05-11 02:36:42 +0900
commit4e99773a3d203e73b8bf6464490d05649a269fa7 (patch)
tree7a6f1a7f773a14ea72dc2f9ff4124badd345833d /crates/mozart/src/commands/install.rs
parent4df5f8491320e5795718cf0222e80fa27e57c8ad (diff)
downloadphp-mozart-4e99773a3d203e73b8bf6464490d05649a269fa7.tar.gz
php-mozart-4e99773a3d203e73b8bf6464490d05649a269fa7.tar.zst
php-mozart-4e99773a3d203e73b8bf6464490d05649a269fa7.zip
test(commands): remove per-command tests
Diffstat (limited to 'crates/mozart/src/commands/install.rs')
-rw-r--r--crates/mozart/src/commands/install.rs511
1 files changed, 0 insertions, 511 deletions
diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs
index 709b934..59baf0b 100644
--- a/crates/mozart/src/commands/install.rs
+++ b/crates/mozart/src/commands/install.rs
@@ -1076,514 +1076,3 @@ pub async fn run(
)
.await
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use tempfile::tempdir;
-
- fn make_locked_package(name: &str, version: &str) -> lockfile::LockedPackage {
- lockfile::LockedPackage {
- name: name.to_string(),
- version: version.to_string(),
- version_normalized: None,
- source: None,
- dist: None,
- require: indexmap::IndexMap::new(),
- require_dev: indexmap::IndexMap::new(),
- conflict: indexmap::IndexMap::new(),
- provide: indexmap::IndexMap::new(),
- replace: indexmap::IndexMap::new(),
- suggest: None,
- package_type: Some("library".to_string()),
- autoload: None,
- autoload_dev: None,
- license: None,
- description: None,
- homepage: None,
- keywords: None,
- authors: None,
- support: None,
- funding: None,
- time: None,
- extra_fields: indexmap::IndexMap::new(),
- }
- }
-
- fn make_installed_entry(name: &str, version: &str) -> installed::InstalledPackageEntry {
- installed::InstalledPackageEntry {
- name: name.to_string(),
- version: version.to_string(),
- version_normalized: None,
- source: None,
- dist: None,
- package_type: None,
- install_path: None,
- autoload: None,
- aliases: vec![],
- homepage: None,
- support: None,
- extra_fields: indexmap::IndexMap::new(),
- }
- }
-
- fn minimal_lock(packages: Vec<lockfile::LockedPackage>) -> lockfile::LockFile {
- lockfile::LockFile {
- readme: lockfile::LockFile::default_readme(),
- content_hash: "abc123".to_string(),
- packages,
- packages_dev: Some(vec![]),
- aliases: vec![],
- minimum_stability: "stable".to_string(),
- stability_flags: serde_json::json!({}),
- prefer_stable: false,
- prefer_lowest: false,
- platform: serde_json::json!({}),
- platform_dev: serde_json::json!({}),
- plugin_api_version: Some("2.6.0".to_string()),
- }
- }
-
- // -----------------------------------------------------------------------
- // compute_operations tests
- // -----------------------------------------------------------------------
-
- #[test]
- fn test_compute_operations_all_new() {
- let locked = [
- make_locked_package("psr/log", "3.0.0"),
- make_locked_package("monolog/monolog", "3.8.0"),
- ];
- let locked_refs: Vec<&lockfile::LockedPackage> = locked.iter().collect();
- let installed = installed::InstalledPackages::new();
-
- let (ops, removals) = compute_operations(&locked_refs, &installed);
-
- assert_eq!(ops.len(), 2);
- assert!(matches!(ops[0].1, Action::Install));
- assert!(matches!(ops[1].1, Action::Install));
- assert!(removals.is_empty());
- }
-
- #[test]
- fn test_compute_operations_all_skipped() {
- let locked = [make_locked_package("psr/log", "3.0.0")];
- let locked_refs: Vec<&lockfile::LockedPackage> = locked.iter().collect();
- let mut installed = installed::InstalledPackages::new();
- installed.upsert(make_installed_entry("psr/log", "3.0.0"));
-
- let (ops, removals) = compute_operations(&locked_refs, &installed);
-
- assert_eq!(ops.len(), 1);
- assert!(matches!(ops[0].1, Action::Skip));
- assert!(removals.is_empty());
- }
-
- #[test]
- fn test_compute_operations_update_needed() {
- let locked = [make_locked_package("psr/log", "3.0.1")];
- let locked_refs: Vec<&lockfile::LockedPackage> = locked.iter().collect();
- let mut installed = installed::InstalledPackages::new();
- installed.upsert(make_installed_entry("psr/log", "3.0.0"));
-
- let (ops, removals) = compute_operations(&locked_refs, &installed);
-
- assert_eq!(ops.len(), 1);
- assert!(matches!(ops[0].1, Action::Update));
- assert!(removals.is_empty());
- }
-
- #[test]
- fn test_compute_operations_removals() {
- let locked = [make_locked_package("psr/log", "3.0.0")];
- let locked_refs: Vec<&lockfile::LockedPackage> = locked.iter().collect();
- let mut installed = installed::InstalledPackages::new();
- installed.upsert(make_installed_entry("psr/log", "3.0.0"));
- installed.upsert(make_installed_entry("monolog/monolog", "3.8.0"));
-
- let (ops, removals) = compute_operations(&locked_refs, &installed);
-
- assert_eq!(ops.len(), 1);
- assert!(matches!(ops[0].1, Action::Skip));
- assert_eq!(removals.len(), 1);
- assert_eq!(removals[0], "monolog/monolog");
- }
-
- #[test]
- fn test_compute_operations_mixed() {
- let locked = [
- make_locked_package("psr/log", "3.0.0"),
- make_locked_package("symfony/console", "7.2.3"),
- make_locked_package("monolog/monolog", "3.8.1"),
- ];
- let locked_refs: Vec<&lockfile::LockedPackage> = locked.iter().collect();
- let mut installed = installed::InstalledPackages::new();
- // psr/log already at correct version -> skip
- installed.upsert(make_installed_entry("psr/log", "3.0.0"));
- // monolog at wrong version -> update
- installed.upsert(make_installed_entry("monolog/monolog", "3.8.0"));
- // old-package not in locked -> removal
- installed.upsert(make_installed_entry("old/package", "1.0.0"));
- // symfony/console not installed at all -> install
-
- let (ops, removals) = compute_operations(&locked_refs, &installed);
-
- assert_eq!(ops.len(), 3);
-
- let psr = ops.iter().find(|(p, _)| p.name == "psr/log").unwrap();
- assert!(matches!(psr.1, Action::Skip));
-
- let symfony = ops
- .iter()
- .find(|(p, _)| p.name == "symfony/console")
- .unwrap();
- assert!(matches!(symfony.1, Action::Install));
-
- let monolog = ops
- .iter()
- .find(|(p, _)| p.name == "monolog/monolog")
- .unwrap();
- assert!(matches!(monolog.1, Action::Update));
-
- assert_eq!(removals.len(), 1);
- assert_eq!(removals[0], "old/package");
- }
-
- #[test]
- fn test_compute_operations_case_insensitive() {
- let locked = [make_locked_package("Monolog/Monolog", "3.8.0")];
- let locked_refs: Vec<&lockfile::LockedPackage> = locked.iter().collect();
- let mut installed = installed::InstalledPackages::new();
- installed.upsert(make_installed_entry("monolog/monolog", "3.8.0"));
-
- let (ops, removals) = compute_operations(&locked_refs, &installed);
-
- assert_eq!(ops.len(), 1);
- assert!(matches!(ops[0].1, Action::Skip));
- assert!(removals.is_empty());
- }
-
- #[test]
- fn test_compute_operations_empty_lock() {
- let locked: Vec<lockfile::LockedPackage> = vec![];
- let locked_refs: Vec<&lockfile::LockedPackage> = locked.iter().collect();
- let mut installed = installed::InstalledPackages::new();
- installed.upsert(make_installed_entry("old/package", "1.0.0"));
-
- let (ops, removals) = compute_operations(&locked_refs, &installed);
-
- assert!(ops.is_empty());
- assert_eq!(removals.len(), 1);
- assert_eq!(removals[0], "old/package");
- }
-
- // -----------------------------------------------------------------------
- // locked_to_installed_entry tests
- // -----------------------------------------------------------------------
-
- #[test]
- fn test_locked_to_installed_entry_conversion() {
- let dir = tempdir().unwrap();
- let vendor_dir = dir.path().join("vendor");
-
- let mut pkg = make_locked_package("psr/log", "3.0.2");
- pkg.version_normalized = Some("3.0.2.0".to_string());
- pkg.package_type = Some("library".to_string());
- pkg.autoload = Some(serde_json::json!({"psr-4": {"Psr\\Log\\": "src/"}}));
-
- let entry = locked_to_installed_entry(&pkg, &vendor_dir);
-
- assert_eq!(entry.name, "psr/log");
- assert_eq!(entry.version, "3.0.2");
- assert_eq!(entry.version_normalized.as_deref(), Some("3.0.2.0"));
- assert_eq!(entry.package_type.as_deref(), Some("library"));
- assert_eq!(entry.install_path.as_deref(), Some("../psr/log"));
- assert!(entry.autoload.is_some());
- assert!(entry.aliases.is_empty());
- assert!(entry.extra_fields.is_empty());
- assert!(entry.source.is_none());
- assert!(entry.dist.is_none());
- }
-
- #[test]
- fn test_locked_to_installed_entry_with_dist() {
- let dir = tempdir().unwrap();
- let vendor_dir = dir.path().join("vendor");
-
- let mut pkg = make_locked_package("monolog/monolog", "3.8.0");
- pkg.dist = Some(lockfile::LockedDist {
- dist_type: "zip".to_string(),
- url: "https://example.com/monolog.zip".to_string(),
- reference: Some("abc123".to_string()),
- shasum: Some("deadbeef".to_string()),
- });
-
- let entry = locked_to_installed_entry(&pkg, &vendor_dir);
-
- assert_eq!(entry.name, "monolog/monolog");
- assert_eq!(entry.install_path.as_deref(), Some("../monolog/monolog"));
- assert!(entry.dist.is_some());
- }
-
- #[test]
- fn test_locked_to_installed_entry_propagates_extra_fields() {
- // Composer's installed.json carries package flags like `abandoned` and
- // `default-branch` that LockedPackage stores in extra_fields. Make sure
- // they survive the conversion so we don't strip them on rewrite.
- let dir = tempdir().unwrap();
- let vendor_dir = dir.path().join("vendor");
-
- let mut pkg = make_locked_package("a/a", "1.0.0");
- pkg.extra_fields.insert(
- "abandoned".to_string(),
- serde_json::Value::String("replacement".to_string()),
- );
- pkg.extra_fields
- .insert("default-branch".to_string(), serde_json::Value::Bool(true));
-
- let entry = locked_to_installed_entry(&pkg, &vendor_dir);
-
- assert_eq!(
- entry.extra_fields.get("abandoned"),
- Some(&serde_json::Value::String("replacement".to_string()))
- );
- assert_eq!(
- entry.extra_fields.get("default-branch"),
- Some(&serde_json::Value::Bool(true))
- );
- }
-
- // -----------------------------------------------------------------------
- // installed.json generation tests
- // -----------------------------------------------------------------------
-
- #[test]
- fn test_installed_json_written_from_lock() {
- let dir = tempdir().unwrap();
- let vendor_dir = dir.path().join("vendor");
-
- // Write a lock file
- let lock_path = dir.path().join("composer.lock");
- let lock = minimal_lock(vec![
- make_locked_package("psr/log", "3.0.2"),
- make_locked_package("vendor/pkg", "1.2.3"),
- ]);
- lock.write_to_file(&lock_path).unwrap();
-
- // Simulate what execute() does for the installed.json write step
- let packages_to_install: Vec<&lockfile::LockedPackage> = lock.packages.iter().collect();
- let mut new_installed = installed::InstalledPackages::new();
- new_installed.dev = false;
- for pkg in &packages_to_install {
- new_installed.upsert(locked_to_installed_entry(pkg, &vendor_dir));
- }
- new_installed.write(&vendor_dir).unwrap();
-
- // Verify installed.json
- let loaded = installed::InstalledPackages::read(&vendor_dir).unwrap();
- assert_eq!(loaded.packages.len(), 2);
- assert!(loaded.is_installed("psr/log", "3.0.2"));
- assert!(loaded.is_installed("vendor/pkg", "1.2.3"));
- assert_eq!(
- loaded
- .packages
- .iter()
- .find(|p| p.name == "psr/log")
- .unwrap()
- .install_path
- .as_deref(),
- Some("../psr/log")
- );
- }
-
- #[test]
- fn test_installed_json_dev_package_names() {
- let dir = tempdir().unwrap();
- let vendor_dir = dir.path().join("vendor");
-
- let mut lock = minimal_lock(vec![make_locked_package("psr/log", "3.0.2")]);
- lock.packages_dev = Some(vec![make_locked_package("phpunit/phpunit", "11.0.0")]);
-
- // Simulate dev mode installed.json generation
- let mut packages_to_install: Vec<&lockfile::LockedPackage> = lock.packages.iter().collect();
- if let Some(ref dev_pkgs) = lock.packages_dev {
- packages_to_install.extend(dev_pkgs.iter());
- }
-
- let mut new_installed = installed::InstalledPackages::new();
- new_installed.dev = true;
- if let Some(ref dev_pkgs) = lock.packages_dev {
- new_installed.dev_package_names = dev_pkgs.iter().map(|p| p.name.clone()).collect();
- }
- for pkg in &packages_to_install {
- new_installed.upsert(locked_to_installed_entry(pkg, &vendor_dir));
- }
- new_installed.write(&vendor_dir).unwrap();
-
- let loaded = installed::InstalledPackages::read(&vendor_dir).unwrap();
- assert_eq!(loaded.packages.len(), 2);
- assert!(loaded.dev);
- assert_eq!(loaded.dev_package_names, vec!["phpunit/phpunit"]);
- }
-
- // -----------------------------------------------------------------------
- // Platform requirement check tests
- // -----------------------------------------------------------------------
-
- fn root_with_require(
- require: &[(&str, &str)],
- require_dev: &[(&str, &str)],
- ) -> RootPackageData {
- let mut raw = mozart_core::package::RawPackageData::new("__root__".to_string());
- for (k, v) in require {
- raw.require.insert((*k).to_string(), (*v).to_string());
- }
- for (k, v) in require_dev {
- raw.require_dev.insert((*k).to_string(), (*v).to_string());
- }
- RootPackageData::from_raw(raw)
- }
-
- fn lock_with_platform(
- platform: serde_json::Value,
- platform_dev: serde_json::Value,
- ) -> lockfile::LockFile {
- let mut lock = minimal_lock(vec![]);
- lock.platform = platform;
- lock.platform_dev = platform_dev;
- lock
- }
-
- fn pp(name: &str, version: &str) -> mozart_core::platform::PlatformPackage {
- mozart_core::platform::PlatformPackage {
- name: name.to_string(),
- version: version.to_string(),
- }
- }
-
- #[test]
- fn combine_platform_requirements_root_overrides_lock() {
- let lock = lock_with_platform(
- serde_json::json!({"php": "^7.4", "ext-foo": "^5"}),
- serde_json::json!({}),
- );
- let root = root_with_require(&[("ext-foo", "^10")], &[]);
- let combined = combine_platform_requirements(&root, &lock, true);
-
- // Root composer.json wins for ext-foo, lock contributes plain php.
- assert_eq!(combined.get("ext-foo").map(String::as_str), Some("^10"));
- assert_eq!(combined.get("php").map(String::as_str), Some("^7.4"));
- }
-
- #[test]
- fn combine_platform_requirements_skips_non_platform_requires() {
- let lock = lock_with_platform(serde_json::json!({}), serde_json::json!({}));
- let root = root_with_require(&[("vendor/pkg", "^1.0"), ("php", "^8.0")], &[]);
- let combined = combine_platform_requirements(&root, &lock, true);
-
- assert_eq!(combined.len(), 1);
- assert_eq!(combined.get("php").map(String::as_str), Some("^8.0"));
- }
-
- #[test]
- fn combine_platform_requirements_includes_dev_only_when_dev_mode() {
- let lock = lock_with_platform(
- serde_json::json!({}),
- serde_json::json!({"ext-only-dev": "^1"}),
- );
- let root = root_with_require(&[], &[("ext-from-dev-require", "^1")]);
-
- let with_dev = combine_platform_requirements(&root, &lock, true);
- assert!(with_dev.contains_key("ext-only-dev"));
- assert!(with_dev.contains_key("ext-from-dev-require"));
-
- let no_dev = combine_platform_requirements(&root, &lock, false);
- assert!(!no_dev.contains_key("ext-only-dev"));
- assert!(!no_dev.contains_key("ext-from-dev-require"));
- }
-
- #[test]
- fn check_platform_requirements_reports_missing_extension() {
- let combined: indexmap::IndexMap<String, String> =
- [("ext-foo".to_string(), "^10".to_string())]
- .into_iter()
- .collect();
- let platform = vec![pp("php", "8.2.0")];
- let problems = check_platform_requirements_against(&combined, &platform, false, &[]);
-
- assert_eq!(problems.len(), 1);
- assert_eq!(
- problems[0],
- "- Root composer.json requires PHP extension ext-foo ^10 but it is missing from your system. Install or enable PHP's foo extension."
- );
- }
-
- #[test]
- fn check_platform_requirements_reports_unsatisfied_php() {
- let combined: indexmap::IndexMap<String, String> = [("php".to_string(), "^20".to_string())]
- .into_iter()
- .collect();
- let platform = vec![pp("php", "8.2.0")];
- let problems = check_platform_requirements_against(&combined, &platform, false, &[]);
-
- assert_eq!(problems.len(), 1);
- assert_eq!(
- problems[0],
- "- Root composer.json requires php ^20 but your php version (8.2.0) does not satisfy that requirement."
- );
- }
-
- #[test]
- fn check_platform_requirements_satisfied_returns_empty() {
- let combined: indexmap::IndexMap<String, String> =
- [("php".to_string(), "^8.0".to_string())]
- .into_iter()
- .collect();
- let platform = vec![pp("php", "8.2.0")];
- let problems = check_platform_requirements_against(&combined, &platform, false, &[]);
-
- assert!(problems.is_empty());
- }
-
- #[test]
- fn check_platform_requirements_ignore_platform_reqs_short_circuits() {
- let combined: indexmap::IndexMap<String, String> =
- [("ext-foo".to_string(), "^10".to_string())]
- .into_iter()
- .collect();
- let platform: Vec<mozart_core::platform::PlatformPackage> = vec![];
- let problems = check_platform_requirements_against(&combined, &platform, true, &[]);
-
- assert!(problems.is_empty());
- }
-
- #[test]
- fn check_platform_requirements_specific_ignore_filters_named_packages() {
- let combined: indexmap::IndexMap<String, String> = [
- ("ext-foo".to_string(), "^10".to_string()),
- ("ext-bar".to_string(), "^10".to_string()),
- ]
- .into_iter()
- .collect();
- let platform = vec![pp("php", "8.2.0")];
- let problems = check_platform_requirements_against(
- &combined,
- &platform,
- false,
- &["ext-foo".to_string()],
- );
-
- assert_eq!(problems.len(), 1);
- assert!(problems[0].contains("ext-bar"));
- }
-
- #[test]
- fn verify_lock_platform_problems_returns_empty_when_no_reqs() {
- // No platform reqs anywhere → returns empty without invoking detect_platform.
- let lock = lock_with_platform(serde_json::json!({}), serde_json::json!({}));
- let root = root_with_require(&[("vendor/pkg", "^1.0")], &[]);
- let problems = verify_lock_platform_problems(&root, &lock, true, false, &[]);
-
- assert!(problems.is_empty());
- }
-}