database_cleaner 0.5.2 → 0.6.0.rc.1

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