Permalink
Browse files

It's more useful to have multiple mandatory steps

This allows organizing the code, and subclasses to add blocks. Mandatory
and best effort blocks are thus very similar: one raises, the other
logs exceptions.
  • Loading branch information...
1 parent 1ed98ab commit 3c440720f0789b061ffddbf1662b2054bbc37689 @francois committed Oct 10, 2010
Showing with 80 additions and 48 deletions.
  1. +0 −9 lib/komando.rb
  2. +5 −3 lib/komando/command.rb
  3. +15 −23 lib/komando/command/dsl.rb
  4. +1 −1 spec/active_record_integration_spec.rb
  5. +53 −6 spec/command_runner_spec.rb
  6. +6 −6 spec/dsl_spec.rb
View
@@ -4,15 +4,6 @@ module Komando
# Indicates the mandatory steps have not been declared on instances of this class.
class MissingMandatoryStepsError < StandardError; end
- # Indicates you tried to declare multiple mandatory steps. Instead of doing that, declare methods and call them.
- #
- # @see Komando::Command::Dsl
- class MultipleMandatoryStepDeclarationsError < StandardError
- def initialize(*args)
- super("Mandatory step blocks can only be declared once per command - declare methods and call the methods from your block")
- end
- end
-
autoload :Command, "komando/command"
def self.make_command(base)
View
@@ -54,9 +54,11 @@ def logger
# Runs and raises
def run_mandatory!
- mandatory = self.class.mandatory_steps
- raise Komando::MissingMandatoryStepsError unless mandatory
- instance_exec(&mandatory)
+ steps = self.class.mandatory_steps
+ raise Komando::MissingMandatoryStepsError if steps.empty?
+ steps.each do |step|
+ instance_exec(&step)
+ end
end
# Runs and logs
View
@@ -14,60 +14,52 @@ module Command
# class CreateUserCommand
# extend Komando::Command::Dsl
#
+ # # If you must override #initialize, make sure you call super,
+ # # or your instance variables won't be assigned.
# def initialize(*args)
# super # MUST call, or all hell will break loose
# end
#
- # mandatory_steps do
- # generate_records
- # generate_audit_log
- # end
- #
- # private
- #
- # def generate_records
+ # mandatory_step "generate records" do
# # TODO
# end
#
- # def generate_audit_log
+ # mandatory_step "generate audit log" do
# # TODO
# end
+ #
# end
module Dsl
+ # Returns the list of mandatory steps
+ def mandatory_steps
+ @mandatory_steps ||= []
+ end
+
# Declares a set of actions that must run to completion for this command to be deemed successful.
# The declared actions may be anything: method calls or direct actions. Parameters are passed from the
# environment as instance variables passed to the instance.
#
- # @raise [MultipleMandatoryStepDeclarationsError] If this method is called multiple times with a block.
- #
# @example
#
# class CreateUserCommand
# extend Komando::Command::Dsl
#
- # mandatory_steps do
+ # mandatory_step do
# # Assuming an ActiveRecord-like User class exists
# User.create!(@attributes)
# end
# end
#
# # Run the command with parameters gathered from the environment
# CreateUserCommand.new(:attributes => params[:user]).run!
- def mandatory_steps(&block)
- if block then
- # Called as a setter
- raise Komando::MultipleMandatoryStepDeclarationsError if @mandatory_steps
- @mandatory_steps = block
- else
- # Called as a query
- @mandatory_steps
- end
+ def mandatory_step(name=nil, &block)
+ mandatory_steps << block
end
# Declares a new best effort step - one that will be executed, but will not stop processing.
# If the block raises an exception, {Komando::Command#run!} will log and swallow the exception.
- # Best effort stop blocks have access to the same environment as {#mandatory_steps} blocks -
+ # Best effort stop blocks have access to the same environment as {#mandatory_step} blocks -
# they execute within the same instance. You can pass values from one block to the next by
# using instance variables.
#
@@ -76,7 +68,7 @@ def mandatory_steps(&block)
# class CreateUserCommand
# extend Komando::Command::Dsl
#
- # mandatory_steps do
+ # mandatory_step do
# @user = User.create!(@attributes)
# end
#
@@ -20,7 +20,7 @@ def adapter_name
attr_reader :open_transactions
- mandatory_steps do
+ mandatory_step do
@open_transactions = ActiveRecord::Base.connection.open_transactions
end
end
@@ -9,7 +9,7 @@
attr_reader :ran
- mandatory_steps do
+ mandatory_step do
@ran = true
end
end
@@ -33,7 +33,7 @@
attr_reader :ran, :log
- mandatory_steps do
+ mandatory_step do
raise "failure to run"
end
@@ -87,7 +87,7 @@
attr_reader :ran
- mandatory_steps do
+ mandatory_step do
# NOP
end
@@ -105,6 +105,53 @@
end
+describe "A command with two mandatory steps" do
+
+ before do
+ @command = Class.new do
+ extend Komando::Command::Dsl
+ include Komando::Command
+
+ attr_accessor :raise_in_first, :raise_in_second
+ attr_reader :log
+
+ def initialize(*args)
+ @log = []
+ super
+ end
+
+ mandatory_step do
+ raise "asked to raise" if raise_in_first
+ log << 1
+ end
+
+ mandatory_step do
+ raise "asked to raise" if raise_in_second
+ log << 2
+ end
+ end
+ end
+
+ should "run both blocks in order" do
+ command = @command.new
+ command.run!
+
+ command.log.should == [1, 2]
+ end
+
+ should "NOT run the 2nd block when the 1st one raises" do
+ command = @command.new
+ command.raise_in_first = true
+
+ lambda do
+ command.run!
+ end.should.raise
+
+ command.log.should == []
+ end
+
+end
+
describe "A command with two best effort steps" do
before do
@@ -114,7 +161,7 @@
attr_reader :log
- mandatory_steps do
+ mandatory_step do
# NOP
end
@@ -151,7 +198,7 @@
attr_reader :log
- mandatory_steps do
+ mandatory_step do
# NOP
end
@@ -189,7 +236,7 @@ def warn(message)
messages = command.logger.messages
messages.length.should == 1
- messages.first.should.match /^ignoring failed.*first.*RuntimeError.*failure to run/im
+ messages.first.should.match /ignoring failed.*first.*RuntimeError.*failure to run/im
end
end
View
@@ -8,8 +8,8 @@
end
end
- should "have no mandatory step block" do
- @command.mandatory_steps.should.be.nil?
+ should "have no mandatory step blocks" do
+ @command.mandatory_steps.should == []
end
should "have no best effort blocks" do
@@ -23,7 +23,7 @@
@command = Class.new do
extend Komando::Command::Dsl
- mandatory_steps do
+ mandatory_step do
end
end
end
@@ -32,13 +32,13 @@
@command.mandatory_steps.should.not.be.nil?
end
- should "NOT allow declaring a second one" do
+ should "allow declaring a second mandatory step" do
lambda do
@command.class_eval do
- mandatory_steps do
+ mandatory_step do
end
end
- end.should.raise(Komando::MultipleMandatoryStepDeclarationsError)
+ end.should.not.raise
end
end

0 comments on commit 3c44072

Please sign in to comment.