Skip to content

Commit

Permalink
support all type kinds
Browse files Browse the repository at this point in the history
Fixes #41.

Hammox blows up when encountering `@typep` and `@opaque`. For now we
will treat them like any other type.

Further work on opaque types in
  • Loading branch information
msz committed May 30, 2020
1 parent df66c8a commit 337ca23
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/hammox/type_engine.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ defmodule Hammox.TypeEngine do

alias Hammox.Utils

@type_kinds [:type, :typep, :opaque]

def match_type(value, {:type, _, :union, union_types} = union) when is_list(union_types) do
results =
Enum.reduce_while(union_types, [], fn type, reason_stacks ->
Expand Down Expand Up @@ -653,7 +655,8 @@ defmodule Hammox.TypeEngine do
)
when is_atom(module_name) and is_atom(type_name) and is_list(args) do
with {:ok, types} <- fetch_types(module_name),
{:ok, {:type, {_name, type, vars}}} <- get_type(types, type_name, length(args)) do
{:ok, {type_kind, {_name, type, vars}}} when type_kind in @type_kinds <-
get_type(types, type_name, length(args)) do
resolved_type =
args
|> Enum.zip(vars)
Expand Down Expand Up @@ -688,7 +691,8 @@ defmodule Hammox.TypeEngine do
end

defp get_type(type_list, type_name, arity) do
case Enum.find(type_list, fn {:type, {name, _type, params}} ->
case Enum.find(type_list, fn {type_kind, {name, _type, params}}
when type_kind in @type_kinds ->
name == type_name and length(params) == arity
end) do
nil -> {:error, {:type_not_found, {type_name, arity}}}
Expand Down
20 changes: 20 additions & 0 deletions test/hammox_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,26 @@ defmodule HammoxTest do
end
end

describe "private types" do
test "pass" do
assert_pass(:foo_private_type, :private_value)
end

test "fail" do
assert_fail(:foo_private_type, :other)
end
end

describe "opaque types" do
test "pass" do
assert_pass(:foo_opaque_type, :opaque_value)
end

test "fail" do
assert_fail(:foo_opaque_type, :other)
end
end

defp assert_pass(function_name, value) do
TestMock |> expect(function_name, fn -> value end)
assert value == apply(TestMock, function_name, [])
Expand Down
7 changes: 7 additions & 0 deletions test/support/behaviour.ex
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,11 @@ defmodule Hammox.Test.Behaviour do
value: param
}
@callback foo_multiline_param_type() :: multiline_param_type(:arg)

@typep private_type :: :private_value
@type type_including_private_type :: private_type()
@callback foo_private_type() :: type_including_private_type()

@opaque opaque_type :: :opaque_value
@callback foo_opaque_type() :: opaque_type
end

0 comments on commit 337ca23

Please sign in to comment.