Repository: msz/hammox (elixir)

Issue:
Exception thrown with Decimal.t
Could you please tell me if `hammox` has support for custom types? For example:

```elixir
defmodule MyType do
  defstruct [:value]

  @type t :: %__MODULE__{
    value: number()
   }
end
```

Looking through the source code and the following error, I am assuming it doesn't currently:

```
     The following arguments were given to Hammox.TypeEngine.match_type/2:

         # 1
         1000

         # 2
         {:op, 93, :-, {:integer, 93, 1}}

     Attempted function clauses (showing 10 out of 89):

         def match_type(value, {:type, _, :union, union_types} = union) when is_list(union_types)
         def match_type(_value, {:type, _, :any, []})
         def match_type(value, {:type, _, :none, []} = type)
         def match_type(value, {:type, _, :atom, []}) when is_atom(value)
         def match_type(value, {:type, _, :atom, []} = type)
         def match_type(value, {:type, _, :map, :any}) when is_map(value)
         def match_type(value, {:type, _, :pid, []}) when is_pid(value)
         def match_type(value, {:type, _, :pid, []} = type)
         def match_type(value, {:type, _, :port, []}) when is_port(value)
         def match_type(value, {:type, _, :port, []} = type)

     stacktrace:
       (hammox) lib/hammox/type_engine.ex:6: Hammox.TypeEngine.match_type/2
       (hammox) lib/hammox/type_engine.ex:9: anonymous fn/3 in Hammox.TypeEngine.match_type/2
       (elixir) lib/enum.ex:3325: Enumerable.List.reduce/3
       (elixir) lib/enum.ex:1998: Enum.reduce_while/3
       (hammox) lib/hammox/type_engine.ex:8: Hammox.TypeEngine.match_type/2
       (hammox) lib/hammox/type_engine.ex:364: anonymous fn/3 in Hammox.TypeEngine.match_type/2
       (elixir) lib/enum.ex:1340: anonymous fn/3 in Enum.map/2
       (stdlib) maps.erl:232: :maps.fold_1/3
       (elixir) lib/enum.ex:1964: Enum.map/2
       (hammox) lib/hammox/type_engine.ex:363: anonymous fn/2 in Hammox.TypeEngine.match_type/2
       (elixir) lib/enum.ex:3358: Enumerable.Map.reduce_list/3
       (elixir) lib/enum.ex:1998: Enum.reduce_while/3
       (hammox) lib/hammox/type_engine.ex:361: Hammox.TypeEngine.match_type/2
       (hammox) lib/hammox/type_engine.ex:364: anonymous fn/3 in Hammox.TypeEngine.match_type/2
       (elixir) lib/enum.ex:1340: anonymous fn/3 in Enum.map/2
       (stdlib) maps.erl:232: :maps.fold_1/3
       (elixir) lib/enum.ex:1964: Enum.map/2
       (hammox) lib/hammox/type_engine.ex:363: anonymous fn/2 in Hammox.TypeEngine.match_type/2
       (elixir) lib/enum.ex:3358: Enumerable.Map.reduce_list/3
       (elixir) lib/enum.ex:1998: Enum.reduce_while/3
```

Thank you for your help!



Pull request description:
add support for negative integers
Fixes #9.

Patch:
diff --git a/lib/hammox/type_engine.ex b/lib/hammox/type_engine.ex
index 85eaacb..ea7fc7c 100644
--- a/lib/hammox/type_engine.ex
+++ b/lib/hammox/type_engine.ex
@@ -301,6 +301,14 @@ defmodule Hammox.TypeEngine do
     type_mismatch(value, type)
   end
 
+  def match_type(value, {:op, _, :-, {:integer, _, integer}}) when value == -integer do
+    :ok
+  end
+
+  def match_type(value, {:op, _, :-, {:integer, _, _}} = type) do
+    type_mismatch(value, type)
+  end
+
   def match_type(value, {:type, _, :range, [{:integer, _, low}, {:integer, _, high}]})
       when value in low..high do
     :ok


Test patch:
diff --git a/test/hammox_test.exs b/test/hammox_test.exs
index 2d05ba4..4b9b317 100644
--- a/test/hammox_test.exs
+++ b/test/hammox_test.exs
@@ -392,6 +392,16 @@ defmodule HammoxTest do
     end
   end
 
+  describe "negative integer literal" do
+    test "pass" do
+      assert_pass(:foo_neg_integer_literal, -1)
+    end
+
+    test "fail" do
+      assert_fail(:foo_neg_integer_literal, 1)
+    end
+  end
+
   describe "integer range literal" do
     test "pass" do
       assert_pass(:foo_integer_range_literal, 5)
diff --git a/test/support/behaviour.ex b/test/support/behaviour.ex
index d832142..dd53d36 100644
--- a/test/support/behaviour.ex
+++ b/test/support/behaviour.ex
@@ -28,6 +28,7 @@ defmodule Hammox.Test.Behaviour do
   @callback foo_binary_function_literal() :: (:a, :b -> :ok)
   @callback foo_any_arity_function_literal() :: (... -> :ok)
   @callback foo_integer_literal() :: 1
+  @callback foo_neg_integer_literal() :: -1
   @callback foo_integer_range_literal() :: 1..10
   @callback foo_list_literal :: [atom()]
   @callback foo_empty_list_literal() :: []