Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
145 lines
6.9 KiB
GDScript
145 lines
6.9 KiB
GDScript
extends SceneTree
|
|
|
|
var _checks := 0
|
|
var _failures := 0
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
func _run() -> void:
|
|
print("S0: domain events")
|
|
_test_snapshot_id_cache()
|
|
_test_single_publish_and_snapshot()
|
|
_test_atomic_batch_and_reentrant_delivery()
|
|
_test_batch_rejection_is_atomic()
|
|
if _failures == 0:
|
|
print("PASS: %d checks" % _checks)
|
|
else:
|
|
push_error("FAIL: %d of %d checks failed" % [_failures, _checks])
|
|
quit(_failures)
|
|
|
|
|
|
func _test_single_publish_and_snapshot() -> void:
|
|
var stream := DomainEventStream.new()
|
|
var delivery_order: Array[StringName] = []
|
|
stream.subscribe(&"SERVICE_COMPLETED", &"z_report", func(_event: SimulationDomainEvent) -> void: delivery_order.append(&"z_report"))
|
|
stream.subscribe(&"*", &"a_log", func(_event: SimulationDomainEvent) -> void: delivery_order.append(&"a_log"))
|
|
var event := SimulationDomainEvent.new(
|
|
&"domain_event.000000000001",
|
|
&"SERVICE_COMPLETED",
|
|
360,
|
|
&"facility_service",
|
|
[&"facility.000000000001"],
|
|
{&"quality": 80},
|
|
12
|
|
)
|
|
_expect(event.is_valid(), "complete domain event is valid")
|
|
_expect(stream.publish(event), "new fact is published")
|
|
_expect(delivery_order == [&"a_log", &"z_report"], "subscribers run in stable ID order")
|
|
_expect(not stream.publish(event), "same event ID cannot be applied twice")
|
|
_expect(delivery_order.size() == 2, "duplicate event is not redelivered")
|
|
var snapshot := stream.create_snapshot()
|
|
var restored := DomainEventStream.new()
|
|
_expect(restored.restore_snapshot(snapshot), "published event state restores")
|
|
_expect(restored.has_published(event.event_id), "deduplication IDs survive restore")
|
|
var recent := restored.recent_events()
|
|
_expect(recent.size() == 1 and recent[0].payload[&"quality"] == 80, "recent fact data survives restore")
|
|
|
|
|
|
func _test_atomic_batch_and_reentrant_delivery() -> void:
|
|
var stream := DomainEventStream.new()
|
|
var deliveries: Array[StringName] = []
|
|
var callback_probe := {
|
|
&"second_committed_before_delivery": false,
|
|
&"restore_rejected_during_delivery": false,
|
|
}
|
|
var event_a := _event(&"domain_event.batch.0001", &"A", 400)
|
|
var event_b := _event(&"domain_event.batch.0002", &"B", 400)
|
|
var event_c := _event(&"domain_event.batch.0003", &"C", 400)
|
|
var snapshot_before := stream.create_snapshot()
|
|
stream.subscribe(&"*", &"observer", func(event: SimulationDomainEvent) -> void:
|
|
deliveries.append(event.event_type)
|
|
if event.event_type == &"A":
|
|
callback_probe[&"second_committed_before_delivery"] = stream.has_published(event_b.event_id)
|
|
callback_probe[&"restore_rejected_during_delivery"] = not stream.restore_snapshot(snapshot_before)
|
|
_expect(stream.publish_batch([event_c]), "reentrant publication is accepted after the committed batch")
|
|
)
|
|
_expect(stream.publish_batch([event_a, event_b]), "valid event batch commits")
|
|
_expect(bool(callback_probe[&"second_committed_before_delivery"]), "every batch ID is committed before the first callback")
|
|
_expect(bool(callback_probe[&"restore_rejected_during_delivery"]), "subscriber cannot replace stream state during delivery")
|
|
_expect(deliveries == [&"A", &"B", &"C"], "reentrant event delivery waits behind the complete batch")
|
|
_expect(
|
|
stream.has_published(event_a.event_id) \
|
|
and stream.has_published(event_b.event_id) \
|
|
and stream.has_published(event_c.event_id),
|
|
"batch and reentrant event IDs are all retained"
|
|
)
|
|
stream.unsubscribe(&"*", &"observer")
|
|
|
|
|
|
func _test_batch_rejection_is_atomic() -> void:
|
|
var stream := DomainEventStream.new()
|
|
var deliveries: Array[StringName] = []
|
|
stream.subscribe(&"*", &"observer", func(event: SimulationDomainEvent) -> void:
|
|
deliveries.append(event.event_type)
|
|
)
|
|
var valid := _event(&"domain_event.reject.0001", &"VALID", 500)
|
|
var duplicate := _event(&"domain_event.reject.0001", &"DUPLICATE", 500)
|
|
var before := stream.create_snapshot()
|
|
_expect(not stream.publish_batch([valid, duplicate]), "duplicate ID inside a batch is rejected")
|
|
_expect(stream.create_snapshot() == before and deliveries.is_empty(), "duplicate batch rejection has no state or notification prefix")
|
|
var invalid := _event(&"domain_event.reject.0002", &"INVALID", 500)
|
|
invalid.event_type = &""
|
|
_expect(not stream.publish_batch([valid, invalid]), "invalid member rejects the whole batch")
|
|
_expect(stream.create_snapshot() == before and deliveries.is_empty(), "invalid batch rejection remains atomic")
|
|
_expect(stream.publish(valid), "single publish still delegates to the batch boundary")
|
|
var after_valid := stream.create_snapshot()
|
|
_expect(not stream.publish_batch([_event(&"domain_event.reject.0003", &"NEW", 500), valid]), "collision with published history rejects the whole batch")
|
|
_expect(stream.create_snapshot() == after_valid and deliveries == [&"VALID"], "history collision cannot commit a new prefix")
|
|
var oversized: Array = []
|
|
oversized.resize(DomainEventStream.MAX_BATCH_SIZE + 1)
|
|
_expect(not stream.publish_batch(oversized), "oversized batch is rejected before member access")
|
|
_expect(stream.create_snapshot() == after_valid, "oversized rejection preserves history")
|
|
|
|
|
|
func _event(event_id: StringName, event_type: StringName, minute: int) -> SimulationDomainEvent:
|
|
return SimulationDomainEvent.new(
|
|
event_id,
|
|
event_type,
|
|
minute,
|
|
&"test",
|
|
[],
|
|
{},
|
|
0
|
|
)
|
|
|
|
func _expect(condition: bool, label: String) -> void:
|
|
_checks += 1
|
|
if condition:
|
|
print(" ✓ %s" % label)
|
|
return
|
|
_failures += 1
|
|
push_error(" ✗ %s" % label)
|
|
|
|
|
|
func _test_snapshot_id_cache() -> void:
|
|
var stream := DomainEventStream.new()
|
|
var ids: Array[String] = ["z", "a", "A", "a10", "a2", String.chr(0x1f333), String.chr(0x3042)]
|
|
_expect(stream.restore_snapshot({"version":1,"published_ids":ids,"recent_events":[]}), "restore unsorted history fixture")
|
|
var expected := ids.duplicate()
|
|
expected.sort_custom(func(a: String,b: String):return a < b)
|
|
var first := stream.create_snapshot()
|
|
_expect(first["published_ids"] == expected, "native string sort preserves reference order including Unicode")
|
|
first["published_ids"].clear()
|
|
_expect(stream.create_snapshot()["published_ids"] == expected, "returned ID array cannot corrupt cached history")
|
|
var event := SimulationDomainEvent.new(&"new_id", &"TEST", 360, &"test", [], {}, 1)
|
|
_expect(stream.publish(event), "publish invalidates cached IDs")
|
|
expected.append("new_id");expected.sort()
|
|
_expect(stream.create_snapshot()["published_ids"] == expected, "new ID appears once after cached snapshot")
|
|
_expect(not stream.publish(event) and stream.create_snapshot()["published_ids"] == expected, "rejected duplicate preserves cached state")
|
|
_expect(stream.restore_snapshot({"version":1,"published_ids":["replacement"],"recent_events":[]}), "replace history through restore")
|
|
_expect(stream.create_snapshot()["published_ids"] == ["replacement"], "restore invalidates old sorted cache")
|
|
var valid := stream.create_snapshot()
|
|
_expect(not stream.restore_snapshot({"version":1,"published_ids":["duplicate","duplicate"],"recent_events":[]}), "invalid restore rejected")
|
|
_expect(stream.create_snapshot() == valid, "failed restore preserves canonical snapshot")
|