autodetect available strategies so we don't need to repeat ourselves, and narrow the ORM Adapter API further.

This commit is contained in:
Micah Geisel 2020-04-10 08:55:42 -07:00 committed by Micah Geisel
parent 6faab63ee8
commit 4f88d22ca1
4 changed files with 21 additions and 21 deletions

View file

@ -50,9 +50,9 @@ The file structure you end up with will look something like this
#### orm_name.rb
File `orm_name.rb` **must** do the following:
* define module method `.available_strategies` on DatabaseCleaner::OrmName.
* require all the gems strategies
* configure DatabaseCleaner with the default strategy for the ORM.
* require `database_cleaner-core`
* require all the strategies
* configure `DatabaseCleaner` with the default strategy for the ORM.
So, in the end you will end up with a file that might look something like this:
@ -65,14 +65,6 @@ require 'database_cleaner/orm_name/transaction'
require 'database_cleaner/orm_name/truncation'
require 'database_cleaner/orm_name/deletion'
module DatabaseCleaner
module OrmName
def self.available_strategies
%i[transaction truncation deletion]
end
end
end
DatabaseCleaner[:orm_name].strategy = :transaction
```

View file

@ -7,6 +7,12 @@ module DatabaseCleaner
class UnknownStrategySpecified < ArgumentError; end
class Cleaner
def self.available_strategies(orm_module)
# introspect publically available constants to get list of strategies, leaving out common but obviously non-strategy constants.
# if you're writing an adapter and this method is finding a constant in it that is not a valid strategy, consider making it private with Module#private_constant.
(orm_module.constants - [:Base, :VERSION]).map(&:downcase)
end
include Comparable
def <=>(other)
@ -79,7 +85,8 @@ module DatabaseCleaner
strategy_module_name = strategy.to_s.capitalize
orm_module.const_get(strategy_module_name)
rescue NameError
raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM! Available strategies: #{orm_module.available_strategies.join(', ')}"
available_strategies = self.class.available_strategies(orm_module)
raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM! Available strategies: #{available_strategies.join(', ')}"
end
def orm_module

View file

@ -1,3 +1,5 @@
require "database_cleaner/cleaner"
RSpec.shared_examples_for "a database_cleaner strategy" do
it { is_expected.to respond_to(:db) }
it { is_expected.to respond_to(:db=) }
@ -7,10 +9,8 @@ RSpec.shared_examples_for "a database_cleaner strategy" do
end
RSpec.shared_examples_for "a database_cleaner adapter" do
it { expect(described_class).to respond_to(:available_strategies) }
describe 'all strategies should adhere to a database_cleaner strategy interface' do
described_class.available_strategies.each do |strategy|
DatabaseCleaner::Cleaner.available_strategies(described_class).each do |strategy|
subject { described_class.const_get(strategy.to_s.capitalize).new }
it_behaves_like 'a database_cleaner strategy'

View file

@ -118,15 +118,16 @@ module DatabaseCleaner
subject(:cleaner) { Cleaner.new(:active_record) }
let(:strategy_class) { Class.new }
let(:orm_module) { Module.new }
before do
orm_module = Module.new do
def self.available_strategies
%i[truncation transaction deletion]
end
end
stub_const "DatabaseCleaner::ActiveRecord", orm_module
stub_const "DatabaseCleaner::ActiveRecord::Truncation", strategy_class
# stub consts that shouldn't show up in strategy list
stub_const "DatabaseCleaner::ActiveRecord::VERSION", "2.0.0"
stub_const "DatabaseCleaner::ActiveRecord::Base", Module.new
stub_const "DatabaseCleaner::ActiveRecord::Helpers", Module.new
orm_module.private_constant :Helpers
end
it "should look up and create a the named strategy for the current ORM" do
@ -159,7 +160,7 @@ module DatabaseCleaner
it "raises UnknownStrategySpecified on a bad strategy, and lists available strategies" do
expect { cleaner.strategy = :horrible_plan }.to \
raise_error(UnknownStrategySpecified, "The 'horrible_plan' strategy does not exist for the active_record ORM! Available strategies: truncation, transaction, deletion")
raise_error(UnknownStrategySpecified, "The 'horrible_plan' strategy does not exist for the active_record ORM! Available strategies: truncation")
end
end