refactor base to pass through database to strategy and let it decide to handle it, gracefully degrades (only errors upon attempt to use different database when strategy doesn't support it

This commit is contained in:
Jon Rowe 2010-05-26 08:20:29 +01:00
parent d2da58156e
commit b7fed145df
10 changed files with 48 additions and 43 deletions

View file

@ -8,6 +8,7 @@ DB_DIR = "#{File.dirname(__FILE__)}/../../db"
orm = ENV['ORM'] orm = ENV['ORM']
another_orm = ENV['ANOTHER_ORM'] another_orm = ENV['ANOTHER_ORM']
strategy = ENV['STRATEGY'] strategy = ENV['STRATEGY']
multiple_db = ENV['MULTIPLE_DBS']
if orm && strategy if orm && strategy
$:.unshift(File.dirname(__FILE__) + '/../../../lib') $:.unshift(File.dirname(__FILE__) + '/../../../lib')
@ -26,18 +27,19 @@ if orm && strategy
rescue LoadError => e rescue LoadError => e
raise "You don't have the #{another_orm} ORM installed" raise "You don't have the #{another_orm} ORM installed"
end end
else
end end
unless another_orm if multiple_db && another_orm
DatabaseCleaner.strategy = strategy.to_sym DatabaseCleaner[ orm.gsub(/(.)([A-Z]+)/,'\1_\2').downcase.to_sym, {:connection => :one} ].strategy = strategy.to_sym
else DatabaseCleaner[ another_orm.gsub(/(.)([A-Z]+)/,'\1_\2').downcase.to_sym, {:connection => :two} ].strategy = strategy.to_sym
elsif another_orm
DatabaseCleaner[ orm.gsub(/(.)([A-Z]+)/,'\1_\2').downcase.to_sym ].strategy = strategy.to_sym DatabaseCleaner[ orm.gsub(/(.)([A-Z]+)/,'\1_\2').downcase.to_sym ].strategy = strategy.to_sym
DatabaseCleaner[ another_orm.gsub(/(.)([A-Z]+)/,'\1_\2').downcase.to_sym ].strategy = strategy.to_sym DatabaseCleaner[ another_orm.gsub(/(.)([A-Z]+)/,'\1_\2').downcase.to_sym ].strategy = strategy.to_sym
else
DatabaseCleaner.strategy = strategy.to_sym
end end
else else

View file

@ -1,5 +1,5 @@
require 'database_cleaner/generic/base' require 'database_cleaner/generic/base'
require 'active_record/base' require 'active_record'
module DatabaseCleaner module DatabaseCleaner
module ActiveRecord module ActiveRecord

View file

@ -36,6 +36,12 @@ module DatabaseCleaner
else else
raise ArgumentError, "You must provide a strategy object, or a symbol for a known strategy along with initialization params." raise ArgumentError, "You must provide a strategy object, or a symbol for a known strategy along with initialization params."
end end
if @strategy.respond_to? :db=
@strategy.db = self.db
elsif self.db != :default
raise ArgumentError, "You must provide a strategy object that supports non default databases when you specify a database"
end
end end
def strategy def strategy

View file

@ -7,12 +7,6 @@ module DatabaseCleaner
module Base module Base
include ::DatabaseCleaner::Generic::Base include ::DatabaseCleaner::Generic::Base
def connection_klass
#TODO, multiple connections...
raise NotImplementedError
#::ActiveRecord::Base
end
end end
end end
end end

View file

@ -8,20 +8,8 @@ module ::DatabaseCleaner
end end
module InstanceMethods module InstanceMethods
def initialize(db = :default)
@db = db
end
def db=(desired_db)
@db = desired_db
end
def db def db
@db :default
end
def connection_klass
raise NotImplementedError
end end
end end

View file

@ -84,10 +84,10 @@ module DatabaseCleaner
it "should be equal if orm, connection and strategy are the same" do it "should be equal if orm, connection and strategy are the same" do
strategy = :truncation strategy = :truncation
one = DatabaseCleaner::Base.new(:active_record,:connection => :one) one = DatabaseCleaner::Base.new(:active_record,:connection => :default)
one.strategy = strategy one.strategy = strategy
two = DatabaseCleaner::Base.new(:active_record,:connection => :one) two = DatabaseCleaner::Base.new(:active_record,:connection => :default)
two.strategy = strategy two.strategy = strategy
one.should == two one.should == two
@ -106,7 +106,31 @@ module DatabaseCleaner
base.db.should == :my_db base.db.should == :my_db
end end
it "should pass through db to the strategy" it "should check to see if strategy supports db specification" do
strategy = mock("strategy",:db= => :my_db)
strategy.stub(:respond_to?).with(anything)
strategy.should_receive(:respond_to?).with(:db=).and_return(true)
::DatabaseCleaner::Base.new(:active_record,:connection => :my_db).strategy = strategy
end
it "should pass db through to the strategy" do
strategy = mock("strategy")
strategy.stub(:respond_to?).with(anything)
strategy.stub(:respond_to?).with(:db=).and_return(true)
strategy.should_receive(:db=).with(:my_db)
::DatabaseCleaner::Base.new(:active_record,:connection => :my_db).strategy = strategy
end
it "should raise ArgumentError if db isn't default and strategy doesn't support different dbs" do
strategy = mock("strategy")
strategy.stub(:respond_to?).with(anything)
strategy.stub(:respond_to?).with(:db=).and_return(false)
expect { ::DatabaseCleaner::Base.new(:active_record,:connection => :my_db).strategy = strategy }.to raise_error ArgumentError
end
end end
describe "orm integration" do describe "orm integration" do

View file

@ -228,9 +228,9 @@ describe ::DatabaseCleaner do
describe "remove_duplicates" do describe "remove_duplicates" do
it "should remove duplicates if they are identical" do it "should remove duplicates if they are identical" do
::DatabaseCleaner[:active_record, {:connection => :one}].strategy = :truncation ::DatabaseCleaner[:active_record, {:connection => :default}].strategy = :truncation
::DatabaseCleaner[:active_record, {:connection => :one}].strategy = :truncation ::DatabaseCleaner[:active_record, {:connection => :default}].strategy = :truncation
::DatabaseCleaner[:active_record, {:connection => :one}].strategy = :truncation ::DatabaseCleaner[:active_record, {:connection => :default}].strategy = :truncation
::DatabaseCleaner.connections.size.should == 3 ::DatabaseCleaner.connections.size.should == 3
::DatabaseCleaner.remove_duplicates ::DatabaseCleaner.remove_duplicates
::DatabaseCleaner.connections.size.should == 1 ::DatabaseCleaner.connections.size.should == 1

View file

@ -14,7 +14,8 @@ module DatabaseCleaner
describe ExampleStrategy do describe ExampleStrategy do
it_should_behave_like "a generic strategy" it_should_behave_like "a generic strategy"
#it { expect{ subject.connection_klass }.to_not raise_error } it { should respond_to :db }
it { should respond_to :db= }
end end
end end
end end

View file

@ -1,4 +1,5 @@
require 'spec_helper' require 'spec_helper'
require 'database_cleaner/shared_strategy_spec'
require 'database_cleaner/generic/base' require 'database_cleaner/generic/base'
module ::DatabaseCleaner module ::DatabaseCleaner
@ -16,15 +17,6 @@ module ::DatabaseCleaner
it_should_behave_like "a generic strategy" it_should_behave_like "a generic strategy"
its (:db) { should == :default } its (:db) { should == :default }
it "should raise NotImplementedError upon access of connection_klass" do
expect { subject.connection_klass }.to raise_error NotImplementedError
end
it "should accept the desired database upon initalisation" do
eg = ExampleStrategy.new :my_database
eg.db.should == :my_database
end
end end
end end
end end

View file

@ -1,7 +1,5 @@
shared_examples_for "a generic strategy" do shared_examples_for "a generic strategy" do
it { should respond_to :db } it { should respond_to :db }
it { should respond_to :db= }
it { should respond_to :connection_klass }
end end
shared_examples_for "a generic truncation strategy" do shared_examples_for "a generic truncation strategy" do