Unlucky Launcher v0.2.0
CI / fmt (rustfmt --check) (push) Waiting to run
CI / clippy (ubuntu-latest) (push) Waiting to run
CI / clippy (windows-latest) (push) Waiting to run
CI / test (ubuntu-latest) (push) Waiting to run
CI / test (windows-latest) (push) Waiting to run
CI / build release (ubuntu-latest) (push) Waiting to run
CI / build release (windows-latest) (push) Waiting to run
CI / runtime smoke (ubuntu x64, xvfb) (push) Waiting to run
CI / runtime smoke (macos arm64, probe) (push) Skipped
Guards / core 零 UI 守门 (push) Waiting to run
Guards / presenter 零 UI 守门 (push) Waiting to run
Guards / design 零第三方依赖守门 (push) Waiting to run
Guards / unsafe 落点守门(集合必须恰好一个文件) (push) Waiting to run
Guards / 文件行数 ≤400 守门 (push) Waiting to run
Guards / 依赖许可与来源(cargo-deny) (push) Waiting to run
CI / fmt (rustfmt --check) (push) Waiting to run
CI / clippy (ubuntu-latest) (push) Waiting to run
CI / clippy (windows-latest) (push) Waiting to run
CI / test (ubuntu-latest) (push) Waiting to run
CI / test (windows-latest) (push) Waiting to run
CI / build release (ubuntu-latest) (push) Waiting to run
CI / build release (windows-latest) (push) Waiting to run
CI / runtime smoke (ubuntu x64, xvfb) (push) Waiting to run
CI / runtime smoke (macos arm64, probe) (push) Skipped
Guards / core 零 UI 守门 (push) Waiting to run
Guards / presenter 零 UI 守门 (push) Waiting to run
Guards / design 零第三方依赖守门 (push) Waiting to run
Guards / unsafe 落点守门(集合必须恰好一个文件) (push) Waiting to run
Guards / 文件行数 ≤400 守门 (push) Waiting to run
Guards / 依赖许可与来源(cargo-deny) (push) Waiting to run
首个 iced + Material 3 Expressive 版本的源码快照。 完整历史与日常提交在 dev 分支;main 只放阶段性快照。
This commit is contained in:
commit
8a8e5ca0c0
1079 files changed
+208035
No files matched your search
@@ -0,0 +1,115 @@
|
||||
//! D19/D21 支持基线:core 的纯判定函数 + CLI 的呈现层(注入样本,不动真机)。
|
||||
|
||||
use unlucky_cli::os;
|
||||
use unlucky_core::platform::linux_caps::{GlProbe, SessionKind};
|
||||
use unlucky_core::platform::os_info::{
|
||||
self, linux_level, macos_level, support_level_for, windows_level, OsFamily, OsInfo,
|
||||
SupportLevel,
|
||||
};
|
||||
use unlucky_core::platform::vk_probe::VkProbe;
|
||||
|
||||
/// 手工构造一份样本系统信息(字段全是探测事实,等级用 core 的纯函数算)。
|
||||
fn sample(family: OsFamily, version: Option<(u32, u32)>, product: &str) -> OsInfo {
|
||||
let version_string =
|
||||
version.map_or_else(String::new, |(major, minor)| format!("{major}.{minor}"));
|
||||
OsInfo {
|
||||
family,
|
||||
arch: "x86_64".to_string(),
|
||||
major_minor: version,
|
||||
build: None,
|
||||
product: product.to_string(),
|
||||
version_string,
|
||||
session: SessionKind::Unknown,
|
||||
gl: GlProbe::Unknown,
|
||||
vk: VkProbe::Unknown,
|
||||
kernel: None,
|
||||
glibc: None,
|
||||
support_level: support_level_for(family, version, None, None),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windows_samples_below_win10_are_unsupported() {
|
||||
// D21 用户拍板「直接 win10 起步」:Win8.1 / 8 / 7 及更旧一律不支持。
|
||||
assert_eq!(windows_level(Some((6, 1))), SupportLevel::Unsupported); // Win7
|
||||
assert_eq!(windows_level(Some((6, 2))), SupportLevel::Unsupported); // Win8
|
||||
assert_eq!(windows_level(Some((6, 3))), SupportLevel::Unsupported); // Win8.1
|
||||
assert_eq!(windows_level(Some((5, 1))), SupportLevel::Unsupported); // XP
|
||||
assert_eq!(windows_level(Some((10, 0))), SupportLevel::One); // Win10
|
||||
|
||||
// 探不到版本 → 保守判不支持(不能因为"探不到"就放行)。
|
||||
assert_eq!(windows_level(None), SupportLevel::Unsupported);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macos_and_linux_samples() {
|
||||
assert_eq!(macos_level(Some(11)), SupportLevel::Unsupported);
|
||||
assert_eq!(macos_level(Some(12)), SupportLevel::One);
|
||||
assert_eq!(macos_level(None), SupportLevel::Unsupported);
|
||||
// Linux:内核/glibc 探得到但过低 → 不支持;取不到(容器/musl/Termux)不阻塞。
|
||||
assert_eq!(linux_level(Some((2, 6)), None), SupportLevel::Unsupported);
|
||||
assert_eq!(linux_level(None, Some((2, 12))), SupportLevel::Unsupported);
|
||||
assert_eq!(linux_level(Some((6, 8)), Some((2, 39))), SupportLevel::One);
|
||||
assert_eq!(linux_level(None, None), SupportLevel::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsupported_sample_renders_upgrade_hint() {
|
||||
let info = sample(OsFamily::Windows, Some((6, 3)), "Windows 8.1");
|
||||
|
||||
assert!(!info.support_level.is_usable());
|
||||
let line = os::summary_line(&info);
|
||||
assert!(line.contains("Windows 8.1"), "{line}");
|
||||
assert!(line.contains("6.3"), "{line}");
|
||||
assert!(line.contains("不支持"), "{line}");
|
||||
|
||||
let notes = os::notes(&info);
|
||||
assert_eq!(notes.len(), 1);
|
||||
assert!(notes[0].contains("Windows 10 或更高版本"), "{notes:?}");
|
||||
|
||||
// 文案是中英双语(core 同一份措辞),脚本只读 --json。
|
||||
let message = info.describe().combined();
|
||||
assert!(message.contains("Windows 10 或更高版本"), "{message}");
|
||||
assert!(message.contains("Windows 10 or newer"), "{message}");
|
||||
|
||||
let value = os::to_json(&info);
|
||||
assert_eq!(value["family"], "windows");
|
||||
assert_eq!(value["product"], "Windows 8.1");
|
||||
assert_eq!(value["support"], "unsupported");
|
||||
assert_eq!(value["major_minor"], "6.3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn supported_sample_has_no_notes() {
|
||||
let info = sample(OsFamily::Windows, Some((10, 0)), "Windows 11");
|
||||
assert!(info.support_level.is_usable());
|
||||
assert!(os::notes(&info).is_empty());
|
||||
assert!(os::summary_line(&info).contains("满足最低要求"));
|
||||
assert_eq!(os::to_json(&info)["support"], "one");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_version_is_reported_as_null_not_zero() {
|
||||
// 探不到版本时 `version` 是 null(脚本按 null 判定"未探测"),而不是空串。
|
||||
let info = sample(OsFamily::Windows, None, "Windows");
|
||||
let value = os::to_json(&info);
|
||||
assert!(value["version"].is_null());
|
||||
assert!(value["major_minor"].is_null());
|
||||
assert_eq!(value["support"], "unsupported");
|
||||
assert!(os::summary_line(&info).contains("版本未知"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn real_detect_matches_core_cache() {
|
||||
// 真机上 CLI 的摘要必须就是 core 的缓存快照(同一份事实,不做二次加工)。
|
||||
let info = os::detect();
|
||||
assert_eq!(&info, os_info::current());
|
||||
assert!(!info.arch.is_empty());
|
||||
assert!(!info.product.is_empty());
|
||||
// 自检形态与事实一致。
|
||||
let check = os::check();
|
||||
assert_eq!(check.level, info.support_level);
|
||||
assert_eq!(check.os, info);
|
||||
assert_eq!(check.is_usable(), info.support_level.is_usable());
|
||||
assert!(check.message.contains(&info.product), "{}", check.message);
|
||||
}
|
||||
Reference in new issue
Block a user