mirror of
https://github.com/DatabaseCleaner/database_cleaner
synced 2023-03-27 23:22:03 -04:00
specs for multi orms/connections and some implementation
This commit is contained in:
parent
ebb6377fe5
commit
f7858cd501
3 changed files with 352 additions and 103 deletions
|
@ -38,6 +38,45 @@ module DatabaseCleaner
|
|||
end
|
||||
|
||||
class << self
|
||||
def [](orm)
|
||||
raise NoORMDetected if orm.nil?
|
||||
DatabaseCleaner::Base.new(orm)
|
||||
end
|
||||
|
||||
def connections
|
||||
@connections ||= [::DatabaseCleaner::Base.new]
|
||||
end
|
||||
|
||||
def strategy=(stratagem)
|
||||
self.connections.first.strategy = stratagem
|
||||
end
|
||||
|
||||
def orm=(orm)
|
||||
self.connections.first.orm = orm
|
||||
end
|
||||
|
||||
def start
|
||||
self.connections.first.start
|
||||
end
|
||||
|
||||
def clean
|
||||
self.connections.first.clean
|
||||
end
|
||||
|
||||
def clean_with(stratagem)
|
||||
self.connections.first.clean_with stratagem
|
||||
end
|
||||
end
|
||||
|
||||
class Base
|
||||
|
||||
def initialize(desired_orm = nil)
|
||||
if desired_orm == :autodetect || desired_orm.nil?
|
||||
autodetect
|
||||
else
|
||||
self.orm = desired_orm
|
||||
end
|
||||
end
|
||||
|
||||
def create_strategy(*args)
|
||||
strategy, *strategy_args = args
|
||||
|
@ -63,8 +102,8 @@ module DatabaseCleaner
|
|||
end
|
||||
end
|
||||
|
||||
def orm=(orm_string)
|
||||
@orm = orm_string
|
||||
def orm=(desired_orm)
|
||||
@orm = desired_orm
|
||||
end
|
||||
|
||||
def start
|
||||
|
@ -77,6 +116,14 @@ module DatabaseCleaner
|
|||
|
||||
alias clean! clean
|
||||
|
||||
def orm
|
||||
@orm || autodetect
|
||||
end
|
||||
|
||||
def auto_detected
|
||||
return true unless @autodetected.nil?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def strategy
|
||||
|
@ -84,44 +131,46 @@ module DatabaseCleaner
|
|||
raise NoStrategySetError, "Please set a strategy with DatabaseCleaner.strategy=."
|
||||
end
|
||||
|
||||
def orm_module
|
||||
::DatabaseCleaner.orm_module(orm)
|
||||
end
|
||||
|
||||
def orm_strategy(strategy)
|
||||
require "database_cleaner/#{orm}/#{strategy}"
|
||||
require "database_cleaner/#{orm.to_s}/#{strategy.to_s}"
|
||||
orm_module.const_get(strategy.to_s.capitalize)
|
||||
rescue LoadError => e
|
||||
raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM! Available strategies: #{orm_module.available_strategies.join(', ')}"
|
||||
end
|
||||
|
||||
|
||||
def orm
|
||||
@orm ||=begin
|
||||
def autodetect
|
||||
@orm ||= begin
|
||||
@autodetected = true
|
||||
if defined? ::ActiveRecord
|
||||
'active_record'
|
||||
:active_record
|
||||
elsif defined? ::DataMapper
|
||||
'data_mapper'
|
||||
:data_mapper
|
||||
elsif defined? ::MongoMapper
|
||||
'mongo_mapper'
|
||||
:mongo_mapper
|
||||
elsif defined? ::CouchPotato
|
||||
'couch_potato'
|
||||
:couch_potato
|
||||
else
|
||||
raise NoORMDetected, "No known ORM was detected! Is ActiveRecord, DataMapper, MongoMapper or CouchPotato loaded?"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def orm_module
|
||||
case orm
|
||||
when 'active_record'
|
||||
when :active_record
|
||||
DatabaseCleaner::ActiveRecord
|
||||
when 'data_mapper'
|
||||
when :data_mapper
|
||||
DatabaseCleaner::DataMapper
|
||||
when 'mongo_mapper'
|
||||
when :mongo_mapper
|
||||
DatabaseCleaner::MongoMapper
|
||||
when 'couch_potato'
|
||||
when :couch_potato
|
||||
DatabaseCleaner::CouchPotato
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -19,76 +19,190 @@ describe DatabaseCleaner do
|
|||
end
|
||||
end
|
||||
|
||||
# These examples muck around with the constants for autodetection so we need to clean up....
|
||||
before(:all) do
|
||||
TempAR = ActiveRecord unless defined?(TempAR)
|
||||
TempMM = MongoMapper unless defined?(TempMM)
|
||||
Object.send(:remove_const, 'MongoMapper') if defined?(::MongoMapper)
|
||||
# need to add one for each ORM that we load in the spec helper...
|
||||
context "orm specification" do
|
||||
|
||||
it "should not accept unrecognised orms" do
|
||||
lambda { ::DatabaseCleaner[nil] }.should raise_error ::DatabaseCleaner::NoORMDetected
|
||||
end
|
||||
after(:all) do
|
||||
Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord) #want to make sure we have the real one...
|
||||
ActiveRecord = TempAR
|
||||
MongoMapper = TempMM
|
||||
|
||||
it "should accept :active_record" do
|
||||
cleaner = ::DatabaseCleaner[:active_record]
|
||||
cleaner.should be_a ::DatabaseCleaner::Base
|
||||
cleaner.orm.should == :active_record
|
||||
end
|
||||
|
||||
it "should accept :data_mapper" do
|
||||
cleaner = ::DatabaseCleaner[:data_mapper]
|
||||
cleaner.should be_a ::DatabaseCleaner::Base
|
||||
cleaner.orm.should == :data_mapper
|
||||
end
|
||||
|
||||
it "should accept :mongo_mapper" do
|
||||
cleaner = ::DatabaseCleaner[:mongo_mapper]
|
||||
cleaner.should be_a ::DatabaseCleaner::Base
|
||||
cleaner.orm.should == :mongo_mapper
|
||||
end
|
||||
|
||||
it "should accept :couch_potato" do
|
||||
cleaner = ::DatabaseCleaner[:couch_potato]
|
||||
cleaner.should be_a ::DatabaseCleaner::Base
|
||||
cleaner.orm.should == :couch_potato
|
||||
end
|
||||
end
|
||||
|
||||
context "class methods" do
|
||||
it "should have array of connections (orm agnostic)" do
|
||||
::DatabaseCleaner.connections.should respond_to(:each)
|
||||
end
|
||||
|
||||
it "should give me a default (autodetection) databasecleaner by default" do
|
||||
::DatabaseCleaner.connections.should have (1).items
|
||||
::DatabaseCleaner.connections.first.should be_a ::DatabaseCleaner::Base
|
||||
end
|
||||
end
|
||||
|
||||
context "instance methods" do
|
||||
it "should default to autodetect upon initalisation" do
|
||||
cleaner = ::DatabaseCleaner::Base.new
|
||||
cleaner.auto_detected.should == true
|
||||
end
|
||||
|
||||
context "autodetect" do
|
||||
before(:all) do
|
||||
Temp_AR = ActiveRecord if defined?(::ActiveRecord) and not defined?(Temp_AR)
|
||||
Temp_DM = DataMapper if defined?(::DataMapper) and not defined?(Temp_DM)
|
||||
Temp_MM = MongoMapper if defined?(::MongoMapper) and not defined?(Temp_MM)
|
||||
Temp_CP = CouchPotato if defined?(::CouchPotato) and not defined?(Temp_CP)
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
DatabaseCleaner::ActiveRecord::Transaction.stub!(:new).and_return(@strategy = mock('strategy'))
|
||||
Object.const_set('ActiveRecord', "just mocking out the constant here...") unless defined?(::ActiveRecord)
|
||||
DatabaseCleaner.strategy = nil
|
||||
DatabaseCleaner.orm = nil
|
||||
# Remove ORM consts for these tests
|
||||
Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord)
|
||||
Object.send(:remove_const, 'DataMapper') if defined?(::DataMapper)
|
||||
Object.send(:remove_const, 'MongoMapper') if defined?(::MongoMapper)
|
||||
Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
|
||||
end
|
||||
|
||||
|
||||
it "should raise an error when no ORM is detected" do
|
||||
running { DatabaseCleaner::Base.new(:autodetect) }.should raise_error(DatabaseCleaner::NoORMDetected)
|
||||
end
|
||||
|
||||
it "should detect ActiveRecord first" do
|
||||
Object.const_set('ActiveRecord','Actively mocking records.')
|
||||
Object.const_set('DataMapper', 'Mapping data mocks')
|
||||
Object.const_set('MongoMapper', 'Mapping mock mongos')
|
||||
Object.const_set('CouchPotato', 'Couching mock potatos')
|
||||
|
||||
cleaner = DatabaseCleaner::Base.new :autodetect
|
||||
cleaner.orm.should == :active_record
|
||||
end
|
||||
it "should detect DataMapper second" do
|
||||
Object.const_set('DataMapper', 'Mapping data mocks')
|
||||
Object.const_set('MongoMapper', 'Mapping mock mongos')
|
||||
Object.const_set('CouchPotato', 'Couching mock potatos')
|
||||
|
||||
cleaner = DatabaseCleaner::Base.new :autodetect
|
||||
cleaner.orm.should == :data_mapper
|
||||
end
|
||||
it "should detect MongoMapper third" do
|
||||
Object.const_set('MongoMapper', 'Mapping mock mongos')
|
||||
Object.const_set('CouchPotato', 'Couching mock potatos')
|
||||
|
||||
cleaner = DatabaseCleaner::Base.new :autodetect
|
||||
cleaner.orm.should == :mongo_mapper
|
||||
end
|
||||
|
||||
it "should detect CouchPotato last" do
|
||||
Object.const_set('CouchPotato', 'Couching mock potatos')
|
||||
|
||||
cleaner = DatabaseCleaner::Base.new :autodetect
|
||||
cleaner.orm.should == :couch_potato
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord)
|
||||
Object.send(:remove_const, 'DataMapper') if defined?(::DataMapper)
|
||||
Object.send(:remove_const, 'MongoMapper') if defined?(::MongoMapper)
|
||||
Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
|
||||
|
||||
# Restore ORMs
|
||||
ActiveRecord = Temp_AR if defined? Temp_AR
|
||||
DataMapper = Temp_DM if defined? Temp_DM
|
||||
MongoMapper = Temp_MM if defined? Temp_MM
|
||||
CouchPotato = Temp_CP if defined? Temp_CP
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "single orm" do
|
||||
let (:connection) { ::DatabaseCleaner.connections.first }
|
||||
it "should proxy strategy=" do
|
||||
stratagum = mock("stratagum")
|
||||
connection.should_receive(:strategy=).with(stratagum)
|
||||
::DatabaseCleaner.strategy = stratagum
|
||||
end
|
||||
|
||||
it "should proxy orm=" do
|
||||
orm = mock("orm")
|
||||
connection.should_receive(:orm=).with(orm)
|
||||
::DatabaseCleaner.orm = orm
|
||||
end
|
||||
|
||||
it "should proxy start" do
|
||||
connection.should_receive(:start)
|
||||
::DatabaseCleaner.start
|
||||
end
|
||||
|
||||
it "should proxy clean" do
|
||||
connection.should_receive(:clean)
|
||||
::DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
it "should proxy clean_with" do
|
||||
stratagem = mock("stratgem")
|
||||
connection.should_receive(:clean_with).with(stratagem)
|
||||
::DatabaseCleaner.clean_with stratagem
|
||||
end
|
||||
end
|
||||
|
||||
describe ::DatabaseCleaner::Base do
|
||||
|
||||
describe "orm_module" do
|
||||
it "should proxy to the class method"
|
||||
end
|
||||
|
||||
let(:strategy) { mock("stratagum") }
|
||||
|
||||
context "active record" do
|
||||
let(:cleaner) { ::DatabaseCleaner::Base.new(:active_record) }
|
||||
|
||||
before(:each) do
|
||||
::DatabaseCleaner::ActiveRecord::Transaction.stub!(:new).and_return(strategy)
|
||||
#Object.const_set('ActiveRecord', "just mocking out the constant here...") unless defined?(::ActiveRecord)
|
||||
cleaner.strategy = nil
|
||||
end
|
||||
|
||||
describe ".create_strategy" do
|
||||
it "should initialize and return the appropirate strategy" do
|
||||
DatabaseCleaner::ActiveRecord::Transaction.should_receive(:new).with('options' => 'hash')
|
||||
result = DatabaseCleaner.create_strategy(:transaction, {'options' => 'hash'})
|
||||
result.should == @strategy
|
||||
result = cleaner.create_strategy(:transaction, {'options' => 'hash'})
|
||||
result.should == strategy
|
||||
end
|
||||
end
|
||||
|
||||
describe ".clean_with" do
|
||||
it "should initialize the appropirate strategy and clean with it" do
|
||||
DatabaseCleaner::ActiveRecord::Transaction.should_receive(:new).with('options' => 'hash')
|
||||
@strategy.should_receive(:clean)
|
||||
DatabaseCleaner.clean_with(:transaction, 'options' => 'hash')
|
||||
strategy.should_receive(:clean)
|
||||
cleaner.clean_with(:transaction, 'options' => 'hash')
|
||||
end
|
||||
end
|
||||
|
||||
describe ".strategy=" do
|
||||
it "should initialize the appropirate strategy based on the ORM adapter detected" do
|
||||
it "should initialize the appropirate strategy for active record" do
|
||||
DatabaseCleaner::ActiveRecord::Transaction.should_receive(:new).with('options' => 'hash')
|
||||
DatabaseCleaner.strategy = :transaction, {'options' => 'hash'}
|
||||
|
||||
Object.send(:remove_const, 'ActiveRecord')
|
||||
Object.const_set('DataMapper', "just mocking out the constant here...")
|
||||
DatabaseCleaner.orm = nil
|
||||
|
||||
DatabaseCleaner::DataMapper::Transaction.should_receive(:new).with(no_args)
|
||||
DatabaseCleaner.strategy = :transaction
|
||||
end
|
||||
|
||||
it "should raise an error when no ORM is detected" do
|
||||
Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord)
|
||||
Object.send(:remove_const, 'DataMapper') if defined?(::DataMapper)
|
||||
Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
|
||||
|
||||
running { DatabaseCleaner.strategy = :transaction }.should raise_error(DatabaseCleaner::NoORMDetected)
|
||||
end
|
||||
|
||||
it "should use the strategy version of the ORM specified with #orm=" do
|
||||
DatabaseCleaner.orm = 'data_mapper'
|
||||
DatabaseCleaner::DataMapper::Transaction.should_receive(:new)
|
||||
|
||||
DatabaseCleaner.strategy = :transaction
|
||||
end
|
||||
|
||||
it "should raise an error when multiple args is passed in and the first is not a symbol" do
|
||||
running { DatabaseCleaner.strategy=Object.new, {:foo => 'bar'} }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "should raise an error when the specified strategy is not found" do
|
||||
running { DatabaseCleaner.strategy = :foo }.should raise_error(DatabaseCleaner::UnknownStrategySpecified)
|
||||
cleaner.strategy = :transaction, {'options' => 'hash'}
|
||||
end
|
||||
|
||||
it "should allow any object to be set as the strategy" do
|
||||
|
@ -96,23 +210,108 @@ describe DatabaseCleaner do
|
|||
running { DatabaseCleaner.strategy = mock_strategy }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should raise an error when the specified strategy is not found" do
|
||||
running { DatabaseCleaner.strategy = :foo }.should raise_error(DatabaseCleaner::UnknownStrategySpecified)
|
||||
end
|
||||
|
||||
it "should raise an error when multiple args is passed in and the first is not a symbol" do
|
||||
running { DatabaseCleaner.strategy=Object.new, {:foo => 'bar'} }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
%w[start clean].each do |strategy_method|
|
||||
describe ".#{strategy_method}" do
|
||||
it "should be delgated to the strategy set with strategy=" do
|
||||
DatabaseCleaner.strategy = :transaction
|
||||
cleaner.strategy = :transaction
|
||||
|
||||
@strategy.should_receive(strategy_method)
|
||||
strategy.should_receive(strategy_method)
|
||||
|
||||
DatabaseCleaner.send(strategy_method)
|
||||
cleaner.send(strategy_method)
|
||||
end
|
||||
|
||||
it "should raise en error when no strategy has been set" do
|
||||
running { DatabaseCleaner.send(strategy_method) }.should raise_error(DatabaseCleaner::NoStrategySetError)
|
||||
running { cleaner.send(strategy_method) }.should raise_error(DatabaseCleaner::NoStrategySetError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "data mapper" do
|
||||
let(:cleaner) { ::DatabaseCleaner::Base.new(:data_mapper) }
|
||||
|
||||
before(:each) do
|
||||
::DatabaseCleaner::DataMapper::Transaction.stub!(:new).and_return(strategy)
|
||||
#Object.const_set('ActiveRecord', "just mocking out the constant here...") unless defined?(::ActiveRecord)
|
||||
cleaner.strategy = nil
|
||||
end
|
||||
|
||||
describe ".create_strategy" do
|
||||
it "should initialize and return the appropirate strategy" do
|
||||
DatabaseCleaner::DataMapper::Transaction.should_receive(:new)
|
||||
result = cleaner.create_strategy(:transaction)
|
||||
result.should == strategy
|
||||
end
|
||||
end
|
||||
|
||||
describe ".clean_with" do
|
||||
it "should initialize the appropirate strategy and clean with it" do
|
||||
DatabaseCleaner::DataMapper::Transaction.should_receive(:new)
|
||||
strategy.should_receive(:clean)
|
||||
cleaner.clean_with(:transaction)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".strategy=" do
|
||||
it "should initalize the appropriate strategy for data mapper" do
|
||||
DatabaseCleaner::DataMapper::Transaction.should_receive(:new).with(no_args)
|
||||
cleaner.strategy = :transaction
|
||||
end
|
||||
|
||||
it "should allow any object to be set as the strategy" do
|
||||
mock_strategy = mock('strategy')
|
||||
running { cleaner.strategy = mock_strategy }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should raise an error when the specified strategy is not found" do
|
||||
running { cleaner.strategy = :foo }.should raise_error(DatabaseCleaner::UnknownStrategySpecified)
|
||||
end
|
||||
|
||||
it "should raise an error when multiple args is passed in and the first is not a symbol" do
|
||||
running { cleaner.strategy=Object.new, {:foo => 'bar'} }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
%w[start clean].each do |strategy_method|
|
||||
describe ".#{strategy_method}" do
|
||||
it "should be delgated to the strategy set with strategy=" do
|
||||
cleaner.strategy = :transaction
|
||||
|
||||
strategy.should_receive(strategy_method)
|
||||
|
||||
cleaner.send(strategy_method)
|
||||
end
|
||||
|
||||
it "should raise en error when no strategy has been set" do
|
||||
running { cleaner.send(strategy_method) }.should raise_error(DatabaseCleaner::NoStrategySetError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# it "should raise an error when no ORM is detected" do
|
||||
# Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord)
|
||||
# Object.send(:remove_const, 'DataMapper') if defined?(::DataMapper)
|
||||
# Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
|
||||
#
|
||||
# running { DatabaseCleaner.strategy = :transaction }.should raise_error(DatabaseCleaner::NoORMDetected)
|
||||
# end
|
||||
|
||||
# it "should use the strategy version of the ORM specified with #orm=" do
|
||||
# DatabaseCleaner.orm = 'data_mapper'
|
||||
# DatabaseCleaner::DataMapper::Transaction.should_receive(:new)
|
||||
#
|
||||
# DatabaseCleaner.strategy = :transaction
|
||||
# end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
mtime
|
||||
--reverse
|
||||
--backtrace
|
||||
--debugger
|
Loading…
Reference in a new issue