Added support for Moped (when used without Mongoid)

Fixed DatabaseCleaner::Base null strategy spec
This commit is contained in:
Cyprian Kowalczyk 2013-03-19 15:01:23 +01:00
parent 8002b46956
commit 7762d2f4f5
10 changed files with 223 additions and 32 deletions

View file

@ -72,6 +72,12 @@ Here is an overview of the strategies supported for each library:
<td> No</td> <td> No</td>
<td> No</td> <td> No</td>
</tr> </tr>
<tr>
<td> Moped</td>
<td> Yes</td>
<td> No</td>
<td> No</td>
</tr>
</tbody> </tbody>
</table> </table>
@ -276,6 +282,11 @@ Usage beyond that remains the same with `DatabaseCleaner.start` calling any setu
<td> <code>DatabaseCleaner[:mongoid]</code></td> <td> <code>DatabaseCleaner[:mongoid]</code></td>
<td> Multiple databases supported for Mongoid 3. Specify <code>DatabaseCleaner[:mongoid, {:connection =&gt; :db_name}]</code> </td> <td> Multiple databases supported for Mongoid 3. Specify <code>DatabaseCleaner[:mongoid, {:connection =&gt; :db_name}]</code> </td>
</tr> </tr>
<tr>
<td> Moped</td>
<td> <code>DatabaseCleaner[:moped]</code></td>
<td> It is necessary to configure database name with <code>DatabaseCleaner[:moped].db = db_name</code> otherwise name `default` will be used.</td>
</tr>
<tr> <tr>
<td> Couch Potato</td> <td> Couch Potato</td>
<td> <code>DatabaseCleaner[:couch_potato]</code></td> <td> <code>DatabaseCleaner[:couch_potato]</code></td>

View file

@ -120,8 +120,10 @@ module DatabaseCleaner
:couch_potato :couch_potato
elsif defined? ::Sequel elsif defined? ::Sequel
:sequel :sequel
elsif defined? ::Moped
:moped
else else
raise NoORMDetected, "No known ORM was detected! Is ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, or CouchPotato loaded?" raise NoORMDetected, "No known ORM was detected! Is ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, Moped, or CouchPotato loaded?"
end end
end end
end end
@ -130,7 +132,7 @@ module DatabaseCleaner
case orm case orm
when :active_record, :data_mapper, :sequel when :active_record, :data_mapper, :sequel
self.strategy = :transaction self.strategy = :transaction
when :mongo_mapper, :mongoid, :couch_potato when :mongo_mapper, :mongoid, :couch_potato, :moped
self.strategy = :truncation self.strategy = :truncation
end end
end end

View file

@ -1,7 +1,7 @@
require 'database_cleaner/mongoid/base' require 'database_cleaner/mongoid/base'
require 'database_cleaner/generic/truncation' require 'database_cleaner/generic/truncation'
require 'database_cleaner/mongo/truncation_mixin' require 'database_cleaner/mongo/truncation_mixin'
require 'database_cleaner/moped/truncation' require 'database_cleaner/moped/truncation_base'
require 'mongoid/version' require 'mongoid/version'
module DatabaseCleaner module DatabaseCleaner
@ -22,7 +22,7 @@ module DatabaseCleaner
else else
include ::DatabaseCleaner::Moped::Truncation include ::DatabaseCleaner::Moped::TruncationBase
private private

View file

@ -0,0 +1,35 @@
require 'database_cleaner/generic/base'
module DatabaseCleaner
module Moped
def self.available_strategies
%w[truncation]
end
module Base
include ::DatabaseCleaner::Generic::Base
def db=(desired_db)
@db = desired_db
end
def db
@db || :default
end
def host_port=(desired_host)
@host = desired_host
end
def host
@host || '127.0.0.1:27017'
end
private
def session
::Moped::Session.new([host], database: db)
end
end
end
end

View file

