From b18f9b7f57d1b02411db9dc8e0836802386b8afa Mon Sep 17 00:00:00 2001 From: Sidney Burks Date: Tue, 13 Apr 2010 09:50:25 -0600 Subject: [PATCH] adds mongoid support --- examples/lib/mongoid_models.rb | 23 +++++ features/cleaning.feature | 1 + .../database_cleaner_steps.rb | 2 +- lib/database_cleaner/configuration.rb | 16 +++- lib/database_cleaner/mongoid/truncation.rb | 23 +++++ spec/database_cleaner/configuration_spec.rb | 3 + .../mongoid/truncation_spec.rb | 84 +++++++++++++++++++ 7 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 examples/lib/mongoid_models.rb create mode 100644 lib/database_cleaner/mongoid/truncation.rb create mode 100644 spec/database_cleaner/mongoid/truncation_spec.rb diff --git a/examples/lib/mongoid_models.rb b/examples/lib/mongoid_models.rb new file mode 100644 index 0000000..f014234 --- /dev/null +++ b/examples/lib/mongoid_models.rb @@ -0,0 +1,23 @@ +require 'mongoid' + +Mongoid.configure do |config| + name = 'database_cleaner_test' + config.master = Mongo::Connection.new.db(name) +end + + +#::MongoMapper.connection = Mongo::Connection.new('127.0.0.1') +#::MongoMapper.database = 'database_cleaner_test' + +class Widget + include Mongoid::Document + field :id, :type => Integer + field :name + + class << self + #mongomapper doesn't seem to provide this... + def create!(*args) + new(*args).save! + end + end +end diff --git a/features/cleaning.feature b/features/cleaning.feature index d527d4a..9a2e974 100644 --- a/features/cleaning.feature +++ b/features/cleaning.feature @@ -17,4 +17,5 @@ Feature: database cleaning | DataMapper | transaction | | DataMapper | truncation | | MongoMapper | truncation | + | Mongoid | truncation | | CouchPotato | truncation | diff --git a/features/step_definitions/database_cleaner_steps.rb b/features/step_definitions/database_cleaner_steps.rb index 475476f..be9ec22 100644 --- a/features/step_definitions/database_cleaner_steps.rb +++ b/features/step_definitions/database_cleaner_steps.rb @@ -1,4 +1,4 @@ -Given /^I am using (ActiveRecord|DataMapper|MongoMapper|CouchPotato)$/ do |orm| +Given /^I am using (ActiveRecord|DataMapper|MongoMapper|Mongoid|CouchPotato)$/ do |orm| @orm = orm end diff --git a/lib/database_cleaner/configuration.rb b/lib/database_cleaner/configuration.rb index 8d74263..ec94839 100644 --- a/lib/database_cleaner/configuration.rb +++ b/lib/database_cleaner/configuration.rb @@ -16,12 +16,19 @@ module DatabaseCleaner end end + module MongoMapper def self.available_strategies %w[truncation] end end + module Mongoid + def self.available_strategies + %w[truncation] + end + end + module CouchPotato def self.available_strategies %w[truncation] @@ -76,7 +83,8 @@ module DatabaseCleaner end def orm_strategy(strategy) - require "database_cleaner/#{orm}/#{strategy}" + puts "Strategy is : #{strategy} and ORM is #{orm}" + require "database_cleaner/#{orm}/#{strategy}" 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(', ')}" @@ -91,10 +99,12 @@ module DatabaseCleaner 'data_mapper' elsif defined? ::MongoMapper 'mongo_mapper' + elsif defined? ::Mongoid + 'mongoid' elsif defined? ::CouchPotato 'couch_potato' else - raise NoORMDetected, "No known ORM was detected! Is ActiveRecord, DataMapper, MongoMapper or CouchPotato loaded?" + raise NoORMDetected, "No known ORM was detected! Is ActiveRecord, DataMapper, MongoMapper, Mongoid, or CouchPotato loaded?" end end end @@ -108,6 +118,8 @@ module DatabaseCleaner DatabaseCleaner::DataMapper when 'mongo_mapper' DatabaseCleaner::MongoMapper + when 'mongoid' + DatabaseCleaner::Mongoid when 'couch_potato' DatabaseCleaner::CouchPotato end diff --git a/lib/database_cleaner/mongoid/truncation.rb b/lib/database_cleaner/mongoid/truncation.rb new file mode 100644 index 0000000..0b958c1 --- /dev/null +++ b/lib/database_cleaner/mongoid/truncation.rb @@ -0,0 +1,23 @@ +require 'database_cleaner/truncation_base' + +module DatabaseCleaner + module Mongoid + class Truncation < DatabaseCleaner::TruncationBase + def clean + 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 + + def collections + ::Mongoid.database.collections + end + + end + end +end diff --git a/spec/database_cleaner/configuration_spec.rb b/spec/database_cleaner/configuration_spec.rb index 77cf595..83d9884 100644 --- a/spec/database_cleaner/configuration_spec.rb +++ b/spec/database_cleaner/configuration_spec.rb @@ -9,13 +9,16 @@ describe DatabaseCleaner do before(:all) do TempAR = ActiveRecord unless defined?(TempAR) TempMM = MongoMapper unless defined?(TempMM) + TempMI = Mongoid unless defined?(TempMI) Object.send(:remove_const, 'MongoMapper') if defined?(::MongoMapper) + Object.send(:remove_const, 'Mongoid') if defined?(::Mongoid) # 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 + Mongoid = TempMI end before(:each) do diff --git a/spec/database_cleaner/mongoid/truncation_spec.rb b/spec/database_cleaner/mongoid/truncation_spec.rb new file mode 100644 index 0000000..a3032fe --- /dev/null +++ b/spec/database_cleaner/mongoid/truncation_spec.rb @@ -0,0 +1,84 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +require 'mongoid' +require 'database_cleaner/mongoid/truncation' + +TEST_DATABASE = 'database_cleaner_specs' +Mongoid.configure do |config| + name = TEST_DATABASE + config.master = Mongo::Connection.new.db(name) +end + +class TestClassA + include Mongoid::Document + field :name +end + +class TestClassB + include Mongoid::Document + field :name +end + + +module DatabaseCleaner + module Mongoid + + describe Truncation do + before(:each) do + ::Mongoid.database.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_testclassa(attrs={}) + TestClassA.new({:name => 'some testclassa'}.merge(attrs)).save! + end + + def create_testclassb(attrs={}) + TestClassB.new({:name => 'some testclassb'}.merge(attrs)).save! + end + + it "truncates all collections by default" do + create_testclassa + create_testclassb + ensure_counts(TestClassA => 1, TestClassB => 1, :sanity_check => true) + Truncation.new.clean + ensure_counts(TestClassA => 0, TestClassB => 0) + end + + context "when collections are provided to the :only option" do + it "only truncates the specified collections" do + create_testclassa + create_testclassb + ensure_counts(TestClassA => 1, TestClassB => 1, :sanity_check => true) + Truncation.new(:only => ['test_class_as']).clean + ensure_counts(TestClassA => 0, TestClassB => 1) + end + end + + context "when collections are provided to the :except option" do + it "truncates all but the specified collections" do + create_testclassa + create_testclassb + ensure_counts(TestClassA => 1, TestClassB => 1, :sanity_check => true) + Truncation.new(:except => ['test_class_as']).clean + ensure_counts(TestClassA => 1, TestClassB => 0) + end + end + + end + + end +end