Commit 026da800 authored by Tomasz Marek Sulima's avatar Tomasz Marek Sulima
Browse files

1.1.0

Added credo, dialyxir and excoveralls support.
Added extra debug functions and guards.
Added more tests.
Changed dependency from ecto 2.x to ecto_sql 3.x.
Fixed generated specs and all found bugs.
Full code refactor: 0 errors/warnings and 100% coverage.
Removed unneeded config/config.exs
Updated all dependencies.
Updated documentation.
parent 30014b3c
# EctoPostgresEnum
Ecto helper library to use PostgreSQL enums
Library which simplifies using `PostgreSQL` enums
## Installation
......@@ -16,20 +16,30 @@ end
## Usage
Te define enum simply use `EctoPostgresEnum` module like:
To define enum simply use `EctoPostgresEnum` module like:
```elixir
defmodule MyEnum do
use EctoPostgresEnum, values: [:my, :enum]
values = [:my, :enum]
use EctoPostgresEnum, values: values
end
# automatically generated type
MyEnum.type() == :my_enum
```
# optionally add schema and type
# by default type is underscored last part of module name and therefore it's not required
You can optionally define `schema` and `type`:
# use EctoPostgresEnum, schema: :non_public, type: :my_enum, values: [:my, :enum]
```elixir
defmodule MyEnum do
values = [:my, :enum]
use EctoPostgresEnum, schema: :my_schema, type: :my_type, values: values
end
```
and then add it to your schema like:
For more informations please take a look at `EctoPostgresEnum` module.
After it add such enum to your schema like:
```elixir
defmodule MySchema do
......@@ -38,11 +48,11 @@ defmodule MySchema do
alias Ecto.Changeset
schema "my_table" do
field(:my_field, MyEnum)
field :my_field, MyEnum # add this
end
def changeset(my_element, my_params) do
Changeset.cast(my_element, my_params, [:my_field])
Changeset.cast(my_element, my_params, [:my_field]) # cast as any other field
end
end
```
......@@ -54,18 +64,23 @@ defmodule Example.Repo.Migrations.MyEnum do
use Ecto.Migration
def up do
MyEnum.create_db_enum
MyEnum.create_db_enum()
alter table(:my_table) do
add :my_field, :my_enum
add :my_field, :my_enum # when automatically generated
# or
add :my_field, :my_type # when manually set
end
end
def down do
# Remember to remove all fields which are using your enum.
# Otherwise migration would fail!
alter table(:my_table) do
remove :my_field
end
MyEnum.drop_db_enum
MyEnum.drop_db_enum()
end
end
```
\ No newline at end of file
%{
configs: [
%{
checks: [
{Credo.Check.Refactor.MapInto, false},
{Credo.Check.Warning.LazyLogging, false}
],
files: %{included: ["lib/"], excluded: []},
name: "default"
}
]
}
defmodule EctoPostgresEnum do
@moduledoc false
defmacro __using__(opts) do
quote(bind_quoted: [opts: opts], unquote: false) do
default_type =
__MODULE__
|> Module.split()
|> List.last()
|> Macro.underscore()
|> String.to_atom()
schema = opts[:schema]
type = opts[:type] || default_type
is_atom(type) || raise "Type needs to be an atom"
values = opts[:values] || raise "Option values (list) is required"
values == Enum.uniq(values) || raise "Duplicates are not allowed in enum values"
Enum.count(values) > 0 || raise "Valid enums requires at least 1 different values"
Enum.all?(values, &is_atom/1) || raise "All values must be atoms"
schema && (is_atom(schema) || raise "Option schema must be atom")
@moduledoc """
Helper module to define enum for `ecto` and `PostgreSQL` with support for dynamic values.
alias Ecto.Migration
## Usage
@behaviour Ecto.Type
@__input_values__ Enum.map(values, &Atom.to_string/1)
@__output_values__ values
@__schema__ schema
@__type__ if is_nil(@__schema__), do: type, else: :"#{@__schema__}.#{type}"
defmodule MyEnum do
values = [:my, :enum]
use EctoPostgresEnum, schema: :my_schema, type: :my_type, values: values
end
types = Enum.map_join(values, ", ", &"'#{&1}'")
@__create_sql__ "CREATE TYPE #{type} AS ENUM (#{types})"
@__drop_sql__ "DROP TYPE #{@__type__}"
## Options
list = Enum.zip(@__output_values__, @__input_values__)
* `schema` - Allows to change [PostgreSQL Schema](https://www.postgresql.org/docs/current/ddl-schemas.html) for specified enum.
* `type` - Allows to change type identifier. It's useful for migrations and required by `c:Ecto.Type.type/0` callback.
[head | tail] = Enum.reverse(@__output_values__)
ast = Enum.reduce(tail, head, &{:|, [], [&1, &2]})
Name | Type | Required | Default
:----- | :--------- | :------- | :------------------------------------------------
schema | atom | false | nil (fallbacks to `PostgreSQL` default: "public")
type | atom | false | atom (underscored last module part)
values | list(atom) | true | N/A
@type t :: unquote(ast)
## Debug
This library automatically generates few useful functions to work with allowed values.
@doc "Casts the given input to the custom type"
@spec cast(value) :: value when value: t()
@spec cast(String.t()) :: t() | :error
@spec cast(term) :: :error
for {atom, string} <- list do
def cast(unquote(atom)), do: {:ok, unquote(atom)}
def cast(unquote(string)), do: {:ok, unquote(atom)}
Example usage:
defmodule MyEnum do
values = [:my, :enum]
use EctoPostgresEnum, schema: :my_schema, type: :my_type, values: values
end
def cast(_term), do: :error
defmodule MyApp do
require MyEnum
def handle_user_input(input) when MyEnum.valid_string?(input) do
IO.puts "Alright, \#{input} is allowed value!"
end
def handle_user_input(input) do
IO.puts "Ooops, \#{input} is not allowed value! Please try again …"
end
end
MyApp.handle_user_input("my")
{:ok, "my"}
MyApp.handle_user_input("something")
{:error. "Wrong enum value!"}
"""
@doc false
def gen_default_type(module),
do: module |> Module.split() |> List.last() |> Macro.underscore() |> String.to_atom()
@doc false
def gen_type_ast(values), do: values |> Enum.reverse() |> do_gen_type_ast()
defp do_gen_type_ast([head | tail]), do: Enum.reduce(tail, head, &{:|, [], [&1, &2]})
@doc false
defmacro __using__(opts), do: [base(opts), database_block(), debug_block(), type()]
@doc "Creates database enum"
defp base(opts), do: [base_definitions_block(opts), base_checks_block(), base_rest_block()]
defp base_definitions_block(opts) do
quote bind_quoted: [opts: opts], unquote: false do
is_list(opts) || raise "Options should be a list!"
@behaviour Ecto.Type
@__schema__ opts[:schema]
@__type__ opts[:type] || EctoPostgresEnum.gen_default_type(__MODULE__)
@__values__ opts[:values]
end
end
defp base_checks_block do
quote do
@__values__ || raise "Option values (list) is required!"
is_atom(@__type__) || raise "Type needs to be an atom!"
@__values__ == Enum.uniq(@__values__) || raise "Duplicates are not allowed in enum values!"
Enum.count(@__values__) > 0 || raise "Valid enums requires at least 1 different values!"
Enum.all?(@__values__, &is_atom/1) || raise "All values must be atoms!"
@__schema__ && (is_atom(@__schema__) || raise "Option schema must be atom!")
end
end
defp base_rest_block do
quote unquote: false do
alias Ecto.Migration
type_sql = if is_nil(@__schema__), do: @__type__, else: :"#{@__schema__}.#{@__type__}"
values_sql = Enum.map_join(@__values__, ", ", &"'#{&1}'")
@__create_sql__ "CREATE TYPE #{type_sql} AS ENUM (#{values_sql})"
@__drop_sql__ "DROP TYPE #{type_sql}"
@__string_values__ Enum.map(@__values__, &Atom.to_string/1)
@__zipped_values__ Enum.zip(@__values__, @__string_values__)
@type t :: unquote(EctoPostgresEnum.gen_type_ast(@__values__))
end
end
defp database_block do
quote do
@doc "Creates database enum."
@spec create_db_enum :: :ok
def create_db_enum, do: Migration.execute(@__create_sql__)
@doc "Drops database enum"
@doc "Drops database enum."
@spec drop_db_enum :: :ok
def drop_db_enum, do: Migration.execute(@__drop_sql__)
end
end
@doc "Dumps the given term into an Ecto native type"
@spec dump(t()) :: {:ok, String.t()}
@spec dump(value) :: value | :error when value: String.t()
@spec dump(term) :: :error
for {atom, string} <- list do
defp debug_block do
quote do
@doc "Returns list of allowed atom values."
@spec atom_values :: [t]
def atom_values, do: @__values__
@doc "Returns list of allowed string values."
@spec string_values :: [String.t()]
def string_values, do: @__string_values__
@doc "Checks if given atom is allowed."
@spec valid_atom?(t) :: true
@spec valid_atom?(term) :: false
defguard valid_atom?(value) when value in @__values__
@doc "Checks if given string is allowed."
@spec valid_string?(String.t()) :: boolean
@spec valid?(term) :: false
defguard valid_string?(value) when value in @__string_values__
@doc "Checks if given atom or string is allowed."
@spec valid?(t) :: true
@spec valid?(String.t()) :: boolean
@spec valid?(term) :: false
defguard valid?(value) when valid_atom?(value) or valid_string?(value)
@doc "Returns zipped list of atom values with list of string values."
@spec values :: [term]
def values, do: @__zipped_values__
end
end
defp type, do: [type_cast(), type_dump(), type_rest()]
defp type_cast do
quote unquote: false do
@doc """
Casts the given input to the custom type.
This is callback implementation for: `c:Ecto.Type.cast/1`
"""
@impl Ecto.Type
@spec cast(String.t()) :: {:ok, t} | :error
for {atom, string} <- @__zipped_values__ do
@spec cast(unquote(atom)) :: {:ok, unquote(atom)}
def cast(unquote(atom)), do: {:ok, unquote(atom)}
def cast(unquote(string)), do: {:ok, unquote(atom)}
end
@spec cast(term) :: :error
def cast(_term), do: :error
end
end
defp type_dump do
quote unquote: false do
@doc """
Dumps the given term into an Ecto native type.
This is callback implementation for: `c:Ecto.Type.dump/1`
"""
@impl Ecto.Type
@spec dump(t) :: {:ok, String.t()}
@spec dump(String.t()) :: {:ok, String.t()} | :error
for {atom, string} <- @__zipped_values__ do
def dump(unquote(atom)), do: {:ok, unquote(string)}
def dump(unquote(string)), do: {:ok, unquote(string)}
end
@spec dump(term) :: :error
def dump(_term), do: :error
end
end
@doc "Loads the given term into a custom type"
@spec load(String.t()) :: {:ok, t()} | :error
@spec load(term) :: :error
for {atom, string} <- list do
defp type_rest do
quote unquote: false do
@doc """
Loads the given term into a custom type.
This is callback implementation for: `c:Ecto.Type.load/1`
"""
@impl Ecto.Type
@spec load(String.t()) :: {:ok, t} | :error
for {atom, string} <- @__zipped_values__ do
def load(unquote(string)), do: {:ok, unquote(atom)}
end
@spec load(term) :: :error
def load(_value), do: :error
@doc """
Returns database enum type
Returns the underlying schema type for the custom type.
This is callback implementation for: `c:Ecto.Type.type/0`
"""
@impl Ecto.Type
@spec type :: atom
def type, do: @__type__
@doc """
Returns list of values
"""
@spec values :: [term]
def values, do: @__output_values__
end
end
end
defmodule EctoPostgresEnum.Mixfile do
use Mix.Project
@version "1.0.2"
@version "1.1.0"
def application, do: [applications: [:logger, :ecto]]
......@@ -9,10 +9,14 @@ defmodule EctoPostgresEnum.Mixfile do
[
app: :ecto_postgres_enum,
deps: [
{:ecto, "~> 2.2"},
{:ex_doc, "~> 0.19", only: :docs}
{:credo, "~> 1.1.0", only: [:test], runtime: false},
{:dialyxir, "~> 1.0.0-rc.4", only: [:dialyzer], runtime: false},
{:ecto_sql, "~> 3.0"},
{:ex_doc, "~> 0.21", only: :docs},
{:excoveralls, "~> 0.10", only: :test}
],
description: "Ecto helper library to use PostgreSQL enums",
dialyzer: [ignore_warnings: "config/dialyzer.ignore-warnings"],
docs: [
extras: ["README.md": [filename: "ecto_postgres_enum"]],
main: "ecto_postgres_enum",
......@@ -28,7 +32,17 @@ defmodule EctoPostgresEnum.Mixfile do
links: %{gitlab: "https://gitlab.com/ex-open-source/ecto-postgres-enum"},
maintainers: ["Tomasz Sulima"]
],
preferred_cli_env: [docs: :docs],
preferred_cli_env: [
coveralls: :test,
"coveralls.html": :test,
credo: :test,
dialyzer: :dialyzer,
"dialyzer.build": :dialyzer,
"dialyzer.clean": :dialyzer,
"dialyzer.explain": :dialyzer,
docs: :docs
],
test_coverage: [tool: ExCoveralls],
version: @version
]
end
......
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"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"},
"makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.4.0", "ee261bb53214943679422be70f1658fff573c5d0b0a1ecd0f18738944f818efe", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
"credo": {:hex, :credo, "1.1.3", "bf31887b8914a4b7e1810ae2b5aab7c657698abbf4cca6a2335a094d57995168", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"db_connection": {:hex, :db_connection, "2.1.1", "a51e8a2ee54ef2ae6ec41a668c85787ed40cb8944928c191280fe34c15b76ae5", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
"decimal": {:hex, :decimal, "1.8.0", "ca462e0d885f09a1c5a342dbd7c1dcf27ea63548c65a65e67334f4b61803822e", [:mix], [], "hexpm"},
"dialyxir": {:hex, :dialyxir, "1.0.0-rc.6", "78e97d9c0ff1b5521dd68041193891aebebce52fc3b93463c0a6806874557d7d", [:mix], [{:erlex, "~> 0.2.1", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"},
"earmark": {:hex, :earmark, "1.3.6", "ce1d0675e10a5bb46b007549362bd3f5f08908843957687d8484fe7f37466b19", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "3.1.7", "fa21d06ef56cdc2fdaa62574e8c3ba34a2751d44ea34c30bc65f0728421043e5", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ecto_sql": {:hex, :ecto_sql, "3.1.6", "1e80e30d16138a729c717f73dcb938590bcdb3a4502f3012414d0cbb261045d8", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:myxql, "~> 0.2.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0 or ~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"erlex": {:hex, :erlex, "0.2.4", "23791959df45fe8f01f388c6f7eb733cc361668cbeedd801bf491c55a029917b", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.11.2", "0c6f2c8db7683b0caa9d490fb8125709c54580b4255ffa7ad35f3264b075a643", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
"telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
}
defmodule MyEnum do
use EctoPostgresEnum, values: [:first, :second]
end
defmodule EctoPostgresEnumTest do
use ExUnit.Case
defmodule MyEnum do
use EctoPostgresEnum, type: :my_enum, values: [:my, :enum]
end
defmodule MySchema do
use Ecto.Schema
......@@ -17,8 +17,34 @@ defmodule EctoPostgresEnumTest do
def changeset(params), do: Changeset.cast(%__MODULE__{}, params, [:my_field])
end
test "greets the world" do
assert MySchema.changeset(%{"my_field" => :me}).valid? == false
assert MySchema.changeset(%{"my_field" => :my}).valid? == true
require MyEnum
test "changeset" do
assert MySchema.changeset(%{"my_field" => :first}).valid? == true
assert MySchema.changeset(%{"my_field" => "first"}).valid? == true
assert MySchema.changeset(%{"my_field" => nil}).valid? == true
assert MySchema.changeset(%{"my_field" => :third}).valid? == false
assert MySchema.changeset(%{"my_field" => 0}).valid? == false
end
test "debug" do
assert MyEnum.atom_values() == [:first, :second]
assert MyEnum.string_values() == ["first", "second"]
assert MyEnum.valid_atom?(:first) == true
assert MyEnum.valid_atom?("first") == false
assert MyEnum.valid_atom?(:third) == false
assert MyEnum.valid_atom?(nil) == false
assert MyEnum.valid_atom?(0) == false
assert MyEnum.valid_string?("first") == true
assert MyEnum.valid_string?(:first) == false
assert MyEnum.valid_string?("third") == false
assert MyEnum.valid_string?(nil) == false
assert MyEnum.valid_string?(0) == false
assert MyEnum.valid?(:first) == true
assert MyEnum.valid?("first") == true
assert MyEnum.valid?(:third) == false
assert MyEnum.valid?(nil) == false
assert MyEnum.valid?(0) == false
assert MyEnum.values() == [first: "first", second: "second"]
end
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment