database_cleaner 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +12 -2
- data/README.textile +1 -1
- data/VERSION.yml +2 -2
- data/examples/features/support/env.rb +3 -3
- data/examples/lib/activerecord_models.rb +12 -0
- data/examples/lib/couchpotato_models.rb +21 -0
- data/examples/lib/{datamapper.rb → datamapper_models.rb} +0 -0
- data/examples/lib/{mongomapper.rb → mongomapper_models.rb} +8 -1
- data/features/cleaning.feature +1 -0
- data/features/step_definitions/database_cleaner_steps.rb +2 -2
- data/lib/database_cleaner/active_record/truncation.rb +5 -1
- data/lib/database_cleaner/configuration.rb +11 -1
- data/lib/database_cleaner/couch_potato/truncation.rb +26 -0
- data/lib/database_cleaner/mongo_mapper/truncation.rb +10 -1
- data/spec/database_cleaner/configuration_spec.rb +5 -2
- data/spec/database_cleaner/couch_potato/truncation_spec.rb +40 -0
- data/spec/database_cleaner/mongo_mapper/truncation_spec.rb +81 -0
- metadata +15 -8
- data/examples/lib/activerecord.rb +0 -12
data/History.txt
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
-
0.
|
1
|
+
0.5.x (In Git)
|
2
|
+
|
3
|
+
== 0.5.0 2010-02-22 - The CouchPotato Release
|
4
|
+
|
5
|
+
=== New features
|
6
|
+
* Basic truncation support for CouchPotato / CouchDB. (Martin Rehfeld)
|
7
|
+
* SQLite3 on JRuby will fall back to delete if truncate doesn't work. (Darrin Holst)
|
8
|
+
* JDBC is used for ActiveRecord automaticaly when JRuby is detected. (Darrin Holst)
|
9
|
+
|
10
|
+
=== Bufixes
|
11
|
+
* MongoMapper truncation strategy now works with :only and :except options. (Ben Mabey)
|
2
12
|
|
3
13
|
== 0.4.3 2010-01-17
|
4
14
|
|
5
15
|
=== New features
|
6
|
-
|
16
|
+
* Truncation for ActiveRecord oracle_enhanced adapter. (Edgars Beigarts)
|
7
17
|
|
8
18
|
== 0.4.2 2010-01-12
|
9
19
|
|
data/README.textile
CHANGED
@@ -5,7 +5,7 @@ The original use case was to ensure a clean state during tests. Each strategy
|
|
5
5
|
is a small amount of code but is code that is usually needed in any ruby app
|
6
6
|
that is testing with a database.
|
7
7
|
|
8
|
-
ActiveRecord, DataMapper and
|
8
|
+
ActiveRecord, DataMapper, MongoMapper and CouchPotato are supported.
|
9
9
|
|
10
10
|
h2. How to use
|
11
11
|
|
data/VERSION.yml
CHANGED
@@ -5,9 +5,9 @@ orm = ENV['ORM']
|
|
5
5
|
strategy = ENV['STRATEGY']
|
6
6
|
|
7
7
|
if orm && strategy
|
8
|
-
|
8
|
+
|
9
9
|
begin
|
10
|
-
require "#{File.dirname(__FILE__)}/../../lib/#{orm}"
|
10
|
+
require "#{File.dirname(__FILE__)}/../../lib/#{orm}_models"
|
11
11
|
rescue LoadError
|
12
12
|
raise "You don't have the #{orm} ORM installed"
|
13
13
|
end
|
@@ -19,5 +19,5 @@ if orm && strategy
|
|
19
19
|
DatabaseCleaner.strategy = strategy.to_sym
|
20
20
|
|
21
21
|
else
|
22
|
-
raise "Run 'ORM=activerecord|datamapper|mongomapper STRATEGY=transaction|truncation cucumber examples/features'"
|
22
|
+
raise "Run 'ORM=activerecord|datamapper|mongomapper|couchpotato STRATEGY=transaction|truncation cucumber examples/features'"
|
23
23
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
ActiveRecord::Base.establish_connection(:adapter => "#{"jdbc" if defined?(JRUBY_VERSION)}sqlite3", :database => ":memory:")
|
4
|
+
|
5
|
+
ActiveRecord::Schema.define(:version => 1) do
|
6
|
+
create_table :widgets do |t|
|
7
|
+
t.string :name
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Widget < ActiveRecord::Base
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'couch_potato'
|
2
|
+
|
3
|
+
::CouchPotato::Config.database_name = 'couch_potato_test'
|
4
|
+
|
5
|
+
class Widget
|
6
|
+
include CouchPotato::Persistence
|
7
|
+
|
8
|
+
property :name
|
9
|
+
view :by_name, :key => :name
|
10
|
+
|
11
|
+
|
12
|
+
# mimic the AR interface used in example_steps
|
13
|
+
|
14
|
+
def self.create!(attrs = {})
|
15
|
+
CouchPotato.database.save(self.new)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.count
|
19
|
+
CouchPotato.database.view(::Widget.by_name).size
|
20
|
+
end
|
21
|
+
end
|
File without changes
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'mongomapper'
|
2
2
|
|
3
3
|
::MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
|
4
4
|
::MongoMapper.database = 'database_cleaner_test'
|
@@ -7,4 +7,11 @@ class Widget
|
|
7
7
|
include MongoMapper::Document
|
8
8
|
key :id, Integer
|
9
9
|
key :name, String
|
10
|
+
|
11
|
+
class << self
|
12
|
+
#mongomapper doesn't seem to provide this...
|
13
|
+
def create!(*args)
|
14
|
+
new(*args).save!
|
15
|
+
end
|
16
|
+
end
|
10
17
|
end
|
data/features/cleaning.feature
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Given /^I am using (ActiveRecord|DataMapper|MongoMapper)$/ do |orm|
|
1
|
+
Given /^I am using (ActiveRecord|DataMapper|MongoMapper|CouchPotato)$/ do |orm|
|
2
2
|
@orm = orm
|
3
3
|
end
|
4
4
|
|
@@ -11,7 +11,7 @@ When "I run my scenarios that rely on a clean database" do
|
|
11
11
|
Dir.chdir(full_dir) do
|
12
12
|
ENV['ORM'] = @orm.downcase
|
13
13
|
ENV['STRATEGY'] = @strategy
|
14
|
-
@out =
|
14
|
+
@out = `#{"jruby -S " if defined?(JRUBY_VERSION)}cucumber features`
|
15
15
|
@status = $?.exitstatus
|
16
16
|
end
|
17
17
|
end
|
@@ -17,7 +17,11 @@ module ActiveRecord
|
|
17
17
|
|
18
18
|
class JdbcAdapter
|
19
19
|
def truncate_table(table_name)
|
20
|
-
|
20
|
+
begin
|
21
|
+
execute("TRUNCATE TABLE #{quote_table_name(table_name)};")
|
22
|
+
rescue ActiveRecord::StatementInvalid
|
23
|
+
execute("DELETE FROM #{quote_table_name(table_name)};")
|
24
|
+
end
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
@@ -22,6 +22,12 @@ module DatabaseCleaner
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
module CouchPotato
|
26
|
+
def self.available_strategies
|
27
|
+
%w[truncation]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
25
31
|
class << self
|
26
32
|
|
27
33
|
def create_strategy(*args)
|
@@ -81,8 +87,10 @@ module DatabaseCleaner
|
|
81
87
|
'data_mapper'
|
82
88
|
elsif defined? ::MongoMapper
|
83
89
|
'mongo_mapper'
|
90
|
+
elsif defined? ::CouchPotato
|
91
|
+
'couch_potato'
|
84
92
|
else
|
85
|
-
raise NoORMDetected, "No known ORM was detected! Is ActiveRecord or
|
93
|
+
raise NoORMDetected, "No known ORM was detected! Is ActiveRecord, DataMapper, MongoMapper or CouchPotato loaded?"
|
86
94
|
end
|
87
95
|
end
|
88
96
|
end
|
@@ -96,6 +104,8 @@ module DatabaseCleaner
|
|
96
104
|
DatabaseCleaner::DataMapper
|
97
105
|
when 'mongo_mapper'
|
98
106
|
DatabaseCleaner::MongoMapper
|
107
|
+
when 'couch_potato'
|
108
|
+
DatabaseCleaner::CouchPotato
|
99
109
|
end
|
100
110
|
end
|
101
111
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'database_cleaner/truncation_base'
|
2
|
+
|
3
|
+
module DatabaseCleaner
|
4
|
+
module CouchPotato
|
5
|
+
class Truncation < DatabaseCleaner::TruncationBase
|
6
|
+
def initialize(options = {})
|
7
|
+
if options.has_key?(:only) || options.has_key?(:except)
|
8
|
+
raise ArgumentError, "The :only and :except options are not available for use with CouchPotato/CouchDB."
|
9
|
+
elsif !options.empty?
|
10
|
+
raise ArgumentError, "Unsupported option. You specified #{options.keys.join(',')}."
|
11
|
+
end
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def clean
|
16
|
+
database.recreate!
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def database
|
22
|
+
::CouchPotato.couchrest_database
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -4,7 +4,12 @@ module DatabaseCleaner
|
|
4
4
|
module MongoMapper
|
5
5
|
class Truncation < DatabaseCleaner::TruncationBase
|
6
6
|
def clean
|
7
|
-
|
7
|
+
if @only
|
8
|
+
collections.each { |c| c.remove if @only.include?(c.name) }
|
9
|
+
else
|
10
|
+
collections.each { |c| c.remove unless @tables_to_exclude.include?(c.name) }
|
11
|
+
end
|
12
|
+
true
|
8
13
|
end
|
9
14
|
|
10
15
|
private
|
@@ -13,6 +18,10 @@ module DatabaseCleaner
|
|
13
18
|
::MongoMapper.connection
|
14
19
|
end
|
15
20
|
|
21
|
+
def collections
|
22
|
+
connection.db(database).collections
|
23
|
+
end
|
24
|
+
|
16
25
|
def database
|
17
26
|
::MongoMapper.database.name
|
18
27
|
end
|
@@ -2,16 +2,20 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
2
|
require 'database_cleaner/active_record/transaction'
|
3
3
|
require 'database_cleaner/data_mapper/transaction'
|
4
4
|
|
5
|
+
|
5
6
|
describe DatabaseCleaner do
|
6
7
|
|
7
8
|
# These examples muck around with the constants for autodetection so we need to clean up....
|
8
9
|
before(:all) do
|
9
10
|
TempAR = ActiveRecord unless defined?(TempAR)
|
11
|
+
TempMM = MongoMapper unless defined?(TempMM)
|
12
|
+
Object.send(:remove_const, 'MongoMapper') if defined?(::MongoMapper)
|
10
13
|
# need to add one for each ORM that we load in the spec helper...
|
11
14
|
end
|
12
15
|
after(:all) do
|
13
16
|
Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord) #want to make sure we have the real one...
|
14
17
|
ActiveRecord = TempAR
|
18
|
+
MongoMapper = TempMM
|
15
19
|
end
|
16
20
|
|
17
21
|
before(:each) do
|
@@ -25,7 +29,6 @@ describe DatabaseCleaner do
|
|
25
29
|
it "should initialize and return the appropirate strategy" do
|
26
30
|
DatabaseCleaner::ActiveRecord::Transaction.should_receive(:new).with('options' => 'hash')
|
27
31
|
result = DatabaseCleaner.create_strategy(:transaction, {'options' => 'hash'})
|
28
|
-
|
29
32
|
result.should == @strategy
|
30
33
|
end
|
31
34
|
end
|
@@ -34,7 +37,6 @@ describe DatabaseCleaner do
|
|
34
37
|
it "should initialize the appropirate strategy and clean with it" do
|
35
38
|
DatabaseCleaner::ActiveRecord::Transaction.should_receive(:new).with('options' => 'hash')
|
36
39
|
@strategy.should_receive(:clean)
|
37
|
-
|
38
40
|
DatabaseCleaner.clean_with(:transaction, 'options' => 'hash')
|
39
41
|
end
|
40
42
|
end
|
@@ -55,6 +57,7 @@ describe DatabaseCleaner do
|
|
55
57
|
it "should raise an error when no ORM is detected" do
|
56
58
|
Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord)
|
57
59
|
Object.send(:remove_const, 'DataMapper') if defined?(::DataMapper)
|
60
|
+
Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
|
58
61
|
|
59
62
|
running { DatabaseCleaner.strategy = :transaction }.should raise_error(DatabaseCleaner::NoORMDetected)
|
60
63
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require 'database_cleaner/couch_potato/truncation'
|
3
|
+
require 'couch_potato'
|
4
|
+
|
5
|
+
module DatabaseCleaner
|
6
|
+
module CouchPotato
|
7
|
+
|
8
|
+
describe Truncation do
|
9
|
+
before(:each) do
|
10
|
+
@database = mock('database')
|
11
|
+
::CouchPotato.stub!(:couchrest_database).and_return(@database)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should re-create the database" do
|
15
|
+
@database.should_receive(:recreate!)
|
16
|
+
|
17
|
+
Truncation.new.clean
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should raise an error when the :only option is used" do
|
21
|
+
running {
|
22
|
+
Truncation.new(:only => ['document-type'])
|
23
|
+
}.should raise_error(ArgumentError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should raise an error when the :except option is used" do
|
27
|
+
running {
|
28
|
+
Truncation.new(:except => ['document-type'])
|
29
|
+
}.should raise_error(ArgumentError)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should raise an error when invalid options are provided" do
|
33
|
+
running {
|
34
|
+
Truncation.new(:foo => 'bar')
|
35
|
+
}.should raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require 'mongomapper'
|
3
|
+
require 'database_cleaner/mongo_mapper/truncation'
|
4
|
+
|
5
|
+
MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
|
6
|
+
TEST_DATABASE = 'database_cleaner_specs'
|
7
|
+
MongoMapper.database = TEST_DATABASE
|
8
|
+
|
9
|
+
class Widget
|
10
|
+
include MongoMapper::Document
|
11
|
+
key :name, String
|
12
|
+
end
|
13
|
+
class Gadget
|
14
|
+
include MongoMapper::Document
|
15
|
+
key :name, String
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
module DatabaseCleaner
|
20
|
+
module MongoMapper
|
21
|
+
|
22
|
+
describe Truncation do
|
23
|
+
before(:each) do
|
24
|
+
::MongoMapper.connection.drop_database(TEST_DATABASE)
|
25
|
+
#::MongoMapper.connection.db(TEST_DATABASE).collections.each {|c| c.remove }
|
26
|
+
#::MongoMapper.database = TEST_DATABASE
|
27
|
+
end
|
28
|
+
|
29
|
+
def ensure_counts(expected_counts)
|
30
|
+
# I had to add this sanity_check garbage because I was getting non-determinisc results from mongomapper at times..
|
31
|
+
# very odd and disconcerting...
|
32
|
+
sanity_check = expected_counts.delete(:sanity_check)
|
33
|
+
begin
|
34
|
+
expected_counts.each do |model_class, expected_count|
|
35
|
+
model_class.count.should equal(expected_count), "#{model_class} expected to have a count of #{expected_count} but was #{model_class.count}"
|
36
|
+
end
|
37
|
+
rescue Spec::Expectations::ExpectationNotMetError => e
|
38
|
+
raise !sanity_check ? e : Spec::ExpectationNotMetError::ExpectationNotMetError.new("SANITY CHECK FAILURE! This should never happen here: #{e.message}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_widget(attrs={})
|
43
|
+
Widget.new({:name => 'some widget'}.merge(attrs)).save!
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_gadget(attrs={})
|
47
|
+
Gadget.new({:name => 'some gadget'}.merge(attrs)).save!
|
48
|
+
end
|
49
|
+
|
50
|
+
it "truncates all collections by default" do
|
51
|
+
create_widget
|
52
|
+
create_gadget
|
53
|
+
ensure_counts(Widget => 1, Gadget => 1, :sanity_check => true)
|
54
|
+
Truncation.new.clean
|
55
|
+
ensure_counts(Widget => 0, Gadget => 0)
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when collections are provided to the :only option" do
|
59
|
+
it "only truncates the specified collections" do
|
60
|
+
create_widget
|
61
|
+
create_gadget
|
62
|
+
ensure_counts(Widget => 1, Gadget => 1, :sanity_check => true)
|
63
|
+
Truncation.new(:only => ['widgets']).clean
|
64
|
+
ensure_counts(Widget => 0, Gadget => 1)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when collections are provided to the :except option" do
|
69
|
+
it "truncates all but the specified collections" do
|
70
|
+
create_widget
|
71
|
+
create_gadget
|
72
|
+
ensure_counts(Widget => 1, Gadget => 1, :sanity_check => true)
|
73
|
+
Truncation.new(:except => ['widgets']).clean
|
74
|
+
ensure_counts(Widget => 1, Gadget => 0)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: database_cleaner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Mabey
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-02-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -32,9 +32,10 @@ files:
|
|
32
32
|
- examples/features/example.feature
|
33
33
|
- examples/features/step_definitions/example_steps.rb
|
34
34
|
- examples/features/support/env.rb
|
35
|
-
- examples/lib/
|
36
|
-
- examples/lib/
|
37
|
-
- examples/lib/
|
35
|
+
- examples/lib/activerecord_models.rb
|
36
|
+
- examples/lib/couchpotato_models.rb
|
37
|
+
- examples/lib/datamapper_models.rb
|
38
|
+
- examples/lib/mongomapper_models.rb
|
38
39
|
- features/cleaning.feature
|
39
40
|
- features/step_definitions/database_cleaner_steps.rb
|
40
41
|
- features/support/env.rb
|
@@ -42,6 +43,7 @@ files:
|
|
42
43
|
- lib/database_cleaner/active_record/transaction.rb
|
43
44
|
- lib/database_cleaner/active_record/truncation.rb
|
44
45
|
- lib/database_cleaner/configuration.rb
|
46
|
+
- lib/database_cleaner/couch_potato/truncation.rb
|
45
47
|
- lib/database_cleaner/cucumber.rb
|
46
48
|
- lib/database_cleaner/data_mapper/transaction.rb
|
47
49
|
- lib/database_cleaner/data_mapper/truncation.rb
|
@@ -49,6 +51,8 @@ files:
|
|
49
51
|
- lib/database_cleaner/truncation_base.rb
|
50
52
|
- spec/database_cleaner/active_record/truncation_spec.rb
|
51
53
|
- spec/database_cleaner/configuration_spec.rb
|
54
|
+
- spec/database_cleaner/couch_potato/truncation_spec.rb
|
55
|
+
- spec/database_cleaner/mongo_mapper/truncation_spec.rb
|
52
56
|
- spec/spec.opts
|
53
57
|
- spec/spec_helper.rb
|
54
58
|
- LICENSE
|
@@ -84,9 +88,12 @@ summary: Strategies for cleaning databases. Can be used to ensure a clean state
|
|
84
88
|
test_files:
|
85
89
|
- spec/database_cleaner/active_record/truncation_spec.rb
|
86
90
|
- spec/database_cleaner/configuration_spec.rb
|
91
|
+
- spec/database_cleaner/couch_potato/truncation_spec.rb
|
92
|
+
- spec/database_cleaner/mongo_mapper/truncation_spec.rb
|
87
93
|
- spec/spec_helper.rb
|
88
94
|
- examples/features/step_definitions/example_steps.rb
|
89
95
|
- examples/features/support/env.rb
|
90
|
-
- examples/lib/
|
91
|
-
- examples/lib/
|
92
|
-
- examples/lib/
|
96
|
+
- examples/lib/activerecord_models.rb
|
97
|
+
- examples/lib/couchpotato_models.rb
|
98
|
+
- examples/lib/datamapper_models.rb
|
99
|
+
- examples/lib/mongomapper_models.rb
|
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'activerecord'
|
2
|
-
|
3
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
|
4
|
-
|
5
|
-
ActiveRecord::Schema.define(:version => 1) do
|
6
|
-
create_table :widgets do |t|
|
7
|
-
t.string :name
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class Widget < ActiveRecord::Base
|
12
|
-
end
|