package eventbus import ( "testing" "time" ) func TestPubSub(t *testing.T) { bus := New() ch, unsub := bus.Subscribe("task-1") defer unsub() bus.Log("task-1", "hello") bus.Phase("task-1", "summoning") bus.Complete("task-1", "essence-abc") got := []string{} for ev := range ch { got = append(got, string(ev.Type)+":"+ev.Data) if ev.Type == EventComplete { break } } if len(got) != 3 { t.Fatalf("expected 3 events, got %d: %v", len(got), got) } if got[0] != "log:hello" { t.Errorf("first event: %s", got[0]) } if got[2] != "complete:essence-abc" { t.Errorf("last event: %s", got[2]) } } func TestTopicIsolation(t *testing.T) { bus := New() ch1, _ := bus.Subscribe("task-1") ch2, _ := bus.Subscribe("task-2") bus.Log("task-1", "only-for-1") bus.Log("task-2", "only-for-2") select { case ev := <-ch1: if ev.Data != "only-for-1" { t.Fatalf("ch1 got %q", ev.Data) } case <-time.After(100 * time.Millisecond): t.Fatal("ch1 timed out") } select { case ev := <-ch2: if ev.Data != "only-for-2" { t.Fatalf("ch2 got %q", ev.Data) } case <-time.After(100 * time.Millisecond): t.Fatal("ch2 timed out") } } func TestUnsubscribe(t *testing.T) { bus := New() ch, unsub := bus.Subscribe("task-x") unsub() // Publishing after unsubscribe should not panic and should not block. bus.Log("task-x", "no-listeners") // Channel should be closed. if _, ok := <-ch; ok { t.Fatal("channel should be closed after unsubscribe") } }