diff --git a/test/strukt_test.exs b/test/strukt_test.exs index a624f94..d4b62fb 100644 --- a/test/strukt_test.exs +++ b/test/strukt_test.exs @@ -545,6 +545,26 @@ defmodule Strukt.Test do Fixtures.EmbedsOneTypeSpec.expected_type_spec_ast_str() end + test "custom ecto type" do + require Fixtures.CustomEctoTypeTypeSepc + + assert inspect( + Strukt.Typespec.generate(%Strukt.Typespec{ + caller: Strukt.Test.Fixtures.CustomEctoTypeTypeSepc, + fields: [:uri], + info: %{ + uri: %{ + type: :field, + value_type: Custom.EctoType, + required: true + } + }, + embeds: [] + }) + ) == + Fixtures.CustomEctoTypeTypeSepc.expected_type_spec_ast_str() + end + defp changeset_errors(%Ecto.Changeset{} = cs) do cs |> Ecto.Changeset.traverse_errors(fn {msg, opts} -> diff --git a/test/support/defstruct_fixtures.ex b/test/support/defstruct_fixtures.ex index 66cb8f2..6565641 100644 --- a/test/support/defstruct_fixtures.ex +++ b/test/support/defstruct_fixtures.ex @@ -9,6 +9,31 @@ defmodule Aux do end end +defmodule Custom.EctoType do + @moduledoc "Custom Ecto Type for test" + @type t() :: URI.t() + + use Ecto.Type + def type, do: :map + + def cast(uri) when is_binary(uri), do: {:ok, URI.parse(uri)} + def cast(%URI{} = uri), do: {:ok, uri} + + def cast(_), do: :error + + def load(data) when is_map(data) do + data = + for {key, val} <- data do + {String.to_existing_atom(key), val} + end + + {:ok, struct!(URI, data)} + end + + def dump(%URI{} = uri), do: {:ok, Map.from_struct(uri)} + def dump(_), do: :error +end + defmodule Strukt.Test.Fixtures do use Strukt @@ -72,6 +97,25 @@ defmodule Strukt.Test.Fixtures do end end + defmodule CustomEctoTypeTypeSepc do + use Strukt + + @primary_key false + defstruct do + field(:uri, Custom.EctoType) + field(:foobar, :string) + end + + defmacro expected_type_spec_ast_str do + quote context: __MODULE__ do + @type t :: %__MODULE__{ + uri: Custom.EctoType.t() + } + end + |> inspect() + end + end + defmodule CustomFields do @moduledoc "This module represents the params keys are not snake case" @@ -327,7 +371,9 @@ defmodule Strukt.Test.Fixtures do defstruct ValidateSets do @moduledoc "This module exercises validations based on set membership" - field(:one_of, :string, one_of: [values: ["a", "b", "c"], message: "must be one of [a, b, c]"]) + field(:one_of, :string, + one_of: [values: ["a", "b", "c"], message: "must be one of [a, b, c]"] + ) field(:none_of, :string, none_of: [values: ["a", "b", "c"], message: "cannot be one of [a, b, c]"]