Skip to content

Commit

Permalink
Merge 9b8c795 into 4d95325
Browse files Browse the repository at this point in the history
  • Loading branch information
snusnu committed Jul 22, 2013
2 parents 4d95325 + 9b8c795 commit 312a456
Show file tree
Hide file tree
Showing 128 changed files with 1,857 additions and 1,192 deletions.
8 changes: 5 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ source 'http://rubygems.org'
gemspec

group :test do
gem 'ducktrap', '~> 0.0.1'
gem 'vanguard', '~> 0.0.3'
gem 'anima', '~> 0.0.6'
gem 'oj', '~> 2.0.13'
gem 'multi_json', '~> 1.7.3'
gem 'ducktrap', '~> 0.0.1'
gem 'vanguard', '~> 0.0.3'
gem 'anima', '~> 0.0.6'
end

group :development do
Expand Down
22 changes: 9 additions & 13 deletions Gemfile.devtools
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,30 @@ group :guard do

# file system change event handling
gem 'listen', '~> 1.2.2'
gem 'rb-fchange', '~> 0.0.6', :require => false
gem 'rb-fsevent', '~> 0.9.3', :require => false
gem 'rb-inotify', '~> 0.9.0', :require => false
gem 'rb-fchange', '~> 0.0.6', require: false
gem 'rb-fsevent', '~> 0.9.3', require: false
gem 'rb-inotify', '~> 0.9.0', require: false

# notification handling
gem 'libnotify', '~> 0.8.0', :require => false
gem 'rb-notifu', '~> 0.0.4', :require => false
gem 'terminal-notifier-guard', '~> 1.5.3', :require => false
gem 'libnotify', '~> 0.8.0', require: false
gem 'rb-notifu', '~> 0.0.4', require: false
gem 'terminal-notifier-guard', '~> 1.5.3', require: false
end

group :metrics do
gem 'coveralls', '~> 0.6.7'
gem 'flay', '~> 2.3.1'
gem 'flog', '~> 4.1.1'
gem 'reek', '~> 1.3.1', :git => 'https://github.com/troessner/reek.git'
gem 'rubocop', '~> 0.9.1', :git => 'https://github.com/bbatsov/rubocop.git'
gem 'reek', '~> 1.3.1', git: 'https://github.com/troessner/reek.git'
gem 'rubocop', '~> 0.10.0', git: 'https://github.com/bbatsov/rubocop.git'
gem 'simplecov', '~> 0.7.1'
gem 'yardstick', '~> 0.9.6'

platforms :ruby_19, :ruby_20 do
gem 'mutant', '~> 0.3.0.beta17'
gem 'mutant', '~> 0.3.0.beta18'
gem 'yard-spellcheck', '~> 0.1.5'
end

platforms :ruby_19 do
gem 'json', '~> 1.8.0'
end

platforms :rbx do
gem 'pelusa', '~> 0.2.2'
end
Expand Down
2 changes: 1 addition & 1 deletion Guardfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ guard :bundler do
watch('Gemfile')
end

guard :rspec, :all_on_start => false, :all_after_pass => false do
guard :rspec, :all_on_start => false, :all_after_pass => false, :cli => '--fail-fast --seed 1' do
# run all specs if the spec_helper or supporting files files are modified
watch('spec/spec_helper.rb') { 'spec/unit' }
watch(%r{\Aspec/(?:lib|support|shared)/.+\.rb\z}) { 'spec/unit' }
Expand Down
2 changes: 1 addition & 1 deletion config/flay.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
threshold: 9
total_score: 125
total_score: 159 # TODO bring it back from 160 closer to the previous 125
1 change: 1 addition & 0 deletions config/reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ LongParameterList:
- Substation::Chain::DSL::Builder#define_dsl_method
- Substation::Chain#self.failure_response
- Substation::Chain#on_failure
- Substation::Environment::DSL#register
max_params: 2
LongYieldList:
enabled: true
Expand Down
5 changes: 4 additions & 1 deletion config/rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ SingleLineMethods:
Enabled: false

LineLength:
Max: 106 # the offending lines are in specs, sadly this means global disabling for now
Max: 112 # the offending lines are in specs, sadly this means global disabling for now

MethodLength:
Max: 12 # reek performs these checks anyway

CaseIndentation:
Enabled: false

Lambda:
Enabled: false # i personally like the look of multiline ->(arg) {} lambdas
16 changes: 13 additions & 3 deletions lib/substation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,22 @@ module Substation

end

require 'substation/request'
require 'substation/response'
require 'substation/response/api'
require 'substation/response/success'
require 'substation/response/failure'
require 'substation/processor'
require 'substation/processor/builder'
require 'substation/processor/config'
require 'substation/processor/executor'
require 'substation/processor/evaluator'
require 'substation/processor/wrapper'
require 'substation/processor/evaluator/result'
require 'substation/processor/evaluator/result/success'
require 'substation/processor/evaluator/result/failure'
require 'substation/processor/evaluator/handler'
require 'substation/processor/transformer'
require 'substation/request'
require 'substation/response'
require 'substation/processor/wrapper'
require 'substation/action'
require 'substation/chain'
require 'substation/chain/dsl'
Expand Down
4 changes: 2 additions & 2 deletions lib/substation/chain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class Chain
include Adamantium::Flat

# Empty chain
EMPTY = Class.new(self).new(EMPTY_ARRAY, EMPTY_ARRAY)
EMPTY = new(EMPTY_ARRAY, EMPTY_ARRAY)

