From be470607b74fc573be24c10f2c9ae10917bfa801 Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:03:45 +0200 Subject: [PATCH 1/9] docs: feature specification --- .feature-spec.md | 104 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 .feature-spec.md diff --git a/.feature-spec.md b/.feature-spec.md new file mode 100644 index 0000000..0577c09 --- /dev/null +++ b/.feature-spec.md @@ -0,0 +1,104 @@ +# Feature Specification: Rename ChatRoom, ChatRooms and Chatroom to Room + +GitHub Issue: https://github.com/joebew42/ex_chat/issues/11 + +## Summary + +Remove the `Chat` term from `ChatRoom`, `ChatRooms` and `Chatroom` — rename them all to `Room`. +This is a pure rename/refactoring: no behavioural change is expected. All tests must keep passing. + +## Scope + +The rename applies to the application source (`lib/`) and its tests (`test/`). It covers module +names, file names, aliases, atoms, and local function/variable names that carry the `Chat` term. + +The `README.md` contains historical development notes/backlog referencing `ChatRoom(s)`/`chatroom`. +These are a record of past work rather than live code and are **out of scope** for this change. + +## Renames + +### Modules + +| Before | After | +| --- | --- | +| `ExChat.ChatRoom` | `ExChat.Room` | +| `ExChat.ChatRooms` | `ExChat.Rooms` | +| `ExChat.ChatRoomRegistry` | `ExChat.RoomRegistry` | +| `ExChat.UseCases.CreateChatRoom` | `ExChat.UseCases.CreateRoom` | +| `ExChat.UseCases.JoinChatRoom` | `ExChat.UseCases.JoinRoom` | +| `ExChat.UseCases.SendMessageToChatRoom` | `ExChat.UseCases.SendMessageToRoom` | + +### Files + +| Before | After | +| --- | --- | +| `lib/ex_chat/chat_room.ex` | `lib/ex_chat/room.ex` | +| `lib/ex_chat/chat_rooms.ex` | `lib/ex_chat/rooms.ex` | +| `lib/ex_chat/use_cases/create_chat_room.ex` | `lib/ex_chat/use_cases/create_room.ex` | +| `lib/ex_chat/use_cases/join_chat_room.ex` | `lib/ex_chat/use_cases/join_room.ex` | +| `lib/ex_chat/use_cases/send_message_to_chat_room.ex` | `lib/ex_chat/use_cases/send_message_to_room.ex` | +| `test/ex_chat/chat_room_test.exs` | `test/ex_chat/room_test.exs` | +| `test/ex_chat/use_cases/create_chat_room_test.exs` | `test/ex_chat/use_cases/create_room_test.exs` | +| `test/ex_chat/use_cases/join_chat_room_test.exs` | `test/ex_chat/use_cases/join_room_test.exs` | +| `test/ex_chat/use_cases/send_message_to_chat_room_test.exs` | `test/ex_chat/use_cases/send_message_to_room_test.exs` | + +### Atoms, functions and variables + +- `:chatroom_supervisor` → `:room_supervisor` +- `try_join_chatroom/2` → `try_join_room/2` +- local vars `chatroom_pid`, `chatroom_name` → `room_pid`, `room_name` +- any remaining `chatroom`/`chat_room` identifiers in the affected files → `room` + +## Affected files (references to update) + +- `lib/ex_chat/room.ex` (renamed from `chat_room.ex`) +- `lib/ex_chat/rooms.ex` (renamed from `chat_rooms.ex`) +- `lib/ex_chat/application.ex` (`ChatRoomRegistry`, `ChatRooms` children) +- `lib/ex_chat/setup.ex` (`alias ExChat.ChatRooms`, `ChatRooms.create/1`) +- `lib/ex_chat/web/websocket_controller.ex` (use-case aliases and calls) +- `lib/ex_chat/use_cases/create_room.ex`, `join_room.ex`, `send_message_to_room.ex` +- corresponding test files under `test/` + +## Acceptance Criteria + +- No occurrences of `ChatRoom`, `ChatRooms`, `Chatroom`, `chat_room`, `chat_rooms`, or `chatroom` + remain in `lib/` and `test/`. +- The project compiles without warnings related to the rename (`mix compile`). +- All tests pass (`mix test`). + +## Implementation Notes + +- Perform the rename module-by-module (inside-out): domain modules (`Room`, `Rooms`) first, then + use cases, then the web/controller and application wiring, then tests last. +- `git mv` the files to preserve history where possible. +- Verify with `mix test` after the rename is complete. + +## Progress + +Implemented as an inside-out sequence of behaviour-preserving refactors, each committed +separately with the full suite kept green (45 tests, 0 failures) after every step. + +- [x] `ExChat.ChatRoom` → `ExChat.Room` (file `room.ex`, internal `chatroom_name` → `room_name`, references + test) +- [x] `ExChat.ChatRoomRegistry` → `ExChat.RoomRegistry` (application wiring + registry lookups) +- [x] `ExChat.ChatRooms` → `ExChat.Rooms` (file `rooms.ex`, atom `:chatroom_supervisor` → `:room_supervisor`, `try_join_chatroom/2` → `try_join_room/2`, `chatroom_pid`/`chatroom_name` → `room_pid`/`room_name`, all references + tests) +- [x] `ExChat.UseCases.CreateChatRoom` → `ExChat.UseCases.CreateRoom` (file + controller alias/call + test) +- [x] `ExChat.UseCases.JoinChatRoom` → `ExChat.UseCases.JoinRoom` (file + controller alias/call + test) +- [x] `ExChat.UseCases.SendMessageToChatRoom` → `ExChat.UseCases.SendMessageToRoom` (file + controller alias/call + test) +- [x] Acceptance-test room-name data `a_chat_room` → `a_room` + +### Verification + +- `mix test`: 45 tests, 0 failures. +- `mix compile --warnings-as-errors`: `ex_chat` compiles clean (only pre-existing warnings come + from the third-party `plug` dependency). +- `grep -riE 'chatroom|chat_room|chat_rooms|chatrooms' lib test`: no matches. + +### Key decisions + +- The user-facing welcome copy `"welcome to the #{room} chat room, ..."` uses "chat room" with a + **space**, which matches none of the acceptance grep patterns and reads as product copy, so it + was intentionally left unchanged. +- `README.md` was left untouched, per the out-of-scope note. +- Files were moved with `git mv` to preserve history. +- Final commit-history shaping (e.g. folding this progress note into the `docs:` commit) is left to + `/3-organize-commits`. From f977bc7fed5648834c051076091dbfd8ebebb146 Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:07:00 +0200 Subject: [PATCH 2/9] refactor: rename ExChat.ChatRoom to ExChat.Room --- lib/ex_chat/chat_rooms.ex | 8 ++++---- lib/ex_chat/{chat_room.ex => room.ex} | 10 +++++----- test/ex_chat/{chat_room_test.exs => room_test.exs} | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) rename lib/ex_chat/{chat_room.ex => room.ex} (78%) rename test/ex_chat/{chat_room_test.exs => room_test.exs} (67%) diff --git a/lib/ex_chat/chat_rooms.ex b/lib/ex_chat/chat_rooms.ex index 9c4cd06..66b9c1d 100644 --- a/lib/ex_chat/chat_rooms.ex +++ b/lib/ex_chat/chat_rooms.ex @@ -1,7 +1,7 @@ defmodule ExChat.ChatRooms do use DynamicSupervisor - alias ExChat.{ChatRoom, ChatRoomRegistry} + alias ExChat.{Room, ChatRoomRegistry} ############## # Client API # @@ -28,13 +28,13 @@ defmodule ExChat.ChatRooms do def send(message, [to: room, as: session_id]) do case find(room) do - {:ok, pid} -> ChatRoom.send(pid, message, as: session_id) + {:ok, pid} -> Room.send(pid, message, as: session_id) error -> error end end defp try_join_chatroom(chatroom_pid, session_id) do - case ChatRoom.join(chatroom_pid, session_id) do + case Room.join(chatroom_pid, session_id) do :ok -> :ok {:error, :already_joined} -> @@ -64,6 +64,6 @@ defmodule ExChat.ChatRooms do defp start(chatroom_name) do name = {:via, Registry, {ChatRoomRegistry, chatroom_name}} - DynamicSupervisor.start_child(:chatroom_supervisor, {ChatRoom, name}) + DynamicSupervisor.start_child(:chatroom_supervisor, {Room, name}) end end diff --git a/lib/ex_chat/chat_room.ex b/lib/ex_chat/room.ex similarity index 78% rename from lib/ex_chat/chat_room.ex rename to lib/ex_chat/room.ex index bde6f6e..7867feb 100644 --- a/lib/ex_chat/chat_room.ex +++ b/lib/ex_chat/room.ex @@ -1,15 +1,15 @@ -defmodule ExChat.ChatRoom do +defmodule ExChat.Room do use GenServer alias ExChat.UserSessions defstruct session_ids: [], name: nil - def create(name = {:via, Registry, {_registry_name, chatroom_name}}) do - GenServer.start_link(__MODULE__, %__MODULE__{name: chatroom_name}, name: name) + def create(name = {:via, Registry, {_registry_name, room_name}}) do + GenServer.start_link(__MODULE__, %__MODULE__{name: room_name}, name: name) end - def create(chatroom_name) do - GenServer.start_link(__MODULE__, %__MODULE__{name: chatroom_name}, name: String.to_atom(chatroom_name)) + def create(room_name) do + GenServer.start_link(__MODULE__, %__MODULE__{name: room_name}, name: String.to_atom(room_name)) end def start_link(name), do: create(name) diff --git a/test/ex_chat/chat_room_test.exs b/test/ex_chat/room_test.exs similarity index 67% rename from test/ex_chat/chat_room_test.exs rename to test/ex_chat/room_test.exs index 5a4354c..9ae4780 100644 --- a/test/ex_chat/chat_room_test.exs +++ b/test/ex_chat/room_test.exs @@ -1,14 +1,14 @@ -defmodule ExChat.ChatRoomTest do +defmodule ExChat.RoomTest do use ExUnit.Case, async: false import Mock alias ExChat.UserSessions - alias ExChat.ChatRoom + alias ExChat.Room test "notify subscribed user session when message is received" do - {:ok, chatroom} = ChatRoom.create("room_name") - ChatRoom.join(chatroom, "a-user-session-id") + {:ok, room} = Room.create("room_name") + Room.join(room, "a-user-session-id") with_mock UserSessions, [notify: fn(_message, [to: _user_session_id]) -> :ok end] do expected_message = %{ @@ -17,7 +17,7 @@ defmodule ExChat.ChatRoomTest do message: "a message" } - ChatRoom.send(chatroom, "a message", as: "another-user-session-id") + Room.send(room, "a message", as: "another-user-session-id") assert called UserSessions.notify(expected_message, to: "a-user-session-id") end From 4d17d6720e6b059851c8c39f8bc6bd9e45eb702f Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:07:16 +0200 Subject: [PATCH 3/9] refactor: rename ExChat.ChatRoomRegistry to ExChat.RoomRegistry --- lib/ex_chat/application.ex | 2 +- lib/ex_chat/chat_rooms.ex | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ex_chat/application.ex b/lib/ex_chat/application.ex index 100e59a..a37d696 100644 --- a/lib/ex_chat/application.ex +++ b/lib/ex_chat/application.ex @@ -12,7 +12,7 @@ defmodule ExChat.Application do def init(:ok) do children = [ - {Registry, keys: :unique, name: ExChat.ChatRoomRegistry}, + {Registry, keys: :unique, name: ExChat.RoomRegistry}, {Registry, keys: :unique, name: ExChat.UserSessionRegistry}, ExChat.ChatRooms, ExChat.UserSessions, diff --git a/lib/ex_chat/chat_rooms.ex b/lib/ex_chat/chat_rooms.ex index 66b9c1d..e08f140 100644 --- a/lib/ex_chat/chat_rooms.ex +++ b/lib/ex_chat/chat_rooms.ex @@ -1,7 +1,7 @@ defmodule ExChat.ChatRooms do use DynamicSupervisor - alias ExChat.{Room, ChatRoomRegistry} + alias ExChat.{Room, RoomRegistry} ############## # Client API # @@ -43,7 +43,7 @@ defmodule ExChat.ChatRooms do end defp find(room) do - case Registry.lookup(ChatRoomRegistry, room) do + case Registry.lookup(RoomRegistry, room) do [] -> {:error, :unexisting_room} [{pid, nil}] -> {:ok, pid} end @@ -62,7 +62,7 @@ defmodule ExChat.ChatRooms do end defp start(chatroom_name) do - name = {:via, Registry, {ChatRoomRegistry, chatroom_name}} + name = {:via, Registry, {RoomRegistry, chatroom_name}} DynamicSupervisor.start_child(:chatroom_supervisor, {Room, name}) end From 52d2ca1332c743aff8a147ef8eafd1283096ad09 Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:08:18 +0200 Subject: [PATCH 4/9] refactor: rename ExChat.ChatRooms to ExChat.Rooms --- lib/ex_chat/application.ex | 2 +- lib/ex_chat/{chat_rooms.ex => rooms.ex} | 16 ++++++++-------- lib/ex_chat/setup.ex | 4 ++-- lib/ex_chat/use_cases/create_chat_room.ex | 4 ++-- lib/ex_chat/use_cases/join_chat_room.ex | 4 ++-- .../use_cases/send_message_to_chat_room.ex | 4 ++-- test/ex_chat/use_cases/create_chat_room_test.exs | 10 +++++----- test/ex_chat/use_cases/join_chat_room_test.exs | 8 ++++---- .../use_cases/send_message_to_chat_room_test.exs | 10 +++++----- 9 files changed, 31 insertions(+), 31 deletions(-) rename lib/ex_chat/{chat_rooms.ex => rooms.ex} (72%) diff --git a/lib/ex_chat/application.ex b/lib/ex_chat/application.ex index a37d696..5d703e1 100644 --- a/lib/ex_chat/application.ex +++ b/lib/ex_chat/application.ex @@ -14,7 +14,7 @@ defmodule ExChat.Application do children = [ {Registry, keys: :unique, name: ExChat.RoomRegistry}, {Registry, keys: :unique, name: ExChat.UserSessionRegistry}, - ExChat.ChatRooms, + ExChat.Rooms, ExChat.UserSessions, ExChat.AccessTokenRepository, ExChat.Setup, diff --git a/lib/ex_chat/chat_rooms.ex b/lib/ex_chat/rooms.ex similarity index 72% rename from lib/ex_chat/chat_rooms.ex rename to lib/ex_chat/rooms.ex index e08f140..6f66d0a 100644 --- a/lib/ex_chat/chat_rooms.ex +++ b/lib/ex_chat/rooms.ex @@ -1,4 +1,4 @@ -defmodule ExChat.ChatRooms do +defmodule ExChat.Rooms do use DynamicSupervisor alias ExChat.{Room, RoomRegistry} @@ -20,7 +20,7 @@ defmodule ExChat.ChatRooms do def join(room, [as: session_id]) do case find(room) do {:ok, pid} -> - try_join_chatroom(pid, session_id) + try_join_room(pid, session_id) {:error, :unexisting_room} -> {:error, :unexisting_room} end @@ -33,8 +33,8 @@ defmodule ExChat.ChatRooms do end end - defp try_join_chatroom(chatroom_pid, session_id) do - case Room.join(chatroom_pid, session_id) do + defp try_join_room(room_pid, session_id) do + case Room.join(room_pid, session_id) do :ok -> :ok {:error, :already_joined} -> @@ -54,16 +54,16 @@ defmodule ExChat.ChatRooms do #################### def start_link(_opts) do - DynamicSupervisor.start_link(__MODULE__, [], name: :chatroom_supervisor) + DynamicSupervisor.start_link(__MODULE__, [], name: :room_supervisor) end def init(_) do DynamicSupervisor.init(strategy: :one_for_one) end - defp start(chatroom_name) do - name = {:via, Registry, {RoomRegistry, chatroom_name}} + defp start(room_name) do + name = {:via, Registry, {RoomRegistry, room_name}} - DynamicSupervisor.start_child(:chatroom_supervisor, {Room, name}) + DynamicSupervisor.start_child(:room_supervisor, {Room, name}) end end diff --git a/lib/ex_chat/setup.ex b/lib/ex_chat/setup.ex index dcc79a5..b75b075 100644 --- a/lib/ex_chat/setup.ex +++ b/lib/ex_chat/setup.ex @@ -1,13 +1,13 @@ defmodule ExChat.Setup do use Task, restart: :transient - alias ExChat.ChatRooms + alias ExChat.Rooms def start_link(_args) do Task.start_link(__MODULE__, :run, []) end def run() do - ChatRooms.create("default") + Rooms.create("default") end end diff --git a/lib/ex_chat/use_cases/create_chat_room.ex b/lib/ex_chat/use_cases/create_chat_room.ex index b1a312b..6872744 100644 --- a/lib/ex_chat/use_cases/create_chat_room.ex +++ b/lib/ex_chat/use_cases/create_chat_room.ex @@ -1,9 +1,9 @@ defmodule ExChat.UseCases.CreateChatRoom do - alias ExChat.ChatRooms + alias ExChat.Rooms def on(room) do - case ChatRooms.create(room) do + case Rooms.create(room) do :ok -> {:ok, "#{room} has been created!"} {:error, :already_exists} -> diff --git a/lib/ex_chat/use_cases/join_chat_room.ex b/lib/ex_chat/use_cases/join_chat_room.ex index 713d744..efe343c 100644 --- a/lib/ex_chat/use_cases/join_chat_room.ex +++ b/lib/ex_chat/use_cases/join_chat_room.ex @@ -1,9 +1,9 @@ defmodule ExChat.UseCases.JoinChatRoom do - alias ExChat.{ChatRooms, UserSessions} + alias ExChat.{Rooms, UserSessions} def on(room, user_id) do - case ChatRooms.join(room, as: user_id) do + case Rooms.join(room, as: user_id) do :ok -> UserSessions.notify(%{room: room, message: "welcome to the #{room} chat room, #{user_id}!"}, to: user_id) :ok diff --git a/lib/ex_chat/use_cases/send_message_to_chat_room.ex b/lib/ex_chat/use_cases/send_message_to_chat_room.ex index 0d69348..5fb99d8 100644 --- a/lib/ex_chat/use_cases/send_message_to_chat_room.ex +++ b/lib/ex_chat/use_cases/send_message_to_chat_room.ex @@ -1,9 +1,9 @@ defmodule ExChat.UseCases.SendMessageToChatRoom do - alias ExChat.ChatRooms + alias ExChat.Rooms def on(message, room, user_id) do - case ChatRooms.send(message, to: room, as: user_id) do + case Rooms.send(message, to: room, as: user_id) do :ok -> :ok {:error, :unexisting_room} -> diff --git a/test/ex_chat/use_cases/create_chat_room_test.exs b/test/ex_chat/use_cases/create_chat_room_test.exs index 1fa303f..4816874 100644 --- a/test/ex_chat/use_cases/create_chat_room_test.exs +++ b/test/ex_chat/use_cases/create_chat_room_test.exs @@ -3,24 +3,24 @@ defmodule ExChat.UseCases.CreateChatRoomTest do import Mock - alias ExChat.ChatRooms + alias ExChat.Rooms alias ExChat.UseCases.CreateChatRoom test "return an error message when the room already exists" do - with_mock(ChatRooms, create: fn(_) -> {:error, :already_exists} end) do + with_mock(Rooms, create: fn(_) -> {:error, :already_exists} end) do result = CreateChatRoom.on("a room") assert result == {:error, "a room already exists"} - assert called ChatRooms.create("a room") + assert called Rooms.create("a room") end end test "return an successful message when create a room" do - with_mock(ChatRooms, create: fn(_) -> :ok end) do + with_mock(Rooms, create: fn(_) -> :ok end) do result = CreateChatRoom.on("a room") assert result == {:ok, "a room has been created!"} - assert called ChatRooms.create("a room") + assert called Rooms.create("a room") end end end \ No newline at end of file diff --git a/test/ex_chat/use_cases/join_chat_room_test.exs b/test/ex_chat/use_cases/join_chat_room_test.exs index c3ef2b6..00a209a 100644 --- a/test/ex_chat/use_cases/join_chat_room_test.exs +++ b/test/ex_chat/use_cases/join_chat_room_test.exs @@ -3,12 +3,12 @@ defmodule ExChat.UseCases.JoinChatRoomTest do import Mock - alias ExChat.{ChatRooms, UserSessions} + alias ExChat.{Rooms, UserSessions} alias ExChat.UseCases.JoinChatRoom test "return an error message when the chat room does not exists" do with_mocks([ - {ChatRooms, [], join: fn(_, _) -> {:error, :unexisting_room} end}, + {Rooms, [], join: fn(_, _) -> {:error, :unexisting_room} end}, {UserSessions, [], notify: fn(_, _) -> nil end} ]) do result = JoinChatRoom.on("a room", "a user id") @@ -20,7 +20,7 @@ defmodule ExChat.UseCases.JoinChatRoomTest do test "return an error message when already joined the chat room" do with_mocks([ - {ChatRooms, [], join: fn(_, _) -> {:error, :already_joined} end}, + {Rooms, [], join: fn(_, _) -> {:error, :already_joined} end}, {UserSessions, [], notify: fn(_, _) -> nil end} ]) do result = JoinChatRoom.on("a room", "a user id") @@ -32,7 +32,7 @@ defmodule ExChat.UseCases.JoinChatRoomTest do test "notifies user sessions when joining a chat room" do with_mocks([ - {ChatRooms, [], join: fn(_, _) -> :ok end}, + {Rooms, [], join: fn(_, _) -> :ok end}, {UserSessions, [], notify: fn(_, _) -> nil end} ]) do result = JoinChatRoom.on("a room", "a user id") diff --git a/test/ex_chat/use_cases/send_message_to_chat_room_test.exs b/test/ex_chat/use_cases/send_message_to_chat_room_test.exs index 6305349..c9d9d68 100644 --- a/test/ex_chat/use_cases/send_message_to_chat_room_test.exs +++ b/test/ex_chat/use_cases/send_message_to_chat_room_test.exs @@ -3,24 +3,24 @@ defmodule ExChat.UseCases.SendMessageToChatRoomTest do import Mock - alias ExChat.ChatRooms + alias ExChat.Rooms alias ExChat.UseCases.SendMessageToChatRoom test "return an error message when the room does not exists" do - with_mock(ChatRooms, send: fn(_, _) -> {:error, :unexisting_room} end) do + with_mock(Rooms, send: fn(_, _) -> {:error, :unexisting_room} end) do result = SendMessageToChatRoom.on("a message", "a room", "a user id") assert result == {:error, "a room does not exists"} - assert called ChatRooms.send("a message", to: "a room", as: "a user id") + assert called Rooms.send("a message", to: "a room", as: "a user id") end end test "return ok when send a message" do - with_mock(ChatRooms, send: fn(_, _) -> :ok end) do + with_mock(Rooms, send: fn(_, _) -> :ok end) do result = SendMessageToChatRoom.on("a message", "a room", "a user id") assert result == :ok - assert called ChatRooms.send("a message", to: "a room", as: "a user id") + assert called Rooms.send("a message", to: "a room", as: "a user id") end end end \ No newline at end of file From 78382ace9a2159a5c08da3f2aeda8dc8c4c2cb10 Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:08:42 +0200 Subject: [PATCH 5/9] refactor: rename CreateChatRoom use case to CreateRoom --- .../use_cases/{create_chat_room.ex => create_room.ex} | 2 +- lib/ex_chat/web/websocket_controller.ex | 4 ++-- .../{create_chat_room_test.exs => create_room_test.exs} | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) rename lib/ex_chat/use_cases/{create_chat_room.ex => create_room.ex} (83%) rename test/ex_chat/use_cases/{create_chat_room_test.exs => create_room_test.exs} (76%) diff --git a/lib/ex_chat/use_cases/create_chat_room.ex b/lib/ex_chat/use_cases/create_room.ex similarity index 83% rename from lib/ex_chat/use_cases/create_chat_room.ex rename to lib/ex_chat/use_cases/create_room.ex index 6872744..6cbaebe 100644 --- a/lib/ex_chat/use_cases/create_chat_room.ex +++ b/lib/ex_chat/use_cases/create_room.ex @@ -1,4 +1,4 @@ -defmodule ExChat.UseCases.CreateChatRoom do +defmodule ExChat.UseCases.CreateRoom do alias ExChat.Rooms diff --git a/lib/ex_chat/web/websocket_controller.ex b/lib/ex_chat/web/websocket_controller.ex index cf1a795..2b6e287 100644 --- a/lib/ex_chat/web/websocket_controller.ex +++ b/lib/ex_chat/web/websocket_controller.ex @@ -4,7 +4,7 @@ defmodule ExChat.Web.WebSocketController do end alias ExChat.UseCases.{ValidateAccessToken, SendMessageToChatRoom, - CreateChatRoom, JoinChatRoom, SubscribeToUserSession} + CreateRoom, JoinChatRoom, SubscribeToUserSession} @default_ping_interval 30_000 @default_idle_timeout 60_000 @@ -70,7 +70,7 @@ defmodule ExChat.Web.WebSocketController do end defp handle(%{"command" => "create", "room" => room}, session_id) do - response = case CreateChatRoom.on(room) do + response = case CreateRoom.on(room) do {:ok, message} -> %{success: message} {:error, message} -> %{error: message} end diff --git a/test/ex_chat/use_cases/create_chat_room_test.exs b/test/ex_chat/use_cases/create_room_test.exs similarity index 76% rename from test/ex_chat/use_cases/create_chat_room_test.exs rename to test/ex_chat/use_cases/create_room_test.exs index 4816874..8f3846c 100644 --- a/test/ex_chat/use_cases/create_chat_room_test.exs +++ b/test/ex_chat/use_cases/create_room_test.exs @@ -1,14 +1,14 @@ -defmodule ExChat.UseCases.CreateChatRoomTest do +defmodule ExChat.UseCases.CreateRoomTest do use ExUnit.Case, async: true import Mock alias ExChat.Rooms - alias ExChat.UseCases.CreateChatRoom + alias ExChat.UseCases.CreateRoom test "return an error message when the room already exists" do with_mock(Rooms, create: fn(_) -> {:error, :already_exists} end) do - result = CreateChatRoom.on("a room") + result = CreateRoom.on("a room") assert result == {:error, "a room already exists"} assert called Rooms.create("a room") @@ -17,7 +17,7 @@ defmodule ExChat.UseCases.CreateChatRoomTest do test "return an successful message when create a room" do with_mock(Rooms, create: fn(_) -> :ok end) do - result = CreateChatRoom.on("a room") + result = CreateRoom.on("a room") assert result == {:ok, "a room has been created!"} assert called Rooms.create("a room") From ed95c947c9c47c02a09edd0dffdefa5aa1957681 Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:08:59 +0200 Subject: [PATCH 6/9] refactor: rename JoinChatRoom use case to JoinRoom --- .../use_cases/{join_chat_room.ex => join_room.ex} | 2 +- lib/ex_chat/web/websocket_controller.ex | 4 ++-- .../{join_chat_room_test.exs => join_room_test.exs} | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) rename lib/ex_chat/use_cases/{join_chat_room.ex => join_room.ex} (91%) rename test/ex_chat/use_cases/{join_chat_room_test.exs => join_room_test.exs} (84%) diff --git a/lib/ex_chat/use_cases/join_chat_room.ex b/lib/ex_chat/use_cases/join_room.ex similarity index 91% rename from lib/ex_chat/use_cases/join_chat_room.ex rename to lib/ex_chat/use_cases/join_room.ex index efe343c..f9727cf 100644 --- a/lib/ex_chat/use_cases/join_chat_room.ex +++ b/lib/ex_chat/use_cases/join_room.ex @@ -1,4 +1,4 @@ -defmodule ExChat.UseCases.JoinChatRoom do +defmodule ExChat.UseCases.JoinRoom do alias ExChat.{Rooms, UserSessions} diff --git a/lib/ex_chat/web/websocket_controller.ex b/lib/ex_chat/web/websocket_controller.ex index 2b6e287..cf19ad0 100644 --- a/lib/ex_chat/web/websocket_controller.ex +++ b/lib/ex_chat/web/websocket_controller.ex @@ -4,7 +4,7 @@ defmodule ExChat.Web.WebSocketController do end alias ExChat.UseCases.{ValidateAccessToken, SendMessageToChatRoom, - CreateRoom, JoinChatRoom, SubscribeToUserSession} + CreateRoom, JoinRoom, SubscribeToUserSession} @default_ping_interval 30_000 @default_idle_timeout 60_000 @@ -48,7 +48,7 @@ defmodule ExChat.Web.WebSocketController do end defp handle(%{"command" => "join", "room" => room}, session_id) do - case JoinChatRoom.on(room, session_id) do + case JoinRoom.on(room, session_id) do :ok -> {:ok, session_id} {:error, message} -> diff --git a/test/ex_chat/use_cases/join_chat_room_test.exs b/test/ex_chat/use_cases/join_room_test.exs similarity index 84% rename from test/ex_chat/use_cases/join_chat_room_test.exs rename to test/ex_chat/use_cases/join_room_test.exs index 00a209a..87363dd 100644 --- a/test/ex_chat/use_cases/join_chat_room_test.exs +++ b/test/ex_chat/use_cases/join_room_test.exs @@ -1,17 +1,17 @@ -defmodule ExChat.UseCases.JoinChatRoomTest do +defmodule ExChat.UseCases.JoinRoomTest do use ExUnit.Case, async: true import Mock alias ExChat.{Rooms, UserSessions} - alias ExChat.UseCases.JoinChatRoom + alias ExChat.UseCases.JoinRoom test "return an error message when the chat room does not exists" do with_mocks([ {Rooms, [], join: fn(_, _) -> {:error, :unexisting_room} end}, {UserSessions, [], notify: fn(_, _) -> nil end} ]) do - result = JoinChatRoom.on("a room", "a user id") + result = JoinRoom.on("a room", "a user id") assert result == {:error, "a room does not exists"} refute called UserSessions.notify(%{room: "a room", message: "welcome to the a room chat room, a user id!"}, to: "a user id") @@ -23,7 +23,7 @@ defmodule ExChat.UseCases.JoinChatRoomTest do {Rooms, [], join: fn(_, _) -> {:error, :already_joined} end}, {UserSessions, [], notify: fn(_, _) -> nil end} ]) do - result = JoinChatRoom.on("a room", "a user id") + result = JoinRoom.on("a room", "a user id") assert result == {:error, "you already joined the a room room!"} refute called UserSessions.notify(%{room: "a room", message: "welcome to the a room chat room, a user id!"}, to: "a user id") @@ -35,7 +35,7 @@ defmodule ExChat.UseCases.JoinChatRoomTest do {Rooms, [], join: fn(_, _) -> :ok end}, {UserSessions, [], notify: fn(_, _) -> nil end} ]) do - result = JoinChatRoom.on("a room", "a user id") + result = JoinRoom.on("a room", "a user id") assert result == :ok assert called UserSessions.notify(%{room: "a room", message: "welcome to the a room chat room, a user id!"}, to: "a user id") From a7b4a8334d51da72268a5d65c982274391b0294f Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:09:19 +0200 Subject: [PATCH 7/9] refactor: rename SendMessageToChatRoom use case to SendMessageToRoom --- ...nd_message_to_chat_room.ex => send_message_to_room.ex} | 2 +- lib/ex_chat/web/websocket_controller.ex | 4 ++-- ...o_chat_room_test.exs => send_message_to_room_test.exs} | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) rename lib/ex_chat/use_cases/{send_message_to_chat_room.ex => send_message_to_room.ex} (82%) rename test/ex_chat/use_cases/{send_message_to_chat_room_test.exs => send_message_to_room_test.exs} (69%) diff --git a/lib/ex_chat/use_cases/send_message_to_chat_room.ex b/lib/ex_chat/use_cases/send_message_to_room.ex similarity index 82% rename from lib/ex_chat/use_cases/send_message_to_chat_room.ex rename to lib/ex_chat/use_cases/send_message_to_room.ex index 5fb99d8..26419d3 100644 --- a/lib/ex_chat/use_cases/send_message_to_chat_room.ex +++ b/lib/ex_chat/use_cases/send_message_to_room.ex @@ -1,4 +1,4 @@ -defmodule ExChat.UseCases.SendMessageToChatRoom do +defmodule ExChat.UseCases.SendMessageToRoom do alias ExChat.Rooms diff --git a/lib/ex_chat/web/websocket_controller.ex b/lib/ex_chat/web/websocket_controller.ex index cf19ad0..db1300e 100644 --- a/lib/ex_chat/web/websocket_controller.ex +++ b/lib/ex_chat/web/websocket_controller.ex @@ -3,7 +3,7 @@ defmodule ExChat.Web.WebSocketController do @behaviour :cowboy_websocket end - alias ExChat.UseCases.{ValidateAccessToken, SendMessageToChatRoom, + alias ExChat.UseCases.{ValidateAccessToken, SendMessageToRoom, CreateRoom, JoinRoom, SubscribeToUserSession} @default_ping_interval 30_000 @@ -61,7 +61,7 @@ defmodule ExChat.Web.WebSocketController do end defp handle(%{"room" => room, "message" => message}, session_id) do - case SendMessageToChatRoom.on(message, room, session_id) do + case SendMessageToRoom.on(message, room, session_id) do {:error, message} -> {:reply, {:text, to_json(%{ error: message })}, session_id} :ok -> diff --git a/test/ex_chat/use_cases/send_message_to_chat_room_test.exs b/test/ex_chat/use_cases/send_message_to_room_test.exs similarity index 69% rename from test/ex_chat/use_cases/send_message_to_chat_room_test.exs rename to test/ex_chat/use_cases/send_message_to_room_test.exs index c9d9d68..e42fe09 100644 --- a/test/ex_chat/use_cases/send_message_to_chat_room_test.exs +++ b/test/ex_chat/use_cases/send_message_to_room_test.exs @@ -1,14 +1,14 @@ -defmodule ExChat.UseCases.SendMessageToChatRoomTest do +defmodule ExChat.UseCases.SendMessageToRoomTest do use ExUnit.Case, async: true import Mock alias ExChat.Rooms - alias ExChat.UseCases.SendMessageToChatRoom + alias ExChat.UseCases.SendMessageToRoom test "return an error message when the room does not exists" do with_mock(Rooms, send: fn(_, _) -> {:error, :unexisting_room} end) do - result = SendMessageToChatRoom.on("a message", "a room", "a user id") + result = SendMessageToRoom.on("a message", "a room", "a user id") assert result == {:error, "a room does not exists"} assert called Rooms.send("a message", to: "a room", as: "a user id") @@ -17,7 +17,7 @@ defmodule ExChat.UseCases.SendMessageToChatRoomTest do test "return ok when send a message" do with_mock(Rooms, send: fn(_, _) -> :ok end) do - result = SendMessageToChatRoom.on("a message", "a room", "a user id") + result = SendMessageToRoom.on("a message", "a room", "a user id") assert result == :ok assert called Rooms.send("a message", to: "a room", as: "a user id") From 48cab8c2a84894b5bfa413627ceab226a8e81cac Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:09:39 +0200 Subject: [PATCH 8/9] test: rename a_chat_room test data to a_room --- test/ex_chat/web/websocket_acceptance_test.exs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/ex_chat/web/websocket_acceptance_test.exs b/test/ex_chat/web/websocket_acceptance_test.exs index 4b457a9..073ee1d 100644 --- a/test/ex_chat/web/websocket_acceptance_test.exs +++ b/test/ex_chat/web/websocket_acceptance_test.exs @@ -88,10 +88,10 @@ defmodule ExChat.Web.WebSocketAcceptanceTest do setup :connect_as_a_user test "I receive an error message if the room already exist", %{client: client} do - send_as_text(client, "{\"command\":\"create\",\"room\":\"a_chat_room\"}") - send_as_text(client, "{\"command\":\"create\",\"room\":\"a_chat_room\"}") + send_as_text(client, "{\"command\":\"create\",\"room\":\"a_room\"}") + send_as_text(client, "{\"command\":\"create\",\"room\":\"a_room\"}") - assert_receive "{\"error\":\"a_chat_room already exists\"}" + assert_receive "{\"error\":\"a_room already exists\"}" end test "I receive a successful message", %{client: client} do @@ -105,10 +105,10 @@ defmodule ExChat.Web.WebSocketAcceptanceTest do setup :connect_as_a_user test "I want to receive a welcome message that contain my name and the chat room name", %{client: client} do - send_as_text(client, "{\"command\":\"create\",\"room\":\"a_chat_room\"}") - send_as_text(client, "{\"command\":\"join\",\"room\":\"a_chat_room\"}") + send_as_text(client, "{\"command\":\"create\",\"room\":\"a_room\"}") + send_as_text(client, "{\"command\":\"join\",\"room\":\"a_room\"}") - assert_receive "{\"room\":\"a_chat_room\",\"message\":\"welcome to the a_chat_room chat room, a-user!\"}" + assert_receive "{\"room\":\"a_room\",\"message\":\"welcome to the a_room chat room, a-user!\"}" end end From 05f682d0a8ad531c0377c7876b73470532e6ec81 Mon Sep 17 00:00:00 2001 From: Joe Bew Date: Wed, 1 Jul 2026 08:12:22 +0200 Subject: [PATCH 9/9] revert: docs: feature specification --- .feature-spec.md | 104 ----------------------------------------------- 1 file changed, 104 deletions(-) delete mode 100644 .feature-spec.md diff --git a/.feature-spec.md b/.feature-spec.md deleted file mode 100644 index 0577c09..0000000 --- a/.feature-spec.md +++ /dev/null @@ -1,104 +0,0 @@ -# Feature Specification: Rename ChatRoom, ChatRooms and Chatroom to Room - -GitHub Issue: https://github.com/joebew42/ex_chat/issues/11 - -## Summary - -Remove the `Chat` term from `ChatRoom`, `ChatRooms` and `Chatroom` — rename them all to `Room`. -This is a pure rename/refactoring: no behavioural change is expected. All tests must keep passing. - -## Scope - -The rename applies to the application source (`lib/`) and its tests (`test/`). It covers module -names, file names, aliases, atoms, and local function/variable names that carry the `Chat` term. - -The `README.md` contains historical development notes/backlog referencing `ChatRoom(s)`/`chatroom`. -These are a record of past work rather than live code and are **out of scope** for this change. - -## Renames - -### Modules - -| Before | After | -| --- | --- | -| `ExChat.ChatRoom` | `ExChat.Room` | -| `ExChat.ChatRooms` | `ExChat.Rooms` | -| `ExChat.ChatRoomRegistry` | `ExChat.RoomRegistry` | -| `ExChat.UseCases.CreateChatRoom` | `ExChat.UseCases.CreateRoom` | -| `ExChat.UseCases.JoinChatRoom` | `ExChat.UseCases.JoinRoom` | -| `ExChat.UseCases.SendMessageToChatRoom` | `ExChat.UseCases.SendMessageToRoom` | - -### Files - -| Before | After | -| --- | --- | -| `lib/ex_chat/chat_room.ex` | `lib/ex_chat/room.ex` | -| `lib/ex_chat/chat_rooms.ex` | `lib/ex_chat/rooms.ex` | -| `lib/ex_chat/use_cases/create_chat_room.ex` | `lib/ex_chat/use_cases/create_room.ex` | -| `lib/ex_chat/use_cases/join_chat_room.ex` | `lib/ex_chat/use_cases/join_room.ex` | -| `lib/ex_chat/use_cases/send_message_to_chat_room.ex` | `lib/ex_chat/use_cases/send_message_to_room.ex` | -| `test/ex_chat/chat_room_test.exs` | `test/ex_chat/room_test.exs` | -| `test/ex_chat/use_cases/create_chat_room_test.exs` | `test/ex_chat/use_cases/create_room_test.exs` | -| `test/ex_chat/use_cases/join_chat_room_test.exs` | `test/ex_chat/use_cases/join_room_test.exs` | -| `test/ex_chat/use_cases/send_message_to_chat_room_test.exs` | `test/ex_chat/use_cases/send_message_to_room_test.exs` | - -### Atoms, functions and variables - -- `:chatroom_supervisor` → `:room_supervisor` -- `try_join_chatroom/2` → `try_join_room/2` -- local vars `chatroom_pid`, `chatroom_name` → `room_pid`, `room_name` -- any remaining `chatroom`/`chat_room` identifiers in the affected files → `room` - -## Affected files (references to update) - -- `lib/ex_chat/room.ex` (renamed from `chat_room.ex`) -- `lib/ex_chat/rooms.ex` (renamed from `chat_rooms.ex`) -- `lib/ex_chat/application.ex` (`ChatRoomRegistry`, `ChatRooms` children) -- `lib/ex_chat/setup.ex` (`alias ExChat.ChatRooms`, `ChatRooms.create/1`) -- `lib/ex_chat/web/websocket_controller.ex` (use-case aliases and calls) -- `lib/ex_chat/use_cases/create_room.ex`, `join_room.ex`, `send_message_to_room.ex` -- corresponding test files under `test/` - -## Acceptance Criteria - -- No occurrences of `ChatRoom`, `ChatRooms`, `Chatroom`, `chat_room`, `chat_rooms`, or `chatroom` - remain in `lib/` and `test/`. -- The project compiles without warnings related to the rename (`mix compile`). -- All tests pass (`mix test`). - -## Implementation Notes - -- Perform the rename module-by-module (inside-out): domain modules (`Room`, `Rooms`) first, then - use cases, then the web/controller and application wiring, then tests last. -- `git mv` the files to preserve history where possible. -- Verify with `mix test` after the rename is complete. - -## Progress - -Implemented as an inside-out sequence of behaviour-preserving refactors, each committed -separately with the full suite kept green (45 tests, 0 failures) after every step. - -- [x] `ExChat.ChatRoom` → `ExChat.Room` (file `room.ex`, internal `chatroom_name` → `room_name`, references + test) -- [x] `ExChat.ChatRoomRegistry` → `ExChat.RoomRegistry` (application wiring + registry lookups) -- [x] `ExChat.ChatRooms` → `ExChat.Rooms` (file `rooms.ex`, atom `:chatroom_supervisor` → `:room_supervisor`, `try_join_chatroom/2` → `try_join_room/2`, `chatroom_pid`/`chatroom_name` → `room_pid`/`room_name`, all references + tests) -- [x] `ExChat.UseCases.CreateChatRoom` → `ExChat.UseCases.CreateRoom` (file + controller alias/call + test) -- [x] `ExChat.UseCases.JoinChatRoom` → `ExChat.UseCases.JoinRoom` (file + controller alias/call + test) -- [x] `ExChat.UseCases.SendMessageToChatRoom` → `ExChat.UseCases.SendMessageToRoom` (file + controller alias/call + test) -- [x] Acceptance-test room-name data `a_chat_room` → `a_room` - -### Verification - -- `mix test`: 45 tests, 0 failures. -- `mix compile --warnings-as-errors`: `ex_chat` compiles clean (only pre-existing warnings come - from the third-party `plug` dependency). -- `grep -riE 'chatroom|chat_room|chat_rooms|chatrooms' lib test`: no matches. - -### Key decisions - -- The user-facing welcome copy `"welcome to the #{room} chat room, ..."` uses "chat room" with a - **space**, which matches none of the acceptance grep patterns and reads as product copy, so it - was intentionally left unchanged. -- `README.md` was left untouched, per the out-of-scope note. -- Files were moved with `git mv` to preserve history. -- Final commit-history shaping (e.g. folding this progress note into the `docs:` commit) is left to - `/3-organize-commits`.