database_cleaner 0.8.0 → 0.9.1

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.
Files changed (57) hide show
  1. data/Gemfile.lock +150 -82
  2. data/History.txt +19 -1
  3. data/README.textile +61 -59
  4. data/Rakefile +7 -17
  5. data/VERSION.yml +3 -3
  6. data/examples/Gemfile +14 -20
  7. data/examples/Gemfile.lock +150 -82
  8. data/examples/features/step_definitions/translation_steps.rb +14 -14
  9. data/examples/features/support/env.rb +6 -2
  10. data/features/cleaning.feature +1 -1
  11. data/features/cleaning_default_strategy.feature +1 -1
  12. data/features/cleaning_multiple_dbs.feature +1 -2
  13. data/features/cleaning_multiple_orms.feature +7 -7
  14. data/features/support/env.rb +1 -1
  15. data/lib/database_cleaner/active_record/base.rb +26 -6
  16. data/lib/database_cleaner/active_record/deletion.rb +2 -2
  17. data/lib/database_cleaner/active_record/transaction.rb +9 -9
  18. data/lib/database_cleaner/active_record/truncation.rb +157 -50
  19. data/lib/database_cleaner/base.rb +2 -2
  20. data/lib/database_cleaner/configuration.rb +26 -3
  21. data/lib/database_cleaner/data_mapper/truncation.rb +2 -2
  22. data/lib/database_cleaner/generic/truncation.rb +7 -5
  23. data/lib/database_cleaner/mongo/base.rb +16 -0
  24. data/lib/database_cleaner/mongo/truncation.rb +9 -14
  25. data/lib/database_cleaner/mongo/truncation_mixin.rb +22 -0
  26. data/lib/database_cleaner/mongo_mapper/truncation.rb +2 -2
  27. data/lib/database_cleaner/mongoid/truncation.rb +2 -2
  28. data/lib/database_cleaner/moped/truncation.rb +6 -2
  29. data/lib/database_cleaner/sequel/truncation.rb +6 -6
  30. data/spec/database_cleaner/active_record/base_spec.rb +27 -15
  31. data/spec/database_cleaner/active_record/truncation/mysql2_spec.rb +40 -0
  32. data/spec/database_cleaner/active_record/truncation/mysql_spec.rb +40 -0
  33. data/spec/database_cleaner/active_record/truncation/postgresql_spec.rb +48 -0
  34. data/spec/database_cleaner/active_record/truncation/shared_fast_truncation.rb +40 -0
  35. data/spec/database_cleaner/active_record/truncation_spec.rb +102 -33
  36. data/spec/database_cleaner/base_spec.rb +14 -14
  37. data/spec/database_cleaner/configuration_spec.rb +15 -10
  38. data/spec/database_cleaner/data_mapper/base_spec.rb +1 -1
  39. data/spec/database_cleaner/data_mapper/transaction_spec.rb +1 -1
  40. data/spec/database_cleaner/data_mapper/truncation_spec.rb +1 -1
  41. data/spec/database_cleaner/generic/base_spec.rb +1 -1
  42. data/spec/database_cleaner/generic/truncation_spec.rb +35 -5
  43. data/spec/database_cleaner/mongo/mongo_examples.rb +26 -0
  44. data/spec/database_cleaner/mongo/truncation_spec.rb +72 -0
  45. data/spec/database_cleaner/mongo_mapper/base_spec.rb +1 -1
  46. data/spec/database_cleaner/sequel/base_spec.rb +1 -1
  47. data/spec/database_cleaner/sequel/transaction_spec.rb +1 -1
  48. data/spec/database_cleaner/sequel/truncation_spec.rb +1 -1
  49. data/spec/database_cleaner/{shared_strategy_spec.rb → shared_strategy.rb} +0 -0
  50. data/spec/spec_helper.rb +6 -4
  51. data/spec/support/active_record/database_setup.rb +4 -0
  52. data/spec/support/active_record/mysql2_setup.rb +38 -0
  53. data/spec/support/active_record/mysql_setup.rb +38 -0
  54. data/spec/support/active_record/postgresql_setup.rb +41 -0
  55. data/spec/support/active_record/schema_setup.rb +10 -0
  56. metadata +313 -46
  57. data/spec/spec.opts +0 -7
