Skip to content

Commit

Permalink
adds specs for stage, and updates transaction specs, fixes a couple m…
Browse files Browse the repository at this point in the history
…inor bugs exposed by the fixed specs
  • Loading branch information
markrebec committed May 27, 2015
1 parent bd176d1 commit e434ce2
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 75 deletions.
6 changes: 4 additions & 2 deletions lib/transactor/actor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ def rollback_on_failure?

def perform!(&block)
@state = :performing
perform &block
result = perform(&block)
@state = :performed
result
rescue StandardError => e
@state = :bombed
@error = e
Expand All @@ -46,8 +47,9 @@ def perform!(&block)

def rollback!(&block)
@state = :rolling_back
rollback &block
result = rollback(&block)
@state = :rolled_back
result
rescue StandardError => e
@state = :rollback_bombed
@rollback_error = e
Expand Down
4 changes: 2 additions & 2 deletions lib/transactor/performance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ def self.perform(actor, *args, &block)
end

def perform(&block)
@result = actor.perform(&block)
@result = actor.perform!(&block)
self
end

def rollback(&block)
actor.rollback(&block)
actor.rollback!(&block)
self
end

Expand Down
17 changes: 7 additions & 10 deletions lib/transactor/transaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,25 @@ def rollback_performances
performance.rollback
rescue RollbackNotImplemented => e
# noop, rollback was not implemented
rescue => e
rescue StandardError => e
# performance rollback failed :(
raise RollbackBombed.new(e, performance) if Transactor.configuration.stop_rollback_on_failure
end
end
end

# TODO remove these when specs are cleaned up
def perform(actor, *args, &block)
stage.perform actor, *args, &block
end
def improvise(*args, &block)
stage.improvise *args, &block
end

def performances
stage.performances
end

def bombed_performances
def bombed
performances.select { |performance| performance.bombed? || performance.rolled_back? }
end

def rolled_back
performances.select { |performance| performance.rolled_back? }
end

def bombed_rollbacks
performances.select { |performance| performance.rollback_bombed? }
end
Expand Down
10 changes: 10 additions & 0 deletions spec/support/test_actors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ def rollback
@rolled_back = true
end
end

class BlockActor < Transactor::Actor
def perform(&block)
instance_eval &block if block_given?
end

def rollback(&block)
instance_eval &block if block_given?
end
end
64 changes: 64 additions & 0 deletions spec/transactor/stage_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require 'spec_helper'

RSpec.describe Transactor::Stage do
describe '#perform' do
it 'adds a performance to the performances array' do
subject.perform(TestActor)
expect(subject.performances.length).to eql(1)
end

it 'casts the provided actor in the performance' do
subject.perform(TestActor)
expect(subject.performances.last.actor).to be_an_instance_of(TestActor)
end

it "triggers the actor's performance" do
subject.perform(TestActor)
expect(subject.performances.last.actor.performed).to be_true
end

it 'bubbles exceptions as PerformanceBombed errors' do
expect { subject.perform(FailingActor) }.to raise_exception(Transactor::PerformanceBombed)
end
end

describe '#improvise' do
it 'returns an improv performance' do
expect(subject.improvise).to be_an_instance_of(Transactor::Improv::Performance)
end

it 'adds a performance to the performances array' do
subject.improvise
expect(subject.performances.length).to eql(1)
end

it 'casts the default actor in the performance' do
subject.improvise
expect(subject.performances.last.actor).to be_an_instance_of(Transactor::Improv::Actor)
end

it 'executes the improv block' do
subject.improvise { 5+5 }.perform
expect(subject.performances.last.result).to eql(10)
end

it 'bubbles exceptions as PerformanceBombed errors' do
expect do
subject.improvise do
raise "Bombing"
end.rollback do
puts "Rolling Back"
end.perform
end.to raise_exception(Transactor::PerformanceBombed)
end
end

