From 037b1054694c50695e1264645c9b7e6ce1b5c966 Mon Sep 17 00:00:00 2001 From: ken-kost Date: Sun, 2 Mar 2025 16:07:48 +0100 Subject: [PATCH 01/10] Add dev opt to generate migrations task --- lib/mix/tasks/ash_postgres.generate_migrations.ex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/mix/tasks/ash_postgres.generate_migrations.ex b/lib/mix/tasks/ash_postgres.generate_migrations.ex index 065942c8..d83fc4df 100644 --- a/lib/mix/tasks/ash_postgres.generate_migrations.ex +++ b/lib/mix/tasks/ash_postgres.generate_migrations.ex @@ -21,6 +21,7 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do * `no-format` - files that are created will not be formatted with the code formatter * `dry-run` - no files are created, instead the new migration is printed * `check` - no files are created, returns an exit(1) code if the current snapshots and resources don't fit + * 'dev' - dev files are created * `snapshots-only` - no migrations are generated, only snapshots are stored * `concurrent-indexes` - new identities will be run concurrently and in a separate migration (like concurrent custom indexes) @@ -97,6 +98,7 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do no_format: :boolean, dry_run: :boolean, check: :boolean, + dev: :boolean, dont_drop_columns: :boolean, concurrent_indexes: :boolean ] @@ -110,7 +112,7 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do |> Keyword.delete(:no_format) |> Keyword.put_new(:name, name) - if !opts[:name] && !opts[:dry_run] && !opts[:check] && !opts[:snapshots_only] do + if !opts[:name] && !opts[:dry_run] && !opts[:check] && !opts[:snapshots_only] && !opts[:dev] do IO.warn(""" Name must be provided when generating migrations, unless `--dry-run` or `--check` is also provided. Using an autogenerated name will be deprecated in a future release. From 6ee9afac441306220ef2ff43b2aec83aea80123a Mon Sep 17 00:00:00 2001 From: ken-kost Date: Sun, 2 Mar 2025 16:08:23 +0100 Subject: [PATCH 02/10] Handle dev flag in migration generator --- .../migration_generator.ex | 79 +++++++++++++++++-- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 1c35b6b0..bc2d6502 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -19,6 +19,7 @@ defmodule AshPostgres.MigrationGenerator do format: true, dry_run: false, check: false, + dev: false, snapshots_only: false, dont_drop_columns: false @@ -452,6 +453,20 @@ defmodule AshPostgres.MigrationGenerator do :ok operations -> + if !opts.dev and any_dev_migrations?(opts, repo) do + if opts.check do + Mix.shell().error(""" + Generated migrations are from dev mode. + + Generate migrations without `--dev` flag. + """) + + exit({:shutdown, 1}) + else + remove_dev_migrations_and_snapshots(opts, tenant?, repo, snapshots) + end + end + if opts.check do Mix.shell().error(""" Migrations would have been generated, but the --check flag was provided. @@ -491,6 +506,50 @@ defmodule AshPostgres.MigrationGenerator do end) end + defp any_dev_migrations?(opts, repo) do + opts + |> migration_path(repo) + |> File.ls!() + |> Enum.any?(&String.contains?(&1, "_dev.exs")) + end + + defp remove_dev_migrations_and_snapshots(opts, tenant?, repo, snapshots) do + opts + |> migration_path(repo) + |> File.ls!() + |> Enum.filter(&String.contains?(&1, "_dev.exs")) + |> Enum.each(fn migration_name -> + opts + |> migration_path(repo) + |> Path.join(migration_name) + |> File.rm!() + end) + + Enum.each(snapshots, fn snapshot -> + snapshot_folder = + if tenant? do + opts + |> snapshot_path(snapshot.repo) + |> Path.join(repo_name(repo)) + |> Path.join("tenants") + |> Path.join(snapshot.table) + else + opts + |> snapshot_path(snapshot.repo) + |> Path.join(repo_name(snapshot.repo)) + |> Path.join(snapshot.table) + end + + File.ls!(snapshot_folder) + |> Enum.filter(&String.contains?(&1, "_dev.json")) + |> Enum.each(fn snapshot_name -> + snapshot_folder + |> Path.join(snapshot_name) + |> File.rm!() + end) + end) + end + defp split_into_migrations(operations) do operations |> Enum.split_with(fn @@ -960,7 +1019,7 @@ defmodule AshPostgres.MigrationGenerator do migration_file = migration_path - |> Path.join(migration_name <> ".exs") + |> Path.join(migration_name <> "#{if opts.dev, do: "_dev"}.exs") module_name = if tenant? do @@ -1054,20 +1113,25 @@ defmodule AshPostgres.MigrationGenerator do |> Path.join(repo_name) end + dev = if opts.dev, do: "_dev" + snapshot_file = if snapshot.schema do - Path.join(snapshot_folder, "#{snapshot.schema}.#{snapshot.table}/#{timestamp()}.json") + Path.join( + snapshot_folder, + "#{snapshot.schema}.#{snapshot.table}/#{timestamp()}#{dev}.json" + ) else - Path.join(snapshot_folder, "#{snapshot.table}/#{timestamp()}.json") + Path.join(snapshot_folder, "#{snapshot.table}/#{timestamp()}#{dev}.json") end File.mkdir_p(Path.dirname(snapshot_file)) create_file(snapshot_file, snapshot_binary, force: true) - old_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}.json") + old_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}#{dev}.json") if File.exists?(old_snapshot_folder) do - new_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}/initial.json") + new_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}/initial#{dev}.json") File.rename(old_snapshot_folder, new_snapshot_folder) end end) @@ -2640,7 +2704,10 @@ defmodule AshPostgres.MigrationGenerator do if File.exists?(snapshot_folder) do snapshot_folder |> File.ls!() - |> Enum.filter(&String.match?(&1, ~r/^\d{14}\.json$/)) + |> Enum.filter( + &(String.match?(&1, ~r/^\d{14}\.json$/) or + (opts.dev and String.match?(&1, ~r/^\d{14}\_dev.json$/))) + ) |> case do [] -> get_old_snapshot(folder, snapshot) From 23e1c425e0a049121c83f0fa458227d6116bcdfd Mon Sep 17 00:00:00 2001 From: ken-kost Date: Mon, 3 Mar 2025 18:53:44 +0100 Subject: [PATCH 03/10] Expand warn message with dev option --- lib/mix/tasks/ash_postgres.generate_migrations.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mix/tasks/ash_postgres.generate_migrations.ex b/lib/mix/tasks/ash_postgres.generate_migrations.ex index d83fc4df..846c0333 100644 --- a/lib/mix/tasks/ash_postgres.generate_migrations.ex +++ b/lib/mix/tasks/ash_postgres.generate_migrations.ex @@ -114,7 +114,7 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do if !opts[:name] && !opts[:dry_run] && !opts[:check] && !opts[:snapshots_only] && !opts[:dev] do IO.warn(""" - Name must be provided when generating migrations, unless `--dry-run` or `--check` is also provided. + Name must be provided when generating migrations, unless `--dry-run` or `--check` or `--dev` is also provided. Using an autogenerated name will be deprecated in a future release. Please provide a name. for example: From af4f4b6bb2b41013403ce765f256eab9bea4577c Mon Sep 17 00:00:00 2001 From: ken-kost Date: Mon, 3 Mar 2025 18:54:05 +0100 Subject: [PATCH 04/10] Add test for dev option --- test/migration_generator_test.exs | 47 +++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 88f76f67..7cd837c2 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -1250,6 +1250,53 @@ defmodule AshPostgres.MigrationGeneratorTest do end end + describe "--dev option" do + setup do + on_exit(fn -> + File.rm_rf!("test_snapshots_path") + File.rm_rf!("test_migration_path") + end) + end + + test "generates dev migration" do + defposts do + attributes do + uuid_primary_key(:id) + attribute(:title, :string, public?: true) + end + end + + defdomain([Post]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + snapshots_only: false, + migration_path: "test_migration_path", + dev: true + ) + + assert [dev_file] = + Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert String.contains?(dev_file, "_dev.exs") + contents = File.read!(dev_file) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path" + ) + + assert [file] = + Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") + |> Enum.reject(&String.contains?(&1, "extensions")) + + refute String.contains?(file, "_dev.exs") + + assert contents == File.read!(file) + end + end + describe "references" do setup do on_exit(fn -> From efb62b706f4a4ce03130048f73c62756533125ca Mon Sep 17 00:00:00 2001 From: ken-kost Date: Fri, 7 Mar 2025 08:21:16 +0100 Subject: [PATCH 05/10] Rollback migrations before file removal --- lib/migration_generator/migration_generator.ex | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index bc2d6502..c896c41f 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -518,6 +518,12 @@ defmodule AshPostgres.MigrationGenerator do |> migration_path(repo) |> File.ls!() |> Enum.filter(&String.contains?(&1, "_dev.exs")) + |> then(fn dev_migrations -> + version = dev_migrations |> Enum.min() |> String.split("_") |> hd() + System.cmd("mix", ["ash_postgres.rollback", "--to", version]) + System.cmd("mix", ["ash_postgres.rollback", "--to", version], env: [{"MIX_ENV", "test"}]) + dev_migrations + end) |> Enum.each(fn migration_name -> opts |> migration_path(repo) From ad981816c523b62151d8f025c8bd55daa9c2abc4 Mon Sep 17 00:00:00 2001 From: ken-kost Date: Fri, 7 Mar 2025 09:07:15 +0100 Subject: [PATCH 06/10] Rollback tenant migrations --- lib/migration_generator/migration_generator.ex | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index c896c41f..ffa3a1bd 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -520,8 +520,17 @@ defmodule AshPostgres.MigrationGenerator do |> Enum.filter(&String.contains?(&1, "_dev.exs")) |> then(fn dev_migrations -> version = dev_migrations |> Enum.min() |> String.split("_") |> hd() + opts = [env: [{"MIX_ENV", "test"}]] System.cmd("mix", ["ash_postgres.rollback", "--to", version]) - System.cmd("mix", ["ash_postgres.rollback", "--to", version], env: [{"MIX_ENV", "test"}]) + System.cmd("mix", ["ash_postgres.rollback", "--to", version], opts) + + if tenant? do + for tenant <- AshPostgres.Mix.Helpers.tenants(repo, opts) do + System.cmd("mix", ["ash_postgres.rollback", "--to", version, "--prefix", tenant]) + System.cmd("mix", ["ash_postgres.rollback", "--to", version, "--prefix", tenant], opts) + end + end + dev_migrations end) |> Enum.each(fn migration_name -> From 50f5b6f79f8a3b981efc2b54c6f91dde0243690b Mon Sep 17 00:00:00 2001 From: ken-kost Date: Fri, 7 Mar 2025 13:22:47 +0100 Subject: [PATCH 07/10] Check dev for tenants, use helper functions to split up logic --- .../migration_generator.ex | 136 +++++++++--------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index ffa3a1bd..f0308cf0 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -453,7 +453,9 @@ defmodule AshPostgres.MigrationGenerator do :ok operations -> - if !opts.dev and any_dev_migrations?(opts, repo) do + dev_migrations = get_dev_migrations(opts, tenant?, repo) + + if !opts.dev and dev_migrations != [] do if opts.check do Mix.shell().error(""" Generated migrations are from dev mode. @@ -463,7 +465,8 @@ defmodule AshPostgres.MigrationGenerator do exit({:shutdown, 1}) else - remove_dev_migrations_and_snapshots(opts, tenant?, repo, snapshots) + remove_dev_migrations(dev_migrations, tenant?, repo, opts) + remove_dev_snapshots(snapshots, opts) end end @@ -506,59 +509,53 @@ defmodule AshPostgres.MigrationGenerator do end) end - defp any_dev_migrations?(opts, repo) do + defp get_dev_migrations(opts, tenant?, repo) do opts - |> migration_path(repo) - |> File.ls!() - |> Enum.any?(&String.contains?(&1, "_dev.exs")) + |> migration_path(repo, tenant?) + |> File.ls() + |> case do + {:error, _error} -> [] + {:ok, migrations} -> Enum.filter(migrations, &String.contains?(&1, "_dev.exs")) + end end - defp remove_dev_migrations_and_snapshots(opts, tenant?, repo, snapshots) do - opts - |> migration_path(repo) - |> File.ls!() - |> Enum.filter(&String.contains?(&1, "_dev.exs")) - |> then(fn dev_migrations -> - version = dev_migrations |> Enum.min() |> String.split("_") |> hd() - opts = [env: [{"MIX_ENV", "test"}]] - System.cmd("mix", ["ash_postgres.rollback", "--to", version]) - System.cmd("mix", ["ash_postgres.rollback", "--to", version], opts) + defp remove_dev_migrations(dev_migrations, tenant?, repo, opts) do + version = dev_migrations |> Enum.min() |> String.split("_") |> hd() + test_env = [env: [{"MIX_ENV", "test"}]] + System.cmd("mix", ["ash_postgres.rollback", "--to", version]) + System.cmd("mix", ["ash_postgres.rollback", "--to", version], test_env) - if tenant? do - for tenant <- AshPostgres.Mix.Helpers.tenants(repo, opts) do - System.cmd("mix", ["ash_postgres.rollback", "--to", version, "--prefix", tenant]) - System.cmd("mix", ["ash_postgres.rollback", "--to", version, "--prefix", tenant], opts) - end + if tenant? do + for tenant <- repo.all_tenants() do + System.cmd("mix", ["ash_postgres.rollback", "--to", version, "--prefix", tenant]) + + System.cmd( + "mix", + ["ash_postgres.rollback", "--to", version, "--prefix", tenant], + opts + ) end + end - dev_migrations - end) + dev_migrations |> Enum.each(fn migration_name -> opts - |> migration_path(repo) + |> migration_path(repo, tenant?) |> Path.join(migration_name) |> File.rm!() end) + end + def remove_dev_snapshots(snapshots, opts) do Enum.each(snapshots, fn snapshot -> - snapshot_folder = - if tenant? do - opts - |> snapshot_path(snapshot.repo) - |> Path.join(repo_name(repo)) - |> Path.join("tenants") - |> Path.join(snapshot.table) - else - opts - |> snapshot_path(snapshot.repo) - |> Path.join(repo_name(snapshot.repo)) - |> Path.join(snapshot.table) - end + folder = get_snapshot_folder(snapshot, opts) + snapshot_path = get_snapshot_path(snapshot, folder) - File.ls!(snapshot_folder) + snapshot_path + |> File.ls!() |> Enum.filter(&String.contains?(&1, "_dev.json")) |> Enum.each(fn snapshot_name -> - snapshot_folder + snapshot_path |> Path.join(snapshot_name) |> File.rm!() end) @@ -2689,35 +2686,11 @@ defmodule AshPostgres.MigrationGenerator do end def get_existing_snapshot(snapshot, opts) do - repo_name = snapshot.repo |> Module.split() |> List.last() |> Macro.underscore() - - folder = - if snapshot.multitenancy.strategy == :context do - opts - |> snapshot_path(snapshot.repo) - |> Path.join(repo_name) - |> Path.join("tenants") - else - opts - |> snapshot_path(snapshot.repo) - |> Path.join(repo_name) - end - - snapshot_folder = - if snapshot.schema do - schema_dir = Path.join(folder, "#{snapshot.schema}.#{snapshot.table}") - - if File.dir?(schema_dir) do - schema_dir - else - Path.join(folder, snapshot.table) - end - else - Path.join(folder, snapshot.table) - end + folder = get_snapshot_folder(snapshot, opts) + snapshot_path = get_snapshot_path(snapshot, folder) - if File.exists?(snapshot_folder) do - snapshot_folder + if File.exists?(snapshot_path) do + snapshot_path |> File.ls!() |> Enum.filter( &(String.match?(&1, ~r/^\d{14}\.json$/) or @@ -2728,7 +2701,7 @@ defmodule AshPostgres.MigrationGenerator do get_old_snapshot(folder, snapshot) snapshot_files -> - snapshot_folder + snapshot_path |> Path.join(Enum.max(snapshot_files)) |> File.read!() |> load_snapshot() @@ -2738,6 +2711,33 @@ defmodule AshPostgres.MigrationGenerator do end end + defp get_snapshot_folder(snapshot, opts) do + if snapshot.multitenancy.strategy == :context do + opts + |> snapshot_path(snapshot.repo) + |> Path.join(repo_name(snapshot.repo)) + |> Path.join("tenants") + else + opts + |> snapshot_path(snapshot.repo) + |> Path.join(repo_name(snapshot.repo)) + end + end + + defp get_snapshot_path(snapshot, folder) do + if snapshot.schema do + schema_dir = Path.join(folder, "#{snapshot.schema}.#{snapshot.table}") + + if File.dir?(schema_dir) do + schema_dir + else + Path.join(folder, snapshot.table) + end + else + Path.join(folder, snapshot.table) + end + end + defp get_old_snapshot(folder, snapshot) do schema_file = if snapshot.schema do From bd090b52bc5c5c0a4f1659e65ffb88c0e40b8aa4 Mon Sep 17 00:00:00 2001 From: ken-kost Date: Fri, 7 Mar 2025 13:23:10 +0100 Subject: [PATCH 08/10] Add dev option test for tenant --- test/migration_generator_test.exs | 51 ++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 7cd837c2..c0f53a01 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -1255,6 +1255,7 @@ defmodule AshPostgres.MigrationGeneratorTest do on_exit(fn -> File.rm_rf!("test_snapshots_path") File.rm_rf!("test_migration_path") + File.rm_rf!("test_tenant_migration_path") end) end @@ -1270,7 +1271,6 @@ defmodule AshPostgres.MigrationGeneratorTest do AshPostgres.MigrationGenerator.generate(Domain, snapshot_path: "test_snapshots_path", - snapshots_only: false, migration_path: "test_migration_path", dev: true ) @@ -1295,6 +1295,55 @@ defmodule AshPostgres.MigrationGeneratorTest do assert contents == File.read!(file) end + + test "generates dev migration for tenant" do + defposts do + postgres do + schema("example") + end + + attributes do + uuid_primary_key(:id) + attribute(:title, :string, public?: true, primary_key?: true, allow_nil?: false) + end + + multitenancy do + strategy(:context) + end + end + + defdomain([Post]) + + send(self(), {:mix_shell_input, :yes?, true}) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + tenant_migration_path: "test_tenant_migration_path", + dev: true + ) + + assert [dev_file] = + Enum.sort(Path.wildcard("test_tenant_migration_path/**/*_migrate_resources*.exs")) + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert String.contains?(dev_file, "_dev.exs") + contents = File.read!(dev_file) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + tenant_migration_path: "test_tenant_migration_path" + ) + + assert [file] = + Path.wildcard("test_tenant_migration_path/**/*_migrate_resources*.exs") + |> Enum.reject(&String.contains?(&1, "extensions")) + + refute String.contains?(file, "_dev.exs") + + assert contents == File.read!(file) + end end describe "references" do From de5d3eec7ee30a8959d2b70428af51fdb26feafd Mon Sep 17 00:00:00 2001 From: ken-kost Date: Sun, 9 Mar 2025 18:02:28 +0100 Subject: [PATCH 09/10] Fix wrong opts pass in tenant rollback --- lib/migration_generator/migration_generator.ex | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index f0308cf0..039edc95 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -526,15 +526,11 @@ defmodule AshPostgres.MigrationGenerator do System.cmd("mix", ["ash_postgres.rollback", "--to", version], test_env) if tenant? do - for tenant <- repo.all_tenants() do - System.cmd("mix", ["ash_postgres.rollback", "--to", version, "--prefix", tenant]) - - System.cmd( - "mix", - ["ash_postgres.rollback", "--to", version, "--prefix", tenant], - opts - ) - end + Enum.each(repo.all_tenants(), fn tenant -> + args = ["ash_postgres.rollback", "--to", version, "--prefix", tenant] + System.cmd("mix", args) + System.cmd("mix", args, test_env) + end) end dev_migrations From 0172b883593c3dc7066acad1210b6503658ba311 Mon Sep 17 00:00:00 2001 From: ken-kost Date: Sun, 9 Mar 2025 18:03:22 +0100 Subject: [PATCH 10/10] Refactor migration generator tests --- test/migration_generator_test.exs | 1050 +++++++++-------------------- 1 file changed, 335 insertions(+), 715 deletions(-) diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index c0f53a01..aa3db94b 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -4,6 +4,8 @@ defmodule AshPostgres.MigrationGeneratorTest do import ExUnit.CaptureLog + alias AshPostgres.MigrationGenerator + setup do current_shell = Mix.shell() @@ -113,11 +115,6 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "creating initial snapshots" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do postgres do migration_types(second_title: {:varchar, 16}) @@ -142,27 +139,23 @@ defmodule AshPostgres.MigrationGeneratorTest do end defdomain([Post]) - - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - :ok + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "the migration sets up resources correctly" do + test "the migration sets up resources correctly", %{opts: opts} do + snapshot_path = "test_snapshots_path/test_repo/posts/*.json" # the snapshot exists and contains valid json - assert File.read!(Path.wildcard("test_snapshots_path/test_repo/posts/*.json")) - |> Jason.decode!(keys: :atoms!) - - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) - - file_contents = File.read!(file) + assert {:ok, contents} = File.read(Path.wildcard(snapshot_path)) + assert {:ok, _json} = Jason.decode(contents, keys: :atoms!) + assert [file] = get_files(opts[:migration_path]) + assert {:ok, file_contents} = File.read(file) # the migration creates the table assert file_contents =~ "create table(:posts, primary_key: false) do" @@ -210,11 +203,6 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "creating initial snapshots for resources with a schema" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do postgres do migration_types(second_title: {:varchar, 16}) @@ -251,26 +239,23 @@ defmodule AshPostgres.MigrationGeneratorTest do """ ) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - :ok + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "the migration sets up resources correctly" do + test "the migration sets up resources correctly", %{opts: opts} do + snapshot_path = "test_snapshots_path/test_repo/example.posts/*.json" # the snapshot exists and contains valid json - assert File.read!(Path.wildcard("test_snapshots_path/test_repo/example.posts/*.json")) - |> Jason.decode!(keys: :atoms!) - - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) - - file_contents = File.read!(file) + assert {:ok, contents} = File.read(Path.wildcard(snapshot_path)) + assert {:ok, _json} = Jason.decode(contents, keys: :atoms!) + assert [file] = get_files(opts[:migration_path]) + assert {:ok, file_contents} = File.read(file) # the migration creates the table assert file_contents =~ "create table(:posts, primary_key: false, prefix: \"example\") do" @@ -306,11 +291,6 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "custom_indexes with `concurrently: true`" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do postgres do custom_indexes do @@ -327,34 +307,26 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "it creates multiple migration files" do - assert [_, custom_index_migration] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - file = File.read!(custom_index_migration) - + test "it creates multiple migration files", %{opts: opts} do + assert [_, custom_index_migration] = get_files(opts[:migration_path]) + assert {:ok, file} = File.read(custom_index_migration) assert file =~ ~S[@disable_ddl_transaction true] - assert file =~ ~S end end describe "custom_indexes with `null_distinct: false`" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do postgres do custom_indexes do @@ -372,21 +344,19 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "it adds nulls_distinct option to create index migration" do - assert [custom_index_migration] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - file = File.read!(custom_index_migration) - + test "it adds nulls_distinct option to create index migration", %{opts: opts} do + assert [custom_index_migration] = get_files(opts[:migration_path]) + assert {:ok, file} = File.read(custom_index_migration) assert file =~ ~S assert file =~ ~S assert file =~ ~S @@ -395,11 +365,6 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "creating follow up migrations with a composite primary key" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do postgres do schema("example") @@ -413,17 +378,17 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - :ok + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "when removing an element, it recreates the primary key" do + test "when removing an element, it recreates the primary key", %{opts: opts} do defposts do postgres do schema("example") @@ -435,24 +400,13 @@ defmodule AshPostgres.MigrationGeneratorTest do end defdomain([Post]) - send(self(), {:mix_shell_input, :yes?, true}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - contents = File.read!(file2) - - [up_side, down_side] = String.split(contents, "def down", parts: 2) + MigrationGenerator.generate(Domain, opts) + assert [_file1, file2] = Enum.sort(get_files(opts[:migration_path])) + assert {:ok, contents} = File.read(file2) + assert [up_side, down_side] = String.split(contents, "def down", parts: 2) assert up_side =~ ~S[execute("ALTER TABLE \"example.posts\" ADD PRIMARY KEY (id)")] assert down_side =~ ~S[execute("ALTER TABLE \"example.posts\" DROP constraint posts_pkey")] assert down_side =~ ~S[execute("ALTER TABLE \"example.posts\" ADD PRIMARY KEY (id, title)")] @@ -469,24 +423,13 @@ defmodule AshPostgres.MigrationGeneratorTest do end defdomain([Post]) - send(self(), {:mix_shell_input, :yes?, true}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, _file2, file3] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - contents = File.read!(file3) - - [up_side, down_side] = String.split(contents, "def down", parts: 2) + MigrationGenerator.generate(Domain, opts) + assert [_file1, _file2, file3] = Enum.sort(get_files(opts[:migration_path])) + {:ok, contents} = File.read(file3) + assert [up_side, down_side] = String.split(contents, "def down", parts: 2) assert up_side =~ ~S[execute("ALTER TABLE \"example.posts\" ADD PRIMARY KEY (id, title)")] assert down_side =~ ~S[execute("ALTER TABLE \"example.posts\" ADD PRIMARY KEY (id)")] end @@ -494,17 +437,16 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "creating a multitenancy resource without composite key, adding it later" do setup do - on_exit(fn -> - nil - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - File.rm_rf!("test_tenant_migration_path") - end) - - :ok + paths = ["test_snapshots_path", "test_migration_path", "test_tenant_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path, tenant_migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts ++ [tenant_migration_path: tenant_migration_path] + {:ok, [opts: opts]} end - test "create without composite key, then add extra key" do + test "create without composite key, then add extra key", %{opts: opts} do defposts do postgres do schema("example") @@ -521,16 +463,8 @@ defmodule AshPostgres.MigrationGeneratorTest do end defdomain([Post]) - send(self(), {:mix_shell_input, :yes?, true}) - - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - tenant_migration_path: "test_tenant_migration_path", - quiet: false, - format: false - ) + MigrationGenerator.generate(Domain, opts) defposts do postgres do @@ -548,24 +482,12 @@ defmodule AshPostgres.MigrationGeneratorTest do end defdomain([Post]) - send(self(), {:mix_shell_input, :yes?, true}) + MigrationGenerator.generate(Domain, opts) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - tenant_migration_path: "test_tenant_migration_path", - quiet: false, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_tenant_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - contents = File.read!(file2) - - [up_side, down_side] = String.split(contents, "def down", parts: 2) + assert [_file1, file2] = get_files(opts[:tenant_migration_path]) + assert {:ok, contents} = File.read(file2) + assert [up_side, down_side] = String.split(contents, "def down", parts: 2) assert up_side =~ ~S[execute("ALTER TABLE \"#{prefix()}\".\"posts\" ADD PRIMARY KEY (id, title)")] @@ -577,11 +499,6 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "creating follow up migrations with a schema" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do postgres do schema("example") @@ -595,17 +512,19 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - :ok + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "when renaming a field, it asks if you are renaming it, and renames it if you are" do + test "when renaming a field, it asks if you are renaming it, and renames it if you are", %{ + opts: opts + } do defposts do postgres do schema("example") @@ -621,21 +540,13 @@ defmodule AshPostgres.MigrationGeneratorTest do send(self(), {:mix_shell_input, :yes?, true}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts) + assert [_file1, file2] = get_files(opts[:migration_path]) assert File.read!(file2) =~ ~S[rename table(:posts, prefix: "example"), :title, to: :name] end - test "renaming a field honors additional changes" do + test "renaming a field honors additional changes", %{opts: opts} do defposts do postgres do schema("example") @@ -651,17 +562,9 @@ defmodule AshPostgres.MigrationGeneratorTest do send(self(), {:mix_shell_input, :yes?, true}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts) + assert [_file1, file2] = get_files(opts[:migration_path]) assert File.read!(file2) =~ ~S[rename table(:posts, prefix: "example"), :title, to: :name] assert File.read!(file2) =~ ~S[modify :title, :text, null: true, default: nil] end @@ -669,11 +572,6 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "changing global multitenancy" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do identities do identity(:title, [:title]) @@ -694,17 +592,17 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - :ok + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "when changing multitenancy to global, identities aren't rewritten" do + test "when changing multitenancy to global, identities aren't rewritten", %{opts: opts} do defposts do identities do identity(:title, [:title]) @@ -725,26 +623,14 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [_file1] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [_file1] = get_files(opts[:migration_path]) end end describe "creating follow up migrations" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do identities do identity(:title, [:title]) @@ -758,17 +644,18 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - :ok + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "when renaming an attribute of an index, it is properly renamed without modifying the attribute" do + test "when renaming an attribute of an index, it is properly renamed without modifying the attribute", + %{opts: opts} do defposts do identities do identity(:title, [:foobar]) @@ -784,22 +671,14 @@ defmodule AshPostgres.MigrationGeneratorTest do send(self(), {:mix_shell_input, :yes?, true}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - contents = File.read!(file2) + assert [_file1, file2] = get_files(opts[:migration_path]) + assert {:ok, contents} = File.read(file2) refute contents =~ "modify" end - test "when renaming an index, it is properly renamed" do + test "when renaming an index, it is properly renamed", %{opts: opts} do defposts do postgres do identity_index_names(title: "titles_r_unique_dawg") @@ -817,22 +696,15 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [_file1, file2] = get_files(opts[:migration_path]) assert File.read!(file2) =~ ~S[ALTER INDEX posts_title_index RENAME TO titles_r_unique_dawg] end - test "when changing the where clause, it is properly dropped and recreated" do + test "when changing the where clause, it is properly dropped and recreated", %{opts: opts} do defposts do postgres do identity_wheres_to_sql(title: "title != 'fred' and title != 'george'") @@ -850,16 +722,9 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [_file1, file2] = get_files(opts[:migration_path]) assert [file_before, _] = String.split( @@ -871,7 +736,7 @@ defmodule AshPostgres.MigrationGeneratorTest do ~S{drop_if_exists unique_index(:posts, [:title], name: "posts_title_index")} end - test "when adding a field, it adds the field" do + test "when adding a field, it adds the field", %{opts: opts} do defposts do identities do identity(:title, [:title]) @@ -886,22 +751,15 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts) - assert File.read!(file2) =~ - ~S[add :name, :text, null: false] + assert [_file1, file2] = get_files(opts[:migration_path]) + assert File.read!(file2) =~ ~S[add :name, :text, null: false] end - test "when renaming a field, it asks if you are renaming it, and renames it if you are" do + test "when renaming a field, it asks if you are renaming it, and renames it if you are", %{ + opts: opts + } do defposts do attributes do uuid_primary_key(:id) @@ -913,21 +771,15 @@ defmodule AshPostgres.MigrationGeneratorTest do send(self(), {:mix_shell_input, :yes?, true}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts) + assert [_file1, file2] = get_files(opts[:migration_path]) assert File.read!(file2) =~ ~S[rename table(:posts), :title, to: :name] end - test "when renaming a field, it asks if you are renaming it, and adds it if you aren't" do + test "when renaming a field, it asks if you are renaming it, and adds it if you aren't", %{ + opts: opts + } do defposts do attributes do uuid_primary_key(:id) @@ -939,22 +791,14 @@ defmodule AshPostgres.MigrationGeneratorTest do send(self(), {:mix_shell_input, :yes?, false}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - assert File.read!(file2) =~ - ~S[add :name, :text, null: false] + assert [_file1, file2] = get_files(opts[:migration_path]) + assert File.read!(file2) =~ ~S[add :name, :text, null: false] end - test "when renaming a field, it asks which field you are renaming it to, and renames it if you are" do + test "when renaming a field, it asks which field you are renaming it to, and renames it if you are", + %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -968,16 +812,9 @@ defmodule AshPostgres.MigrationGeneratorTest do send(self(), {:mix_shell_input, :yes?, true}) send(self(), {:mix_shell_input, :prompt, "subject"}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [_file1, file2] = get_files(opts[:migration_path]) # Up migration assert File.read!(file2) =~ ~S[rename table(:posts), :title, to: :subject] @@ -986,7 +823,8 @@ defmodule AshPostgres.MigrationGeneratorTest do assert File.read!(file2) =~ ~S[rename table(:posts), :subject, to: :title] end - test "when renaming a field, it asks which field you are renaming it to, and adds it if you arent" do + test "when renaming a field, it asks which field you are renaming it to, and adds it if you arent", + %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -999,22 +837,13 @@ defmodule AshPostgres.MigrationGeneratorTest do send(self(), {:mix_shell_input, :yes?, false}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts) - assert File.read!(file2) =~ - ~S[add :subject, :text, null: false] + assert [_file1, file2] = get_files(opts[:migration_path]) + assert File.read!(file2) =~ ~S[add :subject, :text, null: false] end - test "when multiple schemas apply to the same table, all attributes are added" do + test "when multiple schemas apply to the same table, all attributes are added", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1032,25 +861,14 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - assert File.read!(file2) =~ - ~S[add :foobar, :text] + MigrationGenerator.generate(Domain, opts) - assert File.read!(file2) =~ - ~S[add :foobar, :text] + assert [_file1, file2] = get_files(opts[:migration_path]) + assert File.read!(file2) =~ ~S[add :foobar, :text] + assert File.read!(file2) =~ ~S[add :foobar, :text] end - test "when multiple schemas apply to the same table, all identities are added" do + test "when multiple schemas apply to the same table, all identities are added", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1075,23 +893,12 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - file1_content = File.read!(file1) - - assert file1_content =~ - "create unique_index(:posts, [:title], name: \"posts_title_index\")" + MigrationGenerator.generate(Domain, opts) - file2_content = File.read!(file2) + assert [file1, file2] = get_files(opts[:migration_path]) + assert {:ok, file1_content} = File.read(file1) + assert file1_content =~ "create unique_index(:posts, [:title], name: \"posts_title_index\")" + assert {:ok, file2_content} = File.read(file2) assert file2_content =~ "drop_if_exists unique_index(:posts, [:title], name: \"posts_title_index\")" @@ -1103,7 +910,8 @@ defmodule AshPostgres.MigrationGeneratorTest do "create unique_index(:posts, [:title], name: \"posts_unique_title_index\")" end - test "when concurrent-indexes flag set to true, identities are added in separate migration" do + test "when concurrent-indexes flag set to true, identities are added in separate migration", + %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1119,20 +927,10 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - concurrent_indexes: true, - format: false - ) - - assert [_file1, _file2, file3] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - file3_content = File.read!(file3) + MigrationGenerator.generate(Domain, opts ++ [concurrent_indexes: true]) + assert [_file1, _file2, file3] = get_files(opts[:migration_path]) + assert {:ok, file3_content} = File.read(file3) assert file3_content =~ ~S[@disable_ddl_transaction true] assert file3_content =~ @@ -1142,7 +940,8 @@ defmodule AshPostgres.MigrationGeneratorTest do "create unique_index(:posts, [:name], name: \"posts_unique_name_index\")" end - test "when an attribute exists only on some of the resources that use the same table, it isn't marked as null: false" do + test "when an attribute exists only on some of the resources that use the same table, it isn't marked as null: false", + %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1159,31 +958,16 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - assert File.read!(file2) =~ - ~S[add :example, :text] <> "\n" + MigrationGenerator.generate(Domain, opts) + assert [_file1, file2] = get_files(opts[:migration_path]) + assert File.read!(file2) =~ ~S[add :example, :text] <> "\n" refute File.read!(file2) =~ ~S[null: false] end end describe "auto incrementing integer, when generated" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do attributes do attribute(:id, :integer, @@ -1199,31 +983,34 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - :ok + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "when an integer is generated and default nil, it is a bigserial" do - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) - - assert File.read!(file) =~ - ~S[add :id, :bigserial, null: false, primary_key: true] - - assert File.read!(file) =~ - ~S[add :views, :bigint] + test "when an integer is generated and default nil, it is a bigserial", %{opts: opts} do + assert [file] = get_files(opts[:migration_path]) + assert File.read!(file) =~ ~S[add :id, :bigserial, null: false, primary_key: true] + assert File.read!(file) =~ ~S[add :views, :bigint] end end describe "--check option" do setup do + paths = ["test_snapshots_path", "test_migration_path"] + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + {:ok, [opts: opts]} + end + + test "returns code(1) if snapshots and resources don't fit", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1233,17 +1020,8 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - [domain: Domain] - end - - test "returns code(1) if snapshots and resources don't fit", %{domain: domain} do - assert catch_exit( - AshPostgres.MigrationGenerator.generate(domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - check: true - ) - ) == {:shutdown, 1} + assert catch_exit(MigrationGenerator.generate(Domain, opts ++ [check: true])) == + {:shutdown, 1} refute File.exists?(Path.wildcard("test_migration_path2/**/*_migrate_resources*.exs")) refute File.exists?(Path.wildcard("test_snapshots_path2/test_repo/posts/*.json")) @@ -1252,14 +1030,16 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "--dev option" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - File.rm_rf!("test_tenant_migration_path") - end) + paths = ["test_snapshots_path", "test_migration_path", "test_tenant_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path, tenant_migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts ++ [tenant_migration_path: tenant_migration_path] + {:ok, [opts: opts]} end - test "generates dev migration" do + test "generates dev migration", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1269,34 +1049,20 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - dev: true - ) - - assert [dev_file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts ++ [dev: true]) + assert [dev_file] = get_files(opts[:migration_path]) assert String.contains?(dev_file, "_dev.exs") - contents = File.read!(dev_file) + assert {:ok, contents} = File.read(dev_file) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path" - ) - - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts) + assert [file] = get_files(opts[:migration_path]) refute String.contains?(file, "_dev.exs") - assert contents == File.read!(file) end - test "generates dev migration for tenant" do + test "generates dev migration for tenant", %{opts: opts} do defposts do postgres do schema("example") @@ -1316,45 +1082,32 @@ defmodule AshPostgres.MigrationGeneratorTest do send(self(), {:mix_shell_input, :yes?, true}) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - tenant_migration_path: "test_tenant_migration_path", - dev: true - ) - - assert [dev_file] = - Enum.sort(Path.wildcard("test_tenant_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts ++ [dev: true]) + assert [dev_file] = get_files(opts[:tenant_migration_path]) assert String.contains?(dev_file, "_dev.exs") - contents = File.read!(dev_file) + assert {:ok, contents} = File.read(dev_file) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - tenant_migration_path: "test_tenant_migration_path" - ) - - assert [file] = - Path.wildcard("test_tenant_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts) + assert [file] = get_files(opts[:tenant_migration_path]) refute String.contains?(file, "_dev.exs") - assert contents == File.read!(file) end end describe "references" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + {:ok, [opts: opts]} end - test "references are inferred automatically" do + test "references are inferred automatically", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1376,22 +1129,17 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S[references(:posts, column: :id, name: "posts_post_id_fkey", type: :uuid, prefix: "public")] end - test "references are inferred automatically if the attribute has a different type" do + test "references are inferred automatically if the attribute has a different type", %{ + opts: opts + } do defposts do attributes do attribute(:id, :string, primary_key?: true, allow_nil?: false, public?: true) @@ -1413,22 +1161,15 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S[references(:posts, column: :id, name: "posts_post_id_fkey", type: :text, prefix: "public")] end - test "references allow passing :match_with and :match_type" do + test "references allow passing :match_with and :match_type", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1459,22 +1200,15 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S{references(:posts, column: :id, with: [related_key_id: :key_id], match: :partial, name: "posts_post_id_fkey", type: :uuid, prefix: "public")} end - test "references generate related index when index? true" do + test "references generate related index when index? true", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1505,12 +1239,7 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) assert [file] = Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") @@ -1519,7 +1248,9 @@ defmodule AshPostgres.MigrationGeneratorTest do assert File.read!(file) =~ ~S{create index(:posts, [:post_id])} end - test "index generated by index? true also adds column when using attribute multitenancy" do + test "index generated by index? true also adds column when using attribute multitenancy", %{ + opts: opts + } do defresource Org, "orgs" do attributes do uuid_primary_key(:id, writable?: true, public?: true) @@ -1582,21 +1313,13 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Org, Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + MigrationGenerator.generate(Domain, opts) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S{create index(:posts, [:org_id, :post_id])} end - test "references merge :match_with and multitenancy attribute" do + test "references merge :match_with and multitenancy attribute", %{opts: opts} do defresource Org, "orgs" do attributes do uuid_primary_key(:id, writable?: true, public?: true) @@ -1660,22 +1383,16 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Org, User, UserThing]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S{references(:users, column: :secondary_id, with: [related_key_id: :key_id, org_id: :org_id], match: :full, name: "user_things_user_id_fkey", type: :uuid, prefix: "public")} end - test "identities using `all_tenants?: true` will not have the condition on multitenancy attribtue added" do + test "identities using `all_tenants?: true` will not have the condition on multitenancy attribtue added", + %{opts: opts} do defresource Org, "orgs" do attributes do uuid_primary_key(:id, writable?: true) @@ -1715,22 +1432,15 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Org, User]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S{create unique_index(:users, [:name], name: "users_unique_name_index")} end - test "when modified, the foreign key is dropped before modification" do + test "when modified, the foreign key is dropped before modification", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -1754,12 +1464,7 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Post2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) defposts Post2 do postgres do @@ -1780,17 +1485,11 @@ defmodule AshPostgres.MigrationGeneratorTest do end end - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) assert file = - "test_migration_path/**/*_migrate_resources*.exs" - |> Path.wildcard() - |> Enum.reject(&String.contains?(&1, "extensions")) + opts[:migration_path] + |> get_files() |> Enum.sort() |> Enum.at(1) |> File.read!() @@ -1799,7 +1498,6 @@ defmodule AshPostgres.MigrationGeneratorTest do ~S[references(:posts, column: :id, name: "special_post_fkey", type: :uuid, prefix: "public", on_delete: :delete_all, on_update: :update_all)] assert file =~ ~S[drop constraint(:posts, "posts_post_id_fkey")] - assert [_, down_code] = String.split(file, "def down do") assert [_, after_drop] = @@ -1808,7 +1506,7 @@ defmodule AshPostgres.MigrationGeneratorTest do assert after_drop =~ ~S[references(:posts] end - test "references with added only when needed on multitenant resources" do + test "references with added only when needed on multitenant resources", %{opts: opts} do defresource Org, "orgs" do attributes do uuid_primary_key(:id, writable?: true) @@ -1886,16 +1584,9 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Org, User, UserThing1, UserThing2]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S{references(:users, column: :secondary_id, with: [org_id: :org_id], match: :full, name: "user_things1_user_id_fkey", type: :uuid, prefix: "public")} @@ -1904,7 +1595,9 @@ defmodule AshPostgres.MigrationGeneratorTest do ~S[references(:users, column: :id, name: "user_things2_user_id_fkey", type: :uuid, prefix: "public")] end - test "references on_delete: {:nilify, columns} works with multitenant resources" do + test "references on_delete: {:nilify, columns} works with multitenant resources", %{ + opts: opts + } do defresource Tenant, "tenants" do attributes do uuid_primary_key(:id) @@ -1966,16 +1659,9 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Tenant, Group, Item]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S @@ -1984,13 +1670,16 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "check constraints" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + {:ok, [opts: opts]} end - test "when added, the constraint is created" do + test "when added, the constraint is created", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -2006,23 +1695,16 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) assert file = - "test_migration_path/**/*_migrate_resources*.exs" - |> Path.wildcard() - |> Enum.reject(&String.contains?(&1, "extensions")) + opts[:migration_path] + |> get_files() |> Enum.sort() |> Enum.at(0) |> File.read!() - assert file =~ - ~S[create constraint(:posts, :price_must_be_positive, check: "price > 0")] + assert file =~ ~S[create constraint(:posts, :price_must_be_positive, check: "price > 0")] defposts do attributes do @@ -2039,17 +1721,11 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) assert file = - "test_migration_path/**/*_migrate_resources*.exs" - |> Path.wildcard() - |> Enum.reject(&String.contains?(&1, "extensions")) + opts[:migration_path] + |> get_files() |> Enum.sort() |> Enum.at(1) |> File.read!() @@ -2063,7 +1739,7 @@ defmodule AshPostgres.MigrationGeneratorTest do ~S[create constraint(:posts, :price_must_be_positive, check: "price > 0")] end - test "when removed, the constraint is dropped before modification" do + test "when removed, the constraint is dropped before modification", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -2079,12 +1755,7 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) defposts do attributes do @@ -2093,32 +1764,30 @@ defmodule AshPostgres.MigrationGeneratorTest do end end - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) assert file = - "test_migration_path/**/*_migrate_resources*.exs" - |> Path.wildcard() - |> Enum.reject(&String.contains?(&1, "extensions")) + opts[:migration_path] + |> get_files() |> Enum.sort() |> Enum.at(1) - assert File.read!(file) =~ - ~S[drop_if_exists constraint(:posts, :price_must_be_positive)] + assert File.read!(file) =~ ~S[drop_if_exists constraint(:posts, :price_must_be_positive)] end end describe "polymorphic resources" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + {:ok, [opts: opts]} + end + test "it uses the relationship's table context if it is set", %{opts: opts} do defcomments do postgres do polymorphic?(true) @@ -2170,20 +1839,9 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Comment]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - [domain: Domain] - end - - test "it uses the relationship's table context if it is set" do - assert [file] = - Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file] = get_files(opts[:migration_path]) assert File.read!(file) =~ ~S[references(:post_comments, column: :id, name: "posts_best_comment_id_fkey", type: :uuid, prefix: "public")] @@ -2192,13 +1850,16 @@ defmodule AshPostgres.MigrationGeneratorTest do describe "default values" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + {:ok, [opts: opts]} end - test "when default value is specified that implements EctoMigrationDefault" do + test "when default value is specified that implements EctoMigrationDefault", %{opts: opts} do defposts do attributes do uuid_primary_key(:id) @@ -2227,24 +1888,14 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [file1] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) + assert [file1] = get_files(opts[:migration_path]) file = File.read!(file1) - assert file =~ - ~S[add :start_date, :date, default: fragment("'2022-04-19'")] - - assert file =~ - ~S[add :start_time, :time, default: fragment("'08:30:45'")] + assert file =~ ~S[add :start_date, :date, default: fragment("'2022-04-19'")] + assert file =~ ~S[add :start_time, :time, default: fragment("'08:30:45'")] assert file =~ ~S[add :timestamp, :utc_datetime, default: fragment("'2022-02-02 08:30:30Z'")] @@ -2252,26 +1903,17 @@ defmodule AshPostgres.MigrationGeneratorTest do assert file =~ ~S[add :timestamp_naive, :naive_datetime, default: fragment("'2022-02-02 08:30:30'")] - assert file =~ - ~S[add :number, :bigint, default: 5] - - assert file =~ - ~S[add :fraction, :float, default: 0.25] - - assert file =~ - ~S[add :decimal, :decimal, default: "123.4567890987654321987"] - - assert file =~ - ~S[add :name, :text, default: "Fred"] - - assert file =~ - ~S[add :tag, :text, default: "value"] - - assert file =~ - ~S[add :enabled, :boolean, default: false] + assert file =~ ~S[add :number, :bigint, default: 5] + assert file =~ ~S[add :fraction, :float, default: 0.25] + assert file =~ ~S[add :decimal, :decimal, default: "123.4567890987654321987"] + assert file =~ ~S[add :name, :text, default: "Fred"] + assert file =~ ~S[add :tag, :text, default: "value"] + assert file =~ ~S[add :enabled, :boolean, default: false] end - test "when default value is specified that does not implement EctoMigrationDefault" do + test "when default value is specified that does not implement EctoMigrationDefault", %{ + opts: opts + } do defposts do attributes do uuid_primary_key(:id) @@ -2281,36 +1923,16 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post]) - log = - capture_log(fn -> - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - end) - + log = capture_log(fn -> MigrationGenerator.generate(Domain, opts) end) assert log =~ "`{\"xyz\"}`" - - assert [file1] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - + assert [file1] = get_files(opts[:migration_path]) file = File.read!(file1) - - assert file =~ - ~S[add :product_code, :binary] + assert file =~ ~S[add :product_code, :binary] end end describe "follow up with references" do setup do - on_exit(fn -> - File.rm_rf!("test_snapshots_path") - File.rm_rf!("test_migration_path") - end) - defposts do attributes do uuid_primary_key(:id) @@ -2332,17 +1954,17 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Comment]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) - - :ok + paths = ["test_snapshots_path", "test_migration_path"] + on_exit(fn -> for path <- paths, do: File.rm_rf!(path) end) + [snapshot_path, migration_path] = paths + path_opts = [snapshot_path: snapshot_path, migration_path: migration_path] + test_opts = [quiet: true, format: false] + opts = path_opts ++ test_opts + MigrationGenerator.generate(Domain, opts) + {:ok, [opts: opts]} end - test "when changing the primary key, it changes properly" do + test "when changing the primary key, it changes properly", %{opts: opts} do defposts do attributes do attribute(:id, :uuid, @@ -2370,28 +1992,26 @@ defmodule AshPostgres.MigrationGeneratorTest do defdomain([Post, Comment]) - AshPostgres.MigrationGenerator.generate(Domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - quiet: true, - format: false - ) + MigrationGenerator.generate(Domain, opts) - assert [_file1, file2] = - Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) - |> Enum.reject(&String.contains?(&1, "extensions")) - - file = File.read!(file2) + assert [_file1, file2] = get_files(opts[:migration_path]) + assert {:ok, file} = File.read(file2) assert [before_index_drop, after_index_drop] = String.split(file, ~S[drop constraint("posts", "posts_pkey")], parts: 2) assert before_index_drop =~ ~S[drop constraint(:comments, "comments_post_id_fkey")] - assert after_index_drop =~ ~S[modify :id, :uuid, null: true, primary_key: false] assert after_index_drop =~ ~S[modify :post_id, references(:posts, column: :id, name: "comments_post_id_fkey", type: :uuid, prefix: "public")] end end + + defp get_files(path) do + path + |> Path.join("**/*_migrate_resources*.exs") + |> Path.wildcard() + |> Enum.reject(&String.contains?(&1, "extensions")) + end end