76 lines
3.6 KiB
GDScript
76 lines
3.6 KiB
GDScript
# tests/smoke_boot.gd — 冒烟测试:极小启动场景(这版活着吗——零逻辑判定)
|
||
# 以项目运行目标拉起=真实开机路径:autoload 四件注册在位、配置表全载(fail-fast 通道)、
|
||
# 全局字体与主题可加载、主屏场景实例化、启动态菜单可见。
|
||
# 断言只查存在性与可见性,不做任何玩法逻辑判定;断言完打印摘要并以退出码收口,
|
||
# 判定三闸(退出码+摘要失败数+脚本错误扫描)由外部运行器 tools/run_smoke.py 承担。
|
||
# 运行:python tools/run_smoke.py(本地冒烟测试闸)
|
||
extends Node
|
||
|
||
const MAIN_SCENE_PATH: String = "res://presentation/main.tscn"
|
||
const FONT_PATH: String = "res://assets/fonts/ui_font_fusion_pixel_zh_hans.ttf"
|
||
const THEME_PATH: String = "res://assets/theme/main_theme.tres"
|
||
const BOOT_FRAMES: int = 4 # 主屏装配是逐帧推进的挂树过程,等满再断言(探针族同惯例)
|
||
|
||
var _failures: int = 0
|
||
var _checks: int = 0
|
||
|
||
|
||
func check(cond: bool, label: String) -> void:
|
||
_checks += 1
|
||
if cond:
|
||
print(" [PASS] " + label)
|
||
else:
|
||
_failures += 1
|
||
print(" [FAIL] " + label)
|
||
|
||
|
||
func _ready() -> void:
|
||
_check_autoloads()
|
||
var main: Node = await _boot_main_scene()
|
||
_check_main_scene(main)
|
||
print("[smoke] 摘要:%d 项检查,%d 项失败" % [_checks, _failures])
|
||
get_tree().quit(1 if _failures > 0 else 0)
|
||
|
||
|
||
# 开机前置面:autoload 注册与资源可加载(挂主屏之前先查,失败时主屏断言整段跳过)
|
||
func _check_autoloads() -> void:
|
||
for autoload_name in ["ConfigDB", "RngService", "SaveManager", "MetaProgression"]:
|
||
var node: Node = get_node_or_null(NodePath("/root/" + autoload_name))
|
||
check(node != null, "autoload %s 在位" % autoload_name)
|
||
var db: Node = get_node_or_null(NodePath("/root/ConfigDB"))
|
||
check(db != null and bool(db.get("is_ready")) and db.get("combat") != null and db.get("combat").get("hero") != null,
|
||
"ConfigDB 就绪且配置表全载(is_ready+hero 表在座,校验失败会致命中止)")
|
||
check(load(MAIN_SCENE_PATH) != null, "主屏场景资源可加载(%s)" % MAIN_SCENE_PATH)
|
||
check(load(FONT_PATH) != null, "全局字体资源可加载(%s)" % FONT_PATH)
|
||
check(load(THEME_PATH) != null, "全局主题资源可加载(%s)" % THEME_PATH)
|
||
|
||
|
||
# 以项目运行目标同款方式实例化主屏(真实开机路径——区别于 --script 模式的无 autoload 裸跑)
|
||
func _boot_main_scene() -> Node:
|
||
await get_tree().process_frame
|
||
var packed: PackedScene = load(MAIN_SCENE_PATH) as PackedScene
|
||
if packed == null:
|
||
return null
|
||
var main: Node = packed.instantiate()
|
||
if main == null:
|
||
return null
|
||
add_child(main)
|
||
for i in range(BOOT_FRAMES):
|
||
await get_tree().process_frame
|
||
return main
|
||
|
||
|
||
# 主屏存活面:组合根装配句柄在位(main.X 一级句柄契约,探针挂载假设的启动侧证明)
|
||
func _check_main_scene(main: Node) -> void:
|
||
check(main != null and main.is_inside_tree(), "主屏场景已实例化并在树")
|
||
if main == null:
|
||
return
|
||
var run_scope: Node = main.get("run_scope")
|
||
check(run_scope != null and run_scope.is_inside_tree(), "闲时会话 run_scope 在树")
|
||
var start_overlay: Control = main.get("ui").screens.start_overlay
|
||
check(start_overlay != null and start_overlay.visible, "启动态菜单可见(boot 后玩家见菜单)")
|
||
check(main.get("settings_store") != null, "系统设置存储已装配(settings_store)")
|
||
check(main.get("ui").screens.debug_badge != null, "调试入口角标已装配(debug_badge)")
|
||
check(main.get("ui").modals.run.legend_overlay != null, "图例覆盖层已装配(legend_overlay)")
|
||
check(main.get("ui").modals.run.status_panel != null, "局内状态面板已装配(status_panel)")
|