Files
via/internal/examples/chatroom/rooms_test.go
Jeff Winkler 351bed3ea1 Chatroom 2 (#10)
* Remove unused method. Don't panic if unknown room.

* Need a Connected() check for rooms publishing - don't do the work of rendering for a dead connection

* Make vars private.

* Linter issues

* Remove Connected()

* Mutation observer. Publish 4x / second.

---------

Co-authored-by: João Gonçalves <joao.goncalves01@gmail.com>
2025-11-13 14:39:37 -01:00

100 lines
2.0 KiB
Go

package main
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type Statement struct {
text string
author TestUserInfo
}
type RoomData struct {
convo []Statement
}
type TestUserInfo struct {
Name string
}
func TestRoomsZero(t *testing.T) {
rooms := NewRooms[RoomData, TestUserInfo]()
assert.NotNil(t, rooms)
}
func TestRoomsMany(t *testing.T) {
names := []string{"a", "b"}
rooms := NewRooms[RoomData, TestUserInfo](names...)
assert.NotNil(t, rooms)
assert.Equal(t, 2, len(rooms.names))
// Visit
seen := 0
rooms.Visit(func(name string) { seen++ })
assert.Equal(t, seen, 2)
// GetRoom fail
_, ok := rooms.Get("z")
assert.False(t, ok)
// GetRoom
rm, ok := rooms.Get("a")
assert.True(t, ok)
assert.NotNil(t, rm)
assert.Equal(t, string("a"), rm.Name)
}
type DummySyncable struct {
room *Room[RoomData, TestUserInfo]
timesCalled int
}
func (ds *DummySyncable) Sync() {
// Data() hits deadlock conditions from Publish()
ds.room.GetData()
ds.timesCalled++
}
func TestRoomJoinLeaveChannels(t *testing.T) {
rooms := NewRooms[RoomData, TestUserInfo](string("a"))
rm, _ := rooms.Get("a")
u1 := TestUserInfo{"Bob"}
u1Context := DummySyncable{room: rm}
rooms.Start()
defer rooms.Stop()
uas := UserAndSync[RoomData, TestUserInfo]{user: &u1, sync: &u1Context}
// Joining a room does *not* mark it dirty. It's on the user to call Sync() -
// so the user gets the update immediately.
rm.Join(&uas)
// // Give it time to process
time.Sleep(1 * time.Millisecond)
assert.Equal(t, rm.dirty, false)
assert.Equal(t, len(rm.members), 1)
// Room Data
rm.UpdateData(func(data *RoomData) {
data.convo = append(data.convo, Statement{"Hello", u1})
})
assert.Equal(t, rm.dirty, true)
data := rm.GetData()
assert.Equal(t, len(data.convo), 1)
// BROADCAST to connected users. Clears the dirty flag.
rm.Publish()
time.Sleep(1 * time.Millisecond)
assert.Equal(t, rm.dirty, false)
assert.Equal(t, u1Context.timesCalled, 1)
// Leave
rm.Leave(&u1)
time.Sleep(1 * time.Millisecond)
assert.Equal(t, len(rm.members), 0)
}