aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/tick_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/engine/tick_test.go')
-rw-r--r--internal/engine/tick_test.go62
1 files changed, 62 insertions, 0 deletions
diff --git a/internal/engine/tick_test.go b/internal/engine/tick_test.go
new file mode 100644
index 0000000..520ef19
--- /dev/null
+++ b/internal/engine/tick_test.go
@@ -0,0 +1,62 @@
+package engine
+
+import (
+ "sync"
+ "testing"
+)
+
+// TestProcessTickFiresInSubscriptionOrder asserts the engine invokes due
+// tick subscribers in ascending subscription-ID order, i.e. the order in
+// which they registered. This is the determinism contract that callers
+// (notably the game's master subscriber at cmd/thoi/main.go, which subscribes
+// first as ID 1 and must fire before combat/aggro/respawn per-tick callbacks)
+// increasingly rely on.
+func TestProcessTickFiresInSubscriptionOrder(t *testing.T) {
+ e := New()
+ var mu sync.Mutex
+ var order []int
+
+ // Three interval-1 subscribers. Each appends its own index. All return
+ // true to stay subscribed (we Unsubscribe at the end).
+ id1 := e.Subscribe(1, func() bool {
+ mu.Lock()
+ order = append(order, 1)
+ mu.Unlock()
+ return true
+ })
+ id2 := e.Subscribe(1, func() bool {
+ mu.Lock()
+ order = append(order, 2)
+ mu.Unlock()
+ return true
+ })
+ id3 := e.Subscribe(1, func() bool {
+ mu.Lock()
+ order = append(order, 3)
+ mu.Unlock()
+ return true
+ })
+
+ if id1 >= id2 || id2 >= id3 {
+ t.Fatalf("ID monotonicity broken: got %d, %d, %d", id1, id2, id3)
+ }
+
+ // processTick is synchronous: it invokes every due interval-1 subscriber
+ // inline in turn before returning. So `order` is fully populated here.
+ e.processTick()
+
+ mu.Lock()
+ got := append([]int(nil), order...)
+ mu.Unlock()
+
+ e.Unsubscribe(id1)
+ e.Unsubscribe(id2)
+ e.Unsubscribe(id3)
+
+ if len(got) != 3 {
+ t.Fatalf("expected 3 subscriber firings, got %d: %v", len(got), got)
+ }
+ if got[0] != 1 || got[1] != 2 || got[2] != 3 {
+ t.Errorf("subscribers fired out of registration order: got %v, want [1 2 3]", got)
+ }
+}