Skip to content

Commit

Permalink
Set up DatabaseCleaner for tests (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
timriley authored Oct 24, 2024
1 parent 66083a1 commit 26bac83
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 1 deletion.
19 changes: 18 additions & 1 deletion lib/hanami/rspec/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def call(*, **)
copy_dotrspec
copy_spec_helper
copy_support_rspec
copy_support_db
copy_support_features
copy_support_operations
copy_support_requests
Expand All @@ -28,9 +29,11 @@ def call(*, **)
private

def append_gemfile
gemfile_template = Hanami.bundled?("hanami-db") ? "gemfile_db" : "gemfile"

fs.append(
fs.expand_path("Gemfile"),
fs.read(fs.expand_path(fs.join("generators", "gemfile"), __dir__))
fs.read(fs.expand_path(fs.join("generators", gemfile_template), __dir__))
)
end

Expand Down Expand Up @@ -62,6 +65,20 @@ def copy_support_rspec
)
end

def copy_support_db
return unless Hanami.bundled?("hanami-db")

fs.cp(
fs.expand_path(fs.join("generators/support_db.rb"), __dir__),
fs.expand_path(fs.join("spec", "support", "db.rb"))
)

fs.cp(
fs.expand_path(fs.join("generators/support_db_cleaning.rb"), __dir__),
fs.expand_path(fs.join("spec", "support", "db", "cleaning.rb"))
)
end

def copy_support_features
fs.cp(
fs.expand_path(fs.join("generators", "support_features.rb"), __dir__),
Expand Down
1 change: 1 addition & 0 deletions lib/hanami/rspec/generators/gemfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

group :test do
# Web integration
gem "capybara"
gem "rack-test"
end
9 changes: 9 additions & 0 deletions lib/hanami/rspec/generators/gemfile_db
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

group :test do
# Database
gem "database_cleaner-sequel"

# Web integration
gem "capybara"
gem "rack-test"
end
10 changes: 10 additions & 0 deletions lib/hanami/rspec/generators/support_db.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

# Tag feature spec examples as `:db`
#
# See support/db/cleaning.rb for how the database is cleaned around these `:db` examples.
RSpec.configure do |config|
config.define_derived_metadata(type: :feature) do |metadata|
metadata[:db] = true
end
end
42 changes: 42 additions & 0 deletions lib/hanami/rspec/generators/support_db_cleaning.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require "database_cleaner/sequel"

# Clean the databases between tests tagged as `:db`
RSpec.configure do |config|
# Returns all the configured databases across the app and its slices.
#
# Used in the before/after hooks below to ensure each database is cleaned between examples.
#
# Modify this proc (or any code below) if you only need specific databases cleaned.
all_databases = -> {
slices = [Hanami.app] + Hanami.app.slices.with_nested

slices.each_with_object([]) { |slice, dbs|
next unless slice.key?("db.rom")

dbs.concat slice["db.rom"].gateways.values.map(&:connection)
}.uniq
}

config.before :suite do
all_databases.call.each do |db|
DatabaseCleaner[:sequel, db: db].clean_with :truncation, except: ["schema_migrations"]
end
end

config.before :each, :db do |example|
strategy = example.metadata[:js] ? :truncation : :transaction

all_databases.call.each do |db|
DatabaseCleaner[:sequel, db: db].strategy = strategy
DatabaseCleaner[:sequel, db: db].start
end
end

config.after :each, :db do
all_databases.call.each do |db|
DatabaseCleaner[:sequel, db: db].clean
end
end
end
96 changes: 96 additions & 0 deletions spec/unit/hanami/rspec/commands/install_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

let(:arbitrary_argument) { {} }

before do
allow(Hanami).to receive(:bundled?).and_call_original
allow(Hanami).to receive(:bundled?).with("hanami-db").and_return true
end

around do |example|
fs.chdir(dir) { example.run }
ensure
Expand All @@ -25,6 +30,10 @@
# Gemfile
gemfile = <<~EOF
group :test do
# Database
gem "database_cleaner-sequel"
# Web integration
gem "capybara"
gem "rack-test"
end
Expand Down Expand Up @@ -123,6 +132,66 @@
EOF
expect(fs.read("spec/support/rspec.rb")).to eq(support_rspec)

support_db = <<~EOF
# frozen_string_literal: true
# Tag feature spec examples as `:db`
#
# See support/db/cleaning.rb for how the database is cleaned around these `:db` examples.
RSpec.configure do |config|
config.define_derived_metadata(type: :feature) do |metadata|
metadata[:db] = true
end
end
EOF
expect(fs.read("spec/support/db.rb")).to eq support_db

support_db_cleaning = <<~EOF
# frozen_string_literal: true
require "database_cleaner/sequel"
# Clean the databases between tests tagged as `:db`
RSpec.configure do |config|
# Returns all the configured databases across the app and its slices.
#
# Used in the before/after hooks below to ensure each database is cleaned between examples.
#
# Modify this proc (or any code below) if you only need specific databases cleaned.
all_databases = -> {
slices = [Hanami.app] + Hanami.app.slices.with_nested
slices.each_with_object([]) { |slice, dbs|
next unless slice.key?("db.rom")
dbs.concat slice["db.rom"].gateways.values.map(&:connection)
}.uniq
}
config.before :suite do
all_databases.call.each do |db|
DatabaseCleaner[:sequel, db: db].clean_with :truncation, except: ["schema_migrations"]
end
end
config.before :each, :db do |example|
strategy = example.metadata[:js] ? :truncation : :transaction
all_databases.call.each do |db|
DatabaseCleaner[:sequel, db: db].strategy = strategy
DatabaseCleaner[:sequel, db: db].start
end
end
config.after :each, :db do
all_databases.call.each do |db|
DatabaseCleaner[:sequel, db: db].clean
end
end
end
EOF
expect(fs.read("spec/support/db/cleaning.rb")).to eq support_db_cleaning

# spec/support/features.rb
support_features = <<~EOF
# frozen_string_literal: true
Expand Down Expand Up @@ -179,5 +248,32 @@
EOF
expect(fs.read("spec/requests/root_spec.rb")).to eq(request_spec)
end

context "hanami-db not bundled" do
before do
allow(Hanami).to receive(:bundled?).with("hanami-db").and_return false
end

it "does not add the database_cleaner gem to the Gemfile" do
subject.call(arbitrary_argument)

# Gemfile
gemfile = <<~EOF
group :test do
# Web integration
gem "capybara"
gem "rack-test"
end
EOF
expect(fs.read("Gemfile")).to include(gemfile)
end

it "does not add DB-related spec support files" do
subject.call(arbitrary_argument)

expect(fs.exist?("spec/support/db.rb")).to be false
expect(fs.exist?("spec/support/db/cleaning.rb")).to be false
end
end
end
end

0 comments on commit 26bac83

Please sign in to comment.