//! 真实 CLI 参数分派及 Package/Lib 双向锁合并,不安装全局运行时。 use super::super::commands::Services; use super::python_fixture::Python; use dever::compiler::project::dependency::{self, Lock}; use std::process::Command; #[test] fn package_changes_preserve_lib_closure_and_lib_changes_preserve_packages() { let mut python = Python::new(); python.transport.release("alpha", "1.0.0", ""); python.transport.release("beta", "1.0.0", ""); python.command("add", &["pip:alpha@1.0.0"]).unwrap(); let before = python.lock(); let mut packages = Services::default(); packages.release("numbers", "1.0.0", &[]); packages.release("numbers", "2.0.0", &[]); let root = &python.fixture.directory.0; for (action, specs, version) in [ ("add", vec!["numbers@^1".into()], "1.0.0"), ("update", vec!["numbers@^2".into()], "2.0.0"), ] { dependency::execute_with(action, root, &specs, &packages, &python.store).unwrap(); let lock = python.lock(); assert!(lock.libs == before.libs); assert_eq!(lock.packages[0].version, version); } let packages_before = serde_json::to_value(python.lock().packages).unwrap(); python.command("add", &["pip:beta@1.0.0"]).unwrap(); python.command("remove", &["pip:alpha@1.0.0"]).unwrap(); assert_eq!( serde_json::to_value(python.lock().packages).unwrap(), packages_before ); dependency::execute_with( "remove", root, &["numbers".into()], &packages, &python.store, ) .unwrap(); assert!(python.lock().packages.is_empty()); assert_eq!(python.lock().libs[0].spec.name, "beta"); python.command("doctor", &[]).unwrap(); } #[test] fn actual_cli_routes_lib_install_doctor_list_and_rejects_bad_target_arguments() { let python = Python::new(); let root = &python.fixture.directory.0; std::fs::write(root.join("dever.lock"), Lock::new(vec![]).encode().unwrap()).unwrap(); let lock = std::fs::read(root.join("dever.lock")).unwrap(); let setting = std::fs::read(root.join("config/setting.json")).unwrap(); for action in ["doctor", "list", "install"] { let output = Command::new(env!("CARGO_BIN_EXE_dever")) .env_clear() .arg("lib") .arg(action) .arg(root) .output() .unwrap(); assert!( output.status.success(), "{action}: {}", String::from_utf8_lossy(&output.stderr) ); if action != "list" { assert!(String::from_utf8_lossy(&output.stdout).contains("validated 0 Lib(s)")); } if action != "install" { assert!(!root.join(".dever-project.lock").exists()); } } for arguments in [ vec!["list", "--target", "linux-x86_64"], vec!["doctor", "--target"], vec!["doctor", "--target", "invalid-target"], vec![ "doctor", "--target", "linux-x86_64", "--target", "linux-x86_64", ], vec!["install", "pip:unexpected@1.0.0"], ] { let output = Command::new(env!("CARGO_BIN_EXE_dever")) .env_clear() .arg("lib") .arg(arguments[0]) .arg(root) .args(&arguments[1..]) .output() .unwrap(); assert!(!output.status.success(), "accepted {arguments:?}"); } assert_eq!(std::fs::read(root.join("dever.lock")).unwrap(), lock); assert_eq!( std::fs::read(root.join("config/setting.json")).unwrap(), setting ); } #[test] fn official_registry_rejects_ambiguous_urls_before_transport() { use dependency::library::registry::official; assert!(official("https://proxy.golang.org/example.com/mod/@v/v1.0.0.zip").is_ok()); for value in [ "https://pypi.org:443/pypi/a/json", "https://@pypi.org/pypi/a/json", "https://pypi.org/x/%2e%2e/pypi/a/json", "https://pypi.org/x%2fpypi/a/json", "https://pypi.org/../pypi/a/json", "https://pypi.org/pypi/a/json?secret=value", "https://pypi.org/pypi/a/json#fragment", "https://pypi.org.evil.test/pypi/a/json", " http://pypi.org/pypi/a/json", "https://pypi.org\\evil.test/pypi/a/json", ] { assert!(official(value).is_err(), "accepted ambiguous registry URL"); } }