describe '#method_missing' do
it 'translates method calls to actor performances' do
subject.instance_eval do
test_actor
end
expect(subject.performances.last.actor).to be_an_instance_of(TestActor)
end
end
end
100 changes: 39 additions & 61 deletions spec/transactor/transaction_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,62 +44,10 @@
end
end

describe '#perform' do
it 'adds a performance to the performances array' do
subject.perform(TestActor)
expect(subject.performances.length).to eql(1)
end

it 'casts the provided actor in the performance' do
subject.perform(TestActor)
expect(subject.performances.last.actor).to be_an_instance_of(TestActor)
end

it "triggers the actor's performance" do
subject.perform(TestActor)
expect(subject.performances.last.actor.performed).to be_true
end

it 'bubbles exceptions as PerformanceBombed errors' do
expect { subject.perform(FailingActor) }.to raise_exception(Transactor::PerformanceBombed)
end
end

describe '#improvise' do
it 'returns an improv performance' do
expect(subject.improvise).to be_an_instance_of(Transactor::Improv::Performance)
end

it 'adds a performance to the performances array' do
subject.improvise
expect(subject.performances.length).to eql(1)
end

it 'casts the default actor in the performance' do
subject.improvise
expect(subject.performances.last.actor).to be_an_instance_of(Transactor::Improv::Actor)
end

it 'executes the improv block' do
subject.improvise { 5+5 }.perform
expect(subject.performances.last.result).to eql(10)
end

it 'bubbles exceptions as PerformanceBombed errors' do
expect do
subject.improvise do
raise "Bombing"
end.rollback do
puts "Rolling Back"
end.perform
end.to raise_exception(Transactor::PerformanceBombed)
end
end

describe '#rollback' do
context 'when there are no failed performances' do
it 'rolls back all performances' do
3.times { subject.perform(TestActor) }
3.times { subject.stage.perform(TestActor) }
subject.performances.each do |performance|
expect(performance.actor.performed).to be_true
end
Expand All @@ -113,7 +61,7 @@
context 'when the last performance failed' do
context 'and is configured to rollback on failure' do
it 'rolls back all performances' do
3.times { subject.perform(TestActor) }
3.times { subject.stage.perform(TestActor) }
subject.performances.each do |performance|
expect(performance.actor.performed).to be_true
end
Expand All @@ -132,7 +80,7 @@
context 'and is configured not to rollback on failure' do
it 'rolls back all performances except the one that failed' do
TestActor.instance_variable_set :@rollback_on_failure, false
3.times { subject.perform(TestActor) }
3.times { subject.stage.perform(TestActor) }
subject.performances.each do |performance|
expect(performance.actor.performed).to be_true
end
Expand All @@ -146,12 +94,42 @@
end
end

describe '#method_missing' do
it 'translates method calls to actor performances' do
subject.transaction! do
test_actor
end
expect(subject.performances.last.actor).to be_an_instance_of(TestActor)
describe '#performances' do
it 'returns the stage performances' do
3.times { subject.stage.perform(TestActor) }
expect(subject.performances).to eql(subject.stage.performances)
end
end

describe '#bombed' do
it 'returns an array of bombed or rolled back performances' do
5.times { subject.stage.perform(TestActor) }
subject.performances[0].rollback
subject.performances[2].actor.instance_variable_set :@state, :bombed
expect(subject.bombed).to eql([subject.performances[0], subject.performances[2]])
end
end

describe '#rolled_back' do
it 'returns an array of rolled back performances' do
5.times { subject.stage.perform(TestActor) }
subject.performances[0].rollback
subject.performances[2].rollback
expect(subject.rolled_back).to eql([subject.performances[0], subject.performances[2]])
end
end

describe '#bombed_rollbacks' do
it 'returns an array of bombed rollbacks' do
5.times { subject.stage.perform(BlockActor) }
begin
subject.performances[0].rollback { raise 'fail' }
rescue; end
begin
subject.performances[2].rollback { raise 'fail' }
rescue; end
expect(subject.bombed_rollbacks).to eql([subject.performances[0], subject.performances[2]])
end
end

end

0 comments on commit e434ce2

Please sign in to comment.