fix(core): 首轮编译/测试抓到的四个问题(BTreeMap、测试模块布局、display_loader_version、未用 import)

1. liteloader.rs 拆文件后漏了 `use std::collections::BTreeMap`(`loader_library` 里用)。
2. `tests/liteloader.rs` 是 **crate root**,`mod guards;` 会被找去 `tests/guards.rs`;
   改成 `tests/liteloader/main.rs`(与 `tests/game/main.rs` 同形),target 名仍是 liteloader。
3. `display_loader_version` 去通配时丢了 NeoForge@1.20.1(forge 布局)去前缀的语义:
   既有用例 `neoforge_1201_uses_forge_layout` 当场抓住(1.20.1-47.1.106 → 47.1.106)。
   现在按「加载器 + 是否 forge 布局」显式决定,四家原有行为逐字不变。
4. `dto/instances.rs` 的 `pub use super::LaunchArgsView` 在非 test 构建里没人用(-D warnings 会红),
   改由 `dto/instances/tests.rs` 直接 `use crate::dto::LaunchArgsView`。

顺带修两条**我自己写错的测试期望**(不是产品 bug):
- 取消用例里那条 `resolve` 断言用错了父版本表(父版本在内存表里,当然解析成功);
- 新式父链用例误以为 `minecraftArguments` 会是 None,实际会沿链继承祖父层那份
  —— 断言改成「继承来的 legacy 串里不许出现 LiteLoaderTweaker」。
This commit is contained in:
AskaEth committed 2026-11-10 19:34:12 +08:00
1 parent 51ea32284d
commit 3114fa2d4f
8 files changed
+31 -25

No files matched your search