@@ -0,0 +1,40 @@
1
+ shared_examples_for "an adapter with pre-count truncation" do
2
+ describe "#pre_count_truncate_tables" do
3
+
4
+ context "with :reset_ids set true" do
5
+ it "truncates the table" do
6
+ 2.times { User.create }
7
+
8
+ connection.pre_count_truncate_tables(%w[users], :reset_ids => true)
9
+ User.count.should be_zero
10
+ end
11
+
12
+ it "resets AUTO_INCREMENT index of table" do
13
+ 2.times { User.create }
14
+ User.delete_all
15
+
16
+ connection.pre_count_truncate_tables(%w[users]) # true is also the default
17
+ User.create.id.should == 1
18
+ end
19
+ end
20
+
21
+
22
+ context "with :reset_ids set false" do
23
+ it "truncates the table" do
24
+ 2.times { User.create }
25
+
26
+ connection.pre_count_truncate_tables(%w[users], :reset_ids => false)
27
+ User.count.should be_zero
28
+ end
29
+
30
+ it "does not reset AUTO_INCREMENT index of table" do
31
+ 2.times { User.create }
32
+ User.delete_all
33
+
34
+ connection.pre_count_truncate_tables(%w[users], :reset_ids => false)
35
+
36
+ User.create.id.should == 3
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,16 +1,15 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
2
  require 'active_record'
3
- require 'database_cleaner/active_record/truncation'
4
3
 
4
+ require 'database_cleaner/active_record/truncation'
5
5
 
6
6
  module ActiveRecord
7
7
  module ConnectionAdapters
8
8
  [MysqlAdapter, Mysql2Adapter, SQLite3Adapter, JdbcAdapter, PostgreSQLAdapter, IBM_DBAdapter].each do |adapter|
9
9
  describe adapter, "#truncate_table" do
10
10
  it "responds" do
11
- adapter.new("foo").should respond_to(:truncate_table)
11
+ adapter.instance_methods.should include('truncate_table')
12
12
  end
13
- it "should truncate the table"
14
13
  end
15
14
  end
16
15
  end
@@ -22,55 +21,125 @@ module DatabaseCleaner
22
21
  describe Truncation do
23
22
  let(:connection) { mock('connection') }
24
23
 
25
-
26
24
  before(:each) do
27
25
  connection.stub!(:disable_referential_integrity).and_yield
28
- connection.stub!(:views).and_return([])
26
+ connection.stub!(:database_cleaner_view_cache).and_return([])
29
27
  ::ActiveRecord::Base.stub!(:connection).and_return(connection)
30
28
  end
31
29
 
32
- it "should truncate all tables except for schema_migrations" do
33
- connection.stub!(:tables).and_return(%w[schema_migrations widgets dogs])
34
-
35
- connection.should_receive(:truncate_tables).with(['widgets', 'dogs'])
36
- Truncation.new.clean
37
- end
30
+ describe '#clean' do
31
+ it "should truncate all tables except for schema_migrations" do
32
+ connection.stub!(:database_cleaner_table_cache).and_return(%w[schema_migrations widgets dogs])
38
33
 
39
- it "should only truncate the tables specified in the :only option when provided" do
40
- connection.stub!(:tables).and_return(%w[schema_migrations widgets dogs])
34
+ connection.should_receive(:truncate_tables).with(['widgets', 'dogs'])
35
+ Truncation.new.clean
36
+ end
41
37
 
42
- connection.should_receive(:truncate_tables).with(['widgets'])
38
+ it "should only truncate the tables specified in the :only option when provided" do
39
+ connection.stub!(:database_cleaner_table_cache).and_return(%w[schema_migrations widgets dogs])
43
40
 
44
- Truncation.new(:only => ['widgets']).clean
45
- end
41
+ connection.should_receive(:truncate_tables).with(['widgets'])
46
42
 
