Last active
December 18, 2015 23:59
-
-
Save kschiess/5865739 to your computer and use it in GitHub Desktop.
Taking the transaction behaviour discussion into code. Use 'rspec transactions_spec.rb'
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec' | |
require 'dm-transactions' | |
RSpec.configure do |rspec| | |
rspec.mock_with :flexmock | |
end | |
describe 'transaction block behaviour' do | |
let(:t) { DataMapper::Transaction.new() } | |
def transaction &block | |
t.commit &block | |
end | |
def be_committed | |
be_commit | |
end | |
def be_rolled_back | |
be_rollback | |
end | |
# Remove comments on this code block for an alternate implementation that | |
# fixes most of these problems. NOTE The code in this implementation is | |
# not correct, since it drops a few of the original aspects. They should be | |
# easy to add back in. | |
# | |
# def transaction &block | |
# t.begin | |
# begin | |
# t.within(&block) | |
# rescue Exception => e | |
# t.rollback | |
# raise | |
# ensure | |
# t.commit if t.begin? | |
# end | |
# end | |
describe "directly called" do | |
it "can return" do | |
# When not inside the context of a method call, returning should not | |
# work. | |
expect { | |
transaction { return :something } | |
}.to raise_error(LocalJumpError) | |
end | |
it "can call next with a value" do | |
transaction { next :something }.should == :something | |
t.should be_committed | |
end | |
it "can call break with a value" do | |
loop do | |
transaction { break } | |
fail "SHOULD NOT BE REACHED" | |
end | |
pending "break is real hard to catch..." do | |
t.should be_committed | |
end | |
end | |
it "can raise an exception" do | |
e = Exception.new | |
expect { | |
transaction { raise e } | |
}.to raise_error(e) | |
t.should be_rolled_back | |
end | |
it "can throw a value" do | |
pending 'Throwing?' do | |
expect { | |
transaction { throw :value } | |
}.to throw_symbol(:value) | |
t.should be_committed | |
end | |
end | |
end | |
describe "wrapped in a method call" do | |
def mc &block | |
c = Class.new | |
i = c.new | |
m = i.define_singleton_method(:foo, &block) | |
m.call | |
end | |
it "can return" do | |
pending 'Would be nice to have return working.' do | |
mc { | |
transaction { return :something } | |
}.should == :something | |
t.should be_committed | |
end | |
end | |
it "can call next with a value" do | |
mc { | |
transaction { next :something } | |
}.should == :something | |
t.should be_committed | |
end | |
it "can call break with a value" do | |
# Break from inside a method call is not something one would attempt. | |
expect { | |
mc { | |
loop do | |
transaction { break :something } | |
fail "SHOULD NOT BE REACHED" | |
end | |
} | |
}.to raise_error(RuntimeError) | |
end | |
it "can raise an exception" do | |
e = Exception.new | |
expect { | |
mc { | |
transaction { raise e } | |
} | |
}.to raise_error(e) | |
t.should be_rolled_back | |
end | |
it "can throw a value" do | |
pending 'Throwing as a means to exit many levels of call stack quickly...' do | |
expect { | |
mc { | |
transaction { throw :value } | |
} | |
}.to throw_symbol(:value) | |
t.should be_committed | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Running with 1.9.3 - dm-transactions implementation:
Running with my transactions implementation: