565c132848
A Gitea Actions workflow (.gitea/workflows/ci.yml) running the headless test suite on push, plus shared test scaffolding: seeded-RNG / approx / tally helpers (test_helpers.gd), a harness self-test, and a resolution + pseudo-locale UI-layout robustness guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CCyaJPTHCH9EDthpf4A5Sj
48 lines
1.3 KiB
GDScript
48 lines
1.3 KiB
GDScript
class_name TestHelpers
|
|
extends RefCounted
|
|
## Shared primitives for the headless test suite so each test stops re-implementing them: a seeded
|
|
## RNG for determinism, float/vector approximate comparisons, and a small pass/fail tally whose
|
|
## report() doubles as the process exit code. Use the tally directly, or the static helpers alone.
|
|
|
|
var _pass: int = 0
|
|
var _fail: int = 0
|
|
|
|
|
|
# Determinism is the precondition for repeatable AI/physics tests: seed the RNG here instead of the
|
|
# global randf()/randi() so a test replays identically every run.
|
|
static func make_rng(seed_value: int) -> RandomNumberGenerator:
|
|
var rng := RandomNumberGenerator.new()
|
|
rng.seed = seed_value
|
|
return rng
|
|
|
|
|
|
static func approx(a: float, b: float, eps: float = 0.0001) -> bool:
|
|
return absf(a - b) <= eps
|
|
|
|
|
|
static func vec_approx(a: Vector3, b: Vector3, eps: float = 0.0001) -> bool:
|
|
return a.distance_to(b) <= eps
|
|
|
|
|
|
func ok(cond: bool, msg: String) -> void:
|
|
if cond:
|
|
_pass += 1
|
|
print(" PASS: ", msg)
|
|
else:
|
|
_fail += 1
|
|
print(" FAIL: ", msg)
|
|
|
|
|
|
func passed() -> int:
|
|
return _pass
|
|
|
|
|
|
func failed() -> int:
|
|
return _fail
|
|
|
|
|
|
## Prints the tally and returns the process exit code (0 = everything passed).
|
|
func report() -> int:
|
|
print("Results: %d passed, %d failed" % [_pass, _fail])
|
|
return 1 if _fail > 0 else 0
|