47
- it "should not truncate the tables specified in the :except option" do
48
- connection.stub!(:tables).and_return(%w[schema_migrations widgets dogs])
43
+ Truncation.new(:only => ['widgets']).clean
44
+ end
49
45
 
50
- connection.should_receive(:truncate_tables).with(['dogs'])
46
+ it "should not truncate the tables specified in the :except option" do
47
+ connection.stub!(:database_cleaner_table_cache).and_return(%w[schema_migrations widgets dogs])
51
48
 
52
- Truncation.new(:except => ['widgets']).clean
53
- end
49
+ connection.should_receive(:truncate_tables).with(['dogs'])
54
50
 
55
- it "should raise an error when :only and :except options are used" do
56
- running {
57
- Truncation.new(:except => ['widgets'], :only => ['widgets'])
58
- }.should raise_error(ArgumentError)
59
- end
51
+ Truncation.new(:except => ['widgets']).clean
52
+ end
53
+
54
+ it "should raise an error when :only and :except options are used" do
55
+ running {
56
+ Truncation.new(:except => ['widgets'], :only => ['widgets'])
57
+ }.should raise_error(ArgumentError)
58
+ end
59
+
60
+ it "should raise an error when invalid options are provided" do
61
+ running { Truncation.new(:foo => 'bar') }.should raise_error(ArgumentError)
62
+ end
63
+
64
+ it "should not truncate views" do
65
+ connection.stub!(:database_cleaner_table_cache).and_return(%w[widgets dogs])
66
+ connection.stub!(:database_cleaner_view_cache).and_return(["widgets"])
67
+
68
+ connection.should_receive(:truncate_tables).with(['dogs'])
69
+
70
+ Truncation.new.clean
71
+ end
60
72
 
61
- it "should raise an error when invalid options are provided" do
62
- running { Truncation.new(:foo => 'bar') }.should raise_error(ArgumentError)
73
+ describe "relying on #pre_count_truncate_tables if connection allows it" do
74
+ subject { Truncation.new }
75
+
76
+ it "should rely on #pre_count_truncate_tables if #pre_count? returns true" do
77
+ connection.stub!(:database_cleaner_table_cache).and_return(%w[widgets dogs])
78
+ connection.stub!(:database_cleaner_view_cache).and_return(["widgets"])
79
+
80
+ subject.instance_variable_set(:"@pre_count", true)
81
+
82
+ connection.should_not_receive(:truncate_tables).with(['dogs'])
83
+ connection.should_receive(:pre_count_truncate_tables).with(['dogs'], :reset_ids => true)
84
+
85
+ subject.clean
86
+ end
87
+
88
+ it "should not rely on #pre_count_truncate_tables if #pre_count? return false" do
89
+ connection.stub!(:database_cleaner_table_cache).and_return(%w[widgets dogs])
90
+ connection.stub!(:database_cleaner_view_cache).and_return(["widgets"])
91
+
92
+ subject.instance_variable_set(:"@pre_count", false)
93
+
94
+ connection.should_not_receive(:pre_count_truncate_tables).with(['dogs'], :reset_ids => true)
95
+ connection.should_receive(:truncate_tables).with(['dogs'])
96
+
97
+ subject.clean
98
+ end
99
+ end
63
100
  end
64
101
 
65
- it "should not truncate views" do
66
- connection.stub!(:tables).and_return(%w[widgets dogs])
67
- connection.stub!(:views).and_return(["widgets"])
102
+ describe '#pre_count?' do
103
+ before(:each) do
104
+ connection.stub!(:disable_referential_integrity).and_yield
105
+ connection.stub!(:database_cleaner_view_cache).and_return([])
106
+ ::ActiveRecord::Base.stub!(:connection).and_return(connection)
107
+ end
68
108
 
69
- connection.should_receive(:truncate_tables).with(['dogs'])
109
+ subject { Truncation.new }
110
+ its(:pre_count?) { should == false }
70
111
 
