feat: W2 经济核心+数据管线+灰盒 — Balance Bible v1.0 八表逐值落地,EconomyState/sim 14 门/灰盒主场景/单测(GDScript 待本机引擎验证)
This commit is contained in:
1 parent
856326a766
commit
24e5b0c4cc
58 files changed
+7099
-22
No files matched your search
@@ -0,0 +1,78 @@
|
||||
extends SceneTree
|
||||
|
||||
# ============================================================================
|
||||
# test_runner.gd —— core 层无头单测入口(GUT 未装前的自包含方案;W3 换 GUT)
|
||||
#
|
||||
# 运行:godot --headless --path . -s res://tests/unit/test_runner.gd
|
||||
# 退出码:0 = 全过;1 = 有失败;2 = 数据/环境错误。
|
||||
# 每个用例文件 = tests/unit/cases/*.gd,契约:func run(a) -> void(a = TestAssert)。
|
||||
# ============================================================================
|
||||
|
||||
class TestAssert extends RefCounted:
|
||||
var failures: Array[String] = []
|
||||
var checks := 0
|
||||
|
||||
func check(cond: bool, msg: String) -> void:
|
||||
checks += 1
|
||||
if not cond:
|
||||
failures.append(msg)
|
||||
|
||||
func eq(got: Variant, want: Variant, msg: String) -> void:
|
||||
checks += 1
|
||||
if got != want:
|
||||
failures.append("%s:got %s want %s" % [msg, str(got), str(want)])
|
||||
|
||||
func near(got: float, want: float, tol: float, msg: String) -> void:
|
||||
checks += 1
|
||||
if absf(float(got) - float(want)) > tol:
|
||||
failures.append("%s:got %.6g want %.6g(tol %g)" % [msg, got, want, tol])
|
||||
|
||||
func true_(cond: bool, msg: String) -> void:
|
||||
check(cond, msg)
|
||||
|
||||
func false_(cond: bool, msg: String) -> void:
|
||||
check(not cond, msg)
|
||||
|
||||
|
||||
const CASE_FILES: Array[String] = [
|
||||
"res://tests/unit/cases/test_number_format.gd",
|
||||
"res://tests/unit/cases/test_economy_formulas.gd",
|
||||
"res://tests/unit/cases/test_balance_data.gd",
|
||||
"res://tests/unit/cases/test_economy_state.gd",
|
||||
]
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var data := BalanceData.load_from_dir("res://data/build/")
|
||||
if not data.load_errors.is_empty():
|
||||
for e in data.load_errors:
|
||||
printerr("test_runner:数据错误:%s" % e)
|
||||
quit(2)
|
||||
return
|
||||
var total_checks := 0
|
||||
var total_fail: Array[String] = []
|
||||
for path in CASE_FILES:
|
||||
var script: Variant = load(path)
|
||||
if script == null:
|
||||
printerr("test_runner:用例缺失 %s" % path)
|
||||
quit(2)
|
||||
return
|
||||
var case_obj: Variant = script.new()
|
||||
if not (case_obj is RefCounted) or not case_obj.has_method("run"):
|
||||
printerr("test_runner:用例契约不符 %s" % path)
|
||||
quit(2)
|
||||
return
|
||||
var a := TestAssert.new()
|
||||
case_obj.run(a, data)
|
||||
total_checks += a.checks
|
||||
for f in a.failures:
|
||||
total_fail.append("%s → %s" % [path.get_file(), f])
|
||||
print("test_runner:%s:%d 检查,%d 失败" % [path.get_file(), a.checks, a.failures.size()])
|
||||
if total_fail.is_empty():
|
||||
print("test_runner:PASS(%d 检查全过)" % total_checks)
|
||||
quit(0)
|
||||
return
|
||||
print("test_runner:FAIL(%d/%d)" % [total_fail.size(), total_checks])
|
||||
for f in total_fail:
|
||||
printerr(" ✗ %s" % f)
|
||||
quit(1)
|
||||
Reference in new issue
Block a user