surgical_strike 0.7.4

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 (81) hide show
  1. data/Gemfile.lock +163 -0
  2. data/History.txt +210 -0
  3. data/LICENSE +20 -0
  4. data/README.textile +229 -0
  5. data/TODO +3 -0
  6. data/VERSION.yml +5 -0
  7. data/cucumber.yml +1 -0
  8. data/examples/Gemfile +1 -0
  9. data/examples/Gemfile.lock +1 -0
  10. data/examples/config/database.yml.example +8 -0
  11. data/examples/db/sqlite_databases_go_here +0 -0
  12. data/examples/features/example.feature +11 -0
  13. data/examples/features/example_multiple_db.feature +23 -0
  14. data/examples/features/example_multiple_orm.feature +22 -0
  15. data/examples/features/step_definitions/activerecord_steps.rb +31 -0
  16. data/examples/features/step_definitions/couchpotato_steps.rb +31 -0
  17. data/examples/features/step_definitions/datamapper_steps.rb +37 -0
  18. data/examples/features/step_definitions/mongoid_steps.rb +23 -0
  19. data/examples/features/step_definitions/mongomapper_steps.rb +31 -0
  20. data/examples/features/step_definitions/translation_steps.rb +55 -0
  21. data/examples/features/support/env.rb +62 -0
  22. data/examples/lib/activerecord_models.rb +41 -0
  23. data/examples/lib/couchpotato_models.rb +61 -0
  24. data/examples/lib/datamapper_models.rb +50 -0
  25. data/examples/lib/mongoid_models.rb +49 -0
  26. data/examples/lib/mongomapper_models.rb +51 -0
  27. data/features/cleaning.feature +22 -0
  28. data/features/cleaning_default_strategy.feature +19 -0
  29. data/features/cleaning_multiple_dbs.feature +21 -0
  30. data/features/cleaning_multiple_orms.feature +29 -0
  31. data/features/step_definitions/database_cleaner_steps.rb +32 -0
  32. data/features/support/env.rb +7 -0
  33. data/features/support/feature_runner.rb +39 -0
  34. data/lib/database_cleaner/active_record/base.rb +53 -0
  35. data/lib/database_cleaner/active_record/deletion.rb +67 -0
  36. data/lib/database_cleaner/active_record/surgicalstrike.rb +65 -0
  37. data/lib/database_cleaner/active_record/transaction.rb +28 -0
  38. data/lib/database_cleaner/active_record/truncation.rb +152 -0
  39. data/lib/database_cleaner/base.rb +138 -0
  40. data/lib/database_cleaner/configuration.rb +94 -0
  41. data/lib/database_cleaner/couch_potato/base.rb +7 -0
  42. data/lib/database_cleaner/couch_potato/truncation.rb +28 -0
  43. data/lib/database_cleaner/cucumber.rb +11 -0
  44. data/lib/database_cleaner/data_mapper/base.rb +21 -0
  45. data/lib/database_cleaner/data_mapper/transaction.rb +26 -0
  46. data/lib/database_cleaner/data_mapper/truncation.rb +175 -0
  47. data/lib/database_cleaner/generic/base.rb +12 -0
  48. data/lib/database_cleaner/generic/surgicalstrike.rb +47 -0
  49. data/lib/database_cleaner/generic/truncation.rb +37 -0
  50. data/lib/database_cleaner/mongo/truncation.rb +22 -0
  51. data/lib/database_cleaner/mongo_mapper/base.rb +20 -0
  52. data/lib/database_cleaner/mongo_mapper/truncation.rb +19 -0
  53. data/lib/database_cleaner/mongoid/base.rb +20 -0
  54. data/lib/database_cleaner/mongoid/truncation.rb +20 -0
  55. data/lib/database_cleaner/null_strategy.rb +15 -0
  56. data/lib/database_cleaner/sequel/base.rb +22 -0
  57. data/lib/database_cleaner/sequel/transaction.rb +25 -0
  58. data/lib/database_cleaner/sequel/truncation.rb +50 -0
  59. data/lib/surgical_strike.rb +3 -0
  60. data/spec/database_cleaner/active_record/base_spec.rb +144 -0
  61. data/spec/database_cleaner/active_record/transaction_spec.rb +77 -0
  62. data/spec/database_cleaner/active_record/truncation_spec.rb +76 -0
  63. data/spec/database_cleaner/base_spec.rb +493 -0
  64. data/spec/database_cleaner/configuration_spec.rb +294 -0
  65. data/spec/database_cleaner/couch_potato/truncation_spec.rb +41 -0
  66. data/spec/database_cleaner/data_mapper/base_spec.rb +30 -0
  67. data/spec/database_cleaner/data_mapper/transaction_spec.rb +23 -0
  68. data/spec/database_cleaner/data_mapper/truncation_spec.rb +11 -0
  69. data/spec/database_cleaner/generic/base_spec.rb +22 -0
  70. data/spec/database_cleaner/generic/truncation_spec.rb +78 -0
  71. data/spec/database_cleaner/mongo_mapper/base_spec.rb +33 -0
  72. data/spec/database_cleaner/mongo_mapper/mongo_examples.rb +8 -0
  73. data/spec/database_cleaner/mongo_mapper/truncation_spec.rb +74 -0
  74. data/spec/database_cleaner/sequel/base_spec.rb +32 -0
  75. data/spec/database_cleaner/sequel/transaction_spec.rb +21 -0
  76. data/spec/database_cleaner/sequel/truncation_spec.rb +13 -0
  77. data/spec/database_cleaner/shared_strategy_spec.rb +13 -0
  78. data/spec/rcov.opts +1 -0
  79. data/spec/spec.opts +7 -0
  80. data/spec/spec_helper.rb +19 -0
  81. metadata +162 -0
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'database_cleaner/active_record/transaction'
3
+ require 'active_record'
4
+
5
+ module DatabaseCleaner
6
+ module ActiveRecord
7
+
8
+ describe Transaction do
9
+ let (:connection) { mock("connection") }
10
+ before(:each) do
11
+ ::ActiveRecord::Base.stub!(:connection).and_return(connection)
12
+ end
13
+
14
+ describe "#start" do
15
+ it "should increment open transactions if possible" do
16
+ connection.stub!(:respond_to?).with(:increment_open_transactions).and_return(true)
17
+ connection.stub!(:begin_db_transaction)
18
+
19
+ connection.should_receive(:increment_open_transactions)
20
+ Transaction.new.start
21
+ end
22
+
23
+ it "should tell ActiveRecord to increment connection if its not possible to increment current connection" do
24
+ connection.stub!(:respond_to?).with(:increment_open_transactions).and_return(false)
25
+ connection.stub!(:begin_db_transaction)
26
+
27
+ ::ActiveRecord::Base.should_receive(:increment_open_transactions)
28
+ Transaction.new.start
29
+ end
30
+
31
+ it "should start a transaction" do
32
+ connection.stub!(:increment_open_transactions)
33
+
34
+ connection.should_receive(:begin_db_transaction)
35
+ Transaction.new.start
36
+ end
37
+ end
38
+
39
+ describe "#clean" do
40
+ it "should start a transaction" do
41
+ connection.should_receive(:open_transactions).and_return(1)
42
+
43
+ connection.stub!(:decrement_open_transactions)
44
+
45
+ connection.should_receive(:rollback_db_transaction)
46
+ Transaction.new.clean
47
+ end
48
+
49
+ it "should decrement open transactions if possible" do
50
+ connection.should_receive(:open_transactions).and_return(1)
51
+
52
+ connection.stub!(:respond_to?).with(:decrement_open_transactions).and_return(true)
53
+ connection.stub!(:rollback_db_transaction)
54
+
55
+ connection.should_receive(:decrement_open_transactions)
56
+ Transaction.new.clean
57
+ end
58
+
59
+ it "should not try to decrement or rollback if open_transactions is 0 for whatever reason" do
60
+ connection.should_receive(:open_transactions).and_return(0)
61
+
62
+ Transaction.new.clean
63
+ end
64
+
65
+ it "should decrement connection via ActiveRecord::Base if connection won't" do
66
+ connection.should_receive(:open_transactions).and_return(1)
67
+ connection.stub!(:respond_to?).with(:decrement_open_transactions).and_return(false)
68
+ connection.stub!(:rollback_db_transaction)
69
+
70
+ ::ActiveRecord::Base.should_receive(:decrement_open_transactions)
71
+ Transaction.new.clean
72
+ end
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'active_record'
3
+ require 'database_cleaner/active_record/truncation'
4
+
5
+
6
+ module ActiveRecord
7
+ module ConnectionAdapters
8
+ [MysqlAdapter, Mysql2Adapter, SQLite3Adapter, JdbcAdapter, PostgreSQLAdapter, IBM_DBAdapter].each do |adapter|
9
+ describe adapter, "#truncate_table" do
10
+ it "responds" do
11
+ adapter.new("foo").should respond_to(:truncate_table)
12
+ end
13
+ it "should truncate the table"
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ module DatabaseCleaner
20
+ module ActiveRecord
21
+
22
+ describe Truncation do
23
+ let(:connection) { mock('connection') }
24
+
25
+
26
+ before(:each) do
27
+ connection.stub!(:disable_referential_integrity).and_yield
28
+ connection.stub!(:views).and_return([])
29
+ ::ActiveRecord::Base.stub!(:connection).and_return(connection)
30
+ end
31
+
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
38
+
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])
41
+
42
+ connection.should_receive(:truncate_tables).with(['widgets'])
43
+
44
+ Truncation.new(:only => ['widgets']).clean
45
+ end
46
+
47
+ it "should not truncate the tables specified in the :except option" do
48
+ connection.stub!(:tables).and_return(%w[schema_migrations widgets dogs])
49
+
50
+ connection.should_receive(:truncate_tables).with(['dogs'])
51
+
52
+ Truncation.new(:except => ['widgets']).clean
53
+ end
54
+
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
60
+
61
+ it "should raise an error when invalid options are provided" do
62
+ running { Truncation.new(:foo => 'bar') }.should raise_error(ArgumentError)
63
+ end
64
+
65
+ it "should not truncate views" do
66
+ connection.stub!(:tables).and_return(%w[widgets dogs])
67
+ connection.stub!(:views).and_return(["widgets"])
68
+
69
+ connection.should_receive(:truncate_tables).with(['dogs'])
70
+
71
+ Truncation.new.clean
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,493 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'database_cleaner/active_record/transaction'
3
+ require 'database_cleaner/data_mapper/transaction'
4
+ require 'database_cleaner/mongo_mapper/truncation'
5
+ require 'database_cleaner/mongoid/truncation'
6
+ require 'database_cleaner/couch_potato/truncation'
7
+
8
+ module DatabaseCleaner
9
+ describe Base do
10
+
11
+ describe "autodetect" do
12
+
13
+ #Cache all ORMs, we'll need them later but not now.
14
+ before(:all) do
15
+ Temp_AR = ::ActiveRecord if defined?(::ActiveRecord) and not defined?(Temp_AR)
16
+ Temp_DM = ::DataMapper if defined?(::DataMapper) and not defined?(Temp_DM)
17
+ Temp_MM = ::MongoMapper if defined?(::MongoMapper) and not defined?(Temp_MM)
18
+ Temp_MO = ::Mongoid if defined?(::Mongoid) and not defined?(Temp_MO)
19
+ Temp_CP = ::CouchPotato if defined?(::CouchPotato) and not defined?(Temp_CP)
20
+ Temp_SQ = ::Sequel if defined?(::Sequel) and not defined?(Temp_SQ)
21
+ end
22
+
23
+ #Remove all ORM mocks and restore from cache
24
+ after(:all) do
25
+ Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord)
26
+ Object.send(:remove_const, 'DataMapper') if defined?(::DataMapper)
27
+ Object.send(:remove_const, 'MongoMapper') if defined?(::MongoMapper)
28
+ Object.send(:remove_const, 'Mongoid') if defined?(::Mongoid)
29
+ Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
30
+ Object.send(:remove_const, 'Sequel') if defined?(::Sequel)
31
+
32
+
33
+ # Restore ORMs
34
+ ::ActiveRecord = Temp_AR if defined? Temp_AR
35
+ ::DataMapper = Temp_DM if defined? Temp_DM
36
+ ::MongoMapper = Temp_MM if defined? Temp_MM
37
+ ::Mongoid = Temp_MO if defined? Temp_MO
38
+ ::CouchPotato = Temp_CP if defined? Temp_CP
39
+ end
40
+
41
+ #reset the orm mocks
42
+ before(:each) do
43
+ Object.send(:remove_const, 'ActiveRecord') if defined?(::ActiveRecord)
44
+ Object.send(:remove_const, 'DataMapper') if defined?(::DataMapper)
45
+ Object.send(:remove_const, 'MongoMapper') if defined?(::MongoMapper)
46
+ Object.send(:remove_const, 'Mongoid') if defined?(::Mongoid)
47
+ Object.send(:remove_const, 'CouchPotato') if defined?(::CouchPotato)
48
+ Object.send(:remove_const, 'Sequel') if defined?(::Sequel)
49
+ end
50
+
51
+ let(:cleaner) { DatabaseCleaner::Base.new :autodetect }
52
+
53
+ it "should raise an error when no ORM is detected" do
54
+ running { cleaner }.should raise_error(DatabaseCleaner::NoORMDetected)
55
+ end
56
+
57
+ it "should detect ActiveRecord first" do
58
+ Object.const_set('ActiveRecord','Actively mocking records.')
59
+ Object.const_set('DataMapper', 'Mapping data mocks')
60
+ Object.const_set('MongoMapper', 'Mapping mock mongos')
61
+ Object.const_set('Mongoid', 'Mongoid mock')
62
+ Object.const_set('CouchPotato', 'Couching mock potatos')
63
+ Object.const_set('Sequel', 'Sequel mock')
64
+
65
+ cleaner.orm.should == :active_record
66
+ cleaner.should be_auto_detected
67
+ end
68
+
69
+ it "should detect DataMapper second" do
70
+ Object.const_set('DataMapper', 'Mapping data mocks')
71
+ Object.const_set('MongoMapper', 'Mapping mock mongos')
72
+ Object.const_set('Mongoid', 'Mongoid mock')
73
+ Object.const_set('CouchPotato', 'Couching mock potatos')
74
+ Object.const_set('Sequel', 'Sequel mock')
75
+
76
+ cleaner.orm.should == :data_mapper
77
+ cleaner.should be_auto_detected
78
+ end
79
+
80
+ it "should detect MongoMapper third" do
81
+ Object.const_set('MongoMapper', 'Mapping mock mongos')
82
+ Object.const_set('Mongoid', 'Mongoid mock')
83
+ Object.const_set('CouchPotato', 'Couching mock potatos')
84
+ Object.const_set('Sequel', 'Sequel mock')
85
+
86
+ cleaner.orm.should == :mongo_mapper
87
+ cleaner.should be_auto_detected
88
+ end
89
+
90
+ it "should detect Mongoid fourth" do
91
+ Object.const_set('Mongoid', 'Mongoid mock')
92
+ Object.const_set('CouchPotato', 'Couching mock potatos')
93
+ Object.const_set('Sequel', 'Sequel mock')
94
+
95
+ cleaner.orm.should == :mongoid
96
+ cleaner.should be_auto_detected
97
+ end
98
+
99
+ it "should detect CouchPotato fifth" do
100
+ Object.const_set('CouchPotato', 'Couching mock potatos')
101
+ Object.const_set('Sequel', 'Sequel mock')
102
+
103
+ cleaner.orm.should == :couch_potato
104
+ cleaner.should be_auto_detected
105
+ end
106
+
107
+ it "should detect Sequel last" do
108
+ Object.const_set('Sequel', 'Sequel mock')
109
+
110
+ cleaner.orm.should == :sequel
111
+ cleaner.should be_auto_detected
112
+ end
113
+ end
114
+
115
+ describe "orm_module" do
116
+ it "should ask ::DatabaseCleaner what the module is for its orm" do
117
+ orm = mock("orm")
118
+ mockule = mock("module")
119
+
120
+ cleaner = ::DatabaseCleaner::Base.new
121
+ cleaner.should_receive(:orm).and_return(orm)
122
+
123
+ ::DatabaseCleaner.should_receive(:orm_module).with(orm).and_return(mockule)
124
+
125
+ cleaner.send(:orm_module).should == mockule
126
+ end
127
+ end
128
+
129
+ describe "comparison" do
130
+ it "should be equal if orm, connection and strategy are the same" do
131
+ strategy = mock("strategy")
132
+
133
+ one = DatabaseCleaner::Base.new(:active_record,:connection => :default)
134
+ one.strategy = strategy
135
+
136
+ two = DatabaseCleaner::Base.new(:active_record,:connection => :default)
137
+ two.strategy = strategy
138
+
139
+ one.should == two
140
+ two.should == one
141
+ end
142
+ end
143
+
144
+ describe "initialization" do
145
+ context "db specified" do
146
+ subject { ::DatabaseCleaner::Base.new(:active_record,:connection => :my_db) }
147
+
148
+ it "should store db from :connection in params hash" do
149
+ subject.db.should == :my_db
150
+ end
151
+ end
152
+
153
+ describe "orm" do
154
+ it "should store orm" do
155
+ cleaner = ::DatabaseCleaner::Base.new :a_orm
156
+ cleaner.orm.should == :a_orm
157
+ end
158
+
159
+ it "converts string to symbols" do
160
+ cleaner = ::DatabaseCleaner::Base.new "mongoid"
161
+ cleaner.orm.should == :mongoid
162
+ end
163
+
164
+ it "is autodetected if orm is not provided" do
165
+ cleaner = ::DatabaseCleaner::Base.new
166
+ cleaner.should be_auto_detected
167
+ end
168
+
169
+ it "is autodetected if you specify :autodetect" do
170
+ cleaner = ::DatabaseCleaner::Base.new "autodetect"
171
+ cleaner.should be_auto_detected
172
+ end
173
+
174
+ it "should default to autodetect upon initalisation" do
175
+ subject.should be_auto_detected
176
+ end
177
+ end
178
+ end
179
+
180
+ describe "db" do
181
+ it "should default to :default" do
182
+ subject.db.should == :default
183
+ end
184
+
185
+ it "should return any stored db value" do
186
+ subject.stub(:strategy_db=)
187
+ subject.db = :test_db
188
+ subject.db.should == :test_db
189
+ end
190
+
191
+ it "should pass db to any specified strategy" do
192
+ subject.should_receive(:strategy_db=).with(:a_new_db)
193
+ subject.db = :a_new_db
194
+ end
195
+ end
196
+
197
+ describe "strategy_db=" do
198
+ let(:strategy) { mock("strategy") }
199
+
200
+ before(:each) do
201
+ subject.strategy = strategy
202
+ end
203
+
204
+ it "should check that strategy supports db specification" do
205
+ strategy.should_receive(:respond_to?).with(:db=).and_return(true)
206
+ strategy.stub(:db=)
207
+ subject.strategy_db = :a_db
208
+ end
209
+
210
+ context "when strategy supports db specification" do
211
+ before(:each) { strategy.stub(:respond_to?).with(:db=).and_return true }
212
+
213
+ it "should pass db to the strategy" do
214
+ strategy.should_receive(:db=).with(:a_db)
215
+ subject.strategy_db = :a_db
216
+ end
217
+ end
218
+
219
+ context "when strategy doesn't supports db specification" do
220
+ before(:each) { strategy.stub(:respond_to?).with(:db=).and_return false }
221
+
222
+ it "should check to see if db is :default" do
223
+ db = mock("default")
224
+ db.should_receive(:==).with(:default).and_return(true)
225
+
226
+ subject.strategy_db = db
227
+ end
228
+
229
+ it "should raise an argument error when db isn't default" do
230
+ db = mock("a db")
231
+ expect{ subject.strategy_db = db }.to raise_error ArgumentError
232
+ end
233
+ end
234
+ end
235
+
236
+ describe "clean_with" do
237
+ let (:strategy) { mock("strategy",:clean => true) }
238
+
239
+ before(:each) { subject.stub(:create_strategy).with(anything).and_return(strategy) }
240
+
241
+ it "should pass all arguments to create_strategy" do
242
+ subject.should_receive(:create_strategy).with(:lorum, :dollar, :amet, :ipsum => "random").and_return(strategy)
243
+ subject.clean_with :lorum, :dollar, :amet, { :ipsum => "random" }
244
+ end
245
+
246
+ it "should invoke clean on the created strategy" do
247
+ strategy.should_receive(:clean)
248
+ subject.clean_with :strategy
249
+ end
250
+
251
+ it "should return the strategy" do
252
+ subject.clean_with( :strategy ).should == strategy
253
+ end
254
+ end
255
+
256
+ describe "clean_with!" do
257
+ let (:strategy) { mock("strategy",:clean => true) }
258
+
259
+ before(:each) { subject.stub(:create_strategy).with(anything).and_return(strategy) }
260
+
261
+ it "should pass all arguments to create_strategy" do
262
+ subject.should_receive(:create_strategy).with(:lorum, :dollar, :amet, :ipsum => "random").and_return(strategy)
263
+ subject.clean_with! :lorum, :dollar, :amet, { :ipsum => "random" }
264
+ end
265
+
266
+ it "should invoke clean on the created strategy" do
267
+ strategy.should_receive(:clean)
268
+ subject.clean_with! :strategy
269
+ end
270
+
271
+ it "should return the strategy" do
272
+ subject.clean_with!( :strategy ).should == strategy
273
+ end
274
+ end
275
+
276
+ describe "create_strategy" do
277
+ let(:klass) { mock("klass",:new => mock("instance")) }
278
+
279
+ before :each do
280
+ subject.stub(:orm_strategy).and_return(klass)
281
+ end
282
+
283
+ it "should pass the first argument to orm_strategy" do
284
+ subject.should_receive(:orm_strategy).with(:strategy).and_return(Object)
285
+ subject.create_strategy :strategy
286
+ end
287
+ it "should pass the remainding argument to orm_strategy.new" do
288
+ klass.should_receive(:new).with(:params => {:lorum => "ipsum"})
289
+
290
+ subject.create_strategy :strategy, {:params => {:lorum => "ipsum"}}
291
+ end
292
+ it "should return the resulting strategy" do
293
+ subject.create_strategy( :strategy ).should == klass.new
294
+ end
295
+ end
296
+
297
+ describe "strategy=" do
298
+ let(:mock_strategy) { mock("strategy") }
299
+
300
+ it "should proxy symbolised strategies to create_strategy" do
301
+ subject.should_receive(:create_strategy).with(:symbol)
302
+ subject.strategy = :symbol
303
+ end
304
+
305
+ it "should proxy params with symbolised strategies" do
306
+ subject.should_receive(:create_strategy).with(:symbol,:param => "one")
307
+ subject.strategy= :symbol, {:param => "one"}
308
+ end
309
+
310
+ it "should accept strategy objects" do
311
+ expect{ subject.strategy = mock_strategy }.to_not raise_error
312
+ end
313
+
314
+ it "should raise argument error when params given with strategy Object" do
315
+ expect{ subject.strategy = mock("object"), {:param => "one"} }.to raise_error ArgumentError
316
+ end
317
+
318
+ it "should attempt to set strategy db" do
319
+ subject.stub(:db).and_return(:my_db)
320
+ subject.should_receive(:strategy_db=).with(:my_db)
321
+ subject.strategy = mock_strategy
322
+ end
323
+
324
+ it "should return the stored strategy" do
325
+ result = subject.strategy = mock_strategy
326
+ result.should == mock_strategy
327
+ end
328
+ end
329
+
330
+ describe "strategy" do
331
+ subject { ::DatabaseCleaner::Base.new :a_orm }
332
+
333
+ it "returns a null strategy when strategy no set and undetectable" do
334
+ subject.instance_values["@strategy"] = nil
335
+ subject.strategy.should == DatabaseCleaner::NullStrategy
336
+ end
337
+
338
+ it "returns the set strategy" do
339
+ strategum = mock("strategy")
340
+ subject.strategy = strategum
341
+ subject.strategy.should == strategum
342
+ end
343
+ end
344
+
345
+ describe "orm=" do
346
+ it "should stored the desired orm" do
347
+ subject.orm.should_not == :desired_orm
348
+ subject.orm = :desired_orm
349
+ subject.orm.should == :desired_orm
350
+ end
351
+ end
352
+
353
+ describe "orm" do
354
+ let(:mock_orm) { mock("orm") }
355
+
356
+ it "should return orm if orm set" do
357
+ subject.instance_variable_set "@orm", mock_orm
358
+ subject.orm.should == mock_orm
359
+ end
360
+
361
+ context "orm isn't set" do
362
+ before(:each) { subject.instance_variable_set "@orm", nil }
363
+
364
+ it "should run autodetect if orm isn't set" do
365
+ subject.should_receive(:autodetect)
366
+ subject.orm
367
+ end
368
+
369
+ it "should return the result of autodetect if orm isn't set" do
370
+ subject.stub(:autodetect).and_return(mock_orm)
371
+ subject.orm.should == mock_orm
372
+ end
373
+ end
374
+ end
375
+
376
+ describe "proxy methods" do
377
+ let (:strategy) { mock("strategy") }
378
+
379
+ before(:each) do
380
+ subject.stub(:strategy).and_return(strategy)
381
+ end
382
+
383
+ describe "start" do
384
+ it "should proxy start to the strategy" do
385
+ strategy.should_receive(:start)
386
+ subject.start
387
+ end
388
+ end
389
+
390
+ describe "clean" do
391
+ it "should proxy clean to the strategy" do
392
+ strategy.should_receive(:clean)
393
+ subject.clean
394
+ end
395
+ end
396
+
397
+ describe "clean!" do
398
+ it "should proxy clean! to the strategy clean" do
399
+ strategy.should_receive(:clean)
400
+ subject.clean!
401
+ end
402
+ end
403
+ end
404
+
405
+ describe "auto_detected?" do
406
+ it "should return true unless @autodetected is nil" do
407
+ subject.instance_variable_set("@autodetected","not nil")
408
+ subject.auto_detected?.should be_true
409
+ end
410
+
411
+ it "should return false if @autodetect is nil" do
412
+ subject.instance_variable_set("@autodetected",nil)
413
+ subject.auto_detected?.should be_false
414
+ end
415
+ end
416
+
417
+ describe "orm_strategy" do
418
+ let (:klass) { mock("klass") }
419
+
420
+ before(:each) do
421
+ subject.stub(:orm_module).and_return(klass)
422
+ end
423
+
424
+ context "in response to a LoadError" do
425
+ before(:each) { subject.should_receive(:require).with(anything).and_raise(LoadError) }
426
+
427
+ it "should catch LoadErrors" do
428
+ expect { subject.send(:orm_strategy,:a_strategy) }.to_not raise_error LoadError
429
+ end
430
+
431
+ it "should raise UnknownStrategySpecified" do
432
+ expect { subject.send(:orm_strategy,:a_strategy) }.to raise_error UnknownStrategySpecified
433
+ end
434
+
435
+ it "should ask orm_module if it will list available_strategies" do
436
+ klass.should_receive(:respond_to?).with(:available_strategies)
437
+
438
+ subject.stub(:orm_module).and_return(klass)
439
+
440
+ expect { subject.send(:orm_strategy,:a_strategy) }.to raise_error UnknownStrategySpecified
441
+ end
442
+
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([])
446
+
447
+ subject.stub(:orm_module).and_return(klass)
448
+
449
+ expect { subject.send(:orm_strategy,:a_strategy) }.to raise_error UnknownStrategySpecified
450
+ end
451
+ end
452
+
453
+ it "should return the constant of the Strategy class requested" do
454
+ strategy_klass = mock("strategy klass")
455
+
456
+ subject.stub(:require).with(anything).and_return(true)
457
+
458
+ klass.should_receive(:const_get).with("Cunningplan").and_return(strategy_klass)
459
+
460
+ subject.send(:orm_strategy, :cunningplan).should == strategy_klass
461
+ end
462
+
463
+ end
464
+
465
+ describe 'set_default_orm_strategy' do
466
+ it 'sets strategy to :transaction for ActiveRecord' do
467
+ cleaner = DatabaseCleaner::Base.new(:active_record)
468
+ cleaner.strategy.should be_instance_of DatabaseCleaner::ActiveRecord::Transaction
469
+ end
470
+
471
+ it 'sets strategy to :transaction for DataMapper' do
472
+ cleaner = DatabaseCleaner::Base.new(:data_mapper)
473
+ cleaner.strategy.should be_instance_of DatabaseCleaner::DataMapper::Transaction
474
+ end
475
+
476
+ it 'sets strategy to :truncation for MongoMapper' do
477
+ cleaner = DatabaseCleaner::Base.new(:mongo_mapper)
478
+ cleaner.strategy.should be_instance_of DatabaseCleaner::MongoMapper::Truncation
479
+ end
480
+
481
+ it 'sets strategy to :truncation for Mongoid' do
482
+ cleaner = DatabaseCleaner::Base.new(:mongoid)
483
+ cleaner.strategy.should be_instance_of DatabaseCleaner::Mongoid::Truncation
484
+ end
485
+
486
+ it 'sets strategy to :truncation for CouchPotato' do
487
+ cleaner = DatabaseCleaner::Base.new(:couch_potato)
488
+ cleaner.strategy.should be_instance_of DatabaseCleaner::CouchPotato::Truncation
489
+ end
490
+ end
491
+
492
+ end
493
+ end