Skip to content

Commit

Permalink
Bum deps, add .formatter.exs and test_with_mocks shortcut. (#148)
Browse files Browse the repository at this point in the history
* Bump dependencies - Fix error compiling certifi on tests

* Add .formatter.exs, run 'mix format'

* Add shortcut test_with_mocks
  • Loading branch information
stjhimy authored Dec 16, 2024
1 parent 07081c1 commit f02b284
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 130 deletions.
3 changes: 3 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
169 changes: 122 additions & 47 deletions lib/mock.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ defmodule Mock do
defmacro with_mock(mock_module, opts \\ [], mocks, do: test) do
quote do
unquote(__MODULE__).with_mocks(
[{unquote(mock_module), unquote(opts), unquote(mocks)}], do: unquote(test))
[{unquote(mock_module), unquote(opts), unquote(mocks)}],
do: unquote(test)
)
end
end

Expand Down Expand Up @@ -85,7 +87,11 @@ defmodule Mock do
quote do
test unquote(test_name) do
unquote(__MODULE__).with_mock(
unquote(mock_module), unquote(opts), unquote(mocks), unquote(test_block))
unquote(mock_module),
unquote(opts),
unquote(mocks),
unquote(test_block)
)
end
end
end
Expand Down Expand Up @@ -114,7 +120,11 @@ defmodule Mock do
quote do
test unquote(test_name), unquote(context) do
unquote(__MODULE__).with_mock(
unquote(mock_module), unquote(opts), unquote(mocks), unquote(test_block))
unquote(mock_module),
unquote(opts),
unquote(mocks),
unquote(test_block)
)
end
end
end
Expand All @@ -138,51 +148,52 @@ defmodule Mock do
end

@doc """
Use inside a `with_mock` block to determine whether
a mocked function was called as expected.
Use inside a `with_mock` block to determine whether
a mocked function was called as expected.
Pass `:_` as a function argument for wildcard matches.
Pass `:_` as a function argument for wildcard matches.
## Example
## Example
assert called HTTPotion.get("http://example.com")
assert called HTTPotion.get("http://example.com")
# Matches any invocation
assert called HTTPotion.get(:_)
"""
defmacro called({ {:., _, [ module , f ]} , _, args }) do
# Matches any invocation
assert called HTTPotion.get(:_)
"""
defmacro called({{:., _, [module, f]}, _, args}) do
quote do
:meck.called unquote(module), unquote(f), unquote(args)
:meck.called(unquote(module), unquote(f), unquote(args))
end
end

@doc """
Use inside a `with_mock` block to determine whether
a mocked function was called as expected. If the assertion fails,
the calls that were received are displayed in the assertion message.
Use inside a `with_mock` block to determine whether
a mocked function was called as expected. If the assertion fails,
the calls that were received are displayed in the assertion message.
Pass `:_` as a function argument for wildcard matches.
Pass `:_` as a function argument for wildcard matches.
## Example
## Example
assert_called HTTPotion.get("http://example.com")
assert_called HTTPotion.get("http://example.com")
# Matches any invocation
assert_called HTTPotion.get(:_)
"""
# Matches any invocation
assert_called HTTPotion.get(:_)
"""
defmacro assert_called({{:., _, [module, f]}, _, args}) do
quote do
unquoted_module = unquote(module)
value = :meck.called(unquoted_module, unquote(f), unquote(args))

unless value do
calls = unquoted_module
|> :meck.history()
|> Enum.with_index()
|> Enum.map(fn {{_, {m, f, a}, ret}, i} ->
"#{i}. #{m}.#{f}(#{a |> Enum.map(&Kernel.inspect/1) |> Enum.join(",")}) (returned #{inspect ret})"
end)
|> Enum.join("\n")
calls =
unquoted_module
|> :meck.history()
|> Enum.with_index()
|> Enum.map(fn {{_, {m, f, a}, ret}, i} ->
"#{i}. #{m}.#{f}(#{a |> Enum.map(&Kernel.inspect/1) |> Enum.join(",")}) (returned #{inspect(ret)})"
end)
|> Enum.join("\n")

raise ExUnit.AssertionError,
message: "Expected call but did not receive it. Calls which were received:\n\n#{calls}"
Expand Down Expand Up @@ -213,9 +224,12 @@ defmodule Mock do
num_calls = :meck.num_calls(unquoted_module, unquoted_f, unquoted_args)

if num_calls != unquoted_call_times do
mfa_str = "#{unquoted_module}.#{unquoted_f}(#{unquoted_args |> Enum.map(&Kernel.inspect/1) |> Enum.join(", ")})"
mfa_str =
"#{unquoted_module}.#{unquoted_f}(#{unquoted_args |> Enum.map(&Kernel.inspect/1) |> Enum.join(", ")})"

