Unlucky Launcher v0.2.0
CI / runtime smoke (macos arm64, probe) (push) Skipped
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
CI / runtime smoke (ubuntu x64, xvfb) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / presenter 零 UI 守门 (push) Canceled after 0s
Guards / design 零第三方依赖守门 (push) Canceled after 0s
Guards / unsafe 落点守门(集合必须恰好一个文件) (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
CI / runtime smoke (macos arm64, probe) (push) Skipped
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
CI / runtime smoke (ubuntu x64, xvfb) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / presenter 零 UI 守门 (push) Canceled after 0s
Guards / design 零第三方依赖守门 (push) Canceled after 0s
Guards / unsafe 落点守门(集合必须恰好一个文件) (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
首个 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,49 @@
|
||||
//! 原子写:覆盖语义、父目录创建、不留临时文件、可选读。
|
||||
|
||||
use unlucky_core::platform::atomic::{read_optional, tmp_path, write_atomic};
|
||||
|
||||
use crate::common::{dir_entries, TempDir};
|
||||
|
||||
#[test]
|
||||
fn writes_and_replaces_in_place() {
|
||||
let temp = TempDir::new("atomic");
|
||||
let path = temp.child("config/launcher.json");
|
||||
|
||||
write_atomic(&path, b"{\"a\":1}").expect("首次写");
|
||||
assert_eq!(temp.read("config/launcher.json"), "{\"a\":1}");
|
||||
|
||||
write_atomic(&path, b"{\"a\":2}").expect("覆盖写");
|
||||
assert_eq!(temp.read("config/launcher.json"), "{\"a\":2}");
|
||||
|
||||
// 目录里只该有目标文件,临时文件必须被改名掉。
|
||||
assert_eq!(dir_entries(&temp.child("config")), vec!["launcher.json"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_optional_distinguishes_missing_from_failure() {
|
||||
let temp = TempDir::new("atomic-read");
|
||||
let path = temp.child("nope.json");
|
||||
assert!(read_optional(&path).expect("读缺失文件").is_none());
|
||||
|
||||
temp.write("here.json", "内容");
|
||||
let bytes = read_optional(&temp.child("here.json"))
|
||||
.expect("读文件")
|
||||
.expect("有内容");
|
||||
assert_eq!(bytes, "内容".as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tmp_name_stays_in_same_directory() {
|
||||
let temp = TempDir::new("atomic-tmp");
|
||||
let path = temp.child("config/profiles.json");
|
||||
let tmp = tmp_path(&path);
|
||||
assert_eq!(
|
||||
tmp.parent(),
|
||||
path.parent(),
|
||||
"临时文件必须同目录(rename 才原子)"
|
||||
);
|
||||
assert_ne!(tmp, path);
|
||||
let first = tmp_path(&path);
|
||||
let second = tmp_path(&path);
|
||||
assert_ne!(first, second, "并发写要能拿到不同的临时名");
|
||||
}
|
||||
Reference in new issue
Block a user