database_cleaner 0.8.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
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