# Return a failure response
#
Expand All @@ -88,7 +88,7 @@ class Chain
#
# @api private
def self.failure_response(request, data, exception)
Response::Failure.new(request, FailureData.new(data, exception))
Response::Failure.new(request.with_input(data), FailureData.new(data, exception))
end

# Call the chain
Expand Down
14 changes: 8 additions & 6 deletions lib/substation/chain/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def initialize(registry)
#
# @api private
def compile_dsl
@registry.each_with_object(Class.new(DSL)) { |(name, processor), dsl|
define_dsl_method(name, processor, dsl)
@registry.each_with_object(Class.new(DSL)) { |(name, builder), dsl|
define_dsl_method(name, builder, dsl)
}
end

Expand All @@ -60,18 +60,20 @@ def compile_dsl
# @param [Symbol] name
# the name of the method
#
# @param [#call] processor
# the processor to use within the chain
# @param [Processor::Builder] builder
# the processor builder to use within the chain
#
# @param [Class<DSL>] dsl
# the {DSL} subclass to define the method on
#
# @return [undefined]
#
# @api private
def define_dsl_method(name, processor, dsl)
def define_dsl_method(name, builder, dsl)
dsl.class_eval do
define_method(name) { |*args| use(processor.new(name, *args)) }
define_method(name) { |handler, failure_chain = Chain::EMPTY|
use(builder.call(handler, failure_chain))
}
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/substation/environment/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def initialize(&block)
# @return [self]
#
# @api private
def register(name, processor)
@registry[name.to_sym] = processor
def register(name, processor, executor = Processor::Executor::NULL)
@registry[name.to_sym] = Processor::Builder.new(name, processor, executor)
self
end

Expand Down
147 changes: 115 additions & 32 deletions lib/substation/processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,42 @@ module Substation
# Namespace for chain processors
module Processor

include Equalizer.new(:name, :config)
include Adamantium::Flat

# Initialize a new instance
#
# @param [Symbol] name
# the processor's name
#
# @param [Config] config
# the processor's configuration
#
# @return [undefined]
#
# @api private
def initialize(name, config)
@name = name
@config = config
@handler = @config.handler
@failure_chain = @config.failure_chain
@executor = @config.executor
end

# This processor's name
#
# @return [Symbol]
#
# @api private
attr_reader :name

# This processor's config
#
# @return [Builder::Config]
#
# @api private
attr_reader :config

# Test wether chain processing should continue
#
# @param [Response] response
Expand All @@ -31,15 +67,59 @@ def result(response)
response
end

module Fallible
include Concord.new(:name, :handler, :failure_chain)
private

# This processor's name
#
# @return [Symbol]
#
# @api private
attr_reader :name
attr_reader :handler
attr_reader :failure_chain
attr_reader :executor

def execute(state)
compose(state, invoke(decompose(state)))
end

# Transform response data into something else
#
# @param [Response] response
# the response to process
#
# @return [Response]
#
# @api private
def invoke(state)
handler.call(state)
end

# Decompose +input+ before processing
#
# @param [Request, Response] input
# the object to decompose
#
# @return [Object]
# the decomposed object
#
# @api private
def decompose(input)
executor.decompose(input)
end

# Compose a new object based on +input+ and +output+
#
# @param [Request, Response] input
# the input as it was before calling {#decompose}
#
# @param [Object] output
# the data used to compose a new object
#
# @return [Object]
# the composed object
#
# @api private
def compose(input, output)
executor.compose(input, output)
end

# Supports {Processor} instances with a defined failure {Chain}
module Fallible

# Return a new processor with +chain+ as failure_chain
#
Expand All @@ -50,10 +130,11 @@ module Fallible
#
# @api private
def with_failure_chain(chain)
self.class.new(name, handler, chain)
self.class.new(name, config.with_failure_chain(chain))
end
end

# Supports incoming {Processor} instances
module Incoming
include Processor
include Fallible
Expand All @@ -72,28 +153,22 @@ def result(_response)
end
end

# Supports pivot {Processor} instances
module Pivot
include Processor
include Fallible
end

# Supports outgoing {Processor} instances
module Outgoing
include Concord.new(:name, :handler)
include Processor

# This processor's name
#
# @return [Symbol]
#
# @api private
attr_reader :name

# Test wether chain processing should continue
#
# @param [Response] _response
# the response returned from invoking the processor
#
# @return [false]
# @return [true]
#
# @api private
def success?(_response)
Expand All @@ -119,34 +194,42 @@ def respond_with(response, output)

end # module Outgoing

# Namespace for modules that help with processor api compatibility
module API
# Namespace for modules providing {#call} implementations
module Call

# Indicate successful processing
module Success
# Provides {Processor#call} for incoming processors
module Incoming

# Test wether evaluation was successful
# Call the processor
#
# @return [true]
# @param [Request] request
# the request to process
#
# @return [Response::Success]
#
# @api private
def success?
true
def call(request)
request.success(execute(request))
end
end

# Indicate errorneous processing
module Failure
# Provides {Processor#call} for outgoing processors
module Outgoing

# Test wether evaluation was successful
# Call the processor
#
# @param [Response] response
# the response to process
#
# @return [false]
# @return [Response]
# a new instance of the same class as +response+
#
# @api private
def success?
false
def call(response)
respond_with(response, execute(response))
end
end
end

end # module Processor
end # module Substation

0 comments on commit 312a456

Please sign in to comment.