diff --git a/mix.exs b/mix.exs index c0f2096..eb9dead 100644 --- a/mix.exs +++ b/mix.exs @@ -30,12 +30,13 @@ defmodule EctoEnum.Mixfile do end def application do - [applications: [:logger, :ecto]] + [applications: [:logger, :ecto, :ecto_sql]] end defp deps do [ - {:ecto, ">= 2.0.0"}, + {:ecto, ">= 3.0.0"}, + {:ecto_sql, "> 3.0.0"}, {:postgrex, ">= 0.0.0", optional: true}, {:mariaex, ">= 0.0.0", optional: true}, {:ex_doc, "~> 0.19", only: [:docs, :dev]}, diff --git a/mix.lock b/mix.lock index 963c829..3fa13f9 100644 --- a/mix.lock +++ b/mix.lock @@ -1,16 +1,18 @@ %{ "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []}, - "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [: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.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [:mix], [], "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"}, "earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm"}, - "ecto": {:hex, :ecto, "2.2.1", "ccc6fd304f9bb785f2c3cfd0ee8da6bad6544ab12ca5f7162b20a743d938417c", [: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"}, + "ecto": {:hex, :ecto, "3.2.3", "51274df79862845b388733fddcf6f107d0c8c86e27abe7131fa98f8d30761bda", [: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.2.0", "751cea597e8deb616084894dd75cbabfdbe7255ff01e8c058ca13f0353a3921b", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.2.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.2.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "inch_ex": {:hex, :inch_ex, "0.5.5", "b63f57e281467bd3456461525fdbc9e158c8edbe603da6e3e4671befde796a3d", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]}, "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, - "mariaex": {:hex, :mariaex, "0.8.3", "bf51ff4d480f68400bad69d1ebe778b6edbcafa4dd0429826ae1dd89cb90c8ad", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, + "mariaex": {:hex, :mariaex, "0.9.1", "83266fec657ea68dd426f4bbc12594be45ee91fe162ebf1bf017ce3cfa098ddd", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], []}, - "postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [: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"}, + "postgrex": {:hex, :postgrex, "0.15.1", "23ce3417de70f4c0e9e7419ad85bdabcc6860a6925fe2c6f3b1b5b1e8e47bf2f", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, + "telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm"}, } diff --git a/test/ecto_enum_test.exs b/test/ecto_enum_test.exs index b5de1d5..0a7f10b 100644 --- a/test/ecto_enum_test.exs +++ b/test/ecto_enum_test.exs @@ -41,26 +41,26 @@ defmodule EctoEnumTest do end test "casts int and binary to atom" do - %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => "active"}, ~w(status)) + %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => "active"}, ~w(status)a) assert changes.status == :active - %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => 3}, ~w(status)) + %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => 3}, ~w(status)a) assert changes.status == :archived - %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => :inactive}, ~w(status)) + %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => :inactive}, ~w(status)a) assert changes.status == :inactive end test "raises when input is not in the enum map" do error = {:status, {"is invalid", [type: EctoEnumTest.StatusEnum, validation: :cast]}} - changeset = Ecto.Changeset.cast(%User{}, %{"status" => "retroactive"}, ~w(status)) + changeset = Ecto.Changeset.cast(%User{}, %{"status" => "retroactive"}, ~w(status)a) assert error in changeset.errors - changeset = Ecto.Changeset.cast(%User{}, %{"status" => :retroactive}, ~w(status)) + changeset = Ecto.Changeset.cast(%User{}, %{"status" => :retroactive}, ~w(status)a) assert error in changeset.errors - changeset = Ecto.Changeset.cast(%User{}, %{"status" => 4}, ~w(status)) + changeset = Ecto.Changeset.cast(%User{}, %{"status" => 4}, ~w(status)a) assert error in changeset.errors assert_raise Ecto.ChangeError, custom_error_msg("retroactive"), fn -> @@ -228,10 +228,10 @@ defmodule EctoEnumTest do end test "string-backed enum casts string and atom to atom" do - %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => "active"}, ~w(status)) + %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => "active"}, ~w(status)a) assert changes.status == :active - %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => :inactive}, ~w(status)) + %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => :inactive}, ~w(status)a) assert changes.status == :inactive end diff --git a/test/mysql/test_helper.exs b/test/mysql/test_helper.exs index 8dcc312..08714ab 100644 --- a/test/mysql/test_helper.exs +++ b/test/mysql/test_helper.exs @@ -6,13 +6,12 @@ alias Ecto.Integration.PoolRepo Code.require_file("ecto_migration.exs", __DIR__) Application.put_env(:ecto, TestRepo, - adapter: Ecto.Adapters.MySQL, url: "ecto://root@localhost/ecto_test", pool: Ecto.Adapters.SQL.Sandbox ) defmodule TestRepo do - use Ecto.Repo, otp_app: :ecto + use Ecto.Repo, otp_app: :ecto, adapter: Ecto.Adapters.MySQL end Application.put_env(:ecto, PoolRepo, @@ -22,7 +21,7 @@ Application.put_env(:ecto, PoolRepo, ) defmodule PoolRepo do - use Ecto.Repo, otp_app: :ecto + use Ecto.Repo, otp_app: :ecto, adapter: Ecto.Adapters.MySQL def create_prefix(prefix) do "create database #{prefix}" diff --git a/test/pg/ecto_enum_test.exs b/test/pg/ecto_enum_test.exs index 82fd728..29513cd 100644 --- a/test/pg/ecto_enum_test.exs +++ b/test/pg/ecto_enum_test.exs @@ -1,47 +1,32 @@ Code.require_file("../ecto_enum_test.exs", __DIR__) defmodule EctoEnumPostgresTest do - use ExUnit.Case - import EctoEnum + use ExUnit.Case, async: false alias Ecto.Integration.TestRepo - test "create_type/1 can accept schema and creates a type in that schema" do - Ecto.Adapters.SQL.query!(TestRepo, "CREATE SCHEMA other_schema", []) + defmodule User do + use Ecto.Schema - defenum(TestEnum, :role, [:admin, :manager, :user], schema: "other_schema") + @schema_prefix "other_schema" - defmodule TestMigration do - use Ecto.Migration - - def up do - TestEnum.create_type() - - create table("users", prefix: "other_schema") do - add(:role, TestEnum.type()) - end - end - - def down do - drop(table("users", prefix: "other_schema")) - TestEnum.drop_type() - end + schema "users" do + field(:role, TestEnum) end - assert :ok = Ecto.Migrator.up(TestRepo, 1, TestMigration, log: false) - - defmodule User do - use Ecto.Schema + def roles() do + [:admin, :manager, :user] + end + end - schema "other_schema.users" do - field(:role, TestEnum) - end + test "User Defined Type in PG works with EctoEnum" do + error_msg = + "Value `:non_existent_role` is not a valid enum for `TestEnum`. Valid enums are `[:admin, :manager, :user, \"admin\", \"manager\", \"user\"]`" - def roles() do - [:admin, :manager, :user] - end + assert_raise Ecto.ChangeError, error_msg, fn -> + TestRepo.insert!(%User{role: :non_existent_role}) end - Ecto.Migrator.down(TestRepo, 1, TestMigration, log: false) + assert TestRepo.insert!(%User{role: :admin}).role == :admin end end diff --git a/test/pg/ecto_migration.exs b/test/pg/ecto_migration.exs index f830ebc..24c64b4 100644 --- a/test/pg/ecto_migration.exs +++ b/test/pg/ecto_migration.exs @@ -1,4 +1,4 @@ -defmodule Ecto.Integration.Migration do +defmodule Ecto.Integration.SetupMigration do use Ecto.Migration def change do @@ -17,3 +17,23 @@ defmodule Ecto.Integration.Migration do end end end + +import EctoEnum +defenum(TestEnum, :role, [:admin, :manager, :user], schema: "other_schema") + +defmodule Ecto.Integration.TestEnumMigration do + use Ecto.Migration + + def up do + TestEnum.create_type() + + create table("users", prefix: "other_schema") do + add(:role, TestEnum.type()) + end + end + + def down do + drop(table("users", prefix: "other_schema")) + TestEnum.drop_type() + end +end diff --git a/test/pg/postgres_test.exs b/test/pg/postgres_test.exs index 7ad9489..1342040 100644 --- a/test/pg/postgres_test.exs +++ b/test/pg/postgres_test.exs @@ -36,27 +36,27 @@ defmodule EctoEnum.PostgresTest do end test "casts binary to atom" do - %{errors: errors} = Ecto.Changeset.cast(%User{}, %{"status" => 3}, ~w(status)) + %{errors: errors} = Ecto.Changeset.cast(%User{}, %{"status" => 3}, ~w(status)a) error = {:status, {"is invalid", [type: EctoEnum.PostgresTest.StatusEnum, validation: :cast]}} assert error in errors - %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => "active"}, ~w(status)) + %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => "active"}, ~w(status)a) assert changes.status == :active - %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => :inactive}, ~w(status)) + %{changes: changes} = Ecto.Changeset.cast(%User{}, %{"status" => :inactive}, ~w(status)a) assert changes.status == :inactive end test "raises when input is not in the enum map" do error = {:status, {"is invalid", [type: EctoEnum.PostgresTest.StatusEnum, validation: :cast]}} - changeset = Ecto.Changeset.cast(%User{}, %{"status" => "retroactive"}, ~w(status)) + changeset = Ecto.Changeset.cast(%User{}, %{"status" => "retroactive"}, ~w(status)a) assert error in changeset.errors - changeset = Ecto.Changeset.cast(%User{}, %{"status" => :retroactive}, ~w(status)) + changeset = Ecto.Changeset.cast(%User{}, %{"status" => :retroactive}, ~w(status)a) assert error in changeset.errors - changeset = Ecto.Changeset.cast(%User{}, %{"status" => 4}, ~w(status)) + changeset = Ecto.Changeset.cast(%User{}, %{"status" => 4}, ~w(status)a) assert error in changeset.errors assert_raise Ecto.ChangeError, fn -> diff --git a/test/pg/test_helper.exs b/test/pg/test_helper.exs index 914124e..5363ee3 100644 --- a/test/pg/test_helper.exs +++ b/test/pg/test_helper.exs @@ -4,13 +4,12 @@ ExUnit.start() alias Ecto.Integration.TestRepo Application.put_env(:ecto, TestRepo, - adapter: Ecto.Adapters.Postgres, url: "ecto://postgres@localhost/ecto_test", pool: Ecto.Adapters.SQL.Sandbox ) defmodule Ecto.Integration.TestRepo do - use Ecto.Repo, otp_app: :ecto + use Ecto.Repo, otp_app: :ecto, adapter: Ecto.Adapters.Postgres def log(_cmd), do: nil end @@ -19,13 +18,13 @@ end _ = Ecto.Adapters.Postgres.storage_down(TestRepo.config()) :ok = Ecto.Adapters.Postgres.storage_up(TestRepo.config()) -{:ok, pid} = TestRepo.start_link() +{:ok, _pid} = TestRepo.start_link() Code.require_file("ecto_migration.exs", __DIR__) -:ok = Ecto.Migrator.up(TestRepo, 0, Ecto.Integration.Migration, log: false) -Ecto.Adapters.SQL.Sandbox.mode(TestRepo, :manual) -Process.flag(:trap_exit, true) +Ecto.Adapters.SQL.query!(TestRepo, "CREATE SCHEMA other_schema", []) -:ok = TestRepo.stop(pid) -{:ok, _pid} = TestRepo.start_link() +:ok = Ecto.Migrator.up(TestRepo, 0, Ecto.Integration.SetupMigration, log: false) +:ok = Ecto.Migrator.up(TestRepo, 1, Ecto.Integration.TestEnumMigration, log: false) + +Ecto.Adapters.SQL.Sandbox.mode(TestRepo, {:shared, self()})