diff --git a/lib/database_cleaner/configuration.rb b/lib/database_cleaner/configuration.rb index 755247f..fe20107 100644 --- a/lib/database_cleaner/configuration.rb +++ b/lib/database_cleaner/configuration.rb @@ -1,3 +1,5 @@ +require 'database_cleaner/base' + module DatabaseCleaner class NoStrategySetError < StandardError; end @@ -38,9 +40,12 @@ module DatabaseCleaner end class << self - def [](orm) + def [](orm,opts = {}) raise NoORMDetected if orm.nil? - DatabaseCleaner::Base.new(orm) + @connections ||= [] + cleaner = DatabaseCleaner::Base.new(orm,opts) + connections.push cleaner + cleaner end def connections @@ -66,111 +71,13 @@ module DatabaseCleaner def clean_with(stratagem) self.connections.each { |connection| connection.clean_with stratagem } end + + def remove_duplicates + temp = [] + @connections.each do |connect| + temp.push connect unless temp.include? connect + end + @connections = temp + 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 - orm_strategy(strategy).new(*strategy_args) - end - - def clean_with(*args) - strategy = create_strategy(*args) - strategy.clean - strategy - end - - alias clean_with! clean_with - - def strategy=(args) - strategy, *strategy_args = args - if strategy.is_a?(Symbol) - @strategy = create_strategy(*args) - elsif strategy_args.empty? - @strategy = strategy - else - raise ArgumentError, "You must provide a strategy object, or a symbol for a know strategy along with initialization params." - end - end - - def orm=(desired_orm) - @orm = desired_orm - end - - def start - strategy.start - end - - def clean - strategy.clean - end - - alias clean! clean - - def orm - @orm || autodetect - end - - def auto_detected - return true unless @autodetected.nil? - end - - private - - def strategy - return @strategy if @strategy - 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.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 autodetect - @orm ||= begin - @autodetected = true - if defined? ::ActiveRecord - :active_record - elsif defined? ::DataMapper - :data_mapper - elsif defined? ::MongoMapper - :mongo_mapper - elsif defined? ::CouchPotato - :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 - DatabaseCleaner::ActiveRecord - when :data_mapper - DatabaseCleaner::DataMapper - when :mongo_mapper - DatabaseCleaner::MongoMapper - when :couch_potato - DatabaseCleaner::CouchPotato - end - end - end - end diff --git a/spec/database_cleaner/configuration_spec.rb b/spec/database_cleaner/configuration_spec.rb index 714ce12..d4d4ed0 100644 --- a/spec/database_cleaner/configuration_spec.rb +++ b/spec/database_cleaner/configuration_spec.rb @@ -2,9 +2,16 @@ require File.dirname(__FILE__) + '/../spec_helper' require 'database_cleaner/active_record/transaction' require 'database_cleaner/data_mapper/transaction' - +module DatabaseCleaner + class << self + def reset + @connections = nil + end + end +end describe DatabaseCleaner do - + + before (:each) { ::DatabaseCleaner.reset } describe ActiveRecord do describe "connections" do it "should return an array of classes containing ActiveRecord::Base by default" do @@ -50,13 +57,22 @@ describe DatabaseCleaner do end end + context "connection/db specification" do + it "should accept a connection parameter and store it" do + cleaner = ::DatabaseCleaner[:active_record, {:connection => :first_connection}] + cleaner.should be_a ::DatabaseCleaner::Base + cleaner.orm.should == :active_record + cleaner.db.should == :first_connection + 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.should have(1).items ::DatabaseCleaner.connections.first.should be_a ::DatabaseCleaner::Base ::DatabaseCleaner.connections.first.auto_detected.should be_true end @@ -167,8 +183,11 @@ describe DatabaseCleaner do end end - context "multiple orms single connection per orm" do - context "proxy methods" do + context "multiple connections" do + + #these are relativly simple, all we need to do is make sure all connections are cleaned/started/cleaned_with appropriatly. + context "simple proxy methods" do + let(:active_record) { mock("active_mock") } let(:data_mapper) { mock("data_mock") } @@ -198,11 +217,19 @@ describe DatabaseCleaner do ::DatabaseCleaner.clean_with stratagem end end - context "more contentious proxy methods" do + + # ah now we have some difficulty, we mustn't allow duplicate connections to exist, but they could + # plausably want to force orm/strategy change on two sets of orm that differ only on db + context "multiple orm proxy methods" do + let(:active_record_1) { mock("active_mock_on_db_one") } + let(:active_record_2) { mock("active_mock_on_db_two") } + let(:data_mapper_1) { mock("data_mock_on_db_one") } + it "should proxy orm to all connections and remove duplicate connections" do - - ::DatabaseCleaner.orm = :active_record + pending end + it "should proxy strategy to all connections and remove duplicate connections" + end end @@ -348,6 +375,30 @@ describe DatabaseCleaner do # # DatabaseCleaner.strategy = :transaction # end - + describe "comparison" do + it "should be equal if orm, connection and strategy are the same" do + strategy = :truncation + + one = DatabaseCleaner::Base.new(:active_record,:connection => :one) + one.strategy = strategy + + two = DatabaseCleaner::Base.new(:active_record,:connection => :one) + two.strategy = strategy + + one.should == two + two.should == one + end + end + + describe "remove_duplicates" do + it "should remove duplicates if they are identical" do + ::DatabaseCleaner[:active_record, {:connection => :one}].strategy = :truncation + ::DatabaseCleaner[:active_record, {:connection => :one}].strategy = :truncation + ::DatabaseCleaner[:active_record, {:connection => :one}].strategy = :truncation + ::DatabaseCleaner.connections.size.should == 3 + ::DatabaseCleaner.remove_duplicates + ::DatabaseCleaner.connections.size.should == 1 + end + end end end