- 删除 design/dev/architecture/adr-0001~0007 共 7 份文件(内容留 git 历史可查) - architecture.md:删「ADR 审计」「ADR 立项清单」两节;清除全文 ADR-000X 注记、QQ 表/S 表 ADR 引用;未决表关闭已落定项(QQ-01/02/03),立项清单在途事项转登记 QQ-11~14;补 A1 生成姿态事实、autoload 四件清单、board_generator 性能姿态;文档状态立「事实源地位」条 - CLAUDE.md:恢复 RNG 单点硬性红线(去 ADR-0007 引用);新增「架构事实唯一源」红线;规范导航架构行标注唯一事实源 - doc-conventions:§5 增「架构事实唯一源」行;§11 活文档清单补架构文档 - registry:architecture.yaml 删 18 处 adr 字段、autoload_set 补 SaveManager/MetaProgression、board_rending 更新为 Node2D 已落地事实;entities.yaml 12 处引用清除 - game/ 代码注释约 60 处清 ADR-000X 引用(事实与日期保留);豁免标记 ADR-0007-exempt → rng-seed-exempt(main.gd/static_scan.sh/architecture.md/06/iter27 五处同步) - GDD/qa 实现报告/research 卡片/roadmap/tests README 引用全清;死链校验 1206 链接 0 死链、gdd_lint 0 不通过 - 代码中 adr/adr5 等为 adventure_runner 既有局部变量名(非 ADR 引用),未动
76 lines
5.8 KiB
GDScript
76 lines
5.8 KiB
GDScript
# tests/run_all.gd — 单元测试统一入口(双载体的逻辑测试调用点,套件 manifest 协议 D2 AC-2b)
|
||
# 用法:godot --headless --path game --script res://tests/run_all.gd (CI 侧包装外部超时:timeout 120s …)
|
||
# 协议:套件清单逐条"套件 → 期望退出码";致命类独立进程(expect=1)。
|
||
# 执行形态:逐套件起独立 Godot 子进程实跑
|
||
#(OS.get_executable_path() 解析本引擎二进制——--script 模式无 autoload/全局标识符,
|
||
# 每个测试文件自带显式实例化夹具,见 tests/README 协议要点)。
|
||
# 场景探针(.tscn 载体)由 CI/轻闸单独步骤调用,不经本入口。
|
||
extends SceneTree
|
||
|
||
|
||
func _init() -> void:
|
||
print("[run_all] unit/contract suite entry — %d suites" % _suites().size())
|
||
if DisplayServer.get_name() != "headless":
|
||
push_warning("[run_all] 建议以 --headless 运行(D2 冒烟协议)")
|
||
var failures := 0
|
||
for suite in _suites():
|
||
failures += _run_suite(suite)
|
||
if failures > 0:
|
||
push_error("[run_all] %d 个套件失败" % failures)
|
||
quit(1)
|
||
return
|
||
print("[run_all] all green (%d suites)" % _suites().size())
|
||
quit(0)
|
||
|
||
|
||
# 套件清单:{ "path": String, "expect": int };致命类(期望非 0)独立进程断言退出码。
|
||
func _suites() -> Array:
|
||
return [
|
||
{"path": "res://tests/unit/example_test.gd", "expect": 0},
|
||
{"path": "res://tests/unit/data_config/config_db_test.gd", "expect": 0},
|
||
{"path": "res://tests/unit/data_config/forge_table_test.gd", "expect": 0}, # 迭代 23 锻造工坊批 T1——六路线 schema 正反(V1)+特效留空(V11)+几何价格梯(V2 半边)
|
||
{"path": "res://tests/unit/data_config/config_db_fatal_oob_test.gd", "expect": 1},
|
||
{"path": "res://tests/unit/data_config/treasure_target_violation_test.gd", "expect": 1}, # 迭代 7 T1——真视窄域护栏
|
||
{"path": "res://tests/unit/data_config/reward_dangling_treasure_test.gd", "expect": 1}, # 迭代 7 T1——秘宝双表校验
|
||
{"path": "res://tests/unit/data_config/rng_service_test.gd", "expect": 0},
|
||
{"path": "res://tests/unit/core/treasure_items_test.gd", "expect": 0}, # 迭代 7 T7——秘宝结构冻结断言面
|
||
{"path": "res://tests/unit/core/breakpoint_resume_test.gd", "expect": 0}, # 迭代 8 卡①/T9——断点往返/续玩确定性/幂等/退出清断点
|
||
{"path": "res://tests/unit/core/curio_refresh_paid_test.gd", "expect": 0}, # 2026-10-06——三选一刷新免费双源+GP 付费档(对齐商店 MC-1:价曲线/优先序/停点清零/钱包单口)
|
||
{"path": "res://tests/unit/presentation/pacing_queue_test.gd", "expect": 0}, # 迭代 8 卡⑦ AC⑤/T9——排空零分叉/零丢行/延迟双态
|
||
{"path": "res://tests/unit/presentation/reward_overlay_test.gd", "expect": 0}, # 迭代 7 hotfix——奖励节点 UI 直验(盲区补漏)
|
||
{"path": "res://tests/unit/presentation/forge_workbench_test.gd", "expect": 0}, # 迭代 23 锻造工坊批 T6——工作间两区六路线 UI 直验(V13 自动化前置面)
|
||
{"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/battle_settlement/skill_unlock_test.gd", "expect": 0}, # 迭代14④ T6——Boss 半血解锁技·容器机制(门谓词/闩不可逆/双面过滤/保底不逼锁定/零扰动)
|
||
{"path": "res://tests/unit/contracts/system_contracts_test.gd", "expect": 0},
|
||
{"path": "res://tests/unit/presentation/ui_font_asset_test.gd", "expect": 0},
|
||
{"path": "res://tests/unit/presentation/terrain_tile_sets_test.gd", "expect": 0},
|
||
# fog_lantern_wiring_test 随提灯载体行退役摘除(迭代 22 T1——V13 旧验证约束同生死;呈现桥换代断言归 T4 阔视野带参数面)
|
||
{"path": "res://tests/unit/core/effect_words_t1_test.gd", "expect": 0},
|
||
{"path": "res://tests/unit/core/treasure_effects_test.gd", "expect": 0}, # 迭代 22 秘宝批 T3——新目录 12 件逐件行为(V7 附属表正常/边界/反例)
|
||
{"path": "res://tests/unit/core/tree_rules_v11_test.gd", "expect": 0}, # 迭代 21 天赋树批 V11——六键合成行闭集校验 # 迭代 20 T1——词表扩签封闭性(V1:新词在册/出域四路被拒/adventure 计数器往返/mod_eq 预评估口径)
|
||
{"path": "res://tests/unit/core/tree_requires_level_test.gd", "expect": 0}, # R1 机制位批 2026-10-13——requires_level 等级阈值前置(schema 四拒一过+判定三态+投影两态)
|
||
{"path": "res://tests/unit/core/pool_case_d_test.gd", "expect": 0}, # 迭代 20 T2——池结构案D 行为(V6 令牌三态/V7 曝光槽 2+1 回退/V8 概率上限解耦提前退役)
|
||
{"path": "res://tests/unit/core/feat_vouchers_test.gd", "expect": 0}, # 迭代 20 T4——凭证五件+留任二件(V9 路由逐件/F-1 存量账/V10 留任路由+AP 属性轴)
|
||
{"path": "res://tests/unit/core/settle_segments_test.gd", "expect": 0}, # 迭代 27 T2——结算五段 Segment(V4:直接 new/编排器接线/真实一轮走段序)
|
||
{"path": "res://tests/unit/presentation/modal_flow_test.gd", "expect": 0}, # 迭代 27 T4——模态编排纯逻辑(V6:直接 new/互斥域谓词/三例外锁/演播后排窗)
|
||
]
|
||
|
||
|
||
func _run_suite(suite: Dictionary) -> int:
|
||
var path: String = suite.get("path", "")
|
||
var expect: int = int(suite.get("expect", 0))
|
||
if path.is_empty():
|
||
push_error("[run_all] suite missing path")
|
||
return 1
|
||
var args := PackedStringArray(["--headless", "--path", ProjectSettings.globalize_path("res://"), "--script", path])
|
||
var out := PackedStringArray()
|
||
var code: int = OS.execute(OS.get_executable_path(), args, out, true, false)
|
||
var text := "\n".join(out)
|
||
print(text)
|
||
if code != expect:
|
||
push_error("[run_all] FAIL %s — 退出码 %d ≠ 期望 %d" % [path, code, expect])
|
||
return 1
|
||
print("[run_all] PASS %s (exit=%d)" % [path, code])
|
||
return 0
|