Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist
View rspec_rails_transactional.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
# In Rspec, gives you:
# before(:all_transactional) {}
#
# Uses nested transactions to correctly rollback :all before blocks
# You *may* need to reload some instance variables in a separate before(:each) block
# All a bit of a hack, but really handy
module RspecRailsTransactions
def before_all_transactional_parts # :nodoc:
@before_all_transactional_parts ||= []
end
 
# Overridden from rspec implementation to add :all_transactional
def before_parts(scope)
case scope
when :each; before_each_parts
when :all; before_all_parts
when :suite; before_suite_parts
when :all_transactional; before_all_transactional_parts
end
end
 
# Based on a combination of run_before_all and run_after_all methods from rspec
def run_before_all_transactional_parts(success, run_options, instance_variables)
return [success, instance_variables] if example_group_hierarchy.before_all_transactional_parts.empty?
example_proxy = ::Spec::Example::ExampleProxy.new("before(:all_transactional)")
before_all = new(example_proxy)
before_all.set_instance_variables_from_hash(instance_variables)
example_group_hierarchy.run_before_all_transactional(before_all)
[success, before_all.instance_variable_hash]
rescue Exception => e
run_options.reporter.example_failed(example_proxy, e)
[false, before_all.instance_variable_hash]
end
 
# Overridden from the rspec implementation, as it doesn't provide us with necessary hooks
def run_examples(success, instance_variables, examples, run_options)
return [success, instance_variables] unless success
 
after_all_instance_variables = instance_variables
 
ActiveSupport::TestCase.use_transactional_fixtures = false
ActiveRecord::Base.transaction(:joinable => false) do
success, instance_variables = run_before_all_transactional_parts(success, run_options, instance_variables)
 
if success
examples.each do |example|
example_group_instance = new(example, &example_implementations[example])
# .transaction doesn't work here
ActiveRecord::Base.connection.create_savepoint
ActiveRecord::Base.connection.increment_open_transactions
success &= example_group_instance.execute(run_options, instance_variables)
ActiveRecord::Base.connection.decrement_open_transactions
ActiveRecord::Base.connection.rollback_to_savepoint
after_all_instance_variables = example_group_instance.instance_variable_hash
end
end
raise ActiveRecord::Rollback
end
 
return [success, after_all_instance_variables]
end
end
 
module Spec
module Example
class ExampleGroupHierarchy < Array
# Fail fast call was cargo-culted, I need to investigate further
def run_before_all_transactional(example)
example.eval_each_fail_fast(before_all_transactional_parts)
end
 
# Not all of the hierachy has necessary been extended with transactional
# support, so check that each klass responds to the method first
def before_all_transactional_parts
@before_all_transactional_parts ||= collect {|klass| klass.before_all_transactional_parts if klass.respond_to?(:before_all_transactional_parts) }.compact.flatten
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.