test(t7): AuxItems 类单测——结构冻结断言面十二断言全过
①新套件 tests/unit/core/aux_items_test.gd(run_all manifest+1,expect 0):授予归因/句柄受理序/Used 不可逆二次 consume 拒/真视恒可用/预读点击级零信息拒绝不消耗/3x3 边缘窗口∩板(角 4 格)/越板拒/叠加层两集/换图三清(retire 不动库存)/关卡末 reset/零随机重放两遍投影逐位 ②桩表模式:StubDB/StubTable 内联类喂行定义(产品码零测试分支——C1 零特判守住);修三元语句取 void 返回值解析错 闸:aux_items_test PASS;run_all 12 套全过
This commit is contained in:
1 parent
9553d6b182
commit
dd5ed4a753
3 files changed
+120
No files matched your search
@@ -32,6 +32,7 @@ func _suites() -> Array:
|
||||
{"path": "res://tests/unit/data_config/aux_target_violation_test.gd", "expect": 1}, # 迭代 7 T1——真视窄域护栏
|
||||
{"path": "res://tests/unit/data_config/reward_dangling_aux_test.gd", "expect": 1}, # 迭代 7 T1——aux 双表校验
|
||||
{"path": "res://tests/unit/data_config/rng_service_test.gd", "expect": 0},
|
||||
{"path": "res://tests/unit/core/aux_items_test.gd", "expect": 0}, # 迭代 7 T7——魔法道具结构冻结断言面
|
||||
{"path": "res://tests/unit/battle_settlement/damage_math_test.gd", "expect": 0},
|
||||
{"path": "res://tests/unit/battle_settlement/damage_controller_test.gd", "expect": 0},
|
||||
{"path": "res://tests/unit/contracts/system_contracts_test.gd", "expect": 0},
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# 魔法道具 AuxItems 类单测(迭代 7 T7——结构冻结断言面;设计权威 魔法道具.md + registry aux_items)。
|
||||
# 覆盖:授予归因 / Used 不可逆 / 真视恒可用 / 预读点击级零信息拒绝 / 3×3 边缘窗口∩板 /
|
||||
# 叠加层三清(retire_overlays 不动库存)/ 关卡末 reset / 零随机(同操作序列重放两遍投影逐位)。
|
||||
# 运行:godot --headless --path game --script res://tests/unit/core/aux_items_test.gd(expect 0)
|
||||
extends SceneTree
|
||||
|
||||
const AuxItemsScript := preload("res://core/aux_items.gd")
|
||||
|
||||
var _problems: Array = []
|
||||
|
||||
|
||||
func check(cond: bool, msg: String) -> void:
|
||||
if not cond:
|
||||
_problems.append(msg)
|
||||
|
||||
|
||||
class StubTable:
|
||||
var rows := {}
|
||||
func row_by_id(id: String) -> Dictionary:
|
||||
return rows.get(id, {})
|
||||
func active_rows() -> Array:
|
||||
return []
|
||||
|
||||
|
||||
class StubDB:
|
||||
var aux_items: StubTable
|
||||
|
||||
|
||||
func _stub_db() -> StubDB:
|
||||
var t := StubTable.new()
|
||||
t.rows = {
|
||||
"sapper_order": {"item_id": "sapper_order", "display_name": "工兵令", "dimension_tags": ["action"],
|
||||
"effect_kinds": ["ap_grant"], "target": "none", "magnitude": 2, "use_phase": "active_dig"},
|
||||
"nest_pendulum": {"item_id": "nest_pendulum", "display_name": "探巢摆钟", "dimension_tags": ["risk"],
|
||||
"effect_kinds": ["mine_reveal"], "target": "area_3x3", "magnitude": 0, "use_phase": "active_dig"},
|
||||
"loot_compass": {"item_id": "loot_compass", "display_name": "探宝罗盘", "dimension_tags": ["plan"],
|
||||
"effect_kinds": ["reward_preview"], "target": "area_3x3", "magnitude": 0, "use_phase": "active_dig"},
|
||||
}
|
||||
var db := StubDB.new()
|
||||
db.aux_items = t
|
||||
return db
|
||||
|
||||
|
||||
func _new_inv() -> Object:
|
||||
return AuxItemsScript.new(_stub_db())
|
||||
|
||||
|
||||
func _unrevealed(_c: Vector2i) -> bool:
|
||||
return true # 测试板全未开(预读恒有信息——点击级零信息另用假回调测)
|
||||
|
||||
|
||||
func _all_revealed(_c: Vector2i) -> bool:
|
||||
return false # 预读点击级零信息(窗口全已开)
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
# ① 授予归因+受理序+Used 不可逆
|
||||
var inv = _new_inv()
|
||||
var r1: Dictionary = inv.add_item("sapper_order", "safe_cell", Vector2i(3, 4), 2)
|
||||
var r2: Dictionary = inv.add_item("nest_pendulum", "flag_hit", Vector2i(5, 6), 3)
|
||||
check(int(r1.handle) == 1 and int(r2.handle) == 2, "句柄受理序单调(1→2——零随机)")
|
||||
check(String(r1.source_class) == "safe_cell" and r1.origin_cell == Vector2i(3, 4) and int(r1.round_index) == 2,
|
||||
"授予来源可归因(source/cell/round)")
|
||||
var inv_proj: Array = inv.query_inventory(Callable())
|
||||
check(inv_proj.size() == 2 and not bool(inv_proj[0].used), "库存投影两件未用")
|
||||
check(bool(inv.consume(int(r1.handle)).get("used", false)), "consume 返回已用快照回执")
|
||||
check(inv.consume(int(r1.handle)).is_empty(), "Used 不可逆——二次 consume 拒绝(空回执)")
|
||||
check(int(inv.inventory_count()) == 2, "Used 保留只读(库存计数不变)")
|
||||
|
||||
# ② 真视恒可用+边缘窗口∩板(3×3 中心贴角——角 4 格)
|
||||
var v_ok: Dictionary = inv.validate_use(int(r2.handle), Vector2i(0, 0), Vector2i(10, 10), Callable())
|
||||
check(bool(v_ok.ok) and v_ok.resolved.size() == 4,
|
||||
"真视边缘窗口=窗口∩板(角 4 格——护栏只缩不扩)")
|
||||
# 预读点击级零信息:中心板内但回调恒 false(全已开)→拒绝零消耗
|
||||
var inv2 = _new_inv()
|
||||
var rp: Dictionary = inv2.add_item("loot_compass", "safe_cell", Vector2i(1, 1), 1)
|
||||
var v_zero: Dictionary = inv2.validate_use(int(rp.handle), Vector2i(5, 5), Vector2i(10, 10), Callable())
|
||||
check(not bool(v_zero.ok) and int(inv2.inventory_count()) == 1,
|
||||
"预读点击级零信息拒绝(不消耗——库存不变)")
|
||||
# 目标越板
|
||||
var v_oob: Dictionary = inv2.validate_use(int(rp.handle), Vector2i(12, 5), Vector2i(10, 10), Callable())
|
||||
check(not bool(v_zero.ok) and not bool(v_oob.ok), "越板目标拒绝")
|
||||
|
||||
# ③ 叠加层+三清(retire 不动库存;reset 全清)
|
||||
inv2.apply_overlay("mine_reveal", v_ok.resolved)
|
||||
inv2.apply_overlay("reward_preview", [Vector2i(5, 5)])
|
||||
var ov: Dictionary = inv2.query_overlays()
|
||||
check(ov.mine_reveal.size() == 4 and ov.reward_preview.size() == 1, "叠加层两集落位(真视 4/预读 1)")
|
||||
inv2.retire_overlays()
|
||||
check(inv2.query_overlays().mine_reveal.is_empty() and int(inv2.inventory_count()) == 1,
|
||||
"换图三清:叠加层消亡+库存不动(关卡域)")
|
||||
inv2.reset()
|
||||
check(inv2.inventory_count() == 0 and inv2.probe().used == 0, "关卡末 reset 全清(幂等)")
|
||||
|
||||
# ④ 零随机重放:同操作序列两遍,投影逐位相同
|
||||
var replay_a: Array = []
|
||||
var replay_b: Array = []
|
||||
for rep in 2:
|
||||
var inv3 = _new_inv()
|
||||
var h1: Dictionary = inv3.add_item("sapper_order", "safe_cell", Vector2i(2, 3), 1)
|
||||
inv3.validate_use(int(h1.handle), Vector2i(4, 4), Vector2i(10, 10), Callable())
|
||||
inv3.apply_overlay("mine_reveal", [Vector2i(4, 4)])
|
||||
inv3.consume(int(h1.handle))
|
||||
if rep == 0:
|
||||
replay_a = [inv3.query_inventory(Callable()), inv3.query_overlays(), inv3.probe()]
|
||||
else:
|
||||
replay_b = [inv3.query_inventory(Callable()), inv3.query_overlays(), inv3.probe()]
|
||||
check(str(replay_a) == str(replay_b), "零随机重放:库存+叠加层+探针投影逐位相同")
|
||||
|
||||
# ---- 汇总 ----
|
||||
if _problems.is_empty():
|
||||
print("[aux_items_test] PASS — 授予归因/Used 不可逆/真视恒可用/零信息拒绝/边缘窗口/三清/零随机重放 全过")
|
||||
quit(0)
|
||||
else:
|
||||
for p in _problems:
|
||||
push_error("[aux_items_test] FAIL — " + p)
|
||||
quit(1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://dqx67xrrbvp82
|
||||
Reference in new issue
Block a user