@ -1,29 +1,9 @@
require 'database_cleaner/moped/truncation_base'
module DatabaseCleaner module DatabaseCleaner
module Moped module Moped
module Truncation class Truncation
include ::DatabaseCleaner::Moped::TruncationBase
def clean
if @only
collections.each { |c| session[c].find.remove_all if @only.include?(c) }
else
collections.each { |c| session[c].find.remove_all unless @tables_to_exclude.include?(c) }
end
true
end
private
def collections
if db != :default
session.use(db)
end
session['system.namespaces'].find(:name => { '$not' => /system|\$/ }).to_a.map do |collection|
_, name = collection['name'].split('.', 2)
name
end
end
end end
end end
end end

View file

@ -0,0 +1,34 @@
require 'database_cleaner/moped/base'
require 'database_cleaner/generic/truncation'
module DatabaseCleaner
module Moped
module TruncationBase
include ::DatabaseCleaner::Moped::Base
include ::DatabaseCleaner::Generic::Truncation
def clean
if @only
collections.each { |c| session[c].find.remove_all if @only.include?(c) }
else
collections.each { |c| session[c].find.remove_all unless @tables_to_exclude.include?(c) }
end
true
end
private
def collections
if db != :default
session.use(db)
end
session['system.namespaces'].find(:name => { '$not' => /system|\$/ }).to_a.map do |collection|
_, name = collection['name'].split('.', 2)
name
end
end
end
end
end

View file