71
- Truncation.new.clean
112
+ it 'should return true if @reset_id is set and non false or nil' do
113
+ subject.instance_variable_set(:"@pre_count", true)
114
+ subject.send(:pre_count?).should == true
115
+ end
116
+
117
+ it 'should return false if @reset_id is set to false' do
118
+ subject.instance_variable_set(:"@pre_count", false)
119
+ subject.send(:pre_count?).should == false
120
+ end
72
121
  end
122
+
123
+ describe '#reset_ids?' do
124
+ before(:each) do
125
+ connection.stub!(:disable_referential_integrity).and_yield
126
+ connection.stub!(:database_cleaner_view_cache).and_return([])
127
+ ::ActiveRecord::Base.stub!(:connection).and_return(connection)
128
+ end
129
+
130
+ subject { Truncation.new }
131
+ its(:reset_ids?) { should == true }
73
132
 
133
+ it 'should return true if @reset_id is set and non false or nil' do
134
+ subject.instance_variable_set(:"@reset_ids", 'Something')
135
+ subject.send(:reset_ids?).should == true
136
+ end
137
+
138
+ it 'should return false if @reset_id is set to false' do
139
+ subject.instance_variable_set(:"@reset_ids", false)
140
+ subject.send(:reset_ids?).should == false
141
+ end
142
+ end
74
143
  end
75
144
  end
76
145
  end
@@ -274,10 +274,10 @@ module DatabaseCleaner
274
274
  end
275
275
 
276
276
  describe "create_strategy" do
277
- let(:klass) { mock("klass",:new => mock("instance")) }
277
+ let(:strategy_class) { mock("strategy_class",:new => mock("instance")) }
278
278
 
279
279
  before :each do
280
- subject.stub(:orm_strategy).and_return(klass)
280
+ subject.stub(:orm_strategy).and_return(strategy_class)
281
281
  end
282
282
 
283
283
  it "should pass the first argument to orm_strategy" do
@@ -285,12 +285,12 @@ module DatabaseCleaner
285
285
  subject.create_strategy :strategy
286
286
  end
287
287
  it "should pass the remainding argument to orm_strategy.new" do
288
- klass.should_receive(:new).with(:params => {:lorum => "ipsum"})
288
+ strategy_class.should_receive(:new).with(:params => {:lorum => "ipsum"})
289
289
 
290
290
  subject.create_strategy :strategy, {:params => {:lorum => "ipsum"}}
291
291
  end
292
292
  it "should return the resulting strategy" do
293
- subject.create_strategy( :strategy ).should == klass.new
293
+ subject.create_strategy( :strategy ).should == strategy_class.new
294
294
  end
295
295
  end
296
296
 
@@ -415,10 +415,10 @@ module DatabaseCleaner
415
415
  end
416
416
 
417
417
  describe "orm_strategy" do
418
- let (:klass) { mock("klass") }
418
+ let (:strategy_class) { mock("strategy_class") }
419
419
 
420
420
  before(:each) do
421
- subject.stub(:orm_module).and_return(klass)
421
+ subject.stub(:orm_module).and_return(strategy_class)
422
422
  end
423
423
 
424
424
  context "in response to a LoadError" do
@@ -433,31 +433,31 @@ module DatabaseCleaner
433
433
  end
434
434
 
435
435
  it "should ask orm_module if it will list available_strategies" do
436
- klass.should_receive(:respond_to?).with(:available_strategies)
436
+ strategy_class.should_receive(:respond_to?).with(:available_strategies)
437
437
 
438
- subject.stub(:orm_module).and_return(klass)
438
+ subject.stub(:orm_module).and_return(strategy_class)
439
439
 
440
440
  expect { subject.send(:orm_strategy,:a_strategy) }.to raise_error UnknownStrategySpecified
441
441
  end
442
442
 
443
443
  it "should use available_strategies (for the error message) if its available" do
444
- klass.stub(:respond_to?).with(:available_strategies).and_return(true)
445
- klass.should_receive(:available_strategies).and_return([])
444
+ strategy_class.stub(:respond_to?).with(:available_strategies).and_return(true)
445
+ strategy_class.should_receive(:available_strategies).and_return([])
446
446
 
