mirror of
https://github.com/DatabaseCleaner/database_cleaner
synced 2023-03-27 23:22:03 -04:00
commit
b254ce57bd
9 changed files with 92 additions and 23 deletions
|
@ -146,7 +146,7 @@ passed to [`keys`](http://redis.io/commands/keys)).
|
|||
|
||||
(I should point out the truncation strategy will never truncate your schema_migrations table.)
|
||||
|
||||
Some strategies require that you call `DatabaseCleaner.start` before calling `clean` (for example the `:transaction` one needs to know to open up a transaction). So you would have:
|
||||
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:
|
||||
|
||||
```ruby
|
||||
require 'database_cleaner'
|
||||
|
@ -158,6 +158,12 @@ DatabaseCleaner.start # usually this is called in setup of a test
|
|||
dirty_the_db
|
||||
|
||||
DatabaseCleaner.clean # cleanup of the test
|
||||
|
||||
# OR
|
||||
|
||||
DatabaseCleaner.cleaning do
|
||||
dirty_the_db
|
||||
end
|
||||
```
|
||||
|
||||
At times you may want to do a single clean with one strategy.
|
||||
|
@ -196,12 +202,10 @@ RSpec.configure do |config|
|
|||
DatabaseCleaner.clean_with(:truncation)
|
||||
end
|
||||
|
||||
config.before(:each) do
|
||||
DatabaseCleaner.start
|
||||
config.around(:each) do |example|
|
||||
DatabaseCleaner.cleaning do
|
||||
example.run
|
||||
end
|
||||
|
||||
config.after(:each) do
|
||||
DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -221,6 +225,13 @@ class MiniTest::Spec
|
|||
DatabaseCleaner.clean
|
||||
end
|
||||
end
|
||||
|
||||
# with the minitest-around gem, this may be used instead:
|
||||
class Minitest::Spec
|
||||
around do |tests|
|
||||
DatabaseCleaner.cleaning(&tests)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Cucumber Example
|
||||
|
@ -239,12 +250,8 @@ rescue NameError
|
|||
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
|
||||
end
|
||||
|
||||
Before do
|
||||
DatabaseCleaner.start
|
||||
end
|
||||
|
||||
After do |scenario|
|
||||
DatabaseCleaner.clean
|
||||
Around do |scenario, block|
|
||||
DatabaseCleaner.cleaning(&block)
|
||||
end
|
||||
```
|
||||
|
||||
|
@ -358,6 +365,9 @@ If you are using Postgres and have foreign key constraints, the truncation strat
|
|||
client_min_messages = warning
|
||||
```
|
||||
|
||||
### Nothing happens in JRuby with Sequel using transactions
|
||||
|
||||
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.
|
||||
|
||||
## Debugging
|
||||
|
||||
|
|
|
@ -88,6 +88,10 @@ module DatabaseCleaner
|
|||
|
||||
alias clean! clean
|
||||
|
||||
def cleaning(&block)
|
||||
strategy.cleaning(&block)
|
||||
end
|
||||
|
||||
def auto_detected?
|
||||
!!@autodetected
|
||||
end
|
||||
|
|
|
@ -81,6 +81,12 @@ module DatabaseCleaner
|
|||
|
||||
alias clean! clean
|
||||
|
||||
def cleaning(&inner_block)
|
||||
connections.inject(inner_block) do |curr_block, connection|
|
||||
proc { connection.cleaning(&curr_block) }
|
||||
end.call
|
||||
end
|
||||
|
||||
def clean_with(*args)
|
||||
connections.each { |connection| connection.clean_with(*args) }
|
||||
end
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
Before do
|
||||
DatabaseCleaner.start
|
||||
end
|
||||
|
||||
After do
|
||||
begin
|
||||
DatabaseCleaner.clean
|
||||
rescue Exception => e
|
||||
DatabaseCleaner.logger.error "Exception encountered by DatabaseCleaner in Cucumber After block: #{e}"
|
||||
end
|
||||
Around do |scenario, block|
|
||||
DatabaseCleaner.cleaning(&block)
|
||||
end
|
||||
|
|
|
@ -10,6 +10,12 @@ module ::DatabaseCleaner
|
|||
:default
|
||||
end
|
||||
|
||||
def cleaning(&block)
|
||||
start
|
||||
yield
|
||||
clean
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def available_strategies
|
||||
%W[]
|
||||
|
|
|
@ -4,7 +4,18 @@ module DatabaseCleaner
|
|||
class Transaction
|
||||
include ::DatabaseCleaner::Sequel::Base
|
||||
|
||||
def self.check_fiber_brokenness
|
||||
if !@checked_fiber_brokenness && Fiber.new { Thread.current }.resume != Thread.current
|
||||
raise RuntimeError, "This ruby engine's Fibers are not compatible with Sequel's connection pool. " +
|
||||
"To work around this, please use DatabaseCleaner.cleaning with a block instead of " +
|
||||
"DatabaseCleaner.start and DatabaseCleaner.clean"
|
||||
end
|
||||
@checked_fiber_brokenness = true
|
||||
end
|
||||
|
||||
def start
|
||||
self.class.check_fiber_brokenness
|
||||
|
||||
@fibers||= []
|
||||
db= self.db
|
||||
f= Fiber.new do
|
||||
|
@ -20,6 +31,10 @@ module DatabaseCleaner
|
|||
f= @fibers.pop
|
||||
f.resume
|
||||
end
|
||||
|
||||
def cleaning
|
||||
self.db.transaction(:rollback => :always, :savepoint => true) { yield }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -451,6 +451,13 @@ module DatabaseCleaner
|
|||
subject.clean!
|
||||
end
|
||||
end
|
||||
|
||||
describe "cleaning" do
|
||||
it "should proxy cleaning to the strategy" do
|
||||
strategy.should_receive(:cleaning)
|
||||
subject.cleaning { }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "auto_detected?" do
|
||||
|
|
|
@ -163,6 +163,11 @@ describe ::DatabaseCleaner do
|
|||
::DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
it 'should proxy cleaning' do
|
||||
connection.should_receive(:cleaning)
|
||||
::DatabaseCleaner.cleaning { }
|
||||
end
|
||||
|
||||
it "should proxy clean_with" do
|
||||
stratagem = double("stratgem")
|
||||
connection.should_receive(:clean_with).with(stratagem, {})
|
||||
|
@ -203,6 +208,28 @@ describe ::DatabaseCleaner do
|
|||
::DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
it "should initiate cleaning on each connection, yield, and finish cleaning each connection" do
|
||||
[active_record, data_mapper].each do |connection|
|
||||
mc = class << connection; self; end
|
||||
mc.send(:attr_reader, :started, :cleaned)
|
||||
mc.send(:define_method, 'cleaning') do |&block|
|
||||
@started = true
|
||||
block.call
|
||||
@cleaned = true
|
||||
end
|
||||
end
|
||||
|
||||
::DatabaseCleaner.cleaning do
|
||||
active_record.started.should == true
|
||||
data_mapper.started.should == true
|
||||
active_record.cleaned.should == nil
|
||||
data_mapper.cleaned.should == nil
|
||||
@yielded = true
|
||||
end
|
||||
active_record.cleaned.should == true
|
||||
data_mapper.cleaned.should == true
|
||||
end
|
||||
|
||||
it "should proxy clean_with to all connections" do
|
||||
stratagem = double("stratgem")
|
||||
active_record.should_receive(:clean_with).with(stratagem)
|
||||
|
|
|
@ -5,9 +5,11 @@ end
|
|||
shared_examples_for "a generic truncation strategy" do
|
||||
it { should respond_to(:start) }
|
||||
it { should respond_to(:clean) }
|
||||
it { should respond_to(:cleaning) }
|
||||
end
|
||||
|
||||
shared_examples_for "a generic transaction strategy" do
|
||||
it { should respond_to(:start) }
|
||||
it { should respond_to(:clean) }
|
||||
it { should respond_to(:cleaning) }
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue