Multi-Room Chat (#4)
* # This is a combination of 4 commits. # This is the 1st commit message: Chatroom example # This is the commit message #2: Avatar styling # This is the commit message #3: Styling # This is the commit message #4: cleanup * Chatroom example Avatar styling Benchmark tests Cleanup ignore Files Cleanroom chatroom impl * Rewrite. * changes * Fix Deadlocks. Start the rooms. Fix styling. Random things. Bookmarklet. * Subset data * Rm file * Simplify User. Just Comparable. * Remove method.
This commit is contained in:
100
internal/examples/chatroom/rooms_test.go
Normal file
100
internal/examples/chatroom/rooms_test.go
Normal file
@@ -0,0 +1,100 @@
|
||||
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, rm.MemberCount(), 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, rm.MemberCount(), 0)
|
||||
}
|
||||
Reference in New Issue
Block a user