aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands/config.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/config.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/config.rs')
-rw-r--r--crates/mozart/src/commands/config.rs1130
1 files changed, 0 insertions, 1130 deletions
diff --git a/crates/mozart/src/commands/config.rs b/crates/mozart/src/commands/config.rs
index 7f4fd06..9e2e9ff 100644
--- a/crates/mozart/src/commands/config.rs
+++ b/crates/mozart/src/commands/config.rs
@@ -1082,1133 +1082,3 @@ fn execute_read(
Ok(())
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use mozart_core::config::Config;
-
- #[test]
- fn test_defaults_contain_expected_keys() {
- let cfg = Config::default();
-
- let required_keys = [
- "process-timeout",
- "use-include-path",
- "preferred-install",
- "notify-on-install",
- "github-protocols",
- "vendor-dir",
- "bin-dir",
- "bin-compat",
- "cache-dir",
- "cache-files-dir",
- "cache-repo-dir",
- "cache-vcs-dir",
- "cache-files-ttl",
- "cache-files-maxsize",
- "cache-read-only",
- "prepend-autoloader",
- "autoloader-suffix",
- "optimize-autoloader",
- "sort-packages",
- "classmap-authoritative",
- "apcu-autoloader",
- "platform",
- "platform-check",
- "lock",
- "discard-changes",
- "archive-format",
- "archive-dir",
- "htaccess-protect",
- "secure-http",
- "allow-plugins",
- ];
-
- for key in &required_keys {
- assert!(cfg.get(*key).is_some(), "defaults missing key: {key}");
- }
- }
-
- #[test]
- fn test_defaults_values_correct() {
- let cfg = Config::default();
-
- assert_eq!(cfg.process_timeout, 300);
- assert_eq!(cfg.preferred_install, serde_json::json!("dist"));
- assert_eq!(cfg.vendor_dir, "vendor");
- assert_eq!(cfg.github_protocols, vec!["https", "ssh", "git"]);
- assert_eq!(cfg.secure_http, true);
- assert_eq!(cfg.lock, true);
- assert_eq!(cfg.autoloader_suffix, None);
- }
-
- #[test]
- fn test_merge_overrides_existing_key() {
- let mut cfg = Config::default();
-
- let mut overrides = BTreeMap::new();
- overrides.insert("vendor-dir".to_string(), serde_json::json!("packages"));
- overrides.insert("sort-packages".to_string(), serde_json::json!(true));
-
- cfg.merge(&overrides).unwrap();
-
- assert_eq!(cfg.vendor_dir, "packages");
- assert_eq!(cfg.sort_packages, true);
- }
-
- #[test]
- fn test_merge_adds_new_key() {
- let mut cfg = Config::default();
-
- let mut overrides = BTreeMap::new();
- overrides.insert("custom-key".to_string(), serde_json::json!("custom-value"));
-
- cfg.merge(&overrides).unwrap();
-
- assert_eq!(cfg.extra["custom-key"], serde_json::json!("custom-value"));
- }
-
- #[test]
- fn test_merge_empty_overrides_leaves_defaults_intact() {
- let mut cfg = Config::default();
- let original_vendor = cfg.vendor_dir.clone();
-
- cfg.merge(&BTreeMap::new()).unwrap();
-
- assert_eq!(cfg.vendor_dir, original_vendor);
- }
-
- #[test]
- fn test_reference_resolution_bin_dir() {
- let mut cfg = Config::default();
- // bin-dir default is "{$vendor-dir}/bin"; vendor-dir default is "vendor"
- resolve_references(&mut cfg);
-
- assert_eq!(cfg.bin_dir, "vendor/bin");
- }
-
- #[test]
- fn test_reference_resolution_custom_vendor_dir() {
- let mut cfg = Config::default();
-
- cfg.vendor_dir = "lib".to_string();
- resolve_references(&mut cfg);
-
- assert_eq!(cfg.bin_dir, "lib/bin");
- }
-
- #[test]
- fn test_reference_resolution_cache_dirs() {
- let mut cfg = Config::default();
- // Inject a predictable home so the test is environment-independent.
- cfg.cache_dir = "/home/user/.cache/composer".to_string();
- resolve_references(&mut cfg);
-
- assert_eq!(cfg.cache_files_dir, "/home/user/.cache/composer/files");
- assert_eq!(cfg.cache_repo_dir, "/home/user/.cache/composer/repo");
- assert_eq!(cfg.cache_vcs_dir, "/home/user/.cache/composer/vcs");
- }
-
- #[test]
- fn test_reference_resolution_no_change_for_non_string() {
- let mut cfg = Config::default();
- let before = cfg.process_timeout;
- resolve_references(&mut cfg);
- assert_eq!(cfg.process_timeout, before);
- }
-
- #[test]
- fn test_get_existing_key() {
- let cfg = Config::default();
- let value = cfg.get("vendor-dir");
- assert!(value.is_some());
- assert_eq!(value.unwrap(), serde_json::json!("vendor"));
- }
-
- #[test]
- fn test_get_nonexistent_key_returns_none() {
- let cfg = Config::default();
- assert!(cfg.get("does-not-exist").is_none());
- }
-
- #[test]
- fn test_render_value_string() {
- assert_eq!(render_value(&serde_json::json!("hello")), "hello");
- }
-
- #[test]
- fn test_render_value_bool() {
- assert_eq!(render_value(&serde_json::json!(true)), "true");
- assert_eq!(render_value(&serde_json::json!(false)), "false");
- }
-
- #[test]
- fn test_render_value_number() {
- assert_eq!(render_value(&serde_json::json!(300)), "300");
- }
-
- #[test]
- fn test_render_value_null() {
- assert_eq!(render_value(&serde_json::Value::Null), "null");
- }
-
- #[test]
- fn test_render_value_array() {
- let v = serde_json::json!(["https", "ssh", "git"]);
- assert_eq!(render_value(&v), r#"["https","ssh","git"]"#);
- }
-
- #[test]
- fn test_render_value_empty_object() {
- assert_eq!(render_value(&serde_json::json!({})), "{}");
- }
-
- #[test]
- fn test_load_config_section_absent_file() {
- let path = std::path::Path::new("/tmp/nonexistent_composer_abc123.json");
- let result = load_config_section(path).unwrap();
- assert!(result.is_empty());
- }
-
- #[test]
- fn test_load_config_section_with_config_key() {
- use std::io::Write;
- use tempfile::NamedTempFile;
-
- let mut f = NamedTempFile::new().unwrap();
- write!(
- f,
- r#"{{"name":"test/pkg","config":{{"sort-packages":true,"vendor-dir":"packages"}}}}"#
- )
- .unwrap();
-
- let result = load_config_section(f.path()).unwrap();
- assert_eq!(result.get("sort-packages"), Some(&serde_json::json!(true)));
- assert_eq!(
- result.get("vendor-dir"),
- Some(&serde_json::json!("packages"))
- );
- }
-
- #[test]
- fn test_load_config_section_missing_config_key() {
- use std::io::Write;
- use tempfile::NamedTempFile;
-
- let mut f = NamedTempFile::new().unwrap();
- write!(f, r#"{{"name":"test/pkg","require":{{}}}}"#).unwrap();
-
- let result = load_config_section(f.path()).unwrap();
- assert!(result.is_empty());
- }
-
- #[test]
- fn test_full_pipeline_project_overrides_are_applied() {
- use std::io::Write;
- use tempfile::TempDir;
-
- let dir = TempDir::new().unwrap();
- let composer_json = dir.path().join("composer.json");
- let mut f = std::fs::File::create(&composer_json).unwrap();
- write!(
- f,
- r#"{{"name":"test/pkg","config":{{"vendor-dir":"custom_vendor","sort-packages":true}}}}"#
- )
- .unwrap();
-
- let overrides = load_config_section(&composer_json).unwrap();
- let mut cfg = Config::default();
- cfg.merge(&overrides).unwrap();
- resolve_references(&mut cfg);
-
- assert_eq!(cfg.vendor_dir, "custom_vendor");
- assert_eq!(cfg.sort_packages, true);
- // bin-dir should have resolved against the overridden vendor-dir
- assert_eq!(cfg.bin_dir, "custom_vendor/bin");
- }
-
- #[test]
- fn test_match_repository_key_full() {
- assert_eq!(match_repository_key("repositories.foo"), Some("foo"));
- assert_eq!(match_repository_key("repos.foo"), Some("foo"));
- assert_eq!(match_repository_key("repo.foo"), Some("foo"));
- }
-
- #[test]
- fn test_match_repository_key_no_match() {
- assert_eq!(match_repository_key("vendor-dir"), None);
- assert_eq!(match_repository_key("repositories."), None);
- assert_eq!(match_repository_key("sort-packages"), None);
- }
-
- #[test]
- fn test_json_set_nested_simple() {
- let mut root = serde_json::json!({});
- json_set_nested(&mut root, "foo", serde_json::json!("bar"));
- assert_eq!(root["foo"], serde_json::json!("bar"));
- }
-
- #[test]
- fn test_json_set_nested_deep() {
- let mut root = serde_json::json!({});
- json_set_nested(&mut root, "extra.foo.bar", serde_json::json!(42));
- assert_eq!(root["extra"]["foo"]["bar"], serde_json::json!(42));
- }
-
- #[test]
- fn test_json_set_nested_overwrites() {
- let mut root = serde_json::json!({"config": {"sort-packages": false}});
- json_set_nested(&mut root, "config.sort-packages", serde_json::json!(true));
- assert_eq!(root["config"]["sort-packages"], serde_json::json!(true));
- }
-
- #[test]
- fn test_json_remove_nested_simple() {
- let mut root = serde_json::json!({"foo": "bar"});
- let removed = json_remove_nested(&mut root, "foo");
- assert!(removed);
- assert!(root.get("foo").is_none());
- }
-
- #[test]
- fn test_json_remove_nested_deep() {
- let mut root = serde_json::json!({"config": {"sort-packages": true}});
- let removed = json_remove_nested(&mut root, "config.sort-packages");
- assert!(removed);
- assert!(root["config"].get("sort-packages").is_none());
- }
-
- #[test]
- fn test_json_remove_nested_nonexistent() {
- let mut root = serde_json::json!({"foo": "bar"});
- let removed = json_remove_nested(&mut root, "nonexistent");
- assert!(!removed);
- }
-
- #[test]
- fn test_validate_bool_true() {
- let result = validate_and_normalize("sort-packages", "true", &ConfigValueType::Bool);
- assert_eq!(result.unwrap(), serde_json::json!(true));
- }
-
- #[test]
- fn test_validate_bool_false() {
- let result = validate_and_normalize("sort-packages", "0", &ConfigValueType::Bool);
- assert_eq!(result.unwrap(), serde_json::json!(false));
- }
-
- #[test]
- fn test_validate_invalid_bool() {
- let result = validate_and_normalize("sort-packages", "maybe", &ConfigValueType::Bool);
- assert!(result.is_err());
- }
-
- #[test]
- fn test_validate_integer() {
- let result = validate_and_normalize("process-timeout", "600", &ConfigValueType::Integer);
- assert_eq!(result.unwrap(), serde_json::json!(600));
- }
-
- #[test]
- fn test_validate_invalid_integer() {
- let result = validate_and_normalize("process-timeout", "abc", &ConfigValueType::Integer);
- assert!(result.is_err());
- }
-
- #[test]
- fn test_validate_enum_valid() {
- let result = validate_and_normalize(
- "preferred-install",
- "source",
- &ConfigValueType::Enum(&["auto", "source", "dist"]),
- );
- assert_eq!(result.unwrap(), serde_json::json!("source"));
- }
-
- #[test]
- fn test_validate_enum_invalid() {
- let result = validate_and_normalize(
- "preferred-install",
- "invalid",
- &ConfigValueType::Enum(&["auto", "source", "dist"]),
- );
- assert!(result.is_err());
- }
-
- #[test]
- fn test_validate_bool_or_enum_stash() {
- let result = validate_and_normalize(
- "discard-changes",
- "stash",
- &ConfigValueType::BoolOrEnum(&["stash"]),
- );
- assert_eq!(result.unwrap(), serde_json::json!("stash"));
- }
-
- #[test]
- fn test_validate_bool_or_enum_bool() {
- let result = validate_and_normalize(
- "discard-changes",
- "true",
- &ConfigValueType::BoolOrEnum(&["stash"]),
- );
- assert_eq!(result.unwrap(), serde_json::json!(true));
- }
-
- #[test]
- fn test_validate_autoloader_suffix_null() {
- let result = validate_and_normalize("autoloader-suffix", "null", &ConfigValueType::Str);
- assert_eq!(result.unwrap(), serde_json::Value::Null);
- }
-
- #[test]
- fn test_validate_multi_string_array() {
- let values = vec!["a".to_string(), "b".to_string()];
- let result =
- validate_and_normalize_multi("github-domains", &values, &ConfigValueType::StringArray);
- assert_eq!(result.unwrap(), serde_json::json!(["a", "b"]));
- }
-
- #[test]
- fn test_validate_multi_enum_array_valid() {
- let values = vec!["https".to_string(), "ssh".to_string()];
- let result = validate_and_normalize_multi(
- "github-protocols",
- &values,
- &ConfigValueType::EnumArray(&["git", "https", "ssh"]),
- );
- assert_eq!(result.unwrap(), serde_json::json!(["https", "ssh"]));
- }
-
- #[test]
- fn test_validate_multi_enum_array_invalid() {
- let values = vec!["https".to_string(), "ftp".to_string()];
- let result = validate_and_normalize_multi(
- "github-protocols",
- &values,
- &ConfigValueType::EnumArray(&["git", "https", "ssh"]),
- );
- assert!(result.is_err());
- }
-
- fn make_empty_json() -> serde_json::Value {
- serde_json::json!({})
- }
-
- fn make_config_args_default() -> ConfigArgs {
- ConfigArgs {
- setting_key: None,
- setting_value: vec![],
- global: false,
- editor: false,
- auth: false,
- unset: false,
- list: false,
- file: None,
- absolute: false,
- json: false,
- merge: false,
- append: false,
- source: false,
- }
- }
-
- #[test]
- fn test_set_bool_config_value() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "sort-packages", &["true".to_string()], &args).unwrap();
- assert_eq!(json["config"]["sort-packages"], serde_json::json!(true));
- }
-
- #[test]
- fn test_set_integer_config_value() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "process-timeout", &["600".to_string()], &args).unwrap();
- assert_eq!(json["config"]["process-timeout"], serde_json::json!(600));
- }
-
- #[test]
- fn test_set_string_config_value() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "vendor-dir", &["lib".to_string()], &args).unwrap();
- assert_eq!(json["config"]["vendor-dir"], serde_json::json!("lib"));
- }
-
- #[test]
- fn test_set_enum_config_value() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "preferred-install",
- &["source".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["config"]["preferred-install"],
- serde_json::json!("source")
- );
- }
-
- #[test]
- fn test_set_bool_or_enum_stash() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "discard-changes", &["stash".to_string()], &args).unwrap();
- assert_eq!(
- json["config"]["discard-changes"],
- serde_json::json!("stash")
- );
- }
-
- #[test]
- fn test_set_bool_or_enum_bool() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "discard-changes", &["true".to_string()], &args).unwrap();
- assert_eq!(json["config"]["discard-changes"], serde_json::json!(true));
- }
-
- #[test]
- fn test_set_multi_value() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "github-protocols",
- &["https".to_string(), "ssh".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["config"]["github-protocols"],
- serde_json::json!(["https", "ssh"])
- );
- }
-
- #[test]
- fn test_set_invalid_bool_value() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- let result = execute_set(&mut json, "sort-packages", &["maybe".to_string()], &args);
- assert!(result.is_err());
- }
-
- #[test]
- fn test_set_invalid_enum_value() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- let result = execute_set(
- &mut json,
- "preferred-install",
- &["invalid".to_string()],
- &args,
- );
- assert!(result.is_err());
- }
-
- #[test]
- fn test_set_too_many_values() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- let result = execute_set(
- &mut json,
- "sort-packages",
- &["true".to_string(), "false".to_string()],
- &args,
- );
- assert!(result.is_err());
- }
-
- #[test]
- fn test_unset_config_value() {
- let mut json = serde_json::json!({"config": {"sort-packages": true}});
- let args = make_config_args_default();
- execute_unset(&mut json, "sort-packages", &args).unwrap();
- assert!(json["config"].get("sort-packages").is_none());
- }
-
- #[test]
- fn test_unset_nonexistent_key() {
- // A4: unknown top-level single-segment key is silently removed (mirrors Composer 920-924)
- let mut json = make_empty_json();
- let args = make_config_args_default();
- let result = execute_unset(&mut json, "unknown-key-xyz", &args);
- assert!(result.is_ok());
- }
-
- #[test]
- fn test_set_package_property_name() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "name", &["vendor/pkg".to_string()], &args).unwrap();
- assert_eq!(json["name"], serde_json::json!("vendor/pkg"));
- }
-
- #[test]
- fn test_set_minimum_stability() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "minimum-stability", &["dev".to_string()], &args).unwrap();
- assert_eq!(json["minimum-stability"], serde_json::json!("dev"));
- }
-
- #[test]
- fn test_set_prefer_stable() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "prefer-stable", &["true".to_string()], &args).unwrap();
- assert_eq!(json["prefer-stable"], serde_json::json!(true));
- }
-
- #[test]
- fn test_set_keywords() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "keywords",
- &["php".to_string(), "cli".to_string(), "tool".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(json["keywords"], serde_json::json!(["php", "cli", "tool"]));
- }
-
- #[test]
- fn test_set_package_property_global_error() {
- let mut json = make_empty_json();
- let mut args = make_config_args_default();
- args.global = true;
- let result = execute_set(&mut json, "name", &["vendor/pkg".to_string()], &args);
- assert!(result.is_err());
- }
-
- #[test]
- fn test_unset_package_property() {
- let mut json = serde_json::json!({"description": "A test package"});
- let args = make_config_args_default();
- execute_unset(&mut json, "description", &args).unwrap();
- assert!(json.get("description").is_none());
- }
-
- #[test]
- fn test_add_repository() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "repositories.foo",
- &["vcs".to_string(), "https://bar.com".to_string()],
- &args,
- )
- .unwrap();
-
- let repos = json["repositories"].as_array().unwrap();
- assert_eq!(repos.len(), 1);
- assert_eq!(repos[0]["name"], serde_json::json!("foo"));
- assert_eq!(repos[0]["type"], serde_json::json!("vcs"));
- assert_eq!(repos[0]["url"], serde_json::json!("https://bar.com"));
- }
-
- #[test]
- fn test_add_repository_prepend() {
- let mut json = serde_json::json!({
- "repositories": [{"name": "existing", "type": "vcs", "url": "https://existing.com"}]
- });
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "repositories.new",
- &["vcs".to_string(), "https://new.com".to_string()],
- &args,
- )
- .unwrap();
-
- let repos = json["repositories"].as_array().unwrap();
- assert_eq!(repos[0]["name"], serde_json::json!("new"));
- assert_eq!(repos[1]["name"], serde_json::json!("existing"));
- }
-
- #[test]
- fn test_add_repository_append() {
- let mut json = serde_json::json!({
- "repositories": [{"name": "existing", "type": "vcs", "url": "https://existing.com"}]
- });
- let mut args = make_config_args_default();
- args.append = true;
- execute_set(
- &mut json,
- "repositories.new",
- &["vcs".to_string(), "https://new.com".to_string()],
- &args,
- )
- .unwrap();
-
- let repos = json["repositories"].as_array().unwrap();
- assert_eq!(repos[0]["name"], serde_json::json!("existing"));
- assert_eq!(repos[1]["name"], serde_json::json!("new"));
- }
-
- #[test]
- fn test_add_repository_replace_existing() {
- let mut json = serde_json::json!({
- "repositories": [{"name": "foo", "type": "vcs", "url": "https://old.com"}]
- });
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "repositories.foo",
- &["vcs".to_string(), "https://new.com".to_string()],
- &args,
- )
- .unwrap();
-
- let repos = json["repositories"].as_array().unwrap();
- assert_eq!(repos.len(), 1);
- assert_eq!(repos[0]["url"], serde_json::json!("https://new.com"));
- }
-
- #[test]
- fn test_disable_repository() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "repositories.packagist.org",
- &["false".to_string()],
- &args,
- )
- .unwrap();
-
- let repos = json["repositories"].as_array().unwrap();
- assert_eq!(repos.len(), 1);
- assert_eq!(repos[0]["packagist.org"], serde_json::json!(false));
- }
-
- #[test]
- fn test_remove_repository() {
- let mut json = serde_json::json!({
- "repositories": [{"name": "foo", "type": "vcs", "url": "https://bar.com"}]
- });
- let args = make_config_args_default();
- execute_unset(&mut json, "repo.foo", &args).unwrap();
-
- // Array removed when empty
- assert!(json.get("repositories").is_none());
- }
-
- #[test]
- fn test_repo_alias() {
- assert_eq!(match_repository_key("repo.foo"), Some("foo"));
- assert_eq!(match_repository_key("repos.foo"), Some("foo"));
- assert_eq!(match_repository_key("repositories.foo"), Some("foo"));
- }
-
- #[test]
- fn test_set_extra_property() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "extra.key", &["value".to_string()], &args).unwrap();
- assert_eq!(json["extra"]["key"], serde_json::json!("value"));
- }
-
- #[test]
- fn test_set_extra_json() {
- let mut json = make_empty_json();
- let mut args = make_config_args_default();
- args.json = true;
- execute_set(&mut json, "extra.key", &[r#"{"a":1}"#.to_string()], &args).unwrap();
- assert_eq!(json["extra"]["key"], serde_json::json!({"a": 1}));
- }
-
- #[test]
- fn test_set_extra_merge_objects() {
- let mut json = serde_json::json!({"extra": {"key": {"x": 1}}});
- let mut args = make_config_args_default();
- args.json = true;
- args.merge = true;
- execute_set(&mut json, "extra.key", &[r#"{"y":2}"#.to_string()], &args).unwrap();
- assert_eq!(json["extra"]["key"]["x"], serde_json::json!(1));
- assert_eq!(json["extra"]["key"]["y"], serde_json::json!(2));
- }
-
- #[test]
- fn test_set_extra_merge_arrays() {
- let mut json = serde_json::json!({"extra": {"key": [1, 2]}});
- let mut args = make_config_args_default();
- args.json = true;
- args.merge = true;
- execute_set(&mut json, "extra.key", &["[3, 4]".to_string()], &args).unwrap();
- assert_eq!(json["extra"]["key"], serde_json::json!([1, 2, 3, 4]));
- }
-
- #[test]
- fn test_set_suggest() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "suggest.vendor/pkg",
- &["for".to_string(), "testing".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["suggest"]["vendor/pkg"],
- serde_json::json!("for testing")
- );
- }
-
- #[test]
- fn test_unset_extra() {
- let mut json = serde_json::json!({"extra": {"key": "value"}});
- let args = make_config_args_default();
- execute_unset(&mut json, "extra.key", &args).unwrap();
- assert!(json["extra"].get("key").is_none());
- }
-
- #[test]
- fn test_set_platform_php() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(&mut json, "platform.php", &["8.1.0".to_string()], &args).unwrap();
- assert_eq!(
- json["config"]["platform"]["php"],
- serde_json::json!("8.1.0")
- );
- }
-
- #[test]
- fn test_unset_platform_php() {
- let mut json = serde_json::json!({"config": {"platform": {"php": "8.1.0"}}});
- let args = make_config_args_default();
- execute_unset(&mut json, "platform.php", &args).unwrap();
- assert!(json["config"]["platform"].get("php").is_none());
- }
-
- #[test]
- fn test_set_preferred_install_per_package() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "preferred-install.vendor/*",
- &["source".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["config"]["preferred-install"]["vendor/*"],
- serde_json::json!("source")
- );
- }
-
- #[test]
- fn test_set_allow_plugins() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "allow-plugins.vendor/plugin",
- &["true".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["config"]["allow-plugins"]["vendor/plugin"],
- serde_json::json!(true)
- );
- }
-
- #[test]
- fn test_global_config_creates_file() {
- use tempfile::TempDir;
-
- let dir = TempDir::new().unwrap();
- let config_file = dir.path().join("config.json");
-
- // Start from an empty/nonexistent file
- let mut json = read_json_file(&config_file, true).unwrap();
- let args = make_config_args_default();
- execute_set(&mut json, "sort-packages", &["true".to_string()], &args).unwrap();
- write_json_file(&config_file, &json).unwrap();
-
- assert!(config_file.exists());
- let written: serde_json::Value =
- serde_json::from_str(&std::fs::read_to_string(&config_file).unwrap()).unwrap();
- assert_eq!(written["config"]["sort-packages"], serde_json::json!(true));
- }
-
- #[test]
- fn test_global_config_set_and_read() {
- use tempfile::TempDir;
-
- let dir = TempDir::new().unwrap();
- let config_file = dir.path().join("config.json");
-
- // Write
- let mut json = read_json_file(&config_file, true).unwrap();
- let args = make_config_args_default();
- execute_set(&mut json, "vendor-dir", &["custom-lib".to_string()], &args).unwrap();
- write_json_file(&config_file, &json).unwrap();
-
- // Read back
- let json2 = read_json_file(&config_file, true).unwrap();
- assert_eq!(
- json2["config"]["vendor-dir"],
- serde_json::json!("custom-lib")
- );
- }
-
- #[test]
- fn test_read_json_file_missing_global() {
- let path = std::path::Path::new("/tmp/nonexistent_global_abc123.json");
- let v = read_json_file(path, true).unwrap();
- assert!(v["config"].is_object());
- }
-
- #[test]
- fn test_read_json_file_missing_local() {
- let path = std::path::Path::new("/tmp/nonexistent_local_abc123.json");
- let v = read_json_file(path, false).unwrap();
- assert!(v.is_object());
- assert!(v.get("config").is_none());
- }
-
- // --- A2: audit.ignore / audit.ignore-abandoned ---
-
- #[test]
- fn test_set_audit_ignore_simple() {
- let mut json = make_empty_json();
- let mut args = make_config_args_default();
- args.json = true;
- execute_set(
- &mut json,
- "audit.ignore",
- &[r#"["CVE-2024-AAAA"]"#.to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["config"]["audit"]["ignore"],
- serde_json::json!(["CVE-2024-AAAA"])
- );
- }
-
- #[test]
- fn test_set_audit_ignore_merge_arrays() {
- let mut json = serde_json::json!({"config": {"audit": {"ignore": ["CVE-2024-AAAA"]}}});
- let mut args = make_config_args_default();
- args.json = true;
- args.merge = true;
- execute_set(
- &mut json,
- "audit.ignore",
- &[r#"["CVE-2024-XXXX"]"#.to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["config"]["audit"]["ignore"],
- serde_json::json!(["CVE-2024-AAAA", "CVE-2024-XXXX"])
- );
- }
-
- #[test]
- fn test_set_audit_ignore_merge_list_object_error() {
- let mut json = serde_json::json!({"config": {"audit": {"ignore": ["CVE-2024-AAAA"]}}});
- let mut args = make_config_args_default();
- args.json = true;
- args.merge = true;
- let result = execute_set(
- &mut json,
- "audit.ignore",
- &[r#"{"pkg/name": "reason"}"#.to_string()],
- &args,
- );
- assert!(result.is_err());
- }
-
- // --- A3: scripts.X ---
-
- #[test]
- fn test_set_scripts_single() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "scripts.post-install-cmd",
- &["echo done".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["scripts"]["post-install-cmd"],
- serde_json::json!("echo done")
- );
- }
-
- #[test]
- fn test_set_scripts_multi() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "scripts.post-install-cmd",
- &["echo a".to_string(), "echo b".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["scripts"]["post-install-cmd"],
- serde_json::json!(["echo a", "echo b"])
- );
- }
-
- #[test]
- fn test_unset_scripts() {
- let mut json = serde_json::json!({"scripts": {"post-install-cmd": "echo done"}});
- let args = make_config_args_default();
- execute_unset(&mut json, "scripts.post-install-cmd", &args).unwrap();
- assert!(json["scripts"].get("post-install-cmd").is_none());
- }
-
- // --- A4: top-level --unset fallback ---
-
- #[test]
- fn test_unset_unknown_top_level_key_succeeds() {
- let mut json = serde_json::json!({"my-custom-field": "value"});
- let args = make_config_args_default();
- execute_unset(&mut json, "my-custom-field", &args).unwrap();
- assert!(json.get("my-custom-field").is_none());
- }
-
- // --- A5: bare extra / suggest / audit ---
-
- #[test]
- fn test_unset_extra_bare() {
- let mut json = serde_json::json!({"extra": {"key": "value"}});
- let args = make_config_args_default();
- execute_unset(&mut json, "extra", &args).unwrap();
- assert!(json.get("extra").is_none());
- }
-
- #[test]
- fn test_unset_suggest_bare() {
- let mut json = serde_json::json!({"suggest": {"vendor/pkg": "reason"}});
- let args = make_config_args_default();
- execute_unset(&mut json, "suggest", &args).unwrap();
- assert!(json.get("suggest").is_none());
- }
-
- #[test]
- fn test_unset_audit_bare() {
- let mut json = serde_json::json!({"config": {"audit": {"abandoned": "report"}}});
- let args = make_config_args_default();
- execute_unset(&mut json, "audit", &args).unwrap();
- assert!(json["config"].get("audit").is_none());
- }
-
- // --- A10: cache-files-maxsize validation ---
-
- #[test]
- fn test_cache_files_maxsize_valid() {
- for v in &["512M", "512MB", "512MiB", "1g", "1GiB", "100", "1.5k"] {
- let result =
- validate_and_normalize("cache-files-maxsize", v, &ConfigValueType::SizeString);
- assert!(result.is_ok(), "expected ok for {v}");
- }
- }
-
- #[test]
- fn test_cache_files_maxsize_invalid() {
- let result =
- validate_and_normalize("cache-files-maxsize", "abc", &ConfigValueType::SizeString);
- assert!(result.is_err());
- }
-
- // --- A14: merge_json_values existing-wins ---
-
- #[test]
- fn test_merge_objects_existing_wins() {
- // Composer PHP `+` semantics: existing keys take precedence
- let existing = serde_json::json!({"a": 1, "b": 2});
- let new_val = serde_json::json!({"a": 99, "c": 3});
- let result = merge_json_values(Some(&existing), &new_val).unwrap();
- assert_eq!(result["a"], serde_json::json!(1)); // existing wins
- assert_eq!(result["b"], serde_json::json!(2));
- assert_eq!(result["c"], serde_json::json!(3)); // new key added
- }
-
- // --- A11: cafile / capath null clearing ---
-
- #[test]
- fn test_cafile_null_clears() {
- let result = validate_and_normalize("cafile", "null", &ConfigValueType::FilePath);
- assert_eq!(result.unwrap(), serde_json::Value::Null);
- }
-
- #[test]
- fn test_capath_null_clears() {
- let result = validate_and_normalize("capath", "null", &ConfigValueType::DirPath);
- assert_eq!(result.unwrap(), serde_json::Value::Null);
- }
-
- // --- A16: repositories.<name>.url ---
-
- #[test]
- fn test_set_repository_url() {
- let mut json = serde_json::json!({
- "repositories": [{"name": "foo", "type": "vcs", "url": "https://old.com"}]
- });
- let args = make_config_args_default();
- execute_set(
- &mut json,
- "repositories.foo.url",
- &["https://new.com".to_string()],
- &args,
- )
- .unwrap();
- assert_eq!(
- json["repositories"][0]["url"],
- serde_json::json!("https://new.com")
- );
- }
-
- #[test]
- fn test_set_repository_url_not_found() {
- let mut json = serde_json::json!({"repositories": []});
- let args = make_config_args_default();
- let result = execute_set(
- &mut json,
- "repositories.nonexistent.url",
- &["https://x.com".to_string()],
- &args,
- );
- assert!(result.is_err());
- }
-
- // --- A19: add_repository with name injection and assoc-form normalization ---
-
- #[test]
- fn test_add_repository_injects_name() {
- let mut json = make_empty_json();
- let args = make_config_args_default();
- // Passing config without "name" field
- execute_set(
- &mut json,
- "repositories.myrepo",
- &["vcs".to_string(), "https://example.com".to_string()],
- &args,
- )
- .unwrap();
- let repos = json["repositories"].as_array().unwrap();
- assert_eq!(repos[0]["name"], serde_json::json!("myrepo"));
- }
-}