Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions lib/database_rewinder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ class << self
# Set your DB configuration here if you'd like to use something else than the AR configuration
attr_writer :database_configuration

# Set to true to include hidden database configurations (those with database_tasks: false)
attr_accessor :include_hidden

def init
@cleaners, @table_names_cache, @clean_all, @only, @except, @database_configuration = [], {}, false
@cleaners, @table_names_cache, @clean_all, @only, @except, @database_configuration, @include_hidden = [], {}, false, nil, nil, nil, false
end

def database_configuration
Expand Down Expand Up @@ -40,13 +43,20 @@ def record_inserted_table(connection, sql)
config = connection.instance_variable_get(:'@config')
database = config[:database]
host = config[:host]
schema_search_path = config[:schema_search_path]
#NOTE What's the best way to get the app dir besides Rails.root? I know Dir.pwd here might not be the right solution, but it should work in most cases...
root_dir = defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : Dir.pwd
cleaner = cleaners.detect do |c|
if (config[:adapter] == 'sqlite3') && (config[:database] != ':memory:')
File.expand_path(c.db, root_dir) == File.expand_path(database, root_dir)
else
c.db == database && c.host == host
# For PostgreSQL with schema_search_path, match by schema as well as db/host
cleaner_schema_search_path = c.config['schema_search_path']
if schema_search_path || cleaner_schema_search_path
c.db == database && c.host == host && cleaner_schema_search_path == schema_search_path
else
c.db == database && c.host == host
end
end
end or return

Expand Down Expand Up @@ -129,9 +139,9 @@ def traditional_configuration_for(connection_name)

def multiple_database_configuration_for(connection_name)
if (ActiveRecord::VERSION::MAJOR >= 7) || ((ActiveRecord::VERSION::MAJOR >= 6) && (ActiveRecord::VERSION::MINOR >= 1))
database_configuration.configs_for(name: connection_name)
database_configuration.configs_for(name: connection_name, include_hidden: include_hidden)
else
database_configuration.configs_for(spec_name: connection_name)
database_configuration.configs_for(spec_name: connection_name, include_hidden: include_hidden)
end
end
end
Expand Down
112 changes: 112 additions & 0 deletions test/database_rewinder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,118 @@ def perform_clean(options)
end
end

sub_test_case '.include_hidden' do
teardown do
DatabaseRewinder.database_configuration = nil
DatabaseRewinder.include_hidden = false
end

test 'defaults to false' do
assert_equal false, DatabaseRewinder.include_hidden
end

test 'can be set to true' do
DatabaseRewinder.include_hidden = true
assert_equal true, DatabaseRewinder.include_hidden
end

test 'passes include_hidden to configs_for when looking up database configurations' do
hidden_db_config = {'test' => {'hidden_db' => {'adapter' => 'sqlite3', 'database' => ':memory:', 'database_tasks' => false}}}
DatabaseRewinder.database_configuration = ActiveRecord::DatabaseConfigurations.new(hidden_db_config)

assert_raises(RuntimeError, 'Database configuration named "hidden_db" is not configured.') do
DatabaseRewinder['hidden_db']
end

DatabaseRewinder.include_hidden = true

cleaner = DatabaseRewinder['hidden_db']
assert_equal 'hidden_db', cleaner.connection_name
end
end

sub_test_case '.record_inserted_table with schema_search_path' do
setup do
DatabaseRewinder.init
end

teardown do
DatabaseRewinder.database_configuration = nil
end

test 'matches cleaner by schema_search_path when present' do
cleaner1 = DatabaseRewinder::Cleaner.new(
config: {'database' => 'testdb', 'host' => 'localhost', 'schema_search_path' => 'public'},
connection_name: 'test_public',
only: nil,
except: nil
)
cleaner2 = DatabaseRewinder::Cleaner.new(
config: {'database' => 'testdb', 'host' => 'localhost', 'schema_search_path' => 'other_schema'},
connection_name: 'test_other',
only: nil,
except: nil
)
DatabaseRewinder.instance_variable_set(:@cleaners, [cleaner1, cleaner2])

connection = Struct.new(:pool).new(nil)
connection.instance_variable_set(:@config, {
adapter: 'postgresql',
database: 'testdb',
host: 'localhost',
schema_search_path: 'other_schema'
})

DatabaseRewinder.record_inserted_table(connection, 'INSERT INTO foos (name) VALUES (?)')

assert_equal [], cleaner1.inserted_tables
assert_equal ['foos'], cleaner2.inserted_tables
end

test 'matches cleaner without schema_search_path when neither have it' do
cleaner = DatabaseRewinder::Cleaner.new(
config: {'database' => 'testdb', 'host' => 'localhost'},
connection_name: 'test',
only: nil,
except: nil
)
DatabaseRewinder.instance_variable_set(:@cleaners, [cleaner])

connection = Struct.new(:pool).new(nil)
connection.instance_variable_set(:@config, {
adapter: 'postgresql',
database: 'testdb',
host: 'localhost'
})

DatabaseRewinder.record_inserted_table(connection, 'INSERT INTO bars (name) VALUES (?)')

assert_equal ['bars'], cleaner.inserted_tables
end

test 'does not match cleaner when schema_search_path differs' do
cleaner = DatabaseRewinder::Cleaner.new(
config: {'database' => 'testdb', 'host' => 'localhost', 'schema_search_path' => 'public'},
connection_name: 'test',
only: nil,
except: nil
)
DatabaseRewinder.instance_variable_set(:@cleaners, [cleaner])

connection = Struct.new(:pool).new(nil)
connection.instance_variable_set(:@config, {
adapter: 'postgresql',
database: 'testdb',
host: 'localhost',
schema_search_path: 'other_schema'
})

DatabaseRewinder.record_inserted_table(connection, 'INSERT INTO foos (name) VALUES (?)')

assert_equal [], cleaner.inserted_tables
end
end

sub_test_case '.strategy=' do
sub_test_case 'call first with options' do
setup do
Expand Down