Files
gplan-2/game/tests/unit/contracts/source_guard_test.gd
T

78 lines
4.1 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# tests/unit/contracts/source_guard_test.gd — 仓库自身源码契约单元测试宿主
# 断言面 = 两套(批 B 断言迁移自 smoke_all.gd,G12 施工组;被测对象=仓库自身源文件,
# 主会话裁决五新设 source_guard 子目录归「契约」语义):
# 类型闸(project.godot warning 配置在位 + 审计器闸机接线)
# 卫生件 grep 闸(产品码字符串 Callable/死代码/GP 影子账残留零命中 + 层序落位单口)
# 协议照单元侧惯例:extends SceneTree+Kit.check 主通道;被测面是仓库文件直读
# (FileAccess/DirAccess/project.godot 设置),零表夹具零 RNG。
# 运行:godot --headless --path game --script res://tests/unit/contracts/source_guard_test.gd
extends SceneTree
const Kit := preload("res://tests/unit/test_kit.gd")
func _init() -> void:
# 套执行序沿源编排序(_split_tail 尾段调用序)
_smoke_type_gate()
_smoke_hygiene_gates()
quit(Kit.finish("source_guard_test"))
# ---- 类型闸断言(V7——project.godot warning 配置在位〔源码断言〕+审计器脚本在位;
# 审计器归零判定走 static_scan S9 闸机,此处兜配置面)----
func _smoke_type_gate() -> void:
var pj: String = FileAccess.get_file_as_string("res://project.godot")
Kit.check("V7 类型闸 warning 配置在位(untyped_declaration=1 显形)〔迭代27 T5〕",
pj.contains("gdscript/warnings/untyped_declaration=1"))
var scan_src: String = FileAccess.get_file_as_string("res://tests/static_scan.sh")
Kit.check("V7 类型审计器闸机在位(static_scan S9 → tools/audit_type_hints.py)〔迭代27 T5〕",
scan_src.contains("audit_type_hints.py"))
# ---- 卫生件 grep 闸(V8——死代码/字符串 Callable/影子账残留零命中;源码扫描面)----
func _smoke_hygiene_gates() -> void:
var callables := 0
for d in ["res://core", "res://presentation", "res://data"]:
var dir := DirAccess.open(d)
if dir == null:
continue
dir.list_dir_begin()
var f := dir.get_next()
while f != "":
if dir.current_is_dir() and not f.begins_with("."):
var sub := DirAccess.open(d + "/" + f)
if sub != null:
sub.list_dir_begin()
var g := sub.get_next()
while g != "":
if g.ends_with(".gd"):
var t: String = FileAccess.get_file_as_string(d + "/" + f + "/" + g)
callables += t.count("Callable(self, \"")
g = sub.get_next()
elif f.ends_with(".gd"):
var t2: String = FileAccess.get_file_as_string(d + "/" + f)
callables += t2.count("Callable(self, \"")
f = dir.get_next()
Kit.check("V8 字符串 Callable 产品码零命中(实测应 0——方法引用换装闸)〔迭代27 T6〕",
callables == 0)
Kit.check("V8 FeatsEngine 整文件退役(class_name 注销=文件删除)〔迭代27 T6〕",
not FileAccess.file_exists("res://core/feats_engine.gd"))
var bo: String = FileAccess.get_file_as_string("res://core/battle_orchestrator.gd")
Kit.check("V8 死代码抽查·_attune_row 零残留〔迭代27 T6〕",
not bo.contains("func _attune_row"))
var sm: String = FileAccess.get_file_as_string("res://core/save_manager.gd")
Kit.check("V8 死代码抽查·attunement_counters 零残留〔迭代27 T6〕",
not sm.contains("func attunement_counters"))
var mv: String = FileAccess.get_file_as_string("res://presentation/main.gd")
Kit.check("V8 GP 影子账残留零命中(main 源码面——文件已删+委托缝已拆)〔迭代27 T3〕",
not mv.contains("gp_shadow_ledger") and not mv.contains("_gp_ledger"))
# V1d 层序落位单口:main.gd 的 move_child 调用全部收在 _apply_layer_contract 内(合同装配单口——
# 函数体之外零调用点;出现第二处落位=硬编码层序,须改合同表而非加调用)
var fn_start: int = mv.find("func _apply_layer_contract")
var fn_end: int = mv.find("\nfunc ", fn_start + 10)
if fn_end < 0:
fn_end = mv.length()
var outside_calls: int = (mv.substr(0, fn_start) + mv.substr(fn_end)).count("move_child(")
Kit.check("V1d 层序落位单口(_apply_layer_contract 之外 move_child 调用点=%d 应=0)〔装配生命批 V1〕" % outside_calls,
outside_calls == 0)