From 6ff2f91d384e336ea4fa50439ccafe34d78d1325 Mon Sep 17 00:00:00 2001 From: Ben Mabey Date: Mon, 22 Feb 2010 11:48:33 -0700 Subject: [PATCH] Adds :only & :except support to MongoMapper truncation. Closes GH-3. --- History.txt | 3 + .../mongo_mapper/truncation.rb | 11 ++- spec/database_cleaner/configuration_spec.rb | 6 +- .../mongo_mapper/truncation_spec.rb | 81 +++++++++++++++++++ 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 spec/database_cleaner/mongo_mapper/truncation_spec.rb diff --git a/History.txt b/History.txt index 2e7fe2c..b70e935 100644 --- a/History.txt +++ b/History.txt @@ -5,6 +5,9 @@ * SQLite3 on JRuby will fall back to delete if truncate doesn't work. (Darrin Holst) * JDBC is used for ActiveRecord automaticaly when JRuby is detected. (Darrin Holst) + === Bufixes + * MongoMapper truncation strategy now works with :only and :except options. (Ben Mabey) + == 0.4.3 2010-01-17 === New features diff --git a/lib/database_cleaner/mongo_mapper/truncation.rb b/lib/database_cleaner/mongo_mapper/truncation.rb index f41a91d..4af163c 100644 --- a/lib/database_cleaner/mongo_mapper/truncation.rb +++ b/lib/database_cleaner/mongo_mapper/truncation.rb @@ -4,7 +4,12 @@ module DatabaseCleaner module MongoMapper class Truncation < DatabaseCleaner::TruncationBase def clean - connection.db(database).collections.each { |c| c.remove } + if @only + collections.each { |c| c.remove if @only.include?(c.name) } + else + collections.each { |c| c.remove unless @tables_to_exclude.include?(c.name) } + end + true end private @@ -13,6 +18,10 @@ module DatabaseCleaner ::MongoMapper.connection end + def collections + connection.db(database).collections + end + def database ::MongoMapper.database.name end diff --git a/spec/database_cleaner/configuration_spec.rb b/spec/database_cleaner/configuration_spec.rb index 76b6fca..77cf595 100644 --- a/spec/database_cleaner/configuration_spec.rb +++ b/spec/database_cleaner/configuration_spec.rb @@ -2,16 +2,20 @@ require File.dirname(__FILE__) + '/../spec_helper' require 'database_cleaner/active_record/transaction' require 'database_cleaner/data_mapper/transaction' + describe DatabaseCleaner do # 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... 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 end before(:each) do @@ -25,7 +29,6 @@ describe DatabaseCleaner 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 end end @@ -34,7 +37,6 @@ describe DatabaseCleaner 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') end end diff --git a/spec/database_cleaner/mongo_mapper/truncation_spec.rb b/spec/database_cleaner/mongo_mapper/truncation_spec.rb new file mode 100644 index 0000000..5bb608b --- /dev/null +++ b/spec/database_cleaner/mongo_mapper/truncation_spec.rb @@ -0,0 +1,81 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +require 'mongomapper' +require 'database_cleaner/mongo_mapper/truncation' + +MongoMapper.connection = Mongo::Connection.new('127.0.0.1') +TEST_DATABASE = 'database_cleaner_specs' +MongoMapper.database = TEST_DATABASE + +class Widget + include MongoMapper::Document + key :name, String +end +class Gadget + include MongoMapper::Document + key :name, String +end + + +module DatabaseCleaner + module MongoMapper + + describe Truncation do + before(:each) do + ::MongoMapper.connection.drop_database(TEST_DATABASE) + #::MongoMapper.connection.db(TEST_DATABASE).collections.each {|c| c.remove } + #::MongoMapper.database = TEST_DATABASE + end + + def ensure_counts(expected_counts) + # I had to add this sanity_check garbage because I was getting non-determinisc results from mongomapper at times.. + # very odd and disconcerting... + sanity_check = expected_counts.delete(:sanity_check) + begin + expected_counts.each do |model_class, expected_count| + model_class.count.should equal(expected_count), "#{model_class} expected to have a count of #{expected_count} but was #{model_class.count}" + end + rescue Spec::Expectations::ExpectationNotMetError => e + raise !sanity_check ? e : Spec::ExpectationNotMetError::ExpectationNotMetError.new("SANITY CHECK FAILURE! This should never happen here: #{e.message}") + end + end + + def create_widget(attrs={}) + Widget.new({:name => 'some widget'}.merge(attrs)).save! + end + + def create_gadget(attrs={}) + Gadget.new({:name => 'some gadget'}.merge(attrs)).save! + end + + it "truncates all collections by default" do + create_widget + create_gadget + ensure_counts(Widget => 1, Gadget => 1, :sanity_check => true) + Truncation.new.clean + ensure_counts(Widget => 0, Gadget => 0) + end + + context "when collections are provided to the :only option" do + it "only truncates the specified collections" do + create_widget + create_gadget + ensure_counts(Widget => 1, Gadget => 1, :sanity_check => true) + Truncation.new(:only => ['widgets']).clean + ensure_counts(Widget => 0, Gadget => 1) + end + end + + context "when collections are provided to the :except option" do + it "truncates all but the specified collections" do + create_widget + create_gadget + ensure_counts(Widget => 1, Gadget => 1, :sanity_check => true) + Truncation.new(:except => ['widgets']).clean + ensure_counts(Widget => 1, Gadget => 0) + end + end + + end + + end +end