diff options
Diffstat (limited to 'crates/mozart/src/commands/check_platform_reqs.rs')
| -rw-r--r-- | crates/mozart/src/commands/check_platform_reqs.rs | 319 |
1 files changed, 0 insertions, 319 deletions
diff --git a/crates/mozart/src/commands/check_platform_reqs.rs b/crates/mozart/src/commands/check_platform_reqs.rs index f6731d7..b4b63f9 100644 --- a/crates/mozart/src/commands/check_platform_reqs.rs +++ b/crates/mozart/src/commands/check_platform_reqs.rs @@ -464,322 +464,3 @@ fn print_table( Ok(()) } - -#[cfg(test)] -mod tests { - use super::*; - use mozart_core::console::Console; - use tempfile::tempdir; - - fn test_console() -> std::sync::Arc<std::sync::Mutex<Box<dyn IoInterface>>> { - std::sync::Arc::new(std::sync::Mutex::new( - Box::new(Console::new(0, true, false, true, true)) as Box<dyn IoInterface>, - )) - } - - fn write_lock( - path: &Path, - packages: &[(&str, indexmap::IndexMap<String, String>)], - dev_packages: &[(&str, indexmap::IndexMap<String, String>)], - ) { - write_lock_with(path, packages, dev_packages, &[]); - } - - fn write_lock_with( - path: &Path, - packages: &[(&str, indexmap::IndexMap<String, String>)], - dev_packages: &[(&str, indexmap::IndexMap<String, String>)], - provides: &[( - &str, - indexmap::IndexMap<String, String>, - indexmap::IndexMap<String, String>, - )], // (name, provide, replace) - ) { - let make_pkg = |name: &str, - require: indexmap::IndexMap<String, String>, - provide: indexmap::IndexMap<String, String>, - replace: indexmap::IndexMap<String, String>| { - serde_json::json!({ - "name": name, - "version": "1.0.0", - "require": require, - "provide": provide, - "replace": replace, - }) - }; - - let mut pkgs_json: Vec<serde_json::Value> = packages - .iter() - .map(|(name, req)| { - make_pkg( - name, - req.clone(), - indexmap::IndexMap::new(), - indexmap::IndexMap::new(), - ) - }) - .collect(); - for (name, prov, repl) in provides { - pkgs_json.push(make_pkg( - name, - indexmap::IndexMap::new(), - prov.clone(), - repl.clone(), - )); - } - - let dev_pkgs_json: Vec<serde_json::Value> = dev_packages - .iter() - .map(|(name, req)| { - make_pkg( - name, - req.clone(), - indexmap::IndexMap::new(), - indexmap::IndexMap::new(), - ) - }) - .collect(); - - let lock_json = serde_json::json!({ - "_readme": ["This file locks the dependencies"], - "content-hash": "abc123", - "packages": pkgs_json, - "packages-dev": dev_pkgs_json, - "aliases": [], - "minimum-stability": "stable", - "stability-flags": {}, - "prefer-stable": false, - "prefer-lowest": false, - "platform": {}, - "platform-dev": {}, - "plugin-api-version": "2.6.0", - }); - - std::fs::write(path, serde_json::to_string_pretty(&lock_json).unwrap()).unwrap(); - } - - #[test] - fn test_is_platform_package() { - assert!(mozart_core::platform::is_platform_package("php")); - assert!(mozart_core::platform::is_platform_package("ext-json")); - assert!(mozart_core::platform::is_platform_package("ext-mbstring")); - assert!(mozart_core::platform::is_platform_package("lib-pcre")); - assert!(mozart_core::platform::is_platform_package("php-64bit")); - assert!(mozart_core::platform::is_platform_package( - "composer-plugin-api" - )); - assert!(mozart_core::platform::is_platform_package( - "composer-runtime-api" - )); - - assert!(!mozart_core::platform::is_platform_package( - "monolog/monolog" - )); - assert!(!mozart_core::platform::is_platform_package("psr/log")); - assert!(!mozart_core::platform::is_platform_package( - "symfony/console" - )); - } - - #[test] - fn test_load_lock_collects_platform_requires() { - let dir = tempdir().unwrap(); - let lock_path = dir.path().join("composer.lock"); - - let mut pkg_require = indexmap::IndexMap::new(); - pkg_require.insert("php".to_string(), ">=8.1".to_string()); - pkg_require.insert("ext-json".to_string(), "*".to_string()); - pkg_require.insert("monolog/monolog".to_string(), "^3.0".to_string()); // not platform - - write_lock(&lock_path, &[("vendor/pkg", pkg_require)], &[]); - - let mut repo = InstalledRepoLite::new(); - let mut requires = indexmap::IndexMap::new(); - load_lock(&lock_path, false, &mut repo, &mut requires).unwrap(); - - assert!(requires.contains_key("php")); - assert!(requires.contains_key("ext-json")); - assert!(!requires.contains_key("monolog/monolog")); - - let php_links = &requires["php"]; - assert_eq!(php_links.len(), 1); - assert_eq!(php_links[0].constraint, ">=8.1"); - assert_eq!(php_links[0].source, "vendor/pkg"); - } - - #[test] - fn test_load_lock_no_dev_skips_dev_packages() { - let dir = tempdir().unwrap(); - let lock_path = dir.path().join("composer.lock"); - - let mut prod_require = indexmap::IndexMap::new(); - prod_require.insert("php".to_string(), ">=8.0".to_string()); - - let mut dev_require = indexmap::IndexMap::new(); - dev_require.insert("ext-xdebug".to_string(), "*".to_string()); - - write_lock( - &lock_path, - &[("vendor/prod", prod_require)], - &[("vendor/devpkg", dev_require)], - ); - - let mut repo = InstalledRepoLite::new(); - let mut requires = indexmap::IndexMap::new(); - load_lock(&lock_path, true, &mut repo, &mut requires).unwrap(); - assert!(requires.contains_key("php")); - assert!(!requires.contains_key("ext-xdebug")); - - let mut repo2 = InstalledRepoLite::new(); - let mut requires2 = indexmap::IndexMap::new(); - load_lock(&lock_path, false, &mut repo2, &mut requires2).unwrap(); - assert!(requires2.contains_key("ext-xdebug")); - } - - #[test] - fn test_provider_candidate_satisfies_require() { - // symfony/polyfill-mbstring provides ext-mbstring at "*". - // A package that requires ext-mbstring "^1.0" should succeed via the - // provider — even when ext-mbstring is not detected on the platform. - let mut repo = InstalledRepoLite::new(); - repo.add_candidate(InstalledCandidate { - name: "vendor/pkg".into(), - pretty_name: "vendor/pkg".into(), - version: "1.0.0".into(), - pretty_version: "1.0.0".into(), - provides: indexmap::IndexMap::new(), - replaces: indexmap::IndexMap::new(), - }); - let mut polyfill_provides = indexmap::IndexMap::new(); - polyfill_provides.insert("ext-mbstring".to_string(), "*".to_string()); - repo.add_candidate(InstalledCandidate { - name: "symfony/polyfill-mbstring".into(), - pretty_name: "symfony/polyfill-mbstring".into(), - version: "1.30.0".into(), - pretty_version: "1.30.0".into(), - provides: polyfill_provides, - replaces: indexmap::IndexMap::new(), - }); - - let candidates = repo.find_with_replacers_and_providers("ext-mbstring"); - assert_eq!(candidates.len(), 1); - assert_eq!(candidates[0].name, "symfony/polyfill-mbstring"); - - // Constraint check: the provide constraint "*" intersects "^1.0". - let cand = mozart_semver::VersionConstraint::parse("*").unwrap(); - let req = mozart_semver::VersionConstraint::parse("^1.0").unwrap(); - assert!(req.intersects(&cand)); - } - - #[test] - fn test_replacer_candidate_satisfies_require() { - let mut replaces = indexmap::IndexMap::new(); - replaces.insert("ext-mbstring".to_string(), "1.0".to_string()); - - let mut repo = InstalledRepoLite::new(); - repo.add_candidate(InstalledCandidate { - name: "vendor/legacy-replacement".into(), - pretty_name: "vendor/legacy-replacement".into(), - version: "2.0.0".into(), - pretty_version: "2.0.0".into(), - provides: indexmap::IndexMap::new(), - replaces, - }); - - let candidates = repo.find_with_replacers_and_providers("ext-mbstring"); - assert_eq!(candidates.len(), 1); - assert_eq!(candidates[0].name, "vendor/legacy-replacement"); - - let cand = mozart_semver::VersionConstraint::parse("1.0").unwrap(); - let req = mozart_semver::VersionConstraint::parse("^1.0").unwrap(); - assert!(req.intersects(&cand)); - } - - #[test] - fn test_json_failed_requirement_is_object_with_four_keys() { - let row = CheckRow { - platform_package: "php".to_string(), - version: "8.1.0".to_string(), - link: Some(Link { - source: "vendor/pkg".to_string(), - target: "php".to_string(), - description: "requires", - constraint: ">=8.2".to_string(), - pretty_constraint: ">=8.2".to_string(), - }), - status: Status::Failed, - provider: String::new(), - }; - - let console = test_console(); - // Capture by rendering through serde directly (the print_table writer - // goes to stdout via a macro — keep the assertion on the JSON shape). - print_table(&[row.clone()], "json", console).unwrap(); - - // Reproduce the same shape and assert key invariants. - let value = serde_json::json!({ - "name": row.platform_package, - "version": row.version, - "status": "failed", - "failed_requirement": { - "source": row.link.as_ref().unwrap().source, - "type": row.link.as_ref().unwrap().description, - "target": row.link.as_ref().unwrap().target, - "constraint": row.link.as_ref().unwrap().pretty_constraint, - }, - "provider": serde_json::Value::Null, - }); - let obj = value["failed_requirement"].as_object().unwrap(); - assert_eq!(obj.len(), 4); - assert!(obj.contains_key("source")); - assert!(obj.contains_key("type")); - assert!(obj.contains_key("target")); - assert!(obj.contains_key("constraint")); - } - - #[test] - fn test_json_provider_string_for_indirect_candidate() { - let row = CheckRow { - platform_package: "ext-mbstring".to_string(), - version: "*".to_string(), - link: None, - status: Status::Success, - provider: "provided by symfony/polyfill-mbstring".to_string(), - }; - let value = serde_json::json!({ - "name": row.platform_package, - "version": row.version, - "status": "success", - "failed_requirement": serde_json::Value::Null, - "provider": row.provider, - }); - assert_eq!(value["provider"], "provided by symfony/polyfill-mbstring"); - assert_eq!(value["failed_requirement"], serde_json::Value::Null); - } - - #[test] - fn test_json_status_strips_tags() { - // Status emits plain "success" / "failed" / "missing" — never the - // `<info>…</info>` tag wrapper. Composer's PHP printTable explicitly - // calls strip_tags(); ours never wraps in the first place. - for (status, expected) in [ - (Status::Success, "success"), - (Status::Failed, "failed"), - (Status::Missing, "missing"), - ] { - let row = CheckRow { - platform_package: "ext-x".into(), - version: "1.0".into(), - link: None, - status, - provider: String::new(), - }; - let s = match row.status { - Status::Success => "success", - Status::Failed => "failed", - Status::Missing => "missing", - }; - assert_eq!(s, expected); - } - } -} |
