Files
AskaEth bc41dfcf7d
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
Unlucky Launcher v0.0.1-alpha
Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent),
MCP server 接入外部 Agent 工具,GUI 开发中。
2026-10-31 21:54:10 +08:00

110 lines
3.8 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 实例清单:稳定 UUID、增删查、落盘格式兼容。
use unlucky_core::game::profiles::{
InstanceProfile, ProfileId, ProfileList, PROFILE_SCHEMA_VERSION,
};
#[test]
fn generated_ids_are_unique_and_uuid_shaped() {
let ids: Vec<ProfileId> = (0..256).map(|_| ProfileId::generate()).collect();
for id in &ids {
assert!(id.is_uuid_shaped(), "id 形状不对: {id}");
}
let mut unique: Vec<&str> = ids.iter().map(ProfileId::as_str).collect();
let total = unique.len();
unique.sort_unstable();
unique.dedup();
assert_eq!(unique.len(), total, "同一批生成的 id 不能重复");
}
#[test]
fn id_shape_validation_rejects_junk() {
assert!(!ProfileId::new("not-a-uuid").is_uuid_shaped());
assert!(!ProfileId::new("").is_uuid_shaped());
assert!(ProfileId::new("7c9e6679-7425-40de-944b-e07fc1f90ae7").is_uuid_shaped());
}
#[test]
fn upsert_and_remove_keep_one_entry_per_id() {
let mut list = ProfileList::default();
assert_eq!(list.schema_version, PROFILE_SCHEMA_VERSION);
assert!(list.is_empty());
let mut profile = InstanceProfile::new("主世界", "1.20.1");
assert_eq!(list.upsert(profile.clone()), None, "首次插入没有旧值");
assert_eq!(list.len(), 1);
profile.name = "主世界(Fabric)".to_owned();
let replaced = list.upsert(profile.clone()).expect("同 id 应替换");
assert_eq!(replaced.name, "主世界");
assert_eq!(list.len(), 1);
assert_eq!(
list.get(&profile.id).map(|p| p.name.as_str()),
Some("主世界(Fabric)")
);
let removed = list.remove(&profile.id).expect("应可删除");
assert_eq!(removed.id, profile.id);
assert!(list.is_empty());
assert!(list.remove(&profile.id).is_none());
}
#[test]
fn profiles_group_by_version() {
let mut list = ProfileList::default();
list.upsert(InstanceProfile::new("a", "1.20.1"));
list.upsert(InstanceProfile::new("b", "1.20.1"));
list.upsert(InstanceProfile::new("c", "1.19.4"));
assert_eq!(list.for_version("1.20.1").len(), 2);
assert_eq!(list.for_version("1.19.4").len(), 1);
assert!(list.for_version("1.18.2").is_empty());
}
#[test]
fn roundtrips_profiles_json() {
let mut list = ProfileList::default();
let mut profile = InstanceProfile::new("整合包", "1.20.1-forge-47.2.0");
profile.running_dir = Some(std::path::PathBuf::from("D:/mc/runs/pack"));
profile
.extra
.insert("thirdPartyFlag".to_owned(), serde_json::json!(true));
list.upsert(profile.clone());
let json = list.to_json_string().expect("应可序列化");
let reparsed = ProfileList::from_json_str(&json).expect("应可再解析");
assert_eq!(reparsed, list);
assert_eq!(reparsed.schema_version, PROFILE_SCHEMA_VERSION);
}
#[test]
fn reads_minimal_profile_file() {
// 用户手改/旧版本写下的最小档案:只有三个必填语义字段,其它缺省。
let list = ProfileList::from_json_str(
r#"{ "profiles": [ { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"name": "旧档案", "version_id": "1.12.2" } ] }"#,
)
.expect("最小档案应可解析");
assert_eq!(
list.schema_version, PROFILE_SCHEMA_VERSION,
"schemaVersion 缺省补齐"
);
assert_eq!(list.len(), 1);
let profile = &list.profiles[0];
assert_eq!(profile.name, "旧档案");
assert!(profile.running_dir.is_none());
assert!(profile.id.is_uuid_shaped());
}
#[test]
fn invalid_profiles_json_reports_context() {
let error = ProfileList::from_json_str("{").expect_err("非法 JSON 应报错");
match error {
unlucky_core::game::error::GameError::Json { context, .. } => {
assert_eq!(context, "profiles")
}
other => panic!("期望 Json 错误,得到 {other:?}"),
}
}