CI / fmt (rustfmt --check) (push) Canceled after 0s
CI / clippy (ubuntu-latest) (push) Canceled after 0s
CI / clippy (windows-latest) (push) Canceled after 0s
CI / test (ubuntu-latest) (push) Canceled after 0s
CI / test (windows-latest) (push) Canceled after 0s
CI / build release (ubuntu-latest) (push) Canceled after 0s
CI / build release (windows-latest) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent), MCP server 接入外部 Agent 工具,GUI 开发中。
127 lines
4.0 KiB
Rust
127 lines
4.0 KiB
Rust
//! `core::game::java::discover`:标准安装位置扫描与来源优先级。
|
||
//!
|
||
//! 真机上扫到什么取决于本机装了什么,所以断言只钉**不变量**:
|
||
//! 扫描结果形状、来源优先级(env 胜过扫盘)、去重保留高优先级、缺目录不报错。
|
||
|
||
use unlucky_core::game::java::discover;
|
||
use unlucky_core::game::java::mapping::{JavaRequirement, RequirementSource};
|
||
use unlucky_core::game::java::{pick, JavaOrigin, JavaRuntime};
|
||
|
||
fn runtime(path: &str, major: u32, origin: JavaOrigin) -> JavaRuntime {
|
||
JavaRuntime {
|
||
binary: std::path::PathBuf::from(path),
|
||
origin,
|
||
version: Some(format!("openjdk version \"{major}.0.1\"")),
|
||
major: Some(major),
|
||
bits: 64,
|
||
vendor: None,
|
||
}
|
||
}
|
||
|
||
fn at_least(minimum: u32) -> JavaRequirement {
|
||
JavaRequirement::new(minimum, None, RequirementSource::Table)
|
||
}
|
||
|
||
#[test]
|
||
fn scanned_paths_always_point_at_a_java_binary() {
|
||
// 本机可能一个都没有(裸机/容器)——那也算通过,只是列表为空。
|
||
for binary in discover::scan_java_binaries() {
|
||
assert!(
|
||
binary.is_file(),
|
||
"扫描结果必须是真实存在的文件:{}",
|
||
binary.display()
|
||
);
|
||
assert_eq!(
|
||
binary
|
||
.file_name()
|
||
.map(|name| name.to_string_lossy().into_owned()),
|
||
Some(unlucky_core::game::java::java_binary_name().to_string()),
|
||
"扫描结果必须是 bin/java[.exe]:{}",
|
||
binary.display()
|
||
);
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn standard_roots_are_absolute_and_unique() {
|
||
let roots = discover::standard_roots();
|
||
for root in &roots {
|
||
assert!(
|
||
root.is_absolute(),
|
||
"候选根必须是绝对路径:{}",
|
||
root.display()
|
||
);
|
||
}
|
||
let mut keys: Vec<String> = roots.iter().map(|root| discover::path_key(root)).collect();
|
||
let total = keys.len();
|
||
keys.sort();
|
||
keys.dedup();
|
||
assert_eq!(keys.len(), total, "候选根不该重复");
|
||
}
|
||
|
||
#[test]
|
||
fn environment_java_beats_scanned_java_when_both_satisfy() {
|
||
// D13 的「优先级链不变」:环境变量是用户意图,扫盘只是候选。
|
||
let candidates = [
|
||
runtime(
|
||
"C:/Program Files/Eclipse Adoptium/jdk-21/bin/java.exe",
|
||
21,
|
||
JavaOrigin::System,
|
||
),
|
||
runtime(
|
||
"C:/Program Files/Microsoft/jdk-21/bin/java.exe",
|
||
21,
|
||
JavaOrigin::JavaHome,
|
||
),
|
||
];
|
||
let picked = pick(&candidates, &at_least(17)).expect("应有候选");
|
||
assert_eq!(picked.origin, JavaOrigin::JavaHome);
|
||
}
|
||
|
||
#[test]
|
||
fn scanned_java_is_still_used_when_nothing_else_matches() {
|
||
// MSI 装了 Temurin 21、没设环境变量、PATH 上是 Java 8:1.20.5 只认扫盘那个。
|
||
let candidates = [
|
||
runtime("java", 8, JavaOrigin::Path),
|
||
runtime(
|
||
"C:/Program Files/Java/jdk-21/bin/java.exe",
|
||
21,
|
||
JavaOrigin::System,
|
||
),
|
||
];
|
||
let picked = pick(&candidates, &at_least(21)).expect("应有候选");
|
||
assert_eq!(picked.origin, JavaOrigin::System);
|
||
}
|
||
|
||
#[test]
|
||
fn dedupe_collapses_one_install_found_twice() {
|
||
// `JAVA_HOME` 指向 Program Files 里的 JDK → 同一个 java 不应列两次。
|
||
let candidates = discover::dedupe(vec![
|
||
runtime(
|
||
"C:/Program Files/Java/jdk-21/bin/java.exe",
|
||
21,
|
||
JavaOrigin::JavaHome,
|
||
),
|
||
runtime(
|
||
"c:/program files/java/jdk-21/bin/java.exe",
|
||
21,
|
||
JavaOrigin::System,
|
||
),
|
||
]);
|
||
assert_eq!(candidates.len(), 1);
|
||
assert_eq!(candidates[0].origin, JavaOrigin::JavaHome);
|
||
}
|
||
|
||
#[test]
|
||
fn registry_absence_is_tolerated() {
|
||
// 非 Windows 必然为空;Windows 上没装老 Oracle JDK 也是空。
|
||
let homes = discover::registry_homes();
|
||
for home in &homes {
|
||
assert!(
|
||
home.is_absolute(),
|
||
"注册表里的 JavaHome 应是绝对路径:{}",
|
||
home.display()
|
||
);
|
||
}
|
||
}
|