raise ExUnit.AssertionError,
message: "Expected #{mfa_str} to be called exactly #{unquoted_call_times} time(s), but it was called (number of calls: #{num_calls})"
message:
"Expected #{mfa_str} to be called exactly #{unquoted_call_times} time(s), but it was called (number of calls: #{num_calls})"
end
end
end
Expand Down Expand Up @@ -243,27 +257,30 @@ defmodule Mock do
actual_called_count = :meck.num_calls(unquoted_module, unquoted_f, unquoted_args)

if actual_called_count < unquoted_expected_times do
mfa_str = "#{unquoted_module}.#{unquoted_f}(#{unquoted_args |> Enum.map(&Kernel.inspect/1) |> Enum.join(", ")})"
mfa_str =
"#{unquoted_module}.#{unquoted_f}(#{unquoted_args |> Enum.map(&Kernel.inspect/1) |> Enum.join(", ")})"

raise ExUnit.AssertionError,
message: "Expected #{mfa_str} to be called at least #{unquoted_expected_times} time(s), but it was called (number of calls: #{actual_called_count})"
message:
"Expected #{mfa_str} to be called at least #{unquoted_expected_times} time(s), but it was called (number of calls: #{actual_called_count})"
end
end
end

@doc """
Use inside a `with_mock` block to check if
a mocked function was NOT called. If the assertion fails,
the number of calls is displayed in the assertion message.
Use inside a `with_mock` block to check if
a mocked function was NOT called. If the assertion fails,
the number of calls is displayed in the assertion message.
Pass `:_` as a function argument for wildcard matches.
Pass `:_` as a function argument for wildcard matches.
## Example
## Example
assert_not_called HTTPotion.get("http://example.com")
assert_not_called HTTPotion.get("http://example.com")
# Matches any invocation
assert_not_called HTTPotion.get(:_)
"""
# Matches any invocation
assert_not_called HTTPotion.get(:_)
"""
defmacro assert_not_called({{:., _, [module, f]}, _, args}) do
quote do
unquoted_module = unquote(module)
Expand All @@ -272,9 +289,12 @@ defmodule Mock do
num_calls = :meck.num_calls(unquoted_module, unquoted_f, unquoted_args)

if num_calls > 0 do
mfa_str = "#{unquoted_module}.#{unquoted_f}(#{unquoted_args |> Enum.map(&Kernel.inspect/1) |> Enum.join(", ")})"
mfa_str =
"#{unquoted_module}.#{unquoted_f}(#{unquoted_args |> Enum.map(&Kernel.inspect/1) |> Enum.join(", ")})"

raise ExUnit.AssertionError,
message: "Expected #{mfa_str} not to be called, but it was called (number of calls: #{num_calls})"
message:
"Expected #{mfa_str} not to be called, but it was called (number of calls: #{num_calls})"
end
end
end
Expand Down Expand Up @@ -365,11 +385,65 @@ defmodule Mock do
end
end

@doc """
Shortcut to avoid multiple blocks when a test requires multiple
mocks.
For full description see `test_with_mocks`.
## Example
test_with_mocks "test_name", [{HTTPotion,[],
[get: fn(_url) -> "<html></html>" end]}] do
HTTPotion.get("http://example.com")
assert called HTTPotion.get("http://example.com")
end
"""
defmacro test_with_mocks(test_name, mocks, test_block) do
quote do
test unquote(test_name) do
unquote(__MODULE__).with_mocks(
unquote(mocks),
unquote(test_block)
)
end
end
end

@doc """
Shortcut to avoid multiple blocks when a test requires multiple
mocks. Accepts a context argument enabling information to be shared
between callbacks and the test.
For full description see `test_with_mocks`.
## Example
test_with_mocks "test_name", %{foo: foo} [{HTTPotion,[],
[get: fn(_url) -> "<html></html>" end]}] do
HTTPotion.get("http://example.com")
assert called HTTPotion.get("http://example.com")
assert foo == "bar"
end
"""
defmacro test_with_mocks(test_name, context, mocks, test_block) do
quote do
test unquote(test_name), unquote(context) do
unquote(__MODULE__).with_mocks(
unquote(mocks),
unquote(test_block)
)
end
end
end

######################################################

# Helper macro to mock modules. Intended to be called only within this module
# but not defined as `defmacrop` due to the scope within which it's used.
defmacro mock_modules(mocks) do
quote do
Enum.reduce(unquote(mocks), [], fn({m, opts, mock_fns}, ms) ->
Enum.reduce(unquote(mocks), [], fn {m, opts, mock_fns}, ms ->
unless m in ms do
# :meck.validate will throw an error if trying to validate
# a module that was not mocked
Expand All @@ -385,14 +459,15 @@ defmodule Mock do
unquote(__MODULE__)._install_mock(m, mock_fns)
true = :meck.validate(m)

[ m | ms] |> Enum.uniq
[m | ms] |> Enum.uniq()
end)
end
end

@doc false
def _install_mock(_, []), do: :ok
def _install_mock(mock_module, [ {fn_name, value} | tail ]) do

def _install_mock(mock_module, [{fn_name, value} | tail]) do
:meck.expect(mock_module, fn_name, value)
_install_mock(mock_module, tail)
end
Expand Down
10 changes: 6 additions & 4 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ defmodule Mock.Mixfile do
@version "0.3.8"

def project do
[ app: :mock,
[
app: :mock,
name: "Mock",
version: @version,
elixir: "~> 1.0",
Expand All @@ -13,7 +14,8 @@ defmodule Mock.Mixfile do
test_coverage: [tool: ExCoveralls],
docs: [source_ref: "v#{@version}", main: "Mock"],
preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test],
deps: deps() ]
deps: deps()
]
end

defp deps do
Expand Down Expand Up @@ -49,7 +51,7 @@ defmodule Mock.Mixfile do
"matt.freer",
"Mikhail S. Pobolovets",
"parroty",
"xieyunzi",
"xieyunzi"
],
maintainers: [
"Daniel Olshansky ([email protected])",
Expand All @@ -58,7 +60,7 @@ defmodule Mock.Mixfile do
licenses: ["MIT"],
links: %{
"GitHub" => "https://github.com/jjh42/mock",
"Docs" => "https://jjh42.github.io/mock"
"Docs" => "https://jjh42.github.io/mock"
}
]
end
Expand Down
27 changes: 15 additions & 12 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
%{
"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm", "fdc6066ceeccb3aa14049ab6edf0b9af3b64ae1b0db2a92d5c52146f373bbb1c"},
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
"docs_ghpages": {:git, "https://github.com/jjh42/docs_ghpages.git", "48026d548475a5b03e4a39282d0cbd9d9c4973d6", []},
"earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], [], "hexpm", "3b1dcad3067985dd8618c38399a8ee9c4e652d52a17a4aae7a6d6fc4fcc24856"},
"ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "dc87f778d8260da0189a622f62790f6202af72f2f3dee6e78d91a18dd2fcd137"},
"excoveralls": {:hex, :excoveralls, "0.7.2", "f69ede8c122ccd3b60afc775348a53fc8c39fe4278aee2f538f0d81cc5e7ff3a", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "ef8fc1c6014b16a68dccfba3513aa41283d731eeaf8a1b704bbb072cb1ab89cb"},
"earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"},
"ex_doc": {:hex, :ex_doc, "0.35.1", "de804c590d3df2d9d5b8aec77d758b00c814b356119b3d4455e4b8a8687aecaf", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "2121c6402c8d44b05622677b761371a759143b958c6c19f6558ff64d0aed40df"},
"excoveralls": {:hex, :excoveralls, "0.7.5", "339e433e5d3bce09400dc8de7b9040741a409c93917849916c136a0f51fdc183", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "36422936691b6a8a728fe42c528e7b2719b2fde1a56d19fc7e3de31cb2271017"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"},
"hackney": {:hex, :hackney, "1.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "e38f4a7937b6dfc5fa87403ece26b1826bc81838f09ac57fabf2f7a9885fe818"},
"hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"},
"hoedown": {:git, "https://github.com/hoedown/hoedown.git", "980b9c549b4348d50b683ecee6abee470b98acda", []},
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fc1a2f7340c422650504b1662f28fdf381f34cbd30664e8491744e52c9511d40"},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm", "b4c5d3230b397c8d95579e4a3d72826bb6463160130ccf4182f5be8579b5f44c"},
"makeup": {:hex, :makeup, "0.5.1", "966c5c2296da272d42f1de178c1d135e432662eca795d6dc12e5e8787514edf7", [:mix], [{:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "259748a45dfcf5f49765a7c29c9594791c82de23e22d7a3e6e59533fe8e8935b"},
"makeup_elixir": {:hex, :makeup_elixir, "0.8.0", "1204a2f5b4f181775a0e456154830524cf2207cf4f9112215c05e0b76e4eca8b", [:mix], [{:makeup, "~> 0.5.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "393d17c5a648e3b30522b2a4743bd1dc3533e1227c8c2823ebe8c3a8e5be5913"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"},
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},
"makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"},
"markdown": {:git, "https://github.com/devinus/markdown.git", "d065dbcc4e242a85ca2516fdadd0082712871fd8", []},
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm", "7a4c8e1115a2732a67d7624e28cf6c9f30c66711a9e92928e745c255887ba465"},
"nimble_parsec": {:hex, :nimble_parsec, "0.2.2", "d526b23bdceb04c7ad15b33c57c4526bf5f50aaa70c7c141b4b4624555c68259", [:mix], [], "hexpm", "4ababf5c44164f161872704e1cfbecab3935fdebec66c72905abaad0e6e5cef6"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm", "4f8805eb5c8a939cf2359367cb651a3180b27dfb48444846be2613d79355d65e"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm", "da1d9bef8a092cc7e1e51f1298037a5ddfb0f657fe862dfe7ba4c5807b551c29"},
"mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
}
Loading

0 comments on commit f02b284

Please sign in to comment.