From fb0fea81341c76e7bba6171b4fc25090f64272a2 Mon Sep 17 00:00:00 2001 From: Tim Riley Date: Mon, 17 Jun 2024 00:33:35 +1000 Subject: [PATCH] Add `db prepare` command (#176) Add a `db prepare` command for the new db layer. This command will invoke `db create` and `db structure load` (if the database did not already exist), and then `db migrate` and `db seed`. Getting this to work and be well tested required some internal changes: - Update the `db` commands that it calls to otherwise exit themselves using an injected `command_exit` proc, which defaults to `method(:exit)`. This then allows the `db prepare` command to inject an alternative proc that prevents those subcommands from exiting the whole process, allow it to catch the failures and handle them on its own. - Allow `DB::Command#databases` to receive a real `slice:` object as part of its args, so that `db prepare` can pass this along directly to all its subcommands. --- lib/hanami/cli/commands/app.rb | 2 + lib/hanami/cli/commands/app/db/command.rb | 16 +- lib/hanami/cli/commands/app/db/create.rb | 4 +- lib/hanami/cli/commands/app/db/migrate.rb | 4 +- lib/hanami/cli/commands/app/db/prepare.rb | 42 +++ lib/hanami/cli/commands/app/db/setup.rb | 26 -- .../cli/commands/app/db/structure/dump.rb | 4 +- .../cli/commands/app/db/structure/load.rb | 14 +- .../cli/commands/app/db/utils/database.rb | 8 +- .../cli/commands/app/db/utils/postgres.rb | 2 +- spec/support/matchers.rb | 17 + .../cli/commands/app/db/migrate_spec.rb | 16 +- .../cli/commands/app/db/prepare_spec.rb | 348 ++++++++++++++++++ .../hanami/cli/commands/app/db/setup_spec.rb | 18 - .../commands/app/db/structure/load_spec.rb | 7 + 15 files changed, 461 insertions(+), 67 deletions(-) create mode 100644 lib/hanami/cli/commands/app/db/prepare.rb delete mode 100644 lib/hanami/cli/commands/app/db/setup.rb create mode 100644 spec/support/matchers.rb create mode 100644 spec/unit/hanami/cli/commands/app/db/prepare_spec.rb delete mode 100644 spec/unit/hanami/cli/commands/app/db/setup_spec.rb diff --git a/lib/hanami/cli/commands/app.rb b/lib/hanami/cli/commands/app.rb index 4041a810..051463cf 100644 --- a/lib/hanami/cli/commands/app.rb +++ b/lib/hanami/cli/commands/app.rb @@ -30,10 +30,12 @@ def self.extended(base) if Hanami.bundled?("hanami-db") register "db" do |db| db.register "create", DB::Create + db.register "drop", DB::Drop db.register "migrate", DB::Migrate db.register "structure dump", DB::Structure::Dump db.register "structure load", DB::Structure::Load db.register "seed", DB::Seed + db.register "prepare", DB::Prepare db.register "version", DB::Version end end diff --git a/lib/hanami/cli/commands/app/db/command.rb b/lib/hanami/cli/commands/app/db/command.rb index 150eabf9..eac0b8ae 100644 --- a/lib/hanami/cli/commands/app/db/command.rb +++ b/lib/hanami/cli/commands/app/db/command.rb @@ -28,6 +28,15 @@ def initialize( @system_call = system_call end + def run_command(klass, ...) + klass.new( + out: out, + inflector: fs, + fs: fs, + system_call: system_call, + ).call(...) + end + private def databases(app: false, slice: nil) @@ -45,9 +54,12 @@ def database_for_app end def database_for_slice(slice) - slice = inflector.underscore(Shellwords.shellescape(slice)).to_sym + unless slice.is_a?(Class) && slice < Hanami::Slice + slice_name = inflector.underscore(Shellwords.shellescape(slice)).to_sym + slice = app.slices[slice_name] + end - build_database(app.slices[slice]) + build_database(slice) end def all_databases diff --git a/lib/hanami/cli/commands/app/db/create.rb b/lib/hanami/cli/commands/app/db/create.rb index e7750735..8d12db4f 100644 --- a/lib/hanami/cli/commands/app/db/create.rb +++ b/lib/hanami/cli/commands/app/db/create.rb @@ -9,7 +9,7 @@ module DB class Create < DB::Command desc "Create databases" - def call(app: false, slice: nil, **) + def call(app: false, slice: nil, command_exit: method(:exit), **) exit_codes = [] databases(app: app, slice: slice).each do |database| @@ -25,7 +25,7 @@ def call(app: false, slice: nil, **) end exit_codes.each do |code| - break exit code if code > 0 + break command_exit.(code) if code > 0 end end end diff --git a/lib/hanami/cli/commands/app/db/migrate.rb b/lib/hanami/cli/commands/app/db/migrate.rb index 5f04636c..3a6acdf8 100644 --- a/lib/hanami/cli/commands/app/db/migrate.rb +++ b/lib/hanami/cli/commands/app/db/migrate.rb @@ -13,12 +13,12 @@ class Migrate < DB::Command option :dump, required: false, type: :boolean, default: true, desc: "Dump the database structure after migrating" - def call(target: nil, app: false, slice: nil, dump: true, **) + def call(target: nil, app: false, slice: nil, dump: true, command_exit: method(:exit), **) databases(app: app, slice: slice).each do |database| migrate_database(database, target: target) end - run_command(Structure::Dump, app: app, slice: slice) if dump + run_command(Structure::Dump, app: app, slice: slice, command_exit: command_exit) if dump end private diff --git a/lib/hanami/cli/commands/app/db/prepare.rb b/lib/hanami/cli/commands/app/db/prepare.rb new file mode 100644 index 00000000..49b903eb --- /dev/null +++ b/lib/hanami/cli/commands/app/db/prepare.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Hanami + module CLI + module Commands + module App + module DB + # @api private + class Prepare < DB::Command + desc "Prepare databases" + + def call(app: false, slice: nil, **) + exit_codes = [] + + databases(app: app, slice: slice).each do |database| + command_exit = -> code { throw :command_exited, code } + command_args = {slice: database.slice, command_exit: command_exit} + + exit_code = catch :command_exited do + unless database.exists? + run_command(DB::Create, **command_args) + run_command(DB::Structure::Load, **command_args) + end + + run_command(DB::Migrate, **command_args) + run_command(DB::Seed, **command_args) + nil + end + + exit_codes << exit_code if exit_code + end + + exit_codes.each do |code| + break exit code if code > 0 + end + end + end + end + end + end + end +end diff --git a/lib/hanami/cli/commands/app/db/setup.rb b/lib/hanami/cli/commands/app/db/setup.rb deleted file mode 100644 index 0a0ec6ea..00000000 --- a/lib/hanami/cli/commands/app/db/setup.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -require_relative "../../app/command" -require_relative "create" -require_relative "migrate" - -module Hanami - module CLI - module Commands - module App - module DB - # @api private - class Setup < App::Command - desc "Setup database" - - # @api private - def call(**) - run_command Create - run_command Migrate - end - end - end - end - end - end -end diff --git a/lib/hanami/cli/commands/app/db/structure/dump.rb b/lib/hanami/cli/commands/app/db/structure/dump.rb index 807278ff..09d36b14 100644 --- a/lib/hanami/cli/commands/app/db/structure/dump.rb +++ b/lib/hanami/cli/commands/app/db/structure/dump.rb @@ -12,7 +12,7 @@ class Dump < DB::Command desc "Dumps database structure to config/db/structure.sql file" # @api private - def call(app: false, slice: nil, **) + def call(app: false, slice: nil, command_exit: method(:exit), **) exit_codes = [] databases(app: app, slice: slice).each do |database| @@ -39,7 +39,7 @@ def call(app: false, slice: nil, **) end exit_codes.each do |code| - break exit code if code > 0 + break command_exit.(code) if code > 0 end end end diff --git a/lib/hanami/cli/commands/app/db/structure/load.rb b/lib/hanami/cli/commands/app/db/structure/load.rb index 4dcf47c8..1fc4f89d 100644 --- a/lib/hanami/cli/commands/app/db/structure/load.rb +++ b/lib/hanami/cli/commands/app/db/structure/load.rb @@ -9,15 +9,21 @@ module DB module Structure # @api private class Load < DB::Command + STRUCTURE_PATH = File.join("config", "db", "structure.sql").freeze + private_constant :STRUCTURE_PATH + desc "Loads database from config/db/structure.sql file" # @api private - def call(app: false, slice: nil, **) + def call(app: false, slice: nil, command_exit: method(:exit), **) + # TODO: handle exit_codes here + databases(app: app, slice: slice).each do |database| - slice_root = database.slice.root.relative_path_from(database.slice.app.root) - structure_path = slice_root.join("config", "db", "structure.sql") + structure_path = database.slice.root.join(STRUCTURE_PATH) + next unless structure_path.exist? - measure("#{database.name} structure loaded from #{structure_path}") do + relative_structure_path = structure_path.relative_path_from(database.slice.app.root) + measure("#{database.name} structure loaded from #{relative_structure_path}") do database.exec_load_command.tap do |result| unless result.successful? out.puts result.err diff --git a/lib/hanami/cli/commands/app/db/utils/database.rb b/lib/hanami/cli/commands/app/db/utils/database.rb index a585d37c..abed8752 100644 --- a/lib/hanami/cli/commands/app/db/utils/database.rb +++ b/lib/hanami/cli/commands/app/db/utils/database.rb @@ -75,11 +75,15 @@ def connection gateway.connection end - def create_command + def exec_create_command raise Hanami::CLI::NotImplementedError end - def drop_command + def exec_drop_command + raise Hanami::CLI::NotImplementedError + end + + def exists? raise Hanami::CLI::NotImplementedError end diff --git a/lib/hanami/cli/commands/app/db/utils/postgres.rb b/lib/hanami/cli/commands/app/db/utils/postgres.rb index 2fe12253..b7a2b4dc 100644 --- a/lib/hanami/cli/commands/app/db/utils/postgres.rb +++ b/lib/hanami/cli/commands/app/db/utils/postgres.rb @@ -24,7 +24,7 @@ def exec_drop_command system_call.call("dropdb #{escaped_name}", env: cli_env_vars) end - private def exists? + def exists? result = system_call.call("psql -t -A -c '\\list #{escaped_name}'", env: cli_env_vars) result.successful? && result.out.include?("#{name}|") # start_with? end diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb new file mode 100644 index 00000000..1f3d036a --- /dev/null +++ b/spec/support/matchers.rb @@ -0,0 +1,17 @@ +module RSpec + module Support + module Matchers + def include_in_order(*strings) + re = Regexp.new( + strings.map { Regexp.escape(_1) }.join(".+"), + Regexp::MULTILINE | Regexp::EXTENDED + ) + match(re) + end + end + end +end + +RSpec.configure do |config| + config.include RSpec::Support::Matchers +end diff --git a/spec/unit/hanami/cli/commands/app/db/migrate_spec.rb b/spec/unit/hanami/cli/commands/app/db/migrate_spec.rb index c7a25ed6..70b6a685 100644 --- a/spec/unit/hanami/cli/commands/app/db/migrate_spec.rb +++ b/spec/unit/hanami/cli/commands/app/db/migrate_spec.rb @@ -86,7 +86,7 @@ class Posts < Hanami::DB::Relation expect(Hanami.app["relations.posts"].to_a).to eq [] - expect(dump_command).to have_received(:call).with(app: false, slice: nil) + expect(dump_command).to have_received(:call).with(hash_including(app: false, slice: nil)) expect(dump_command).to have_received(:call).exactly(1).time end @@ -175,7 +175,7 @@ class Posts < Hanami::DB::Relation expect(Admin::Slice["relations.posts"].to_a).to eq [] - expect(dump_command).to have_received(:call).with(app: false, slice: "admin") + expect(dump_command).to have_received(:call).with(hash_including(app: false, slice: "admin")) expect(dump_command).to have_received(:call).exactly(1).time end end @@ -203,7 +203,7 @@ class Posts < Hanami::DB::Relation end RUBY - write "slices/main/config/db/migrate/20240602201330_create_users.rb", <<~RUBY + write "slices/main/config/db/migrate/20240602201330_create_comments.rb", <<~RUBY ROM::SQL.migration do change do create_table :comments do @@ -239,7 +239,7 @@ class Comments < Hanami::DB::Relation expect(Hanami.app["relations.posts"].to_a).to eq [] expect(Main::Slice["relations.comments"].to_a).to eq [] - expect(dump_command).to have_received(:call).with(app: false, slice: nil) + expect(dump_command).to have_received(:call).with(hash_including(app: false, slice: nil)) expect(dump_command).to have_received(:call).exactly(1).time end @@ -252,7 +252,7 @@ class Comments < Hanami::DB::Relation expect(Hanami.app["relations.posts"].to_a).to eq [] expect { Main::Slice["relations.comments"].to_a }.to raise_error Sequel::Error - expect(dump_command).to have_received(:call).with(app: true, slice: nil) + expect(dump_command).to have_received(:call).with(hash_including(app: true, slice: nil)) expect(dump_command).to have_received(:call).exactly(1).time end @@ -265,7 +265,7 @@ class Comments < Hanami::DB::Relation expect(Main::Slice["relations.comments"].to_a).to eq [] expect { Hanami.app["relations.posts"].to_a }.to raise_error Sequel::Error - expect(dump_command).to have_received(:call).with(app: false, slice: "main") + expect(dump_command).to have_received(:call).with(hash_including(app: false, slice: "main")) expect(dump_command).to have_received(:call).exactly(1).time end end @@ -329,7 +329,7 @@ class Comments < Hanami::DB::Relation expect(Admin::Slice["relations.posts"].to_a).to eq [] expect(Main::Slice["relations.comments"].to_a).to eq [] - expect(dump_command).to have_received(:call).with(app: false, slice: nil) + expect(dump_command).to have_received(:call).with(hash_including(app: false, slice: nil)) expect(dump_command).to have_received(:call).exactly(1).time end @@ -342,7 +342,7 @@ class Comments < Hanami::DB::Relation expect(Admin::Slice["relations.posts"].to_a).to eq [] expect { Main::Slice["relations.comments"].to_a }.to raise_error Sequel::Error - expect(dump_command).to have_received(:call).with(app: false, slice: "admin") + expect(dump_command).to have_received(:call).with(hash_including(app: false, slice: "admin")) expect(dump_command).to have_received(:call).exactly(1).time end end diff --git a/spec/unit/hanami/cli/commands/app/db/prepare_spec.rb b/spec/unit/hanami/cli/commands/app/db/prepare_spec.rb new file mode 100644 index 00000000..26ab9d1f --- /dev/null +++ b/spec/unit/hanami/cli/commands/app/db/prepare_spec.rb @@ -0,0 +1,348 @@ +# frozen_string_literal: true + +RSpec.describe Hanami::CLI::Commands::App::DB::Prepare, :app_integration, :postgres do + subject(:command) { + described_class.new( + system_call: system_call, + out: out + ) + } + + let(:system_call) { Hanami::CLI::SystemCall.new } + + let(:out) { StringIO.new } + let(:output) { + out.rewind + out.read + } + + before do + @env = ENV.to_h + allow(Hanami::Env).to receive(:loaded?).and_return(false) + end + + after do + ENV.replace(@env) + end + + before do + # Prevent the command from exiting the spec run in the case of unexpected system call failures + allow(command).to receive(:exit) + end + + before do + with_directory(@dir = make_tmp_directory) do + write "config/app.rb", <<~RUBY + module TestApp + class App < Hanami::App + end + end + RUBY + + require "hanami/setup" + before_prepare if respond_to?(:before_prepare) + require "hanami/prepare" + end + end + + context "single db in app" do + def before_prepare + write "config/db/migrate/20240602201330_create_posts.rb", <<~RUBY + ROM::SQL.migration do + change do + create_table :posts do + primary_key :id + column :title, :text, null: false + end + end + end + RUBY + + write "config/db/seeds.rb", <<~RUBY + app = Hanami.app + + app["relations.posts"].changeset(:create, title: "First post").commit + RUBY + + write "app/relations/posts.rb", <<~RUBY + module TestApp + module Relations + class Posts < Hanami::DB::Relation + schema :posts, infer: true + end + end + end + RUBY + end + + before do + ENV["DATABASE_URL"] = "#{POSTGRES_BASE_URL}_app" + end + + context "database not created, no structure dump" do + it "creates the database, migrates the database, and loads the seeds" do + command.call + + expect(Hanami.app["relations.posts"].to_a).to eq [{id: 1, title: "First post"}] + + dump = File.read(Hanami.app.root.join("config", "db", "structure.sql")) + expect(dump).to include("CREATE TABLE public.posts") + expect(dump).to include(<<~SQL) + SET search_path TO "$user", public; + + INSERT INTO schema_migrations (filename) VALUES + ('20240602201330_create_posts.rb'); + SQL + end + end + + context "database not created, structure dump exists" do + before do + command.run_command(Hanami::CLI::Commands::App::DB::Create) + command.run_command(Hanami::CLI::Commands::App::DB::Migrate) # Dumps the structure + + # `db migrate` establishes a connection to the database, which will prevent it from being + # dropped. To allow the drop, disconnect from the database by stopping the :db provider + # (which requires starting it first, a prerequesite for it to be stopped). + Hanami.app.start :db and Hanami.app.stop :db + command.run_command(Hanami::CLI::Commands::App::DB::Drop) + + out.truncate(0) + end + + it "creates the database, loads the structure, migrates the database, and loads the seeds" do + expect(Hanami.app.root.join("config", "db", "structure.sql").exist?).to be true + + # Add a migration not included in structure dump + write Hanami.app.root.join("config/db/migrate/20240603201330_create_comments.rb"), <<~RUBY + ROM::SQL.migration do + change do + create_table :comments do + primary_key :id + column :body, :text, null: false + end + end + end + RUBY + + command.call + + expect(Hanami.app["relations.posts"].to_a).to eq [{id: 1, title: "First post"}] + + dump = File.read(Hanami.app.root.join("config", "db", "structure.sql")) + expect(dump).to include("CREATE TABLE public.posts") + expect(dump).to include("CREATE TABLE public.comments") + expect(dump).to include(<<~SQL) + SET search_path TO "$user", public; + + INSERT INTO schema_migrations (filename) VALUES + ('20240602201330_create_posts.rb'), + ('20240603201330_create_comments.rb'); + SQL + end + end + + context "database already exists" do + before do + command.run_command(Hanami::CLI::Commands::App::DB::Create) + command.run_command(Hanami::CLI::Commands::App::DB::Migrate) + out.truncate(0) + end + + it "migrates the database and loads the seeds" do + # Add a not-yet-applied migration + write Hanami.app.root.join("config/db/migrate/20240603201330_create_comments.rb"), <<~RUBY + ROM::SQL.migration do + change do + create_table :comments do + primary_key :id + column :body, :text, null: false + end + end + end + RUBY + + command.call + + expect(Hanami.app["relations.posts"].to_a).to eq [{id: 1, title: "First post"}] + + dump = File.read(Hanami.app.root.join("config", "db", "structure.sql")) + expect(dump).to include("CREATE TABLE public.posts") + expect(dump).to include("CREATE TABLE public.comments") + expect(dump).to include(<<~SQL) + SET search_path TO "$user", public; + + INSERT INTO schema_migrations (filename) VALUES + ('20240602201330_create_posts.rb'), + ('20240603201330_create_comments.rb'); + SQL + end + end + end + + context "multiple dbs across app and slices" do + def before_prepare + write "config/db/migrate/20240602201330_create_posts.rb", <<~RUBY + ROM::SQL.migration do + change do + create_table :posts do + primary_key :id + column :title, :text, null: false + end + end + end + RUBY + + write "config/db/seeds.rb", <<~RUBY + app = Hanami.app + + app["relations.posts"].changeset(:create, title: "First post").commit + RUBY + + write "app/relations/posts.rb", <<~RUBY + module TestApp + module Relations + class Posts < Hanami::DB::Relation + schema :posts, infer: true + end + end + end + RUBY + + write "slices/main/config/db/migrate/20240602201330_create_comments.rb", <<~RUBY + ROM::SQL.migration do + change do + create_table :comments do + primary_key :id + column :body, :text, null: false + end + end + end + RUBY + + write "slices/main/config/db/seeds.rb", <<~RUBY + slice = Main::Slice + + slice["relations.comments"].changeset(:create, body: "First comment").commit + RUBY + + write "slices/main/relations/comments.rb", <<~RUBY + module Main + module Relations + class Comments < Hanami::DB::Relation + schema :comments, infer: true + end + end + end + RUBY + end + + before do + ENV["DATABASE_URL"] = "#{POSTGRES_BASE_URL}_app" + ENV["MAIN__DATABASE_URL"] = "#{POSTGRES_BASE_URL}_main" + end + + it "prepares all databases" do + command.call + + expect(Hanami.app["relations.posts"].to_a).to eq [{id: 1, title: "First post"}] + expect(Main::Slice["relations.comments"].to_a).to eq [{id: 1, body: "First comment"}] + + dump = File.read(Hanami.app.root.join("config", "db", "structure.sql")) + expect(dump).to include("CREATE TABLE public.posts") + expect(dump).to include(<<~SQL) + SET search_path TO "$user", public; + + INSERT INTO schema_migrations (filename) VALUES + ('20240602201330_create_posts.rb'); + SQL + + dump = File.read(Main::Slice.root.join("config", "db", "structure.sql")) + expect(dump).to include("CREATE TABLE public.comments") + expect(dump).to include(<<~SQL) + SET search_path TO "$user", public; + + INSERT INTO schema_migrations (filename) VALUES + ('20240602201330_create_comments.rb'); + SQL + + expect(output).to include_in_order( + "database hanami_cli_test_app created", + "database hanami_cli_test_app migrated", + "hanami_cli_test_app structure dumped to config/db/structure.sql", + "seed data loaded from config/db/seeds.rb", + "database hanami_cli_test_main created", + "database hanami_cli_test_main migrated", + "hanami_cli_test_main structure dumped to slices/main/config/db/structure.sql", + "seed data loaded from slices/main/config/db/seeds.rb" + ) + end + + it "prepares the app db when given --app" do + command.call(app: true) + + expect(Hanami.app["relations.posts"].to_a).to eq [{id: 1, title: "First post"}] + expect { Main::Slice["relations.comments"].to_a }.to raise_error Sequel::DatabaseError + + dump = File.read(Hanami.app.root.join("config", "db", "structure.sql")) + expect(dump).to include("CREATE TABLE public.posts") + expect(Main::Slice.root.join("config", "db", "structure.sql").exist?).to be false + + expect(output).to include_in_order( + "database hanami_cli_test_app created", + "database hanami_cli_test_app migrated", + "hanami_cli_test_app structure dumped to config/db/structure.sql", + "seed data loaded from config/db/seeds.rb", + ) + expect(output).not_to include "hanami_cli_test_main" + end + + it "prepares a slice db when given --slice" do + command.call(slice: "main") + + expect(Main::Slice["relations.comments"].to_a).to eq [{id: 1, body: "First comment"}] + expect { Hanami.app["relations.posts"].to_a }.to raise_error Sequel::DatabaseError + + dump = File.read(Main::Slice.root.join("config", "db", "structure.sql")) + expect(dump).to include("CREATE TABLE public.comments") + expect(Hanami.app.root.join("config", "db", "structure.sql").exist?).to be false + + expect(output).to include_in_order( + "database hanami_cli_test_main created", + "database hanami_cli_test_main migrated", + "hanami_cli_test_main structure dumped to slices/main/config/db/structure.sql", + "seed data loaded from slices/main/config/db/seeds.rb" + ) + expect(output).not_to include "hanami_cli_test_app" + end + + it "prints errors for any prepares that fail and exits with a non-zero status" do + # Fail to create the app db + allow(system_call).to receive(:call).and_call_original + allow(system_call) + .to receive(:call) + .with(a_string_matching(/createdb.+_app/), anything) + .and_return Hanami::CLI::SystemCall::Result.new(exit_code: 2, out: "", err: "app-db-err") + + command.call + + expect(Main::Slice["relations.comments"].to_a).to eq [{id: 1, body: "First comment"}] + expect { Hanami.app["relations.posts"].to_a }.to raise_error Sequel::DatabaseError + + dump = File.read(Main::Slice.root.join("config", "db", "structure.sql")) + expect(dump).to include("CREATE TABLE public.comments") + expect(Hanami.app.root.join("config", "db", "structure.sql").exist?).to be false + + expect(output).to include_in_order( + "failed to create database hanami_cli_test_app", + "app-db-err", + "database hanami_cli_test_main created", + "database hanami_cli_test_main migrated", + "hanami_cli_test_main structure dumped to slices/main/config/db/structure.sql", + "seed data loaded from slices/main/config/db/seeds.rb" + ) + + expect(command).to have_received(:exit).with 2 + end + end +end diff --git a/spec/unit/hanami/cli/commands/app/db/setup_spec.rb b/spec/unit/hanami/cli/commands/app/db/setup_spec.rb deleted file mode 100644 index d9fbcca8..00000000 --- a/spec/unit/hanami/cli/commands/app/db/setup_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe Hanami::CLI::Commands::App::DB::Setup, :app, :command do - let(:database) do - instance_double(Hanami::CLI::Commands::DB::Utils::Database, name: "test") - end - - it "sets up a database" do - pending "No proper fixtures yet to make this pass" - - allow(command).to receive(:database).and_return(database) - expect(database).to receive(:create_command).and_return(true) - - command.call - - expect(output).to include("database test created") - end -end diff --git a/spec/unit/hanami/cli/commands/app/db/structure/load_spec.rb b/spec/unit/hanami/cli/commands/app/db/structure/load_spec.rb index 99921ea7..339d10af 100644 --- a/spec/unit/hanami/cli/commands/app/db/structure/load_spec.rb +++ b/spec/unit/hanami/cli/commands/app/db/structure/load_spec.rb @@ -47,6 +47,7 @@ class App < Hanami::App context "single db in app" do def before_prepare + write "config/db/structure.sql", "" write "app/relations/.keep", "" end @@ -72,8 +73,13 @@ def before_prepare context "multiple dbs across app and slices" do def before_prepare + write "config/db/structure.sql", "" write "app/relations/.keep", "" + + write "slices/admin/config/db/structure.sql", "" write "slices/admin/relations/.keep", "" + + write "slices/main/config/db/structure.sql", "" write "slices/main/relations/.keep", "" end @@ -159,6 +165,7 @@ def before_prepare context "load command fails" do def before_prepare write "config/db/.keep", "" + write "config/db/structure.sql", "" write "app/relations/.keep", "" end