forked from fixin.me/fixin.me
Compare commits
1 Commits
feature/mu
...
fix/test-h
| Author | SHA1 | Date | |
|---|---|---|---|
| c5331f41c7 |
@@ -20,10 +20,6 @@ Bundler.require(*Rails.groups)
|
|||||||
|
|
||||||
module FixinMe
|
module FixinMe
|
||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
# Allow RAILS_DATABASE_YML to override the database config file path.
|
|
||||||
# Used by `rails test:all_databases` to test against multiple DB adapters.
|
|
||||||
config.paths['config/database'] = [ENV['RAILS_DATABASE_YML']] if ENV['RAILS_DATABASE_YML']
|
|
||||||
|
|
||||||
# Initialize configuration defaults for originally generated Rails version.
|
# Initialize configuration defaults for originally generated Rails version.
|
||||||
config.load_defaults 7.0
|
config.load_defaults 7.0
|
||||||
|
|
||||||
|
|||||||
@@ -48,26 +48,3 @@ production:
|
|||||||
#test:
|
#test:
|
||||||
# <<: *default
|
# <<: *default
|
||||||
# database: fixinme_test
|
# database: fixinme_test
|
||||||
|
|
||||||
# Multi-database testing — `bundle exec rails test:all_databases`
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Add any number of `test_<name>:` blocks to run the full test suite
|
|
||||||
# against additional database adapters in a single command.
|
|
||||||
# Each adapter's gem must be available in the bundle:
|
|
||||||
# bundle config --local with "mysql:sqlite" # mysql + sqlite
|
|
||||||
# bundle config --local with "mysql:pg" # mysql + postgresql
|
|
||||||
#
|
|
||||||
# Example — run tests against MySQL and SQLite:
|
|
||||||
#
|
|
||||||
#test_sqlite:
|
|
||||||
# adapter: sqlite3
|
|
||||||
# database: db/fixinme_test.sqlite3
|
|
||||||
#
|
|
||||||
# Example — run tests against MySQL and PostgreSQL:
|
|
||||||
#
|
|
||||||
#test_pg:
|
|
||||||
# adapter: postgresql
|
|
||||||
# database: fixinme_test
|
|
||||||
# username: fixinme
|
|
||||||
# password: Some-password1%
|
|
||||||
# host: localhost
|
|
||||||
|
|||||||
@@ -58,4 +58,7 @@ Rails.application.configure do
|
|||||||
# config.action_view.annotate_rendered_view_with_filenames = true
|
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||||
|
|
||||||
config.log_level = :info
|
config.log_level = :info
|
||||||
|
|
||||||
|
# Allow Capybara's dynamic test server host (127.0.0.1:<random_port>)
|
||||||
|
config.hosts << '127.0.0.1'
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
require 'yaml'
|
|
||||||
require 'erb'
|
|
||||||
require 'tmpdir'
|
|
||||||
|
|
||||||
namespace :test do
|
|
||||||
desc <<~DESC
|
|
||||||
Run the full test suite against every test database configured in database.yml.
|
|
||||||
|
|
||||||
Any top-level key that starts with "test" and contains a Hash is treated as a
|
|
||||||
test database configuration:
|
|
||||||
|
|
||||||
test: # always required — the primary test database
|
|
||||||
adapter: mysql2
|
|
||||||
database: fixinme_test
|
|
||||||
...
|
|
||||||
|
|
||||||
test_sqlite: # optional additional databases
|
|
||||||
adapter: sqlite3
|
|
||||||
database: db/fixinme_test.sqlite3
|
|
||||||
|
|
||||||
test_pg:
|
|
||||||
adapter: postgresql
|
|
||||||
database: fixinme_test
|
|
||||||
...
|
|
||||||
|
|
||||||
For each database the task will:
|
|
||||||
1. Check that the required adapter gem is available (skip with warning if not).
|
|
||||||
2. Run `rails db:test:prepare` to create/migrate the database.
|
|
||||||
3. Run `rails test` and record pass/fail.
|
|
||||||
|
|
||||||
A summary is printed at the end. The task exits non-zero if any database fails.
|
|
||||||
DESC
|
|
||||||
task :all_databases do
|
|
||||||
db_file = Rails.root.join('config', 'database.yml')
|
|
||||||
all = YAML.safe_load(ERB.new(db_file.read).result, aliases: true) || {}
|
|
||||||
test_cfgs = all.select { |k, v| k.to_s.start_with?('test') && v.is_a?(Hash) }
|
|
||||||
non_test = all.reject { |k, _| k.to_s.start_with?('test') }
|
|
||||||
|
|
||||||
abort "No test database configurations found in #{db_file}." if test_cfgs.empty?
|
|
||||||
|
|
||||||
results = {}
|
|
||||||
|
|
||||||
test_cfgs.each do |name, config|
|
|
||||||
adapter = config['adapter'].to_s
|
|
||||||
|
|
||||||
puts "\n#{'─' * 64}"
|
|
||||||
puts " #{name} (adapter: #{adapter})"
|
|
||||||
puts '─' * 64
|
|
||||||
|
|
||||||
unless adapter_available?(adapter)
|
|
||||||
puts " SKIPPED — gem for '#{adapter}' adapter not available in bundle."
|
|
||||||
puts " Add it to Gemfile (e.g. `bundle config --local with #{adapter_group(adapter)}`)"
|
|
||||||
results[name] = :skipped
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
Dir.mktmpdir('rails_test_db_') do |tmpdir|
|
|
||||||
tmp_yml = File.join(tmpdir, 'database.yml')
|
|
||||||
# Write a standalone database.yml with just this config as `test:`
|
|
||||||
# (non-test configs are preserved so boot doesn't fail on `production:` lookup)
|
|
||||||
File.write(tmp_yml, non_test.merge('test' => config).to_yaml)
|
|
||||||
|
|
||||||
env = { 'RAILS_DATABASE_YML' => tmp_yml }
|
|
||||||
|
|
||||||
if system(env, 'bundle exec rails db:test:prepare')
|
|
||||||
results[name] = system(env, 'bundle exec rails test') ? :pass : :fail
|
|
||||||
else
|
|
||||||
results[name] = :prepare_failed
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
puts "\n#{'═' * 64}"
|
|
||||||
puts " SUMMARY"
|
|
||||||
puts '═' * 64
|
|
||||||
results.each do |name, status|
|
|
||||||
adapter = test_cfgs[name]['adapter']
|
|
||||||
icon = { pass: '✓', fail: '✗', prepare_failed: '✗', skipped: '–' }[status]
|
|
||||||
label = { pass: 'PASS', fail: 'FAIL',
|
|
||||||
prepare_failed: 'PREPARE FAILED', skipped: 'SKIPPED' }[status]
|
|
||||||
puts " #{icon} #{name.ljust(26)} (#{adapter.ljust(12)}) #{label}"
|
|
||||||
end
|
|
||||||
puts '═' * 64
|
|
||||||
|
|
||||||
failed = results.count { |_, s| s == :fail || s == :prepare_failed }
|
|
||||||
abort "\n #{failed} database(s) failed." if failed > 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# Returns true if the gem required for this adapter is loadable.
|
|
||||||
ADAPTER_GEMS = {
|
|
||||||
'mysql2' => 'mysql2',
|
|
||||||
'sqlite3' => 'sqlite3',
|
|
||||||
'postgresql' => 'pg',
|
|
||||||
'pg' => 'pg',
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
def adapter_available?(adapter)
|
|
||||||
gem_name = ADAPTER_GEMS.fetch(adapter, adapter)
|
|
||||||
require gem_name
|
|
||||||
true
|
|
||||||
rescue LoadError
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the Bundler group name that installs the adapter gem.
|
|
||||||
ADAPTER_GROUPS = {
|
|
||||||
'mysql2' => 'mysql',
|
|
||||||
'sqlite3' => 'sqlite',
|
|
||||||
'postgresql' => 'postgresql',
|
|
||||||
'pg' => 'postgresql',
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
def adapter_group(adapter)
|
|
||||||
ADAPTER_GROUPS.fetch(adapter, adapter)
|
|
||||||
end
|
|
||||||
Reference in New Issue
Block a user