Linked repository source
examples/ripple_pond/tests/oracle.gd
This read-only view comes from the file in the Gododin repository. It retains its design, example or evidence context.
Download the original file · Return to the guide
extends SceneTree
## The ripple pond's application test (run through the public launcher):
##
## gododin run --project-root <this project> --headless \
## --script res://tests/oracle.gd
##
## It drives the native RipplePond class and the preserved GDScript
## reference (gd_ripples.gd) through the same scripted splash sequence and
## requires byte-identical RGBA8 frames at every checkpoint. It also counts
## the native node's typed `splashed` signal emissions. Pass/fail is the
## process exit status; the sentinel line is the human-readable record.
const GRID := 96
const FRAMES := 600
const EXTENT_CHECKS := [99, 199, 299, 399, 499, 599]
# Deterministic scripted splashes: frame -> [x, y, strength].
const SPLASHES := {
0: [[24, 24, 3.0], [70, 30, -2.5]],
120: [[10, 80, 4.0]],
300: [[48, 50, -3.0], [20, 60, 1.5]],
450: [[80, 15, 2.0]],
}
func _initialize() -> void:
var failures := 0
var native: Node2D = ClassDB.instantiate("RipplePond")
if native == null:
print("GODODIN_RIPPLE_ORACLE_FAIL reason=native_class_absent")
quit(1)
return
# Lambdas capture locals by value, so the count lives in a one-slot array
# (captured by reference) to survive the handler's increments.
var signals_received := [0]
native.splashed.connect(func(_at: Vector2, _strength: float) -> void:
signals_received[0] += 1)
var reference: GdRipples = load("res://gd_ripples.gd").new()
native.set("damping", 0.991)
reference.configure(GRID, GRID)
reference.damping = 0.991
if int(native.call("configure", GRID, GRID)) != 0:
print("GODODIN_RIPPLE_ORACLE_FAIL reason=configure_refused")
quit(1)
return
for frame in FRAMES:
for s in SPLASHES.get(frame, []):
reference.splash(s[0], s[1], s[2])
native.call("splash", s[0], s[1], s[2])
reference.step()
native.call("step")
if frame in EXTENT_CHECKS:
var want: PackedByteArray = reference.frame_bytes()
var got: PackedByteArray = native.call("frame_bytes")
if want != got:
failures += 1
print("ORACLE_FRAME_MISMATCH frame=%d reference_bytes=%d native_bytes=%d" % [
frame, want.size(), got.size()])
var native_steps: int = native.call("get_steps")
if native_steps != FRAMES:
failures += 1
print("ORACLE_STEP_COUNT_MISMATCH native=%d expected=%d" % [native_steps, FRAMES])
if int(native.call("get_splash_count")) != 6:
failures += 1
print("ORACLE_SPLASH_COUNT_MISMATCH native=%d expected=6" % native.call("get_splash_count"))
if signals_received[0] != 6:
failures += 1
print("ORACLE_SIGNAL_COUNT_MISMATCH signals=%d expected=6" % signals_received[0])
if int(native.call("get_last_error")) != 0:
failures += 1
print("ORACLE_UNEXPECTED_LAST_ERROR code=%d" % native.call("get_last_error"))
native.free()
if failures == 0:
print("GODODIN_RIPPLE_ORACLE_PASS frames=%d cells=%d checkpoints=%d signals=6" % [
FRAMES, GRID * GRID, EXTENT_CHECKS.size()])
quit(0)
else:
print("GODODIN_RIPPLE_ORACLE_FAIL failures=%d" % failures)
quit(1)