extends SceneTree const Weather = preload("res://scripts/environment/weather_timeline.gd") var checks := 0 var failures := 0 func expect(ok: bool, message: String) -> void: checks += 1 if not ok: failures += 1; push_error(message) func _initialize() -> void: var weather = Weather.new() expect(not weather.permits_new_arrivals(), "uninitialized weather never grants admission") expect(not weather.initialize(&"unknown", 360) and not weather.initialize(&"clear", 1.5), "invalid initial data rejected") expect(weather.initialize(&"clear", 360), "caller explicitly chooses initial weather and time") expect(not weather.initialize(&"storm", 400), "initialize cannot reset a live simulation") expect(weather.schedule(&"clear", 390)[&"ok"] and weather.schedule(&"storm", 380)[&"ok"] and weather.schedule(&"rain", 370)[&"ok"], "out of order scheduling retains chronological execution") expect(weather.schedule(&"storm", 380)[&"replayed"] and not weather.schedule(&"rain", 380)[&"ok"], "same boundary retry is idempotent and conflict rejected") expect(not weather.schedule(&"storm", 360)[&"ok"], "past and current weather cannot be retroactively changed") var checkpoint: Dictionary = weather.create_snapshot() expect(weather.advance_to(379)[&"changes"] == [{&"from": &"clear", &"to": &"rain", &"minute": 370}], "rain changes at its scheduled time") expect(weather.permits_new_arrivals(), "rain is not treated as a storm admission ban") expect(weather.advance_to(380)[&"changes"].size() == 1 and not weather.permits_new_arrivals(), "storm blocks admission at exact boundary") var storm: Dictionary = weather.create_snapshot() var replay: Dictionary = weather.advance_to(380) expect(replay[&"replayed"] and replay[&"changes"].is_empty() and weather.create_snapshot() == storm, "same minute cannot duplicate a transition") expect(not weather.advance_to(379)[&"ok"] and weather.create_snapshot() == storm, "time reversal cannot change state") expect(weather.advance_to(390)[&"ok"] and weather.permits_new_arrivals(), "clear restores admission") var finished: Dictionary = weather.create_snapshot() expect(weather.restore_snapshot(checkpoint), "restore earlier weather and pending schedule") expect(weather.advance_to(390)[&"changes"].size() == 3 and weather.create_snapshot() == finished, "jump and minute-step replay produce identical weather state") var encoded: Dictionary = bytes_to_var(var_to_bytes(storm)) expect(weather.restore_snapshot(encoded) and weather.get_kind() == &"storm", "production Variant codec preserves integer weather time and IDs") var baseline: Dictionary = weather.create_snapshot() for field: String in ["version", "minute", "kind", "since", "pending"]: var bad := baseline.duplicate(true); bad.erase(field) expect(not weather.restore_snapshot(bad) and weather.create_snapshot() == baseline, "missing field rejects atomically: " + field) for change: Dictionary in [{"version": 2}, {"minute": 380.0}, {"kind": "snow"}, {"since": 381}, {"pending": [{"kind":"clear","minute":380}]}, {"pending": [{"kind":"clear","minute":400},{"kind":"rain","minute":390}]}, {"extra":true}]: var bad := baseline.duplicate(true) bad.merge(change, true) expect(not weather.restore_snapshot(bad) and weather.create_snapshot() == baseline, "malformed or contradictory state rejects atomically") var detached: Dictionary = weather.create_snapshot(); detached[&"pending"].clear() expect(not weather.create_snapshot()[&"pending"].is_empty(), "caller cannot mutate pending weather through snapshot alias") expect(weather.schedule(&"mana_fog", 400)[&"ok"] and weather.advance_to(400)[&"ok"] and weather.get_kind() == &"mana_fog", "mana fog is persisted without invented efficiency multipliers") print("Weather timeline: %d checks, %d failures" % [checks, failures]) quit(failures)