@ -18,6 +18,7 @@ module DatabaseCleaner
Temp_MO = ::Mongoid if defined?(::Mongoid) and not defined?(Temp_MO) Temp_MO = ::Mongoid if defined?(::Mongoid) and not defined?(Temp_MO)
Temp_CP = ::CouchPotato if defined?(::CouchPotato) and not defined?(Temp_CP) Temp_CP = ::CouchPotato if defined?(::CouchPotato) and not defined?(Temp_CP)
Temp_SQ = ::Sequel if defined?(::Sequel) and not defined?(Temp_SQ) Temp_SQ = ::Sequel if defined?(::Sequel) and not defined?(Temp_SQ)
Temp_MP = ::Moped if defined?(::Moped) and not defined?(Temp_MP)
end end
#Remove all ORM mocks and restore from cache #Remove all ORM mocks and restore from cache
@ -28,6 +29,7 @@ module DatabaseCleaner
Object.send(:remove_const, 'Mongoid') if defined?(::Mongoid) Object.send(:remove_const, 'Mongoid') if defined?(::Mongoid)
Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato) Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
Object.send(:remove_const, 'Sequel') if defined?(::Sequel) Object.send(:remove_const, 'Sequel') if defined?(::Sequel)
Object.send(:remove_const, 'Moped') if defined?(::Moped)
# Restore ORMs # Restore ORMs
@ -36,6 +38,7 @@ module DatabaseCleaner
::MongoMapper = Temp_MM if defined? Temp_MM ::MongoMapper = Temp_MM if defined? Temp_MM
::Mongoid = Temp_MO if defined? Temp_MO ::Mongoid = Temp_MO if defined? Temp_MO
::CouchPotato = Temp_CP if defined? Temp_CP ::CouchPotato = Temp_CP if defined? Temp_CP
::Moped = Temp_MP if defined? Temp_MP
end end
#reset the orm mocks #reset the orm mocks
@ -46,6 +49,7 @@ module DatabaseCleaner
Object.send(:remove_const, 'Mongoid') if defined?(::Mongoid) Object.send(:remove_const, 'Mongoid') if defined?(::Mongoid)
Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato) Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
Object.send(:remove_const, 'Sequel') if defined?(::Sequel) Object.send(:remove_const, 'Sequel') if defined?(::Sequel)
Object.send(:remove_const, 'Moped') if defined?(::Moped)
end end
let(:cleaner) { DatabaseCleaner::Base.new :autodetect } let(:cleaner) { DatabaseCleaner::Base.new :autodetect }
@ -61,6 +65,7 @@ module DatabaseCleaner
Object.const_set('Mongoid', 'Mongoid mock') Object.const_set('Mongoid', 'Mongoid mock')
Object.const_set('CouchPotato', 'Couching mock potatos') Object.const_set('CouchPotato', 'Couching mock potatos')
Object.const_set('Sequel', 'Sequel mock') Object.const_set('Sequel', 'Sequel mock')
Object.const_set('Moped', 'Moped mock')
cleaner.orm.should == :active_record cleaner.orm.should == :active_record
cleaner.should be_auto_detected cleaner.should be_auto_detected
@ -72,6 +77,7 @@ module DatabaseCleaner
Object.const_set('Mongoid', 'Mongoid mock') Object.const_set('Mongoid', 'Mongoid mock')
Object.const_set('CouchPotato', 'Couching mock potatos') Object.const_set('CouchPotato', 'Couching mock potatos')
Object.const_set('Sequel', 'Sequel mock') Object.const_set('Sequel', 'Sequel mock')
Object.const_set('Moped', 'Moped mock')
cleaner.orm.should == :data_mapper cleaner.orm.should == :data_mapper
cleaner.should be_auto_detected cleaner.should be_auto_detected
@ -82,6 +88,7 @@ module DatabaseCleaner
Object.const_set('Mongoid', 'Mongoid mock') Object.const_set('Mongoid', 'Mongoid mock')
Object.const_set('CouchPotato', 'Couching mock potatos') Object.const_set('CouchPotato', 'Couching mock potatos')
Object.const_set('Sequel', 'Sequel mock') Object.const_set('Sequel', 'Sequel mock')
Object.const_set('Moped', 'Moped mock')
cleaner.orm.should == :mongo_mapper cleaner.orm.should == :mongo_mapper
cleaner.should be_auto_detected cleaner.should be_auto_detected
@ -91,6 +98,7 @@ module DatabaseCleaner
Object.const_set('Mongoid', 'Mongoid mock') Object.const_set('Mongoid', 'Mongoid mock')
Object.const_set('CouchPotato', 'Couching mock potatos') Object.const_set('CouchPotato', 'Couching mock potatos')
Object.const_set('Sequel', 'Sequel mock') Object.const_set('Sequel', 'Sequel mock')
Object.const_set('Moped', 'Moped mock')
cleaner.orm.should == :mongoid cleaner.orm.should == :mongoid
cleaner.should be_auto_detected cleaner.should be_auto_detected
@ -99,17 +107,26 @@ module DatabaseCleaner
it "should detect CouchPotato fifth" do it "should detect CouchPotato fifth" do
Object.const_set('CouchPotato', 'Couching mock potatos') Object.const_set('CouchPotato', 'Couching mock potatos')
Object.const_set('Sequel', 'Sequel mock') Object.const_set('Sequel', 'Sequel mock')
Object.const_set('Moped', 'Moped mock')
cleaner.orm.should == :couch_potato cleaner.orm.should == :couch_potato
cleaner.should be_auto_detected cleaner.should be_auto_detected
end end
it "should detect Sequel last" do it "should detect Sequel sixth" do
Object.const_set('Sequel', 'Sequel mock') Object.const_set('Sequel', 'Sequel mock')
Object.const_set('Moped', 'Moped mock')
cleaner.orm.should == :sequel cleaner.orm.should == :sequel
cleaner.should be_auto_detected cleaner.should be_auto_detected
end end
it "should detect Moped seventh" do
Object.const_set('Moped', 'Moped mock')
cleaner.orm.should == :moped
cleaner.should be_auto_detected
end
end end
describe "orm_module" do describe "orm_module" do
@ -330,8 +347,7 @@ module DatabaseCleaner
describe "strategy" do describe "strategy" do
subject { ::DatabaseCleaner::Base.new :a_orm } subject { ::DatabaseCleaner::Base.new :a_orm }
it "returns a null strategy when strategy no set and undetectable" do it "returns a null strategy when strategy is not set and undetectable" do
subject.instance_values["@strategy"] = nil
subject.strategy.should == DatabaseCleaner::NullStrategy subject.strategy.should == DatabaseCleaner::NullStrategy
end end
@ -487,6 +503,11 @@ module DatabaseCleaner
cleaner = DatabaseCleaner::Base.new(:couch_potato) cleaner = DatabaseCleaner::Base.new(:couch_potato)
cleaner.strategy.should be_instance_of DatabaseCleaner::CouchPotato::Truncation cleaner.strategy.should be_instance_of DatabaseCleaner::CouchPotato::Truncation
end end
it 'sets strategy to :truncation for Moped' do
cleaner = DatabaseCleaner::Base.new(:moped)
cleaner.strategy.should be_instance_of DatabaseCleaner::Moped::Truncation
end
end end
end end