@@ -29,6 +29,8 @@
//! 只在 Mojang 库仓有(Central / Forge maven 都 404)。所以 `net.minecraft` 走 Mojang 默认基址、 //! 只在 Mojang 库仓有(Central / Forge maven 都 404)。所以 `net.minecraft` 走 Mojang 默认基址、
//! 其余走 Maven Central(实测 206)。这条分流有单测钉住,别把两侧弄反。 //! 其余走 Maven Central(实测 206)。这条分流有单测钉住,别把两侧弄反。
use std::collections::BTreeMap;
use super::plan::{LoaderRelease, LoaderSupport}; use super::plan::{LoaderRelease, LoaderSupport};
use super::{LoaderError, LoaderKind}; use super::{LoaderError, LoaderKind};
use crate::game::arguments::{Argument, Arguments}; use crate::game::arguments::{Argument, Arguments};
+15 -7
View File
@@ -168,17 +168,25 @@ pub fn normalize_maven_version(kind: LoaderKind, mc_version: &str, raw: &str) ->
} }
} }
/// 用户视角的加载器版本号(Forge 去掉原版前缀,NeoForge 与非 maven 族原样)。 /// 用户视角的加载器版本号(带原版前缀的 maven 版本要去掉前缀)。
///
/// 谁带前缀是**按加载器 + 布局**定的:Forge 恒带;NeoForge 只有「1.20.1 走 forge 布局」
/// 那一段带(`1.20.1-47.1.106` → `47.1.106`),其余 NeoForge 版本本身就是完整 maven 版本;
/// fabric 系与 LiteLoader 的版本号本来就是用户视角的。
#[must_use] #[must_use]
pub fn display_loader_version(kind: LoaderKind, mc_version: &str, maven_version: &str) -> String { pub fn display_loader_version(kind: LoaderKind, mc_version: &str, maven_version: &str) -> String {
match kind { let strip = match kind {
LoaderKind::Forge => maven_version LoaderKind::Forge => true,
LoaderKind::NeoForge => mc_version == NEOFORGE_FORGE_LAYOUT_MC,
LoaderKind::Fabric | LoaderKind::Quilt | LoaderKind::LiteLoader => false,
};
if strip {
maven_version
.strip_prefix(&format!("{mc_version}-")) .strip_prefix(&format!("{mc_version}-"))
.unwrap_or(maven_version) .unwrap_or(maven_version)
.to_string(), .to_string()
LoaderKind::NeoForge | LoaderKind::Fabric | LoaderKind::Quilt | LoaderKind::LiteLoader => { } else {
maven_version.to_string() maven_version.to_string()
}
} }
} }
@@ -228,7 +228,7 @@ fn build_release_synthesizes_launchwrapper_manifest() {
); );
// 父子链靠 arguments.game 追加,不写 minecraftArguments(写了会顶掉 Forge 的 tweakClass)。 // 父子链靠 arguments.game 追加,不写 minecraftArguments(写了会顶掉 Forge 的 tweakClass)。
assert!(json.minecraft_arguments.is_none()); assert!(json.minecraft_arguments.is_none());
let game: Vec<&str> = json let game: Vec<String> = json
.arguments .arguments
.as_ref() .as_ref()
.expect("arguments 必须有") .expect("arguments 必须有")
+1 -13
View File
@@ -12,13 +12,10 @@ use unlucky_core::addon::loader::{
}; };
use unlucky_core::download::blocking::block_on; use unlucky_core::download::blocking::block_on;
use unlucky_core::game::arguments::Environment; use unlucky_core::game::arguments::Environment;
use unlucky_core::game::inherit::resolve;
use unlucky_core::game::install::{execute_with_cancel, InstallErrorKind}; use unlucky_core::game::install::{execute_with_cancel, InstallErrorKind};
use unlucky_core::game::layout::GameLayout; use unlucky_core::game::layout::GameLayout;
use crate::support::{ use crate::support::{engine, liteloader_release, prefill, put_version, TempDir, VANILLA_1122};
engine, liteloader_release, prefill, put_version, read_version, TempDir, VANILLA_1122,
};
/// 父版本不是原版、又没装在盘上 → **具名报错**,绝不默默改成叠原版。 /// 父版本不是原版、又没装在盘上 → **具名报错**,绝不默默改成叠原版。
#[test] #[test]
@@ -145,15 +142,6 @@ fn cancel_leaves_no_manifest() {
!layout.version_json(&release.version_id).exists(), !layout.version_json(&release.version_id).exists(),
"取消之后不许留下版本清单" "取消之后不许留下版本清单"
); );
// 继承链在缺清单时也应明确报「父版本缺失」,而不是静默降级成原版。
let mut source = std::collections::BTreeMap::new();
source.insert("1.12.2".to_string(), read_version(&layout, "1.12.2"));
let error = resolve(&source, &release.version_json).expect_err("父版本缺失");
assert!(matches!(
error,
unlucky_core::game::GameError::MissingParent { .. }
));
} }
/// 同一个 loader 版本 id 被两条父链请求:**具名报错**,且盘上那份清单一个字节都不动。 /// 同一个 loader 版本 id 被两条父链请求:**具名报错**,且盘上那份清单一个字节都不动。
+10 -2
View File
@@ -219,8 +219,16 @@ fn new_style_parent_args_are_appended_not_replaced() {
); );
let resolved = resolve(&source, &source[&release.version_id]).expect("三层继承应可解析"); let resolved = resolve(&source, &source[&release.version_id]).expect("三层继承应可解析");
// 父层用的是新式参数:子层没有把 legacy 串写进来,继承后仍然没有。 // 子层没写 legacy 串:继承结果里的 `minecraftArguments` 只能是祖父层(原版)那一份,
assert!(resolved.minecraft_arguments.is_none()); // 里面绝不能出现 LiteLoader 的 tweakClass(写了就说明我们用了覆盖语义)。
let legacy = resolved
.minecraft_arguments
.as_deref()
.expect("原版那份 legacy 串应沿链继承下来");
assert!(
!legacy.contains("LiteLoaderTweaker"),
"loader 层不许往 minecraftArguments 里写:{legacy}"
);
let game = resolved let game = resolved
.arguments .arguments
.as_ref() .as_ref()
File renamed without changes.
-2
View File
@@ -26,5 +26,3 @@ pub use super::launch_failure::{LaunchFailureCause, LaunchFailureStage, LaunchFa
/// 实例标识:core::game 生成的稳定 id,app 视为不透明字符串。 /// 实例标识:core::game 生成的稳定 id,app 视为不透明字符串。
pub type InstanceId = String; pub type InstanceId = String;
pub use super::LaunchArgsView;
@@ -3,6 +3,8 @@
use super::*; use super::*;
use unlucky_core::game::LoaderKind as CoreLoaderKind; use unlucky_core::game::LoaderKind as CoreLoaderKind;
use crate::dto::LaunchArgsView;
#[test] #[test]
fn loader_badges_and_ids() { fn loader_badges_and_ids() {
let vanilla = LoaderInfo::default(); let vanilla = LoaderInfo::default();