From 4e99773a3d203e73b8bf6464490d05649a269fa7 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Mon, 11 May 2026 02:36:42 +0900 Subject: test(commands): remove per-command tests --- crates/mozart/src/commands/bump.rs | 518 ------------------------------------- 1 file changed, 518 deletions(-) (limited to 'crates/mozart/src/commands/bump.rs') diff --git a/crates/mozart/src/commands/bump.rs b/crates/mozart/src/commands/bump.rs index 2d6eea8..2dbd84a 100644 --- a/crates/mozart/src/commands/bump.rs +++ b/crates/mozart/src/commands/bump.rs @@ -355,521 +355,3 @@ fn strip_inline_constraint(arg: &str) -> &str { .map(|pos| &arg[..pos]) .unwrap_or(arg) } - -#[cfg(test)] -mod tests { - use super::*; - use mozart_core::repository::lockfile::{LockFile, LockedPackage}; - use tempfile::tempdir; - - fn minimal_lock(packages: Vec, packages_dev: Vec) -> LockFile { - LockFile { - readme: LockFile::default_readme(), - content_hash: "placeholder".to_string(), - packages, - packages_dev: Some(packages_dev), - 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()), - } - } - - fn make_locked_package(name: &str, version: &str) -> LockedPackage { - LockedPackage { - name: name.to_string(), - version: version.to_string(), - version_normalized: Some(format!("{version}.0")), - 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: None, - 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 write_composer_json(dir: &std::path::Path, content: &str) { - std::fs::write(dir.join("composer.json"), content).unwrap(); - } - - fn write_lock_with_hash(dir: &std::path::Path, mut lock: LockFile, composer_json: &str) { - let hash = LockFile::compute_content_hash(composer_json).unwrap(); - lock.content_hash = hash; - lock.write_to_file(&dir.join("composer.lock")).unwrap(); - } - - fn make_cli(working_dir: &std::path::Path) -> super::super::Cli { - super::super::Cli { - command: Some(super::super::Commands::Bump(BumpArgs { - packages: vec![], - dev_only: false, - no_dev_only: false, - dry_run: false, - })), - version: false, - verbose: 0, - profile: false, - no_plugins: false, - no_scripts: false, - working_dir: Some(working_dir.to_str().unwrap().to_string()), - no_cache: false, - no_interaction: false, - quiet: false, - ansi: false, - no_ansi: false, - } - } - - fn quiet_io() -> std::sync::Arc>> { - std::sync::Arc::new(std::sync::Mutex::new( - Box::new(mozart_core::console::Console::new( - 0, false, false, false, false, - )) as Box, - )) - } - - #[tokio::test] - async fn test_basic_bump_modifies_composer_json() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock(vec![make_locked_package("psr/log", "1.1.4")], vec![]); - write_lock_with_hash(dir.path(), lock, composer_json); - - let args = BumpArgs { - packages: vec![], - dev_only: false, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - let updated = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&updated).unwrap(); - assert_eq!(parsed["require"]["psr/log"], "^1.1.4"); - } - - #[tokio::test] - async fn test_dry_run_does_not_modify_files() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock(vec![make_locked_package("psr/log", "1.1.4")], vec![]); - write_lock_with_hash(dir.path(), lock, composer_json); - - let args = BumpArgs { - packages: vec![], - dev_only: false, - no_dev_only: false, - dry_run: true, - }; - let cli = make_cli(dir.path()); - let result = execute(&args, &cli, quiet_io()).await; - - // dry-run with changes returns exit code 1 (for CI usage) - let err = result.unwrap_err(); - let mozart_err = err - .downcast_ref::() - .expect("should be MozartError"); - assert_eq!(mozart_err.exit_code, mozart_core::exit_code::GENERAL_ERROR); - - // composer.json should be unchanged - let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&content).unwrap(); - assert_eq!(parsed["require"]["psr/log"], "^1.0"); - } - - #[tokio::test] - async fn test_no_changes_when_already_bumped() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.1.4" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock(vec![make_locked_package("psr/log", "1.1.4")], vec![]); - write_lock_with_hash(dir.path(), lock, composer_json); - - let args = BumpArgs { - packages: vec![], - dev_only: false, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - // No changes should be made - let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&content).unwrap(); - assert_eq!(parsed["require"]["psr/log"], "^1.1.4"); - } - - #[tokio::test] - async fn test_dev_only_flag_only_bumps_require_dev() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock( - vec![make_locked_package("psr/log", "1.1.4")], - vec![make_locked_package("phpunit/phpunit", "9.5.0")], - ); - write_lock_with_hash(dir.path(), lock, composer_json); - - let args = BumpArgs { - packages: vec![], - dev_only: true, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&content).unwrap(); - // require should NOT be bumped - assert_eq!(parsed["require"]["psr/log"], "^1.0"); - // require-dev should be bumped - assert_eq!(parsed["require-dev"]["phpunit/phpunit"], "^9.5"); - } - - #[tokio::test] - async fn test_no_dev_only_flag_only_bumps_require() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock( - vec![make_locked_package("psr/log", "1.1.4")], - vec![make_locked_package("phpunit/phpunit", "9.5.0")], - ); - write_lock_with_hash(dir.path(), lock, composer_json); - - let args = BumpArgs { - packages: vec![], - dev_only: false, - no_dev_only: true, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&content).unwrap(); - // require should be bumped - assert_eq!(parsed["require"]["psr/log"], "^1.1.4"); - // require-dev should NOT be bumped - assert_eq!(parsed["require-dev"]["phpunit/phpunit"], "^9.0"); - } - - #[tokio::test] - async fn test_stale_lock_file_produces_exit_code_2() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "require": { - "psr/log": "^1.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - // Write lock with a wrong hash (stale) - let mut lock = minimal_lock(vec![make_locked_package("psr/log", "1.1.4")], vec![]); - lock.content_hash = "wrong_hash_here".to_string(); - lock.write_to_file(&dir.path().join("composer.lock")) - .unwrap(); - - let args = BumpArgs { - packages: vec![], - dev_only: false, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - let result = execute(&args, &cli, quiet_io()).await; - - // stale lock file should return exit code 2 (ERROR_LOCK_OUTDATED) - let err = result.unwrap_err(); - let mozart_err = err - .downcast_ref::() - .expect("should be MozartError"); - assert_eq!(mozart_err.exit_code, ERROR_LOCK_OUTDATED); - } - - #[tokio::test] - async fn test_lock_file_hash_updated_after_bump() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock(vec![make_locked_package("psr/log", "1.1.4")], vec![]); - write_lock_with_hash(dir.path(), lock, composer_json); - - let args = BumpArgs { - packages: vec![], - dev_only: false, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - // The lock file content-hash should now match the updated composer.json - let updated_composer = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let updated_lock = LockFile::read_from_file(&dir.path().join("composer.lock")).unwrap(); - assert!( - updated_lock.is_fresh(&updated_composer), - "Lock file hash should be updated to match new composer.json" - ); - } - - #[tokio::test] - async fn test_no_lock_falls_back_to_local_repository() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - // No composer.lock — instead populate vendor/composer/installed.json. - let installed_dir = dir.path().join("vendor/composer"); - std::fs::create_dir_all(&installed_dir).unwrap(); - let installed = serde_json::json!({ - "packages": [ - { - "name": "psr/log", - "version": "1.1.4", - "version_normalized": "1.1.4.0", - } - ], - "dev": false, - }); - std::fs::write( - installed_dir.join("installed.json"), - serde_json::to_string_pretty(&installed).unwrap(), - ) - .unwrap(); - - let args = BumpArgs { - packages: vec![], - dev_only: false, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&content).unwrap(); - assert_eq!(parsed["require"]["psr/log"], "^1.1.4"); - } - - #[test] - fn test_strip_inline_constraint_colon() { - assert_eq!(strip_inline_constraint("vendor/pkg:^2.0"), "vendor/pkg"); - } - - #[test] - fn test_strip_inline_constraint_equals() { - assert_eq!(strip_inline_constraint("vendor/pkg=2.0.0"), "vendor/pkg"); - } - - #[test] - fn test_strip_inline_constraint_space() { - assert_eq!(strip_inline_constraint("vendor/pkg ^2.0"), "vendor/pkg"); - } - - #[test] - fn test_strip_inline_constraint_no_suffix() { - assert_eq!(strip_inline_constraint("vendor/pkg"), "vendor/pkg"); - assert_eq!(strip_inline_constraint("psr/log"), "psr/log"); - } - - #[tokio::test] - async fn test_package_filter_only_bumps_specified_packages() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0", - "psr/http-message": "^1.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock( - vec![ - make_locked_package("psr/log", "1.1.4"), - make_locked_package("psr/http-message", "1.2.0"), - ], - vec![], - ); - write_lock_with_hash(dir.path(), lock, composer_json); - - let args = BumpArgs { - packages: vec!["psr/log".to_string()], - dev_only: false, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&content).unwrap(); - assert_eq!(parsed["require"]["psr/log"], "^1.1.4"); - // psr/http-message should NOT be bumped - assert_eq!(parsed["require"]["psr/http-message"], "^1.0"); - } - - #[tokio::test] - async fn test_package_filter_glob_wildcard() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0", - "psr/container": "^1.0", - "monolog/monolog": "^2.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock( - vec![ - make_locked_package("psr/log", "1.1.4"), - make_locked_package("psr/container", "1.1.1"), - make_locked_package("monolog/monolog", "2.9.0"), - ], - vec![], - ); - write_lock_with_hash(dir.path(), lock, composer_json); - - // Filter using a wildcard: only bump psr/* packages - let args = BumpArgs { - packages: vec!["psr/*".to_string()], - dev_only: false, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&content).unwrap(); - // Both psr/* packages should be bumped - assert_eq!(parsed["require"]["psr/log"], "^1.1.4"); - assert_eq!(parsed["require"]["psr/container"], "^1.1.1"); - // monolog/monolog should NOT be bumped - assert_eq!(parsed["require"]["monolog/monolog"], "^2.0"); - } - - #[tokio::test] - async fn test_package_filter_with_inline_constraint() { - let dir = tempdir().unwrap(); - let composer_json = r#"{ - "name": "test/project", - "type": "project", - "require": { - "psr/log": "^1.0", - "monolog/monolog": "^2.0" - } -}"#; - write_composer_json(dir.path(), composer_json); - - let lock = minimal_lock( - vec![ - make_locked_package("psr/log", "1.1.4"), - make_locked_package("monolog/monolog", "2.9.0"), - ], - vec![], - ); - write_lock_with_hash(dir.path(), lock, composer_json); - - // Specify filter with an inline constraint suffix (Composer-style: "psr/log:^1.0") - let args = BumpArgs { - packages: vec!["psr/log:^1.0".to_string()], - dev_only: false, - no_dev_only: false, - dry_run: false, - }; - let cli = make_cli(dir.path()); - execute(&args, &cli, quiet_io()).await.unwrap(); - - let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap(); - let parsed: serde_json::Value = serde_json::from_str(&content).unwrap(); - // psr/log should be bumped (constraint suffix stripped from filter arg) - assert_eq!(parsed["require"]["psr/log"], "^1.1.4"); - // monolog/monolog should NOT be bumped - assert_eq!(parsed["require"]["monolog/monolog"], "^2.0"); - } -} -- cgit v1.3.1