Skip to content

Instantly share code, notes, and snippets.

View ihumanable's full-sized avatar

Matt Nowack ihumanable

  • San Francisco, CA
View GitHub Profile
@ihumanable
ihumanable / call_graph.ex
Created November 23, 2021 00:38
Patch Call Graph
assert {:bad, :error} == Discord.send_message(%Message{})
# We start at the Facade
Discord.send_message(%Message{}) {
# The Facade calls the Delegate
Delegate.send_message(message) {
# The Delegate checks if the Server has a patch for send_message/1
Server.delegate(Discord, :send_message, [message]) {
# The Server doesn't, so it calls the Original
Original.send_message(message) {
@ihumanable
ihumanable / test_output_patch.ex
Created November 23, 2021 00:38
Test Output (Patch)
~/src/discord > mix test
...
3 tests, 0 failures
@ihumanable
ihumanable / discord_test.exs
Created November 23, 2021 00:37
Invalid Message Test Case with Patch
defmodule Discord.Test do
use ExUnit.Case
use Patch
describe "send_message/1" do
test "errors on invalid messages" do
patch(Discord, :validate_message, {:error, :bad})
assert {:error, :bad} == Discord.send_message(%Message{})
end
end
@ihumanable
ihumanable / discord_original.ex
Created November 23, 2021 00:36
Patch Original for Discord
defmodule Patch.Mock.Original.For.Discord do
alias Patch.Mock.Delegate.For.Discord, as: Delegate
def send_message(%Message{} = message) do
with :ok <- Delegate.validate_message(message),
:ok <- Delegate.save_message(message) do
Delegate.broadcast_message(message)
end
end
@ihumanable
ihumanable / server.ex
Created November 23, 2021 00:36
Patch.Mock.Server delegate/3 simplified
def delegate(module, name, arguments) do
server = Naming.server(module)
case GenServer.call(server, {:delegate, name, arguments}) do
{:ok, reply} ->
reply
:error ->
original = Naming.original(module)
apply(original, name, arguments)
@ihumanable
ihumanable / discord_delegate.ex
Created November 23, 2021 00:35
Patch Delegate for Discord
defmodule Patch.Mock.Delegate.For.Discord do
alias Patch.Mock.Server
def send_message(%Message{} = message) do
Server.delegate(Discord, :send_message, [message])
end
def validate_message(message) do
Server.delegate(Discord, :validate_message, [message])
end
@ihumanable
ihumanable / discord_facade.ex
Created November 23, 2021 00:34
Patch Facade for Discord
defmodule Discord do
alias Patch.Mock.Delegate.For.Discord, as: Delegate
def send_message(%Message{} = message) do
Delegate.send_message(message)
end
end
@ihumanable
ihumanable / patch_example.exs
Created November 23, 2021 00:34
Patch Example
test "something" do
patch(ModuleA, :function_a, :ok)
patch(ModuleA, :function_b, fn arg -> {:ok, arg} end)
patch(ModuleB, :function_c, false)
patch(ModuleB, :function_d, true)
assert Something.here()
end
@ihumanable
ihumanable / mock_example.exs
Created November 23, 2021 00:33
Multiple Mocks Example
test "something" do
with_mocks([
{
ModuleA,
[:passthrough],
function_a: fn _ -> :ok end,
function_b: fn arg ->
{:ok, arg}
end
},
@ihumanable
ihumanable / test_output_mock_3.ex
Created November 23, 2021 00:32
Test Output (Mock 3)
~/src/discord > mix test
1) test send_message/1 errors on invalid messages (Discord.Test)
test/discord_test.exs:7
Assertion with == failed
code: assert {:error, :bad} == Discord.send_message(%Message{})
left: {:error, :bad}
right: :ok
stacktrace:
test/discord_test.exs:9: (test)