97 lines
4.5 KiB
GDScript
97 lines
4.5 KiB
GDScript
# 致命类用例(独立进程,期望退出码 1)
|
||
# 甲案词表退役〔架构整改 V3〕——overflow/attack_segments 两死效果通道摘出 EFFECT_KINDS:
|
||
# 向 feats.tres 注入 do.kind="overflow" 与 do.kind="attack_segments" 探针行 → validate_trigger_row
|
||
# 须以 EFFECT_KINDS 出域拒绝(词表闭面收窄——误写即加载致命)。任一违规被放行即回归(退出码 2)。
|
||
# 运行:godot --headless --path game --script res://tests/unit/data_config/effect_kind_retired_test.gd
|
||
extends SceneTree
|
||
|
||
const ConfigDBScript := preload("res://core/config_db.gd")
|
||
const Kit := preload("res://tests/unit/test_kit.gd")
|
||
|
||
const SRC_DIR := "res://data/tables"
|
||
const BAD_OVERFLOW_DIR := "user://effect_kind_fixture_overflow"
|
||
const BAD_SEGMENTS_DIR := "user://effect_kind_fixture_segments"
|
||
const BAD_SPIKE_DIR := "user://effect_kind_fixture_spike"
|
||
const BAD_TRADEKEY_DIR := "user://effect_kind_fixture_tradekey"
|
||
|
||
# 注入探针:死通道 do.kind(甲案摘名两族——各一探针行)
|
||
const PROBE_OVERFLOW := ' {\n "feat_id": "kind_overflow_probe",\n "display_name": "通道探针·溢出",\n "rarity": "common",\n "triggers": [ { "on": "dig_reveal", "when": [], "do": { "kind": "overflow", "value": 50 } } ],\n "desc": "夹具探针——甲案退役词 overflow"\n},\n'
|
||
const PROBE_SEGMENTS := ' {\n "feat_id": "kind_segments_probe",\n "display_name": "通道探针·连珠",\n "rarity": "common",\n "triggers": [ { "on": "dig_reveal", "when": [], "do": { "kind": "attack_segments", "cap": 2, "divisor": 3, "value": 0 } } ],\n "desc": "夹具探针——甲案退役词 attack_segments"\n},\n'
|
||
|
||
|
||
# 注入探针:改写族退役词(改写族清退批 T2)——spike kind 出域与 trade 键出域(各一探针行)
|
||
const PROBE_SPIKE_MODE := ' {
|
||
"feat_id": "kind_spike_probe",
|
||
"display_name": "词表探针·甲",
|
||
"rarity": "common",
|
||
"triggers": [ { "on": "dig_reveal", "when": [], "do": { "kind": "spike", "value": 2 } } ],
|
||
"desc": "夹具探针——改写族退役 kind spike"
|
||
},
|
||
'
|
||
const PROBE_TRADE_KEY := ' {
|
||
"feat_id": "kind_tradekey_probe",
|
||
"display_name": "键闭探针·乙",
|
||
"rarity": "common",
|
||
"triggers": [ { "on": "dig_reveal", "when": [], "do": { "kind": "grant_ap", "trade_hit": 5, "value": 50 } } ],
|
||
"desc": "夹具探针——改写族退役 do 键 trade_hit"
|
||
},
|
||
'
|
||
|
||
|
||
func _inject(dir: String, probe: String) -> bool:
|
||
var path := dir + "/feats.tres"
|
||
var f := FileAccess.open(path, FileAccess.READ)
|
||
if f == null:
|
||
push_error("注入失败:读不到 %s" % path)
|
||
return false
|
||
var s := f.get_as_text()
|
||
f.close()
|
||
var anchor := "rows = ["
|
||
var idx := s.find(anchor)
|
||
if idx < 0:
|
||
push_error("注入失败:锚点 '%s' 未找到(len=%d)" % [anchor, s.length()])
|
||
return false
|
||
var cut := idx + anchor.length()
|
||
s = s.substr(0, cut) + "\n" + probe + s.substr(cut)
|
||
var w := FileAccess.open(path, FileAccess.WRITE)
|
||
if w == null:
|
||
push_error("注入失败:写不开 %s" % path)
|
||
return false
|
||
w.store_string(s)
|
||
w.close()
|
||
return true
|
||
|
||
|
||
func _assert_rejected(bad_dir: String, probe: String, label: String) -> bool:
|
||
# 返回 true=正确拒绝;false=放行或夹具失败(调用方据此退出 2)
|
||
if not Kit.copy_tables(SRC_DIR, bad_dir) or not _inject(bad_dir, probe):
|
||
push_error("[%s] 夹具目录准备失败" % label)
|
||
return false
|
||
var db = ConfigDBScript.new()
|
||
var ok: bool = db.load_tables(bad_dir, false)
|
||
if ok:
|
||
push_error("[%s] 违规表被放行——EFFECT_KINDS 出域校验失守(回归)" % label)
|
||
return false
|
||
if db.diagnostics_count("error") < 1:
|
||
push_error("[%s] 加载被拒但零 error 诊断——校验通道静默化(回归)" % label)
|
||
return false
|
||
print("[%s] 正确拒绝(error 诊断在案——EFFECT_KINDS 出域)" % label)
|
||
return true
|
||
|
||
|
||
func _init() -> void:
|
||
if not _assert_rejected(BAD_OVERFLOW_DIR, PROBE_OVERFLOW, "effect_kind_retired_test/①overflow 出域"):
|
||
quit(2)
|
||
return
|
||
if not _assert_rejected(BAD_SEGMENTS_DIR, PROBE_SEGMENTS, "effect_kind_retired_test/②attack_segments 出域"):
|
||
quit(2)
|
||
return
|
||
if not _assert_rejected(BAD_SPIKE_DIR, PROBE_SPIKE_MODE, "effect_kind_retired_test/③词表闭面:kind=spike 出域拒绝"):
|
||
quit(2)
|
||
return
|
||
if not _assert_rejected(BAD_TRADEKEY_DIR, PROBE_TRADE_KEY, "effect_kind_retired_test/④do 键闭面:trade_hit 出域拒绝"):
|
||
quit(2)
|
||
return
|
||
print("[effect_kind_retired_test] 四探针均正确拒绝(甲案词表退役+改写族清退——退役词/键误写加载致命)〔架构整改 V3〕〔改写族清退 T2〕")
|
||
quit(1)
|