database_cleaner 0.5.2 → 0.6.0.rc.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 (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