Gododin Gododin Documentation

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)