feat(app-iced): Java 页「下载一个 JDK」+ 三个设置键(M197)
用户原话:「我们内置了那么多镜像源 甚至用户不能手动选择指定版本下载。」
「自动下载 jdk17 作为基准版本,后续在设置中提供多版本可供用户下载。」
- core:新增 `game::java::catalog`(8/11/17/21/25 五档 × 能承接的发行版 × 「该装哪档」),
数据全部来自 `JdkVendor::supports` 与 `vendor::order`,不复制第二份真相。
- progress:`SourceFailed` 补一个结构化的 `kind`(在这之前只有中文 `reason`,双语界面
要么放弃语言、要么放弃「哪个源为什么退避」这条用户可见信息)。
- app-iced:`downloads` 模块真下(后台线程 + `ProgressEmitter` + 快照),三态(选择列表 /
下载中 / 失败)都能说出「命中的源 / 退避原因 / 试过哪些源」;成功后重扫并(在
`java.auto_install` 开着且没有默认 JDK 时)把新装的那份设为默认。
- 三个设置键做成可改 UI:`java.installRoot` / `java.vendorPriority` / `java.auto_install`,
各自带「现在生效什么、从哪一层来」(数据目录模式 / 地区默认序),改完回读落盘值。
- `State::satisfied` 换成带方向的 `Fit`:1.12.2 + Java 21 不再被说成「低于要求」。
- i18n:删掉 `SettingsJavaEmptyBody` / `SettingsJavaAddHint` 的 markdown 反引号;
`SettingsJavaNeverScannedBody` 改成不与首屏自动扫矛盾的表述。
- 出图三张(选择列表 / 下载中 / 失败)在 DevDocs/artifacts/m197/。
顺带拆文件守 400 行:`golden/tail.rs` 的 M174 段搬到 `golden/tail_ai.rs`,
`pages/settings/java/{context,prefs,prefs_store,downloads,download_view}` 各自成模块。
This commit is contained in:
1 parent
329c529bea
commit
ce463cc9b5
33 files changed
+3839
-322
No files matched your search
@@ -161,3 +161,142 @@ fn a_schema_rejection_surfaces_as_a_page_key_not_the_core_sentence() {
|
||||
);
|
||||
std::fs::remove_dir_all(path.parent().unwrap().parent().unwrap()).ok();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- M197:三个设置键 + 真下载的落点
|
||||
|
||||
/// 三键改完点保存:**真落盘**、草稿被读回值收尾、不再脏,并且保存顺手重扫一次。
|
||||
///
|
||||
/// 变异证明:`save_java_prefs` 里不调 `prefs.adopt(snapshot)` ⇒ 草稿还是 `" D:/JDKs "`、
|
||||
/// `dirty` 仍为真 ⇒ 本条红;不调 `start_java_scan` ⇒ `scan.report().running` 那条红。
|
||||
#[test]
|
||||
fn saving_the_three_keys_writes_them_and_reads_them_back() {
|
||||
use pages::settings::java::prefs_store;
|
||||
|
||||
let (mut app, path) = bridged_app("java-prefs");
|
||||
// 落点用这个临时数据根下的绝对路径:Windows / macOS / Linux 上都是绝对的,
|
||||
// 断言于是与平台无关(写 "D:/JDKs" 在非 Windows 上是相对路径,会被解析到数据根下)。
|
||||
let home = path.parent().unwrap().parent().unwrap().to_path_buf();
|
||||
let jdks = home.join("JDKs").display().to_string();
|
||||
let _ = app.update(java(pages::settings::java::Message::EditInstallRoot(
|
||||
format!(" {jdks} "),
|
||||
)));
|
||||
let _ = app.update(java(pages::settings::java::Message::ToggleAutoInstall(
|
||||
false,
|
||||
)));
|
||||
let _ = app.update(java(pages::settings::java::Message::MoveVendor {
|
||||
index: 0,
|
||||
up: false,
|
||||
}));
|
||||
assert!(app.settings.java.prefs.dirty(), "改过三键就该是脏的");
|
||||
|
||||
let _ = app.update(java(pages::settings::java::Message::SavePrefs));
|
||||
|
||||
assert_eq!(
|
||||
app.settings.java.notice,
|
||||
Some(pages::settings::java::Notice::PrefsSaved)
|
||||
);
|
||||
assert!(
|
||||
!app.settings.java.prefs.dirty(),
|
||||
"保存并把读回值当草稿之后不该还脏"
|
||||
);
|
||||
assert_eq!(
|
||||
app.settings.java.prefs.install_root, jdks,
|
||||
"草稿必须等于磁盘上那份(trim 过的),不是用户刚敲的原样"
|
||||
);
|
||||
assert!(
|
||||
!app.settings.java.prefs.saved_auto_install,
|
||||
"auto_install 要真变成关"
|
||||
);
|
||||
|
||||
// 冷读:另起一次 load,确认三个键都在文件里。
|
||||
let snapshot = prefs_store::load(&path);
|
||||
assert_eq!(snapshot.install_root, jdks);
|
||||
assert!(!snapshot.auto_install);
|
||||
assert_eq!(snapshot.priority.len(), 4, "下移之后落盘的是整条链");
|
||||
assert_ne!(snapshot.priority[0], "temurin", "顺序真的被改过");
|
||||
assert!(
|
||||
app.settings.java.scan.report().running,
|
||||
"改了落点必须重扫一次,否则列表还停在旧目录里"
|
||||
);
|
||||
// 生效值也跟着换了层级(设了 installRoot ⇒ 落点来自设置)。
|
||||
assert_eq!(
|
||||
app.settings.java.effective.root, jdks,
|
||||
"生效落点必须是刚保存的那一个"
|
||||
);
|
||||
std::fs::remove_dir_all(path.parent().unwrap().parent().unwrap()).ok();
|
||||
}
|
||||
|
||||
/// `java.auto_install` 开着且还没有默认 JDK:装完之后自动把新装的那份设为默认。
|
||||
///
|
||||
/// 变异证明:把 `hydrate_java_downloads` 里那段 `saved_auto_install && selected.is_empty()`
|
||||
/// 的判据删掉 ⇒ 本条红(`selected` 还是空);把关掉那一档的断言反过来说明判据不是恒真。
|
||||
#[test]
|
||||
fn auto_install_adopts_the_fresh_jdk_when_no_default_is_set() {
|
||||
use pages::settings::java::downloads::{Report, Success};
|
||||
|
||||
let (mut app, path) = bridged_app("java-adopt");
|
||||
app.settings.java.prefs.saved_auto_install = true;
|
||||
app.settings.java.selected = String::new();
|
||||
app.settings.java.downloads.seed_report(Report {
|
||||
job: None,
|
||||
tries: Vec::new(),
|
||||
failure: None,
|
||||
success: Some(Success {
|
||||
major: 21,
|
||||
vendor: "Eclipse Temurin",
|
||||
root: "D:/jdks/temurin/21".to_string(),
|
||||
binary: "D:/jdks/temurin/21/bin/java.exe".to_string(),
|
||||
source: Some("tuna".to_string()),
|
||||
reused: false,
|
||||
}),
|
||||
});
|
||||
assert!(app.hydrate_java_downloads(), "快照变了就要重建视图");
|
||||
assert_eq!(
|
||||
app.settings.java.selected, "D:/jdks/temurin/21/bin/java.exe",
|
||||
"auto_install 开着 + 没有默认 JDK ⇒ 新装的那份自动成为默认"
|
||||
);
|
||||
let snapshot = pages::settings::java::store::load(&path);
|
||||
assert_eq!(
|
||||
snapshot.selected, "D:/jdks/temurin/21/bin/java.exe",
|
||||
"而且真写进了 java.selected_path"
|
||||
);
|
||||
|
||||
// 关掉 auto_install 时同样的成功快照**不**改默认。
|
||||
let (mut app, path) = bridged_app("java-adopt-off");
|
||||
app.settings.java.prefs.saved_auto_install = false;
|
||||
app.settings.java.selected = String::new();
|
||||
app.settings.java.downloads.seed_report(Report {
|
||||
job: None,
|
||||
tries: Vec::new(),
|
||||
failure: None,
|
||||
success: Some(Success {
|
||||
major: 17,
|
||||
vendor: "Eclipse Temurin",
|
||||
root: "D:/jdks/temurin/17".to_string(),
|
||||
binary: "D:/jdks/temurin/17/bin/java.exe".to_string(),
|
||||
source: None,
|
||||
reused: true,
|
||||
}),
|
||||
});
|
||||
assert!(app.hydrate_java_downloads());
|
||||
assert_eq!(app.settings.java.selected, "", "关掉就不许替用户改默认");
|
||||
std::fs::remove_dir_all(path.parent().unwrap().parent().unwrap()).ok();
|
||||
}
|
||||
|
||||
/// 点一个目录里没有的大版本:立刻在下载区顶上写清原因,**不**起线程。
|
||||
///
|
||||
/// 变异证明:把 `start_java_download` 里 `catalog::find(major).is_none()` 那道判据删掉 ⇒
|
||||
/// `download_notice` 为 `None`,本条红(点了却什么都不说是禁止的)。
|
||||
#[test]
|
||||
fn an_unknown_major_is_refused_on_the_spot() {
|
||||
use pages::settings::java::downloads::Refusal;
|
||||
|
||||
let (mut app, path) = bridged_app("java-dl-refuse");
|
||||
let _ = app.update(java(pages::settings::java::Message::Download(99)));
|
||||
assert_eq!(
|
||||
app.settings.java.download_notice,
|
||||
Some(Refusal::UnknownMajor)
|
||||
);
|
||||
assert!(!app.settings.java.downloads.busy(), "不该起任何作业");
|
||||
std::fs::remove_dir_all(path.parent().unwrap().parent().unwrap()).ok();
|
||||
}
|
||||
Reference in new issue
Block a user