Skip to content

Commit

Permalink
Merge pull request #24 from ExpressApp/compile-deps-check
Browse files Browse the repository at this point in the history
ensure module is trying to be compiled
  • Loading branch information
artemeff authored Aug 13, 2019
2 parents 0b40806 + a5a093b commit 7a563da
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 18 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ sudo: false

matrix:
include:
- elixir: 1.9.1
otp_release: 22.0.7
- elixir: 1.8.2
otp_release: 21.3.8
- elixir: 1.7.2
otp_release: 21.0
- elixir: 1.7.2
Expand Down
15 changes: 9 additions & 6 deletions lib/construct.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ defmodule Construct do
@type_checker_name Construct.TypeRegistry
@no_default :__construct_no_default__

# elixir 1.9.0 do not raise deadlocks for Code.ensure_compiled/1
@no_raise_on_deadlocks Version.compare(System.version(), "1.9.0") != :lt

@doc false
defmacro __using__(opts \\ [])

Expand Down Expand Up @@ -117,11 +120,11 @@ defmodule Construct do
module = unquote(struct)

unless Code.ensure_compiled?(module) do
raise Construct.DefinitionError, "undefined module #{module}"
raise Construct.DefinitionError, "undefined module #{inspect(module)}"
end

unless function_exported?(module, :__construct__, 1) do
raise Construct.DefinitionError, "provided #{module} is not Construct module"
raise Construct.DefinitionError, "provided #{inspect(module)} is not Construct module"
end

Enum.each(module.__construct__(:types), fn({name, {type, opts}}) ->
Expand Down Expand Up @@ -354,13 +357,15 @@ defmodule Construct do
end

defp check_type_complex!(module) do
if @no_raise_on_deadlocks, do: Code.ensure_compiled(module)

unless construct_module?(module) do
unless Code.ensure_compiled?(module) do
raise Construct.DefinitionError, "undefined module #{module}"
raise Construct.DefinitionError, "undefined module #{inspect(module)}"
end

unless function_exported?(module, :cast, 1) do
raise Construct.DefinitionError, "undefined function cast/1 for #{module}"
raise Construct.DefinitionError, "undefined function cast/1 for #{inspect(module)}"
end
end
end
Expand Down Expand Up @@ -407,8 +412,6 @@ defmodule Construct do
end

defp construct_module?(module) do
Code.ensure_compiled(module)

Agent.get(@type_checker_name, &MapSet.member?(&1, module)) ||
Code.ensure_compiled?(module) && function_exported?(module, :__construct__, 1)
end
Expand Down
24 changes: 12 additions & 12 deletions test/integration/build_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,19 @@ defmodule Construct.Integration.BuildTest do
end

test "raise when trying to use undefined module as custom type" do
assert_raise(Construct.DefinitionError, ~s(undefined module Elixir.UndefinedModule), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined module UndefinedModule), fn ->
create_construct do
field :key, UndefinedModule
end
end)

assert_raise(Construct.DefinitionError, ~s(undefined module Elixir.UndefinedModule), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined module UndefinedModule), fn ->
create_construct do
field :key, {:array, UndefinedModule}
end
end)

assert_raise(Construct.DefinitionError, ~s(undefined module Elixir.UndefinedModule), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined module UndefinedModule), fn ->
create_construct do
field :key, {:map, UndefinedModule}
end
Expand All @@ -144,33 +144,33 @@ defmodule Construct.Integration.BuildTest do
end
end)

assert_raise(Construct.DefinitionError, ~s(undefined module Elixir.UndefinedModule), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined module UndefinedModule), fn ->
create_construct do
field :key, [UndefinedModule]
end
end)

assert_raise(Construct.DefinitionError, ~s(undefined module Elixir.UndefinedModule), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined module UndefinedModule), fn ->
create_construct do
field :key, [CustomType, UndefinedModule]
end
end)
end

test "raise when trying to use custom type that doesn't have cast/1 function" do
assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for Elixir.CustomTypeEmpty), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for CustomTypeEmpty), fn ->
create_construct do
field :key, CustomTypeEmpty
end
end)

assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for Elixir.CustomTypeEmpty), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for CustomTypeEmpty), fn ->
create_construct do
field :key, {:array, CustomTypeEmpty}
end
end)

assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for Elixir.CustomTypeEmpty), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for CustomTypeEmpty), fn ->
create_construct do
field :key, {:map, CustomTypeEmpty}
end
Expand All @@ -182,29 +182,29 @@ defmodule Construct.Integration.BuildTest do
end
end)

assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for Elixir.CustomTypeEmpty), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for CustomTypeEmpty), fn ->
create_construct do
field :key, [CustomTypeEmpty]
end
end)

assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for Elixir.CustomTypeEmpty), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined function cast/1 for CustomTypeEmpty), fn ->
create_construct do
field :key, [CustomType, CustomTypeEmpty]
end
end)
end

test "raise when trying to include undefined module" do
assert_raise(Construct.DefinitionError, ~s(undefined module Elixir.UndefinedModule), fn ->
assert_raise(Construct.DefinitionError, ~s(undefined module UndefinedModule), fn ->
create_construct do
include UndefinedModule
end
end)
end

test "raise when trying to include invalid structure (some module)" do
assert_raise(Construct.DefinitionError, ~s(provided Elixir.CustomTypeEmpty is not Construct module), fn ->
assert_raise(Construct.DefinitionError, ~s(provided CustomTypeEmpty is not Construct module), fn ->
create_construct do
include CustomTypeEmpty
end
Expand Down

0 comments on commit 7a563da

Please sign in to comment.