Files
Unlucky-Launcher/crates/core/tests/game/snapshot.rs
T
AskaEth 0522a41a52
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
CI / update-e2e (windows x64) (push) Waiting to run
GPU evidence / GPU 判据自测(不需 GPU;跳过 ≠ 已验证) (push) Waiting to run
GPU evidence / GPU 证据 — 探测可用产物与硬件适配器 (push) Waiting to run
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
Release guard / 发布标记语义守门(push tag → 稳定版) (push) Waiting to run
Signing status(播报,不是门禁) / 判据自测(三行/退出码/变异重放/接线) (push) Waiting to run
Signing status(播报,不是门禁) / 签名就绪度(播报) (push) Waiting to run
Release / 选槽位(默认四个:Windows 两档 + Linux 两档) (push) Waiting to run
release: v0.2.5
2026-11-12 12:06:59 +08:00

76 lines
2.3 KiB
Rust

//! 快照仓库:不可变读、单写者草稿、发布即指针交换。
use std::sync::Arc;
use unlucky_core::game::error::GameError;
use unlucky_core::game::snapshot::{Snapshot, Store};
#[test]
fn snapshot_survives_draft_publish() {
let store = Store::new(vec!["1.20.1".to_owned()]);
let before = store.snapshot();
let mut draft = store.open_draft().expect("首个草稿应可打开");
draft.edit().push("1.20.2".to_owned());
let published = draft.commit();
// 旧快照不变(读端遍历时不会看到半新半旧的状态)。
assert_eq!(before.get().len(), 1);
assert_eq!(published.get().len(), 2);
assert_eq!(store.snapshot().get().len(), 2);
}
#[test]
fn only_one_draft_at_a_time() {
let store = Store::new(0u32);
let draft = store.open_draft().expect("首个草稿应可打开");
match store.open_draft() {
Err(GameError::DraftBusy) => {}
other => panic!("第二个草稿必须被拒绝,得到 {other:?}"),
}
drop(draft);
let reopened = store.open_draft();
assert!(reopened.is_ok(), "放弃草稿后写权必须释放");
}
#[test]
fn dropping_draft_discards_changes() {
let store = Store::new(vec![1u32]);
{
let mut draft = store.open_draft().expect("草稿应可打开");
draft.edit().push(2);
}
assert_eq!(store.snapshot().get(), &vec![1u32]);
}
#[test]
fn replace_publishes_whole_table() {
let store = Store::new(vec!["old".to_owned()]);
let snapshot = store.replace(vec!["new".to_owned()]).expect("替换应成功");
assert_eq!(snapshot.get(), &vec!["new".to_owned()]);
assert_eq!(store.snapshot().get(), &vec!["new".to_owned()]);
}
#[test]
fn clones_share_one_allocation() {
let store = Store::new(vec![1u32]);
let first = store.snapshot();
let second = first.clone();
assert!(Arc::ptr_eq(&first.shared(), &second.shared()));
assert_eq!(first, second);
let published = store.replace(vec![2u32]).expect("替换应成功");
assert!(!Arc::ptr_eq(&first.shared(), &published.shared()));
assert_eq!(first.get(), &vec![1u32], "旧快照保持旧内容");
}
#[test]
fn snapshot_new_wraps_value() {
let snapshot = Snapshot::new("payload".to_owned());
assert_eq!(snapshot.get(), "payload");
assert_eq!(snapshot.clone().get(), "payload");
}