110 lines
6.3 KiB
GDScript
110 lines
6.3 KiB
GDScript
extends SceneTree
|
||
# 锻造工坊工作间 UI 直验套件(V13 人闸的自动化前置面:两区结构/钮态/意图信号/锁定态纪律)
|
||
# 覆盖:锁定态零行板零购买路径(占位纪律延续)· 两区各三路线 · 初始持有行购买钮(几何价 20)·
|
||
# 待解锁行解锁钮(200)+无购买钮 · 选中钮当前态禁用 · 余额不足禁用态 · 满级无购买钮 ·
|
||
# 三意图信号外发(UI 只发意图——契约 9,写口归 MetaProgression 由冒烟侧覆盖)。
|
||
# 运行:godot --headless --path game --script res://tests/unit/presentation/forge_workbench_test.gd(expect 0)
|
||
const Kit := preload("res://tests/unit/test_kit.gd")
|
||
|
||
const _TEST_SAVE := "user://test_forge_workbench.json"
|
||
|
||
|
||
func _initialize() -> void:
|
||
call_deferred("_run")
|
||
|
||
|
||
func _row_by_id(ov) -> Dictionary:
|
||
var out := {}
|
||
for r in ov._forge_rows:
|
||
out[String(r.route_id)] = r
|
||
return out
|
||
|
||
|
||
func _run() -> void:
|
||
var db = load("res://core/config_db.gd").new()
|
||
var load_ok: bool = db.load_tables("res://data/tables", true)
|
||
if not load_ok:
|
||
Kit.check("ConfigDb 加载(工作间测试夹具前提)", false)
|
||
quit(Kit.finish("forge_workbench_test"))
|
||
return
|
||
var sv = load("res://core/save_manager.gd").new(_TEST_SAVE)
|
||
sv.load_from_disk()
|
||
var mp = load("res://core/meta_progression.gd").new(db, sv)
|
||
var ov = load("res://presentation/views/camp_overlay_view.gd").new()
|
||
root.add_child(ov)
|
||
var buys := []
|
||
var unlocks := []
|
||
var selects := []
|
||
ov.forge_buy_requested.connect(func(rid): buys.append(rid))
|
||
ov.forge_unlock_requested.connect(func(rid): unlocks.append(rid))
|
||
ov.forge_select_requested.connect(func(rid): selects.append(rid))
|
||
|
||
# ① 锁定态:树钥匙未点亮 → 工作间不可见、两区零行板(无任何可交互购买路径)
|
||
ov.open_camp({"balance": 999, "forge": mp.forge_shop_status(), "tree": []})
|
||
Kit.check("锁定态:工作间不可见(forge_workshop 钥匙未点亮)〔锻造工坊批 V13〕",
|
||
not ov._forge_workbench.visible and ov._forge_lock_l.visible)
|
||
Kit.check("锁定态:两区零行板(占位纪律——零购买路径)〔锻造工坊批 V13〕",
|
||
ov._forge_zone_weapon.get_child_count() == 0 and ov._forge_zone_armor.get_child_count() == 0)
|
||
|
||
# ② 解锁态:钥匙点亮 → 两区各三路线
|
||
ov.open_camp({"balance": 500, "forge": mp.forge_shop_status(),
|
||
"tree": [{"node_id": "forge_workshop", "level": 1}]})
|
||
Kit.check("解锁态:工作间可见(钥匙点亮展开)〔锻造工坊批 V13〕", ov._forge_workbench.visible)
|
||
Kit.check("两区各三路线(武器锻造区 3 + 护甲锻造区 3)〔锻造工坊批 V13〕",
|
||
ov._forge_zone_weapon.get_child_count() == 3 and ov._forge_zone_armor.get_child_count() == 3)
|
||
var rows: Dictionary = _row_by_id(ov)
|
||
Kit.check("六路线行册恰全(sword/spear/staff/light/heavy/ward)〔锻造工坊批 V13〕",
|
||
rows.has("sword") and rows.has("spear") and rows.has("staff")
|
||
and rows.has("light") and rows.has("heavy") and rows.has("ward"))
|
||
|
||
# ③ 初始持有行(长剑/轻甲):购买钮现形带几何价、选中钮=当前禁用
|
||
var rsw = rows.get("sword", {})
|
||
var rli = rows.get("light", {})
|
||
Kit.check("长剑行:购买钮「锻造 20」(0 级位几何价)+选中钮「当前」禁用〔锻造工坊批 V13〕",
|
||
rsw.get("buy_btn") != null and String(rsw.buy_btn.text) == "锻造 20" and not rsw.buy_btn.disabled
|
||
and rsw.get("select_btn") != null and String(rsw.select_btn.text) == "当前" and rsw.select_btn.disabled)
|
||
Kit.check("轻甲行:购买钮「锻造 20」+选中钮「当前」禁用〔锻造工坊批 V13〕",
|
||
rli.get("buy_btn") != null and String(rli.buy_btn.text) == "锻造 20"
|
||
and String(rli.select_btn.text) == "当前" and rli.select_btn.disabled)
|
||
|
||
# ④ 待解锁行(长枪/法杖/重甲/魔法护甲):解锁钮 200、无购买钮、无选中钮、状态含双通道文案
|
||
var rsp = rows.get("spear", {})
|
||
var rwa = rows.get("ward", {})
|
||
Kit.check("长枪行:解锁钮「解锁 200」+无购买钮+无选中钮〔锻造工坊批 V13〕",
|
||
rsp.get("unlock_btn") != null and String(rsp.unlock_btn.text) == "解锁 200" and not rsp.unlock_btn.disabled
|
||
and rsp.get("buy_btn") == null and rsp.get("select_btn") == null)
|
||
Kit.check("魔法护甲行:解锁钮「解锁 200」+状态含并联双通道文案(练满轻甲锻造 或 200 钥石直购)〔锻造工坊批 V13〕",
|
||
rwa.get("unlock_btn") != null and String(rwa.status_l.text).contains("练满轻甲锻造")
|
||
and String(rwa.status_l.text).contains("200"))
|
||
|
||
# ⑤ 余额不足禁用态(常态防线)
|
||
ov.refresh_camp({"balance": 0, "forge": mp.forge_shop_status(),
|
||
"tree": [{"node_id": "forge_workshop", "level": 1}]})
|
||
rows = _row_by_id(ov)
|
||
Kit.check("余额 0:长剑购买钮禁用+长枪解锁钮禁用(余额联动常态防线)〔锻造工坊批 V13〕",
|
||
rows.sword.buy_btn.disabled and rows.spear.unlock_btn.disabled)
|
||
|
||
# ⑥ 满级行:无购买钮、状态=已满级(直置存档域构造——两分法调试口径)
|
||
sv.meta_state.set_forge_route_level("sword", 5)
|
||
ov.refresh_camp({"balance": 500, "forge": mp.forge_shop_status(),
|
||
"tree": [{"node_id": "forge_workshop", "level": 1}]})
|
||
rows = _row_by_id(ov)
|
||
Kit.check("长剑满级:无购买钮+状态「已满级」+长枪派生解锁出解锁钮消失(练满通道)〔锻造工坊批 V13〕",
|
||
rows.sword.get("buy_btn") == null and String(rows.sword.status_l.text) == "已满级"
|
||
and rows.spear.get("unlock_btn") == null and rows.spear.get("buy_btn") != null)
|
||
|
||
# ⑦ 三意图信号外发(UI 只发意图——按真实按钮路径;选中钮直发信号面)
|
||
buys.clear(); unlocks.clear(); selects.clear()
|
||
rows.spear.buy_btn.pressed.emit() # 长枪已派生解锁——真实按钮路径
|
||
rows.heavy.unlock_btn.pressed.emit() # 重甲待解锁——真实按钮路径
|
||
ov.forge_select_requested.emit("spear") # 选中意图(当前行选中钮禁用态——信号面直发)
|
||
Kit.check("三意图信号外发(buy=spear/unlock=heavy/select=spear——UI 只发意图)〔锻造工坊批 V13〕",
|
||
buys == ["spear"] and unlocks == ["heavy"] and selects == ["spear"])
|
||
|
||
# 尾清(测试文件绝不残留)
|
||
ov.queue_free()
|
||
for suffix in ["", ".tmp", ".corrupt.bak"]:
|
||
if FileAccess.file_exists(_TEST_SAVE + suffix):
|
||
DirAccess.remove_absolute(_TEST_SAVE + suffix)
|
||
quit(Kit.finish("forge_workbench_test"))
|