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
42 changes: 12 additions & 30 deletions lib/database_cleaner/cleaner.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
require 'database_cleaner/null_strategy'
require 'database_cleaner/strategy'
require 'database_cleaner/string_helper'
require 'forwardable'

module DatabaseCleaner
class UnknownStrategySpecified < ArgumentError; end

class Cleaner
def self.available_strategies(orm_module)
# 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
# introspect publicly available constants for descendents of Strategy to get list of strategies
# ignore classes named Base, because it's 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|
orm_module.constants.filter_map do |constant_name|
next if constant_name == :Base

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]
next unless ancestors.include?(DatabaseCleaner::Strategy)

StringHelper.underscore(constant_name).to_sym
end
end

include Comparable
Expand Down Expand Up @@ -86,37 +89,16 @@ def create_strategy(*args)
end

def orm_strategy(strategy)
strategy_module_name = camelize(strategy)
strategy_module_name = StringHelper.camelize(strategy)
orm_module.const_get(strategy_module_name)
rescue NameError
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
orm_module_name = camelize(orm)
orm_module_name = StringHelper.camelize(orm)
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 }
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
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
2 changes: 1 addition & 1 deletion lib/database_cleaner/spec/shared_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
RSpec.shared_examples_for "a database_cleaner adapter" do
describe 'all strategies should adhere to a database_cleaner strategy interface' do
DatabaseCleaner::Cleaner.available_strategies(described_class).each do |strategy|
subject { described_class.const_get(strategy.to_s.capitalize).new }
subject { described_class.const_get(DatabaseCleaner::StringHelper.camelize(strategy.to_s)).new }

it_behaves_like 'a database_cleaner strategy'
end
Expand Down
22 changes: 22 additions & 0 deletions lib/database_cleaner/string_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module DatabaseCleaner
# Methods copied from ActiveSupport to avoid adding it as a dependency
module StringHelper
def self.camelize(term)
string = term.to_s
string = string.sub(/^[a-z\d]*/) { |match| match.capitalize }
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
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
end
end