View file

@ -55,6 +55,13 @@ describe ::DatabaseCleaner do
cleaner.orm.should == :couch_potato cleaner.orm.should == :couch_potato
::DatabaseCleaner.connections.size.should == 1 ::DatabaseCleaner.connections.size.should == 1
end end
it "should accept :moped" do
cleaner = ::DatabaseCleaner[:moped]
cleaner.should be_a(::DatabaseCleaner::Base)
cleaner.orm.should == :moped
::DatabaseCleaner.connections.size.should == 1
end
end end
it "should accept multiple orm's" do it "should accept multiple orm's" do

View file

@ -0,0 +1,26 @@
module MopedTest
class ThingBase
def self.collection
@db ||= 'database_cleaner_specs'
@session ||= ::Moped::Session.new(['127.0.0.1:27017'], database: @db)
@collection ||= @session[name]
end
def self.count
@collection.find.count
end
def initialize(attrs={})
@attrs = attrs
end
def save!
self.class.collection.insert(@attrs)
end
end
class Widget < ThingBase
end
class Gadget < ThingBase
end
end

View file

@ -0,0 +1,75 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'moped'
require 'database_cleaner/moped/truncation'
require File.dirname(__FILE__) + '/moped_examples'
module DatabaseCleaner
module Moped
describe Truncation do
let(:args) {{}}
let(:truncation) { described_class.new(args).tap { |t| t.db=@db } }
#doing this in the file root breaks autospec, doing it before(:all) just fails the specs
before(:all) do
@test_db = 'database_cleaner_specs'
@session = ::Moped::Session.new(['127.0.0.1:27017'], database: @test_db)
end
before(:each) do
truncation.db = @test_db
end
after(:each) do
@session.drop
end
def ensure_counts(expected_counts)
# I had to add this sanity_check garbage because I was getting non-determinisc results from mongo at times..
# very odd and disconcerting...
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
end
def create_widget(attrs={})
MopedTest::Widget.new({:name => 'some widget'}.merge(attrs)).save!
end
def create_gadget(attrs={})
MopedTest::Gadget.new({:name => 'some gadget'}.merge(attrs)).save!
end
it "truncates all collections by default" do
create_widget
create_gadget
ensure_counts(MopedTest::Widget => 1, MopedTest::Gadget => 1)
truncation.clean
ensure_counts(MopedTest::Widget => 0, MopedTest::Gadget => 0)
end
context "when collections are provided to the :only option" do
let(:args) {{:only => ['MopedTest::Widget']}}
it "only truncates the specified collections" do
create_widget
create_gadget
ensure_counts(MopedTest::Widget => 1, MopedTest::Gadget => 1)
truncation.clean
ensure_counts(MopedTest::Widget => 0, MopedTest::Gadget => 1)
end
end
context "when collections are provided to the :except option" do
let(:args) {{:except => ['MopedTest::Widget']}}
it "truncates all but the specified collections" do
create_widget
create_gadget
ensure_counts(MopedTest::Widget => 1, MopedTest::Gadget => 1)
truncation.clean
ensure_counts(MopedTest::Widget => 1, MopedTest::Gadget => 0)
end
end
end
end
end