Skip to content

Commit

Permalink
Added test for useGameRoom (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
predatorray authored Dec 16, 2024
1 parent 7609f88 commit 25b28d0
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 9 deletions.
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@
"react-app/jest"
]
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{ts,tsx}",
"!<rootDir>/src/index.tsx",
"!<rootDir>/src/setupTests.ts",
"!<rootDir>/src/reportWebVitals.ts",
"!<rootDir>/src/lib/setup.ts"
]
},
"browserslist": {
"production": [
">0.2%",
Expand Down
97 changes: 97 additions & 0 deletions src/lib/useChatRoom.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import useChatRoom, {ChatRoomLike} from "./useChatRoom";
import {renderHook, waitFor} from "@testing-library/react";
import EventEmitter from "eventemitter3";
import {ChatRoomEvents} from "./ChatRoom";

class MockChatRoom implements ChatRoomLike {
listener = new EventEmitter<ChatRoomEvents>();
nameSet: string | undefined;
textMessages: string[] = [];

async setMyName(name: string) {
this.nameSet = name;
}

async sendTextMessage(text: string) {
this.textMessages.push(text);
}
}

describe('useChatRoom', () => {
test('initial names and messages are empty', async () => {
const mockChatRoom = new MockChatRoom();
const { result } = renderHook(() => useChatRoom(mockChatRoom));
const {
names,
messages,
} = result.current;

expect(names.size).toBe(0);
expect(messages.length).toBe(0);
});

test('setMyName', async () => {
const mockChatRoom = new MockChatRoom();
const { result } = renderHook(() => useChatRoom(mockChatRoom));
const {
setMyName,
} = result.current;

setMyName('Alice');
expect(mockChatRoom.nameSet).toBe('Alice');
});

test('sendMessage', async () => {
const mockChatRoom = new MockChatRoom();
const { result } = renderHook(() => useChatRoom(mockChatRoom));
const {
sendMessage,
} = result.current;

sendMessage('text1');
sendMessage('text2');
expect(mockChatRoom.textMessages).toEqual(['text1', 'text2']);
});

test('messages received from listener', async () => {
const mockChatRoom = new MockChatRoom();
const { result } = renderHook(() => useChatRoom(mockChatRoom));

mockChatRoom.listener.emit('text', 'text1', 'p1');
const messageReceived = await waitFor(() => {
expect(result.current.messages.length).toBe(1);
return result.current.messages[0]
});

expect(messageReceived.type).toBe('message');
expect(messageReceived.whose).toBe('p1');
expect(messageReceived.text).toBe('text1');
expect(messageReceived.timestamp).toBeDefined();
});

test('name received from listener', async () => {
const mockChatRoom = new MockChatRoom();
const { result } = renderHook(() => useChatRoom(mockChatRoom));

mockChatRoom.listener.emit('name', 'Alice', 'p1');
let namesUpdated = await waitFor(() => {
expect(result.current.names.size).toBe(1);
return result.current.names;
});

expect(namesUpdated.get('p1')).toBe('Alice');

mockChatRoom.listener.emit('name', 'Bob', 'p1');
await waitFor(() => {
expect(result.current.names.get('p1')).toBe('Bob');
});

mockChatRoom.listener.emit('name', 'Carlie', 'p2');
namesUpdated = await waitFor(() => {
expect(result.current.names.size).toBe(2);
return result.current.names;
});
expect(namesUpdated.get('p1')).toBe('Bob');
expect(namesUpdated.get('p2')).toBe('Carlie');
});
});
28 changes: 19 additions & 9 deletions src/lib/useChatRoom.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {useEffect, useState} from "react";
import {Chat} from "./setup";
import {ChatRoomEvents} from "./ChatRoom";
import {EventListener} from "./types";

export interface Message {
type: 'message';
Expand All @@ -10,7 +12,15 @@ export interface Message {

export type Messages = Message[];

export default function useChatRoom() {
export interface ChatRoomLike {
listener: EventListener<ChatRoomEvents>;
setMyName(name: string): Promise<any>;
sendTextMessage(text: string): Promise<any>;
}

export default function useChatRoom(
chatRoom: ChatRoomLike = Chat,
) {
const [messages, setMessages] = useState<Messages>([]);

useEffect(() => {
Expand All @@ -25,11 +35,11 @@ export default function useChatRoom() {
},
]);
};
Chat.listener.on('text', textListener);
chatRoom.listener.on('text', textListener);
return () => {
Chat.listener.off('text', textListener);
chatRoom.listener.off('text', textListener);
}
}, []);
}, [chatRoom.listener]);

const [names, setNames] = useState(new Map<string, string>());

Expand All @@ -41,18 +51,18 @@ export default function useChatRoom() {
return next;
});
};
Chat.listener.on('name', nameListener);
chatRoom.listener.on('name', nameListener);
return () => {
Chat.listener.off('name', nameListener);
chatRoom.listener.off('name', nameListener);
}
}, []);
}, [chatRoom.listener]);

const setMyName = (name: string) => {
Chat.setMyName(name);
chatRoom.setMyName(name);
};

const sendMessage = (text: string) => {
Chat.sendTextMessage(text);
chatRoom.sendTextMessage(text);
};

return {
Expand Down

0 comments on commit 25b28d0

Please sign in to comment.