module Workout

Constants

VERSION

Public Class Methods

new(**opts) click to toggle source
# File lib/workout.rb, line 32
def initialize(**opts)
  @_fsm = MicroMachine.new(:pending).tap do |fsm|
    fsm.when(:complete, :pending => :completed)
    fsm.when(:fail,     :pending => :failed)
  end
  @_failures = []
end

Public Instance Methods

call() click to toggle source
# File lib/workout.rb, line 105
def call
  # don't even try if we are already invalid
  return self if invalid?

  rescuing do
    # run each step, possibly feeding the last result to the next
    self.class.steps.reduce(nil) do |last, name|
      self.current_step = name

      # #fail will throw :failure instead of raising
      result = catch :failure do
        if method(name).arity == 1
          send name, last
        else
          send name
        end
      end

      if invalid?
        break
      else
        result
      end
    end

    complete if valid?
  end
ensure
  self.current_step = nil
end
complete() click to toggle source
# File lib/workout.rb, line 44
def complete
  @_fsm.trigger(:complete)
end
complete!() click to toggle source
# File lib/workout.rb, line 48
def complete!
  @_fsm.trigger!(:complete)
end
complete?() click to toggle source
# File lib/workout.rb, line 40
def complete?
  @_fsm.state == :completed
end
fail(**args) click to toggle source
# File lib/workout.rb, line 52
def fail(**args)
  should_throw = args.delete(:throw) != false
  @_failures.push({ step: current_step, args: args })
  @_fsm.trigger(:fail)
  validate
  throw :failure if should_throw
end
step(name, &blk) click to toggle source
# File lib/workout.rb, line 14
def step(name, &blk)
  define_method name, &blk
  self.steps << name
end
steps() click to toggle source
# File lib/workout.rb, line 10
def steps
  @_steps ||= []
end
success?() click to toggle source
# File lib/workout.rb, line 66
def success?
  complete? && valid?
end
work(&blk) click to toggle source
# File lib/workout.rb, line 19
def work(&blk)
  define_method :work, &blk
  self.steps.replace([:work])
end

Private Instance Methods

copy_failures_to_errors() click to toggle source
# File lib/workout.rb, line 60
        def copy_failures_to_errors
  @_failures.each do |info|
    errors.add info[:step], info[:args]
  end
end
rescuing(&blk) click to toggle source
# File lib/workout.rb, line 70
        def rescuing(&blk)
  if defined?(ActiveRecord::ActiveRecordError)
    rescuing_with_active_record(&blk)
  else
    rescuing_without_active_record(&blk)
  end
end
rescuing_with_active_record(&blk) click to toggle source
# File lib/workout.rb, line 78
        def rescuing_with_active_record(&blk)
  rescuing_without_active_record do
    blk.call
  end
rescue ActiveRecord::ActiveRecordError => e
  fail({
    message: e.message,
    subject: e.record,
    exception: e,
    throw: false
  })
  self
end
rescuing_without_active_record(&blk) click to toggle source
# File lib/workout.rb, line 92
        def rescuing_without_active_record(&blk)
  blk.call
  self
rescue StandardError => e
  fail({
    message: e.message,
    subject: e,
    exception: e,
    throw: false
  })
  self
end