require strategies to inherit from DatabaseCleaner::Strategy.

This commit is contained in:
Micah Geisel 2020-04-18 11:46:13 -07:00 committed by Micah Geisel
parent 4f88d22ca1
commit f536f174f8
3 changed files with 33 additions and 12 deletions

View file

@ -70,12 +70,12 @@ DatabaseCleaner[:orm_name].strategy = :transaction
### Strategy classes
Each strategy class can inherit from DatabaseCleaner::Strategy to get it most of the way there. If you do, you only need to define one method!
Each strategy class **must** inherit from `DatabaseCleaner::Strategy`.
Each strategy **must** have the following instance methods
Each strategy **must** have the following instance methods:
* `#clean` -- where the cleaning happens
Optionally, depending on how your strategy works you may define
Optionally, depending on how your strategy works you may also need to define
* `#start` -- if your strategy is transactional, this is where you would start the database transaction that `#clean` later rolls back.
Given that we're creating a strategy for truncation, you may end up with something like the following class:
@ -117,7 +117,7 @@ end
### What's next
Now you should be set up to with your own database_cleaner ORM adapter.
Now you should be all set up with your very own database_cleaner ORM adapter!
Also, don't forget to take a look at the already created adapters, if you encounter any problems.
When you are done with your adapter gem, only a few things left to do

View file

@ -1,6 +1,7 @@
require 'database_cleaner/deprecation'
require 'database_cleaner/null_strategy'
require 'database_cleaner/safeguard'
require 'database_cleaner/strategy'
require 'forwardable'
module DatabaseCleaner
@ -8,9 +9,15 @@ module DatabaseCleaner
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)
# introspect publically available constants for descendents of Strategy to get list of strategies
# ignore classes named Base, because its a common name for a shared base class that adds ORM access stuff to Strategy before being inherited by final concrete class
# if you're writing an adapter and this method is falsely returning an internal constant that isn't a valid strategy, consider making it private with Module#private_constant.
orm_module.constants.select do |constant_name|
ancestors = orm_module.const_get(constant_name).ancestors rescue []
ancestors.include?(DatabaseCleaner::Strategy)
end.map do |constant_name|
underscore(constant_name).to_sym
end - [:base]
end
include Comparable
@ -94,6 +101,8 @@ module DatabaseCleaner
DatabaseCleaner.const_get(orm_module_name)
end
# copied from ActiveSupport to avoid adding it as a dependency
def camelize(term)
string = term.to_s
string = string.sub(/^[a-z\d]*/) { |match| match.capitalize }
@ -101,5 +110,16 @@ module DatabaseCleaner
string.gsub!("/", "::")
string
end
def self.underscore(camel_cased_word)
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
word = camel_cased_word.to_s.gsub("::", "/")
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
word.tr!("-", "_")
word.downcase!
word
end
private_class_method :underscore
end
end

View file

@ -89,8 +89,8 @@ module DatabaseCleaner
describe "clean_with" do
subject(:cleaner) { Cleaner.new(:active_record) }
let(:strategy_class) { Class.new }
let(:strategy) { double }
let(:strategy_class) { Class.new(DatabaseCleaner::Strategy) }
let(:strategy) { strategy_class.new }
before { allow(strategy_class).to receive(:new).and_return(strategy) }
before do
@ -117,7 +117,7 @@ module DatabaseCleaner
describe "strategy=" do
subject(:cleaner) { Cleaner.new(:active_record) }
let(:strategy_class) { Class.new }
let(:strategy_class) { Class.new(DatabaseCleaner::Strategy) }
let(:orm_module) { Module.new }
before do
@ -125,9 +125,10 @@ module DatabaseCleaner
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
stub_const "DatabaseCleaner::ActiveRecord::Base", Class.new(strategy_class)
stub_const "DatabaseCleaner::ActiveRecord::ExtendedBase", Class.new(strategy_class)
orm_module.private_constant :ExtendedBase
end
it "should look up and create a the named strategy for the current ORM" do