447
- subject.stub(:orm_module).and_return(klass)
447
+ subject.stub(:orm_module).and_return(strategy_class)
448
448
 
449
449
  expect { subject.send(:orm_strategy,:a_strategy) }.to raise_error UnknownStrategySpecified
450
450
  end
451
451
  end
452
452
 
453
453
  it "should return the constant of the Strategy class requested" do
454
- strategy_klass = mock("strategy klass")
454
+ strategy_strategy_class = mock("strategy strategy_class")
455
455
 
456
456
  subject.stub(:require).with(anything).and_return(true)
457
457
 
458
- klass.should_receive(:const_get).with("Cunningplan").and_return(strategy_klass)
458
+ strategy_class.should_receive(:const_get).with("Cunningplan").and_return(strategy_strategy_class)
459
459
 
460
- subject.send(:orm_strategy, :cunningplan).should == strategy_klass
460
+ subject.send(:orm_strategy, :cunningplan).should == strategy_strategy_class
461
461
  end
462
462
 
463
463
  end
@@ -1,12 +1,20 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
+ module ArrayHelper
3
+ def zipmap(array, vals)
4
+ Hash[*(array.zip(vals).flatten)]
5
+ end
6
+ module_function :zipmap
7
+ end
2
8
 
3
9
  module DatabaseCleaner
4
10
  class << self
5
11
  def reset
12
+ @cleaners = nil
6
13
  @connections = nil
7
14
  end
8
-
15
+ # hackey, hack.. connections needs to stick around until I can properly deprecate the API
9
16
  def connections_stub!(array)
17
+ @cleaners = ArrayHelper.zipmap((1..array.size).to_a, array)
10
18
  @connections = array
11
19
  end
12
20
  end
@@ -17,7 +25,7 @@ describe ::DatabaseCleaner do
17
25
 
18
26
  context "orm specification" do
19
27
  it "should not accept unrecognised orms" do
20
- expect { ::DatabaseCleaner[nil] }.should raise_error(::DatabaseCleaner::NoORMDetected)
28
+ expect { ::DatabaseCleaner[nil] }.to raise_error(::DatabaseCleaner::NoORMDetected)
21
29
  end
22
30
 
23
31
  it "should accept :active_record" do
@@ -108,14 +116,11 @@ describe ::DatabaseCleaner do
108
116
  context "class methods" do
109
117
  subject { ::DatabaseCleaner }
110
118
 
111
- its(:connections) { should respond_to(:each) }
112
-
113
119
  it "should give me a default (autodetection) databasecleaner by default" do
114
120
  cleaner = mock("cleaner").as_null_object
115
- ::DatabaseCleaner::Base.should_receive(:new).with().and_return(cleaner)
116
-
117
- ::DatabaseCleaner.connections.should have(1).items
118
- ::DatabaseCleaner.connections.first.should == cleaner
121
+ ::DatabaseCleaner::Base.stub!(:new).and_return(cleaner)
122
+
123
+ ::DatabaseCleaner.connections.should == [cleaner]
119
124
  end
120
125
  end
121
126
 
@@ -197,7 +202,7 @@ describe ::DatabaseCleaner do
197
202
  # plausably want to force orm/strategy change on two sets of orm that differ only on db
198
203
  context "multiple orm proxy methods" do
199
204
 
200
- it "should proxy orm to all connections and remove duplicate connections" do
205
+ pending "should proxy orm to all connections and remove duplicate connections" do
201
206
  active_record_1 = mock("active_mock_on_db_one").as_null_object
202
207
  active_record_2 = mock("active_mock_on_db_two").as_null_object
203
208
  data_mapper_1 = mock("data_mock_on_db_one").as_null_object
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'database_cleaner/data_mapper/base'
3
- require 'database_cleaner/shared_strategy_spec'
3
+ require 'database_cleaner/shared_strategy'
4
4
 
