database_cleaner 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +12 -0
- data/README.markdown +24 -14
- data/Rakefile +1 -1
- data/VERSION.yml +1 -1
- data/lib/database_cleaner/active_record/deletion.rb +7 -1
- data/lib/database_cleaner/active_record/transaction.rb +2 -2
- data/lib/database_cleaner/active_record/truncation.rb +10 -4
- data/lib/database_cleaner/base.rb +4 -0
- data/lib/database_cleaner/configuration.rb +6 -0
- data/lib/database_cleaner/cucumber.rb +2 -10
- data/lib/database_cleaner/data_mapper/truncation.rb +13 -3
- data/lib/database_cleaner/generic/base.rb +6 -0
- data/lib/database_cleaner/sequel/transaction.rb +15 -0
- data/spec/database_cleaner/active_record/transaction_spec.rb +3 -3
- data/spec/database_cleaner/base_spec.rb +13 -0
- data/spec/database_cleaner/configuration_spec.rb +27 -0
- data/spec/database_cleaner/sequel/truncation/sqlite3_spec.rb +0 -0
- data/spec/database_cleaner/sequel/truncation_spec.rb +131 -0
- data/spec/database_cleaner/shared_strategy.rb +2 -0
- data/spec/support/active_record/database_setup.rb +2 -0
- metadata +344 -6
data/History.rdoc
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
== 1.3.0 2014-05-23
|
2
|
+
|
3
|
+
=== New Features/Changes
|
4
|
+
* Introduced `DatabaseCleaener::cleaninng` method that takes a block. (@ethco)
|
5
|
+
* Improved Sequel support and added more tests (@ethco, @rhunter)
|
6
|
+
|
7
|
+
=== Bug Fixes
|
8
|
+
|
9
|
+
* Fixed an issue with the `Transaction` strategy and Active Record where application-level transactions
|
10
|
+
are not rolledback correctly. (Godfrey Chan)
|
11
|
+
* activerecord-oracle_enhanced-adapter now works again (#259, @sockmonk)
|
12
|
+
|
1
13
|
== 1.2.0 2013-10-09
|
2
14
|
|
3
15
|
A huge thanks goes to @tommeier for fixing the bug with class loading that was cuasing the wrong adapters
|
data/README.markdown
CHANGED
@@ -146,7 +146,7 @@ passed to [`keys`](http://redis.io/commands/keys)).
|
|
146
146
|
|
147
147
|
(I should point out the truncation strategy will never truncate your schema_migrations table.)
|
148
148
|
|
149
|
-
Some strategies
|
149
|
+
Some strategies need to be started before tests are run (for example the `:transaction` strategy needs to know to open up a transaction). This can be accomplished by calling `DatabaseCleaner.start` at the beginning of the run, or by running the tests inside a block to `Database.cleaning`. So you would have:
|
150
150
|
|
151
151
|
```ruby
|
152
152
|
require 'database_cleaner'
|
@@ -158,6 +158,12 @@ DatabaseCleaner.start # usually this is called in setup of a test
|
|
158
158
|
dirty_the_db
|
159
159
|
|
160
160
|
DatabaseCleaner.clean # cleanup of the test
|
161
|
+
|
162
|
+
# OR
|
163
|
+
|
164
|
+
DatabaseCleaner.cleaning do
|
165
|
+
dirty_the_db
|
166
|
+
end
|
161
167
|
```
|
162
168
|
|
163
169
|
At times you may want to do a single clean with one strategy.
|
@@ -196,12 +202,10 @@ RSpec.configure do |config|
|
|
196
202
|
DatabaseCleaner.clean_with(:truncation)
|
197
203
|
end
|
198
204
|
|
199
|
-
config.
|
200
|
-
DatabaseCleaner.
|
201
|
-
|
202
|
-
|
203
|
-
config.after(:each) do
|
204
|
-
DatabaseCleaner.clean
|
205
|
+
config.around(:each) do |example|
|
206
|
+
DatabaseCleaner.cleaning do
|
207
|
+
example.run
|
208
|
+
end
|
205
209
|
end
|
206
210
|
|
207
211
|
end
|
@@ -221,6 +225,13 @@ class MiniTest::Spec
|
|
221
225
|
DatabaseCleaner.clean
|
222
226
|
end
|
223
227
|
end
|
228
|
+
|
229
|
+
# with the minitest-around gem, this may be used instead:
|
230
|
+
class Minitest::Spec
|
231
|
+
around do |tests|
|
232
|
+
DatabaseCleaner.cleaning(&tests)
|
233
|
+
end
|
234
|
+
end
|
224
235
|
```
|
225
236
|
|
226
237
|
### Cucumber Example
|
@@ -239,12 +250,8 @@ rescue NameError
|
|
239
250
|
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
|
240
251
|
end
|
241
252
|
|
242
|
-
|
243
|
-
DatabaseCleaner.
|
244
|
-
end
|
245
|
-
|
246
|
-
After do |scenario|
|
247
|
-
DatabaseCleaner.clean
|
253
|
+
Around do |scenario, block|
|
254
|
+
DatabaseCleaner.cleaning(&block)
|
248
255
|
end
|
249
256
|
```
|
250
257
|
|
@@ -314,7 +321,7 @@ Usage beyond that remains the same with `DatabaseCleaner.start` calling any setu
|
|
314
321
|
<tr>
|
315
322
|
<td> Sequel</td>
|
316
323
|
<td> <code>DatabaseCleaner[:sequel]</code></td>
|
317
|
-
<td> Multiple databases supported; specify <code>
|
324
|
+
<td> Multiple databases supported; specify <code>DatabaseCleaner[:sequel, {:connection => Sequel.connect(uri)}]</code></td>
|
318
325
|
</tr>
|
319
326
|
<tr>
|
320
327
|
<td>Redis</td>
|
@@ -358,6 +365,9 @@ If you are using Postgres and have foreign key constraints, the truncation strat
|
|
358
365
|
client_min_messages = warning
|
359
366
|
```
|
360
367
|
|
368
|
+
### Nothing happens in JRuby with Sequel using transactions
|
369
|
+
|
370
|
+
Due to an inconsistency in JRuby's implementation of Fibers, Sequel gives a different connection to `DatabaseCleaner.start` than is used for tests run between `.start` and `.clean`. This can be worked around by running your tests in a block like `DatabaseCleaner.cleaning { run_my_tests }` instead, which does not use Fibers.
|
361
371
|
|
362
372
|
## Debugging
|
363
373
|
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ begin
|
|
14
14
|
s.description = "Strategies for cleaning databases. Can be used to ensure a clean state for testing."
|
15
15
|
s.files = FileList["[A-Z]*.*", "{examples,lib,features,spec}/**/*", "Rakefile", "cucumber.yml"]
|
16
16
|
s.authors = ["Ben Mabey"]
|
17
|
-
s.licence = 'MIT'
|
17
|
+
# s.licence = 'MIT'
|
18
18
|
end
|
19
19
|
rescue LoadError
|
20
20
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
data/VERSION.yml
CHANGED
@@ -17,6 +17,12 @@ module DatabaseCleaner
|
|
17
17
|
execute("DELETE FROM #{quote_table_name(table_name)};")
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
module OracleDeleteAdapter
|
22
|
+
def delete_table(table_name)
|
23
|
+
execute("DELETE FROM #{quote_table_name(table_name)}")
|
24
|
+
end
|
25
|
+
end
|
20
26
|
end
|
21
27
|
end
|
22
28
|
|
@@ -32,7 +38,7 @@ module ActiveRecord
|
|
32
38
|
PostgreSQLAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(PostgreSQLAdapter)
|
33
39
|
IBM_DBAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(IBM_DBAdapter)
|
34
40
|
SQLServerAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(SQLServerAdapter)
|
35
|
-
OracleEnhancedAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::
|
41
|
+
OracleEnhancedAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::OracleDeleteAdapter } if defined?(OracleEnhancedAdapter)
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
@@ -19,7 +19,7 @@ module DatabaseCleaner::ActiveRecord
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
if connection_class.connection.respond_to?(:begin_transaction)
|
22
|
-
connection_class.connection.begin_transaction
|
22
|
+
connection_class.connection.begin_transaction joinable: false
|
23
23
|
else
|
24
24
|
connection_class.connection.begin_db_transaction
|
25
25
|
end
|
@@ -36,7 +36,7 @@ module DatabaseCleaner::ActiveRecord
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# The below is for handling after_commit hooks.. see https://github.com/bmabey/database_cleaner/issues/99
|
39
|
-
if connection_class.connection.respond_to?(:rollback_transaction_records)
|
39
|
+
if connection_class.connection.respond_to?(:rollback_transaction_records, true)
|
40
40
|
connection_class.connection.send(:rollback_transaction_records, true)
|
41
41
|
end
|
42
42
|
|
@@ -114,13 +114,13 @@ module DatabaseCleaner
|
|
114
114
|
def truncate_table(table_name)
|
115
115
|
begin
|
116
116
|
execute("TRUNCATE TABLE #{quote_table_name(table_name)};")
|
117
|
-
rescue ActiveRecord::StatementInvalid
|
117
|
+
rescue ::ActiveRecord::StatementInvalid
|
118
118
|
execute("DELETE FROM #{quote_table_name(table_name)};")
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
module
|
123
|
+
module OracleAdapter
|
124
124
|
def truncate_table(table_name)
|
125
125
|
execute("TRUNCATE TABLE #{quote_table_name(table_name)}")
|
126
126
|
end
|
@@ -176,7 +176,13 @@ module ActiveRecord
|
|
176
176
|
#Apply adapter decoraters where applicable (adapter should be loaded)
|
177
177
|
AbstractAdapter.class_eval { include DatabaseCleaner::ConnectionAdapters::AbstractAdapter }
|
178
178
|
|
179
|
-
|
179
|
+
if defined?(JdbcAdapter)
|
180
|
+
if defined?(OracleJdbcConnection)
|
181
|
+
JdbcAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::OracleAdapter }
|
182
|
+
else
|
183
|
+
JdbcAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::TruncateOrDelete }
|
184
|
+
end
|
185
|
+
end
|
180
186
|
AbstractMysqlAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::AbstractMysqlAdapter } if defined?(AbstractMysqlAdapter)
|
181
187
|
Mysql2Adapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::AbstractMysqlAdapter } if defined?(Mysql2Adapter)
|
182
188
|
SQLiteAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::SQLiteAdapter } if defined?(SQLiteAdapter)
|
@@ -184,7 +190,7 @@ module ActiveRecord
|
|
184
190
|
PostgreSQLAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::PostgreSQLAdapter } if defined?(PostgreSQLAdapter)
|
185
191
|
IBM_DBAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::IBM_DBAdapter } if defined?(IBM_DBAdapter)
|
186
192
|
SQLServerAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::TruncateOrDelete } if defined?(SQLServerAdapter)
|
187
|
-
OracleEnhancedAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::
|
193
|
+
OracleEnhancedAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::OracleAdapter } if defined?(OracleEnhancedAdapter)
|
188
194
|
end
|
189
195
|
end
|
190
196
|
|
@@ -81,6 +81,12 @@ module DatabaseCleaner
|
|
81
81
|
|
82
82
|
alias clean! clean
|
83
83
|
|
84
|
+
def cleaning(&inner_block)
|
85
|
+
connections.inject(inner_block) do |curr_block, connection|
|
86
|
+
proc { connection.cleaning(&curr_block) }
|
87
|
+
end.call
|
88
|
+
end
|
89
|
+
|
84
90
|
def clean_with(*args)
|
85
91
|
connections.each { |connection| connection.clean_with(*args) }
|
86
92
|
end
|
@@ -1,11 +1,3 @@
|
|
1
|
-
|
2
|
-
DatabaseCleaner.
|
3
|
-
end
|
4
|
-
|
5
|
-
After do
|
6
|
-
begin
|
7
|
-
DatabaseCleaner.clean
|
8
|
-
rescue Exception => e
|
9
|
-
DatabaseCleaner.logger.error "Exception encountered by DatabaseCleaner in Cucumber After block: #{e}"
|
10
|
-
end
|
1
|
+
Around do |scenario, block|
|
2
|
+
DatabaseCleaner.cleaning(&block)
|
11
3
|
end
|
@@ -10,6 +10,12 @@ module DataMapper
|
|
10
10
|
raise NotImplementedError
|
11
11
|
end
|
12
12
|
|
13
|
+
def truncate_tables(table_names)
|
14
|
+
table_names.each do |table_name|
|
15
|
+
adapter.truncate_table table_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
13
19
|
end
|
14
20
|
|
15
21
|
class MysqlAdapter < DataObjectsAdapter
|
@@ -136,6 +142,12 @@ module DataMapper
|
|
136
142
|
execute("TRUNCATE TABLE #{quote_name(table_name)} RESTART IDENTITY CASCADE;")
|
137
143
|
end
|
138
144
|
|
145
|
+
# override to use a single statement
|
146
|
+
def truncate_tables(table_names)
|
147
|
+
quoted_names = table_names.collect { |n| quote_name(n) }.join(', ')
|
148
|
+
execute("TRUNCATE TABLE #{quoted_names} RESTART IDENTITY;")
|
149
|
+
end
|
150
|
+
|
139
151
|
# FIXME
|
140
152
|
# copied from activerecord
|
141
153
|
def supports_disable_referential_integrity?
|
@@ -177,9 +189,7 @@ module DatabaseCleaner
|
|
177
189
|
def clean(repository = self.db)
|
178
190
|
adapter = ::DataMapper.repository(repository).adapter
|
179
191
|
adapter.disable_referential_integrity do
|
180
|
-
tables_to_truncate(repository)
|
181
|
-
adapter.truncate_table table_name
|
182
|
-
end
|
192
|
+
adapter.truncate_tables(tables_to_truncate(repository))
|
183
193
|
end
|
184
194
|
end
|
185
195
|
|
@@ -4,7 +4,18 @@ module DatabaseCleaner
|
|
4
4
|
class Transaction
|
5
5
|
include ::DatabaseCleaner::Sequel::Base
|
6
6
|
|
7
|
+
def self.check_fiber_brokenness
|
8
|
+
if !@checked_fiber_brokenness && Fiber.new { Thread.current }.resume != Thread.current
|
9
|
+
raise RuntimeError, "This ruby engine's Fibers are not compatible with Sequel's connection pool. " +
|
10
|
+
"To work around this, please use DatabaseCleaner.cleaning with a block instead of " +
|
11
|
+
"DatabaseCleaner.start and DatabaseCleaner.clean"
|
12
|
+
end
|
13
|
+
@checked_fiber_brokenness = true
|
14
|
+
end
|
15
|
+
|
7
16
|
def start
|
17
|
+
self.class.check_fiber_brokenness
|
18
|
+
|
8
19
|
@fibers||= []
|
9
20
|
db= self.db
|
10
21
|
f= Fiber.new do
|
@@ -20,6 +31,10 @@ module DatabaseCleaner
|
|
20
31
|
f= @fibers.pop
|
21
32
|
f.resume
|
22
33
|
end
|
34
|
+
|
35
|
+
def cleaning
|
36
|
+
self.db.transaction(:rollback => :always, :savepoint => true) { yield }
|
37
|
+
end
|
23
38
|
end
|
24
39
|
end
|
25
40
|
end
|
@@ -58,7 +58,7 @@ module DatabaseCleaner
|
|
58
58
|
connection.should_receive(:open_transactions).and_return(1)
|
59
59
|
|
60
60
|
connection.stub(:respond_to?).with(:decrement_open_transactions).and_return(true)
|
61
|
-
connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
|
61
|
+
connection.stub(:respond_to?).with(:rollback_transaction_records, true).and_return(false)
|
62
62
|
connection.stub(:respond_to?).with(:rollback_transaction).and_return(false)
|
63
63
|
connection.stub(:rollback_db_transaction)
|
64
64
|
|
@@ -75,7 +75,7 @@ module DatabaseCleaner
|
|
75
75
|
it "should decrement connection via ActiveRecord::Base if connection won't" do
|
76
76
|
connection.should_receive(:open_transactions).and_return(1)
|
77
77
|
connection.stub(:respond_to?).with(:decrement_open_transactions).and_return(false)
|
78
|
-
connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
|
78
|
+
connection.stub(:respond_to?).with(:rollback_transaction_records, true).and_return(false)
|
79
79
|
connection.stub(:respond_to?).with(:rollback_transaction).and_return(false)
|
80
80
|
connection.stub(:rollback_db_transaction)
|
81
81
|
|
@@ -112,7 +112,7 @@ module DatabaseCleaner
|
|
112
112
|
|
113
113
|
it "should decrement connection via ActiveRecord::Base if connection won't" do
|
114
114
|
connection.should_receive(:open_transactions).and_return(1)
|
115
|
-
connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
|
115
|
+
connection.stub(:respond_to?).with(:rollback_transaction_records, true).and_return(false)
|
116
116
|
connection.stub(:respond_to?).with(:rollback_transaction).and_return(true)
|
117
117
|
connection.stub(:rollback_transaction)
|
118
118
|
|
@@ -42,6 +42,7 @@ module DatabaseCleaner
|
|
42
42
|
::MongoMapper = Temp_MM if defined? Temp_MM
|
43
43
|
::Mongoid = Temp_MO if defined? Temp_MO
|
44
44
|
::CouchPotato = Temp_CP if defined? Temp_CP
|
45
|
+
::Sequel = Temp_SQ if defined? Temp_SQ
|
45
46
|
::Moped = Temp_MP if defined? Temp_MP
|
46
47
|
::Ohm = Temp_OH if defined? Temp_OH
|
47
48
|
::Redis = Temp_RS if defined? Temp_RS
|
@@ -451,6 +452,13 @@ module DatabaseCleaner
|
|
451
452
|
subject.clean!
|
452
453
|
end
|
453
454
|
end
|
455
|
+
|
456
|
+
describe "cleaning" do
|
457
|
+
it "should proxy cleaning to the strategy" do
|
458
|
+
strategy.should_receive(:cleaning)
|
459
|
+
subject.cleaning { }
|
460
|
+
end
|
461
|
+
end
|
454
462
|
end
|
455
463
|
|
456
464
|
describe "auto_detected?" do
|
@@ -535,6 +543,11 @@ module DatabaseCleaner
|
|
535
543
|
cleaner.strategy.should be_instance_of DatabaseCleaner::CouchPotato::Truncation
|
536
544
|
end
|
537
545
|
|
546
|
+
it 'sets strategy to :transaction for Sequel' do
|
547
|
+
cleaner = DatabaseCleaner::Base.new(:sequel)
|
548
|
+
cleaner.strategy.should be_instance_of DatabaseCleaner::Sequel::Transaction
|
549
|
+
end
|
550
|
+
|
538
551
|
it 'sets strategy to :truncation for Moped' do
|
539
552
|
cleaner = DatabaseCleaner::Base.new(:moped)
|
540
553
|
cleaner.strategy.should be_instance_of DatabaseCleaner::Moped::Truncation
|
@@ -163,6 +163,11 @@ describe ::DatabaseCleaner do
|
|
163
163
|
::DatabaseCleaner.clean
|
164
164
|
end
|
165
165
|
|
166
|
+
it 'should proxy cleaning' do
|
167
|
+
connection.should_receive(:cleaning)
|
168
|
+
::DatabaseCleaner.cleaning { }
|
169
|
+
end
|
170
|
+
|
166
171
|
it "should proxy clean_with" do
|
167
172
|
stratagem = double("stratgem")
|
168
173
|
connection.should_receive(:clean_with).with(stratagem, {})
|
@@ -203,6 +208,28 @@ describe ::DatabaseCleaner do
|
|
203
208
|
::DatabaseCleaner.clean
|
204
209
|
end
|
205
210
|
|
211
|
+
it "should initiate cleaning on each connection, yield, and finish cleaning each connection" do
|
212
|
+
[active_record, data_mapper].each do |connection|
|
213
|
+
mc = class << connection; self; end
|
214
|
+
mc.send(:attr_reader, :started, :cleaned)
|
215
|
+
mc.send(:define_method, 'cleaning') do |&block|
|
216
|
+
@started = true
|
217
|
+
block.call
|
218
|
+
@cleaned = true
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
::DatabaseCleaner.cleaning do
|
223
|
+
active_record.started.should == true
|
224
|
+
data_mapper.started.should == true
|
225
|
+
active_record.cleaned.should == nil
|
226
|
+
data_mapper.cleaned.should == nil
|
227
|
+
@yielded = true
|
228
|
+
end
|
229
|
+
active_record.cleaned.should == true
|
230
|
+
data_mapper.cleaned.should == true
|
231
|
+
end
|
232
|
+
|
206
233
|
it "should proxy clean_with to all connections" do
|
207
234
|
stratagem = double("stratgem")
|
208
235
|
active_record.should_receive(:clean_with).with(stratagem)
|
File without changes
|
@@ -3,11 +3,142 @@ require 'database_cleaner/sequel/truncation'
|
|
3
3
|
require 'database_cleaner/shared_strategy'
|
4
4
|
require 'sequel'
|
5
5
|
|
6
|
+
# XXX: use ActiveRecord's db_config (`db/config.yml`) for CI/dev convenience
|
7
|
+
require 'support/active_record/database_setup'
|
8
|
+
|
6
9
|
module DatabaseCleaner
|
7
10
|
module Sequel
|
8
11
|
describe Truncation do
|
9
12
|
it_should_behave_like "a generic strategy"
|
10
13
|
it_should_behave_like "a generic truncation strategy"
|
11
14
|
end
|
15
|
+
|
16
|
+
shared_examples 'a Sequel truncation strategy' do
|
17
|
+
|
18
|
+
# XXX: it'd be really nice if Truncation accepted db: constructor parameter
|
19
|
+
let(:truncation) do
|
20
|
+
t = Truncation.new
|
21
|
+
t.db = db
|
22
|
+
t
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when several tables have data' do
|
26
|
+
before(:each) do
|
27
|
+
db.create_table!(:precious_stones) { primary_key :id }
|
28
|
+
db.create_table!(:replaceable_trifles) { primary_key :id }
|
29
|
+
db.create_table!(:worthless_junk) { primary_key :id }
|
30
|
+
|
31
|
+
db[:precious_stones].insert
|
32
|
+
db[:replaceable_trifles].insert
|
33
|
+
db[:worthless_junk].insert
|
34
|
+
end
|
35
|
+
context 'by default' do
|
36
|
+
it 'truncates all the tables' do
|
37
|
+
t = Truncation.new
|
38
|
+
t.db = db
|
39
|
+
t.clean
|
40
|
+
|
41
|
+
expect(db[:replaceable_trifles]).to have(0).rows
|
42
|
+
expect(db[:worthless_junk]).to have(0).rows
|
43
|
+
expect(db[:precious_stones]).to have(0).rows
|
44
|
+
end
|
45
|
+
end
|
46
|
+
context 'when the Truncation is restricted to "only: [...]" some tables' do
|
47
|
+
it 'truncates only the mentioned tables (and leaves the rest alone)' do
|
48
|
+
t = Truncation.new(only: ['worthless_junk', 'replaceable_trifles'])
|
49
|
+
t.db = db
|
50
|
+
t.clean
|
51
|
+
|
52
|
+
expect(db[:replaceable_trifles]).to have(0).rows
|
53
|
+
expect(db[:worthless_junk]).to have(0).rows
|
54
|
+
expect(db[:precious_stones]).to have(1).rows
|
55
|
+
end
|
56
|
+
end
|
57
|
+
context 'when the Truncation is restricted to "except: [...]" some tables' do
|
58
|
+
it 'leaves the mentioned tables alone (and truncates the rest)' do
|
59
|
+
t = Truncation.new(except: ['precious_stones']) # XXX: Strings only, symbols are ignored
|
60
|
+
t.db = db
|
61
|
+
t.clean
|
62
|
+
|
63
|
+
expect(db[:replaceable_trifles]).to be_empty
|
64
|
+
expect(db[:worthless_junk]).to be_empty
|
65
|
+
expect(db[:precious_stones]).to have(1).item
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
shared_examples_for 'a truncation strategy without autoincrement resets' do
|
72
|
+
it "leaves AUTO_INCREMENT index alone by default (BUG: it should be reset instead)" do
|
73
|
+
# Jordan Hollinger made everything reset auto increment IDs
|
74
|
+
# in commit 6a0104382647e5c06578aeac586c0333c8944492 so I'm pretty sure
|
75
|
+
# everything is meant to reset by default.
|
76
|
+
#
|
77
|
+
# For Postgres, db[:mytable].truncate(restart: true) should work.
|
78
|
+
# For SQLite, db[:sqlite_sequence].where(name: 'mytable').delete
|
79
|
+
|
80
|
+
db.create_table!(:replaceable_trifles) { primary_key :id }
|
81
|
+
table = db[:replaceable_trifles]
|
82
|
+
2.times { table.insert }
|
83
|
+
|
84
|
+
truncation.clean
|
85
|
+
|
86
|
+
id_after_clean = table.insert
|
87
|
+
pending('the bug being fixed') do
|
88
|
+
expect(id_after_clean).to eq 1
|
89
|
+
end
|
90
|
+
end
|
91
|
+
# XXX: it'd be really nice if Truncation accepted db: constructor parameter
|
92
|
+
let(:truncation) do
|
93
|
+
t = Truncation.new
|
94
|
+
t.db = db
|
95
|
+
t
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
shared_examples_for 'a truncation strategy that resets autoincrement keys by default' do
|
100
|
+
it "resets AUTO_INCREMENT primary keys" do
|
101
|
+
db.create_table!(:replaceable_trifles) { primary_key :id }
|
102
|
+
table = db[:replaceable_trifles]
|
103
|
+
2.times { table.insert }
|
104
|
+
|
105
|
+
truncation.clean
|
106
|
+
|
107
|
+
id_after_clean = table.insert
|
108
|
+
expect(id_after_clean).to eq 1
|
109
|
+
end
|
110
|
+
|
111
|
+
# XXX: it'd be really nice if Truncation accepted db: constructor parameter
|
112
|
+
let(:truncation) do
|
113
|
+
t = Truncation.new
|
114
|
+
t.db = db
|
115
|
+
t
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
half_supported_configurations = [
|
120
|
+
{url: 'sqlite:///', connection_options: db_config['sqlite3']},
|
121
|
+
{url: 'postgres:///', connection_options: db_config['postgres']},
|
122
|
+
]
|
123
|
+
supported_configurations = [
|
124
|
+
{url: 'mysql:///', connection_options: db_config['mysql']},
|
125
|
+
{url: 'mysql2:///', connection_options: db_config['mysql2']}
|
126
|
+
]
|
127
|
+
supported_configurations.each do |config|
|
128
|
+
describe "Sequel truncation (using a #{config[:url]} connection)" do
|
129
|
+
let(:db) { ::Sequel.connect(config[:url], config[:connection_options]) }
|
130
|
+
|
131
|
+
it_behaves_like 'a Sequel truncation strategy'
|
132
|
+
it_behaves_like 'a truncation strategy that resets autoincrement keys by default'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
half_supported_configurations.each do |config|
|
136
|
+
describe "Sequel truncation (using a #{config[:url]} connection)" do
|
137
|
+
let(:db) { ::Sequel.connect(config[:url], config[:connection_options]) }
|
138
|
+
|
139
|
+
it_behaves_like 'a Sequel truncation strategy'
|
140
|
+
it_behaves_like 'a truncation strategy without autoincrement resets'
|
141
|
+
end
|
142
|
+
end
|
12
143
|
end
|
13
144
|
end
|
@@ -5,9 +5,11 @@ end
|
|
5
5
|
shared_examples_for "a generic truncation strategy" do
|
6
6
|
it { should respond_to(:start) }
|
7
7
|
it { should respond_to(:clean) }
|
8
|
+
it { should respond_to(:cleaning) }
|
8
9
|
end
|
9
10
|
|
10
11
|
shared_examples_for "a generic transaction strategy" do
|
11
12
|
it { should respond_to(:start) }
|
12
13
|
it { should respond_to(:clean) }
|
14
|
+
it { should respond_to(:cleaning) }
|
13
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: database_cleaner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,344 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
12
|
+
date: 2014-05-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: jeweler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: json_pure
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: activerecord
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: datamapper
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: dm-migrations
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: dm-sqlite-adapter
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: mongoid
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: tzinfo
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: mongo_ext
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: bson_ext
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
- !ruby/object:Gem::Dependency
|
207
|
+
name: mongo_mapper
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
209
|
+
none: false
|
210
|
+
requirements:
|
211
|
+
- - ! '>='
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: '0'
|
214
|
+
type: :development
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ! '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
- !ruby/object:Gem::Dependency
|
223
|
+
name: couch_potato
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
none: false
|
226
|
+
requirements:
|
227
|
+
- - ! '>='
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
none: false
|
234
|
+
requirements:
|
235
|
+
- - ! '>='
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
version: '0'
|
238
|
+
- !ruby/object:Gem::Dependency
|
239
|
+
name: sequel
|
240
|
+
requirement: !ruby/object:Gem::Requirement
|
241
|
+
none: false
|
242
|
+
requirements:
|
243
|
+
- - ~>
|
244
|
+
- !ruby/object:Gem::Version
|
245
|
+
version: 3.21.0
|
246
|
+
type: :development
|
247
|
+
prerelease: false
|
248
|
+
version_requirements: !ruby/object:Gem::Requirement
|
249
|
+
none: false
|
250
|
+
requirements:
|
251
|
+
- - ~>
|
252
|
+
- !ruby/object:Gem::Version
|
253
|
+
version: 3.21.0
|
254
|
+
- !ruby/object:Gem::Dependency
|
255
|
+
name: mysql
|
256
|
+
requirement: !ruby/object:Gem::Requirement
|
257
|
+
none: false
|
258
|
+
requirements:
|
259
|
+
- - ~>
|
260
|
+
- !ruby/object:Gem::Version
|
261
|
+
version: 2.8.1
|
262
|
+
type: :development
|
263
|
+
prerelease: false
|
264
|
+
version_requirements: !ruby/object:Gem::Requirement
|
265
|
+
none: false
|
266
|
+
requirements:
|
267
|
+
- - ~>
|
268
|
+
- !ruby/object:Gem::Version
|
269
|
+
version: 2.8.1
|
270
|
+
- !ruby/object:Gem::Dependency
|
271
|
+
name: mysql2
|
272
|
+
requirement: !ruby/object:Gem::Requirement
|
273
|
+
none: false
|
274
|
+
requirements:
|
275
|
+
- - ! '>='
|
276
|
+
- !ruby/object:Gem::Version
|
277
|
+
version: '0'
|
278
|
+
type: :development
|
279
|
+
prerelease: false
|
280
|
+
version_requirements: !ruby/object:Gem::Requirement
|
281
|
+
none: false
|
282
|
+
requirements:
|
283
|
+
- - ! '>='
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: '0'
|
286
|
+
- !ruby/object:Gem::Dependency
|
287
|
+
name: pg
|
288
|
+
requirement: !ruby/object:Gem::Requirement
|
289
|
+
none: false
|
290
|
+
requirements:
|
291
|
+
- - ! '>='
|
292
|
+
- !ruby/object:Gem::Version
|
293
|
+
version: '0'
|
294
|
+
type: :development
|
295
|
+
prerelease: false
|
296
|
+
version_requirements: !ruby/object:Gem::Requirement
|
297
|
+
none: false
|
298
|
+
requirements:
|
299
|
+
- - ! '>='
|
300
|
+
- !ruby/object:Gem::Version
|
301
|
+
version: '0'
|
302
|
+
- !ruby/object:Gem::Dependency
|
303
|
+
name: sqlite3
|
304
|
+
requirement: !ruby/object:Gem::Requirement
|
305
|
+
none: false
|
306
|
+
requirements:
|
307
|
+
- - ! '>='
|
308
|
+
- !ruby/object:Gem::Version
|
309
|
+
version: '0'
|
310
|
+
type: :development
|
311
|
+
prerelease: false
|
312
|
+
version_requirements: !ruby/object:Gem::Requirement
|
313
|
+
none: false
|
314
|
+
requirements:
|
315
|
+
- - ! '>='
|
316
|
+
- !ruby/object:Gem::Version
|
317
|
+
version: '0'
|
318
|
+
- !ruby/object:Gem::Dependency
|
319
|
+
name: ohm
|
320
|
+
requirement: !ruby/object:Gem::Requirement
|
321
|
+
none: false
|
322
|
+
requirements:
|
323
|
+
- - ~>
|
324
|
+
- !ruby/object:Gem::Version
|
325
|
+
version: 0.1.3
|
326
|
+
type: :development
|
327
|
+
prerelease: false
|
328
|
+
version_requirements: !ruby/object:Gem::Requirement
|
329
|
+
none: false
|
330
|
+
requirements:
|
331
|
+
- - ~>
|
332
|
+
- !ruby/object:Gem::Version
|
333
|
+
version: 0.1.3
|
334
|
+
- !ruby/object:Gem::Dependency
|
335
|
+
name: guard-rspec
|
336
|
+
requirement: !ruby/object:Gem::Requirement
|
337
|
+
none: false
|
338
|
+
requirements:
|
339
|
+
- - ! '>='
|
340
|
+
- !ruby/object:Gem::Version
|
341
|
+
version: '0'
|
342
|
+
type: :development
|
343
|
+
prerelease: false
|
344
|
+
version_requirements: !ruby/object:Gem::Requirement
|
345
|
+
none: false
|
346
|
+
requirements:
|
347
|
+
- - ! '>='
|
348
|
+
- !ruby/object:Gem::Version
|
349
|
+
version: '0'
|
14
350
|
description: Strategies for cleaning databases. Can be used to ensure a clean state
|
15
351
|
for testing.
|
16
352
|
email: ben@benmabey.com
|
@@ -119,6 +455,7 @@ files:
|
|
119
455
|
- spec/database_cleaner/redis/truncation_spec.rb
|
120
456
|
- spec/database_cleaner/sequel/base_spec.rb
|
121
457
|
- spec/database_cleaner/sequel/transaction_spec.rb
|
458
|
+
- spec/database_cleaner/sequel/truncation/sqlite3_spec.rb
|
122
459
|
- spec/database_cleaner/sequel/truncation_spec.rb
|
123
460
|
- spec/database_cleaner/shared_strategy.rb
|
124
461
|
- spec/rcov.opts
|
@@ -132,8 +469,7 @@ files:
|
|
132
469
|
- LICENSE
|
133
470
|
- TODO
|
134
471
|
homepage: http://github.com/bmabey/database_cleaner
|
135
|
-
licenses:
|
136
|
-
- MIT
|
472
|
+
licenses: []
|
137
473
|
post_install_message:
|
138
474
|
rdoc_options: []
|
139
475
|
require_paths:
|
@@ -144,6 +480,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
480
|
- - ! '>='
|
145
481
|
- !ruby/object:Gem::Version
|
146
482
|
version: '0'
|
483
|
+
segments:
|
484
|
+
- 0
|
485
|
+
hash: 2066839847000143499
|
147
486
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
487
|
none: false
|
149
488
|
requirements:
|
@@ -158,4 +497,3 @@ specification_version: 3
|
|
158
497
|
summary: Strategies for cleaning databases. Can be used to ensure a clean state for
|
159
498
|
testing.
|
160
499
|
test_files: []
|
161
|
-
has_rdoc:
|