5
5
  module DatabaseCleaner
6
6
  describe DataMapper do
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
2
  require 'database_cleaner/data_mapper/transaction'
3
- require 'database_cleaner/shared_strategy_spec'
3
+ require 'database_cleaner/shared_strategy'
4
4
  #require 'data_mapper'
5
5
 
6
6
  module DatabaseCleaner
@@ -1,5 +1,5 @@
1
1
  require 'database_cleaner/data_mapper/truncation'
2
- require 'database_cleaner/shared_strategy_spec'
2
+ require 'database_cleaner/shared_strategy'
3
3
 
4
4
  module DatabaseCleaner
5
5
  module DataMapper
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'database_cleaner/shared_strategy_spec'
2
+ require 'database_cleaner/shared_strategy'
3
3
  require 'database_cleaner/generic/base'
4
4
 
5
5
  module ::DatabaseCleaner
@@ -13,11 +13,19 @@ module ::DatabaseCleaner
13
13
  def except
14
14
  @tables_to_exclude
15
15
  end
16
+
17
+ def reset_ids?
18
+ !!@reset_ids
19
+ end
20
+
21
+ def pre_count?
22
+ !!@pre_count
23
+ end
16
24
  end
17
25
 
18
26
  class MigrationExample < TruncationExample
19
- def migration_storage_name
20
- "migration_storage_name"
27
+ def migration_storage_names
28
+ %w[migration_storage_name]
21
29
  end
22
30
  end
23
31
 
@@ -29,8 +37,8 @@ module ::DatabaseCleaner
29
37
  it { should_not respond_to(:tables_to_truncate) }
30
38
  its(:tables_to_truncate) { expect{ subject }.to raise_error(NotImplementedError) }
31
39
 
32
- it { should_not respond_to(:migration_storage_name) }
33
- its(:migration_storage_name) { should be_nil }
40
+ it { should_not respond_to(:migration_storage_names) }
41
+ its(:migration_storage_names) { should be_empty }
34
42
  end
35
43
 
36
44
  describe "initialize" do
@@ -44,6 +52,8 @@ module ::DatabaseCleaner
44
52
  it { expect{ TruncationExample.new( { :except => "something",:only => "something else" } ) }.to raise_error(ArgumentError) }
45
53
  it { expect{ TruncationExample.new( { :only => "something" } ) }.to_not raise_error(ArgumentError) }
46
54
  it { expect{ TruncationExample.new( { :except => "something" } ) }.to_not raise_error(ArgumentError) }
55
+ it { expect{ TruncationExample.new( { :pre_count => "something" } ) }.to_not raise_error(ArgumentError) }
56
+ it { expect{ TruncationExample.new( { :reset_ids => "something" } ) }.to_not raise_error(ArgumentError) }
47
57
 
48
58
  context "" do
49
59
  subject { TruncationExample.new( { :only => ["something"] } ) }
@@ -57,10 +67,30 @@ module ::DatabaseCleaner
57
67
  its(:except) { should include("something") }
58
68
  end
59
69
 
70
+ context "" do
71
+ subject { TruncationExample.new( { :reset_ids => ["something"] } ) }
72
+ its(:reset_ids?) { should == true }
73
+ end
74
+
75
+ context "" do
76
+ subject { TruncationExample.new( { :reset_ids => nil } ) }
77
+ its(:reset_ids?) { should == false }
78
+ end
79
+
80
+ context "" do
81
+ subject { TruncationExample.new( { :pre_count => ["something"] } ) }
82
+ its(:pre_count?) { should == true }
83
+ end
84
+
85
+ context "" do
86
+ subject { TruncationExample.new( { :pre_count => nil } ) }
87
+ its(:pre_count?) { should == false }
88
+ end
89
+
60
90
  context "" do
61
91
  subject { MigrationExample.new }
62
92
  its(:only) { should == nil }
63
- its(:except) { should == ["migration_storage_name"] }
93
+ its(:except) { should == %w[migration_storage_name] }
64
94
  end
65
95
 
66
96
  context "" do