hero 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/hero/formula.rb +91 -13
- data/lib/hero/observer.rb +9 -12
- data/spec/formula_spec.rb +2 -2
- metadata +3 -2
data/lib/hero/formula.rb
CHANGED
@@ -5,31 +5,65 @@ require File.join(File.dirname(__FILE__), "observer")
|
|
5
5
|
|
6
6
|
module Hero
|
7
7
|
|
8
|
+
# Represents a business process that can be easily modeled and implemented.
|
9
|
+
#
|
10
|
+
# The idea is to encourage implementations that more closely resemble
|
11
|
+
# business requirements in order to reduce the dissonance
|
12
|
+
# that is typical between business nomenclature and actual implementation.
|
13
|
+
#
|
14
|
+
# Additional benefits include:
|
15
|
+
# * Composable units of code which support changing requirements
|
16
|
+
# * Testable components
|
17
|
+
# * Simplified implementation
|
18
|
+
#
|
19
|
+
# @example A basic example.
|
20
|
+
# Hero::Formula[:checkout].add_step(:total) do |context, options|
|
21
|
+
# # total order (apply discounts etc...)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Hero::Formula[:checkout].add_step(:charge) do |context, options|
|
25
|
+
# # charge for order (handle failure and timeouts gracefully etc...)
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# Hero::Formula[:checkout].add_step(:complete) do |context, options|
|
29
|
+
# # handle shipping arrangements and follow up email etc...
|
30
|
+
# end
|
8
31
|
class Formula
|
9
32
|
|
10
33
|
# Class attributes & methods ==============================================
|
11
34
|
class << self
|
12
35
|
extend Forwardable
|
36
|
+
|
37
|
+
# Iterates over all registered formulas.
|
13
38
|
def_delegator :formulas, :each, :each
|
39
|
+
|
40
|
+
# Indicates the total number of registered formulas.
|
14
41
|
def_delegator :formulas, :length, :count
|
15
42
|
|
16
|
-
|
43
|
+
# Returns a string representation of all registered formulas.
|
44
|
+
def to_s
|
17
45
|
value = []
|
18
|
-
each
|
19
|
-
value << formula.publish
|
20
|
-
end
|
46
|
+
each { |name, formula| value << formula.to_s }
|
21
47
|
value.join("\n\n")
|
22
48
|
end
|
23
49
|
|
50
|
+
# Removes all registered formulas.
|
24
51
|
def reset
|
25
52
|
formulas.values.each { |f| f.delete_observers }
|
26
53
|
@formulas = {}
|
27
54
|
end
|
28
55
|
|
56
|
+
# Returns the named formula.
|
57
|
+
# @note Implicitly registers the formula if it has not already been registered.
|
58
|
+
# @param [Symbol, String] name The name of the formula.
|
59
|
+
# @return Hero::Formula
|
29
60
|
def [](name)
|
30
61
|
formulas[name] ||= register(name)
|
31
62
|
end
|
32
63
|
|
64
|
+
# Registers a formula an prepares it to receive steps.
|
65
|
+
# @param [Symbol, String] name The name of the formula.
|
66
|
+
# @return Hero::Formula
|
33
67
|
def register(name)
|
34
68
|
observer = Hero::Observer.new(name)
|
35
69
|
formula = Class.new(Hero::Formula).instance
|
@@ -43,6 +77,7 @@ module Hero
|
|
43
77
|
|
44
78
|
private
|
45
79
|
|
80
|
+
# Returns a Hash of all registered formulas.
|
46
81
|
def formulas
|
47
82
|
@formulas ||= {}
|
48
83
|
end
|
@@ -53,18 +88,47 @@ module Hero
|
|
53
88
|
include Observable
|
54
89
|
include Singleton
|
55
90
|
|
56
|
-
|
91
|
+
# The name of this formula.
|
92
|
+
attr_reader :name
|
93
|
+
|
94
|
+
# The observer attached to this formula.
|
95
|
+
attr_reader :observer
|
96
|
+
|
97
|
+
# All registered steps.
|
57
98
|
def_delegator :observer, :steps, :steps
|
58
|
-
def_delegator :observer, :add_step, :add_step
|
59
99
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
100
|
+
# Adds a step to be executed when this formula is run.
|
101
|
+
# @note Steps are called in the order they are added. 1st in 1st invoked.
|
102
|
+
#
|
103
|
+
# @example A step must implement the interface.
|
104
|
+
# def call(*args)
|
105
|
+
#
|
106
|
+
# # or more specifically
|
107
|
+
# def call(context, options={})
|
108
|
+
#
|
109
|
+
# @example Add a step using a block.
|
110
|
+
# add_step(:my_step) do |context, options|
|
111
|
+
# # logic here...
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
# @example Add a step using an Object.
|
115
|
+
# class MyStep
|
116
|
+
# def self.call(context, options={})
|
117
|
+
# # logic here...
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
# add_step(:my_step, MyStep)
|
122
|
+
#
|
123
|
+
# @param [Symbol, String] name The name of the step.
|
124
|
+
# @param optional [Object] step The step to be executed.
|
125
|
+
# @block optional [Object] A block to use as the step to be executed.
|
126
|
+
def_delegator :observer, :add_step, :add_step
|
67
127
|
|
128
|
+
# Observable notify implementation.
|
129
|
+
# Invokes #update on all observers.
|
130
|
+
# @param optional [Object] context The context to be passed to each step.
|
131
|
+
# @param optional [Hash] options An option Hash to be passed to each step.
|
68
132
|
def notify(context=nil, options={})
|
69
133
|
changed
|
70
134
|
notify_observers(context, options)
|
@@ -72,6 +136,20 @@ module Hero
|
|
72
136
|
|
73
137
|
alias :run :notify
|
74
138
|
|
139
|
+
# Returns a String representation of the formula.
|
140
|
+
# @example
|
141
|
+
# Hero::Formula[:example].add_step(:one) {}
|
142
|
+
# Hero::Formula[:example].add_step(:two) {}
|
143
|
+
# Hero::Formula[:example].add_step(:three) {}
|
144
|
+
# Hero::Formula[:example].to_s # => "example\n 1. one\n 2. two\n 3. three"
|
145
|
+
def to_s
|
146
|
+
value = [name]
|
147
|
+
steps.each_with_index do |step, index|
|
148
|
+
value << "#{(index + 1).to_s.rjust(3)}. #{step.first}"
|
149
|
+
end
|
150
|
+
value.join("\n")
|
151
|
+
end
|
152
|
+
|
75
153
|
end
|
76
154
|
end
|
77
155
|
|
data/lib/hero/observer.rb
CHANGED
@@ -19,23 +19,20 @@ module Hero
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# Adds a step to be executed when the Hero::Formula is run.
|
22
|
+
# @note Steps are called in the order they are added. 1st in 1st invoked.
|
22
23
|
#
|
23
|
-
# @example A step must implement the interface
|
24
|
+
# @example A step must implement the interface.
|
24
25
|
# def call(*args)
|
25
26
|
#
|
26
|
-
#
|
27
|
+
# # or more specifically
|
27
28
|
# def call(context, options={})
|
28
29
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# @note Steps are called in the order they are added. 1st in 1st called
|
32
|
-
#
|
33
|
-
# @example
|
30
|
+
# @example Add a step using a block.
|
34
31
|
# add_step(:my_step) do |context, options|
|
35
32
|
# # logic here...
|
36
33
|
# end
|
37
34
|
#
|
38
|
-
# @example
|
35
|
+
# @example Add a step using an Object.
|
39
36
|
# class MyStep
|
40
37
|
# def self.call(context, options={})
|
41
38
|
# # logic here...
|
@@ -46,7 +43,7 @@ module Hero
|
|
46
43
|
#
|
47
44
|
# @param [Symbol, String] name The name of the step.
|
48
45
|
# @param optional [Object] step The step to be executed.
|
49
|
-
# @
|
46
|
+
# @block optional [Object] A block to use as the step to be executed.
|
50
47
|
def add_step(name, step=nil, &block)
|
51
48
|
steps.delete_if { |s| s.first == name }
|
52
49
|
step ||= block if block_given?
|
@@ -58,9 +55,9 @@ module Hero
|
|
58
55
|
#
|
59
56
|
# @note A log message will be written to Hero.logger for each step that is called if Hero.logger has been set.
|
60
57
|
#
|
61
|
-
# @param [Object] context The context to be passed to each step.
|
62
|
-
# @param [Hash] options An option Hash to be passed to each step.
|
63
|
-
def update(context, options={})
|
58
|
+
# @param optional [Object] context The context to be passed to each step.
|
59
|
+
# @param optional [Hash] options An option Hash to be passed to each step.
|
60
|
+
def update(context=nil, options={})
|
64
61
|
steps.each do |step|
|
65
62
|
if Hero.logger
|
66
63
|
Hero.logger.info "HERO Formula: #{formula_name}, Step: #{step.first}, Context: #{context.inspect}, Options: #{options.inspect}"
|
data/spec/formula_spec.rb
CHANGED
@@ -54,7 +54,7 @@ describe Hero::Formula do
|
|
54
54
|
Hero::Formula[:second].add_step(:four) {}
|
55
55
|
|
56
56
|
expected = "first 1. one 2. two 3. three 4. foursecond 1. one 2. two 3. three 4. four"
|
57
|
-
assert_equal Hero::Formula.
|
57
|
+
assert_equal Hero::Formula.to_s.gsub(/\n/, ""), expected
|
58
58
|
end
|
59
59
|
|
60
60
|
describe "a registered formula" do
|
@@ -112,7 +112,7 @@ describe Hero::Formula do
|
|
112
112
|
Hero::Formula[:test_formula].add_step(:three) {}
|
113
113
|
Hero::Formula[:test_formula].add_step(:four) {}
|
114
114
|
expected = "test_formula 1. one 2. two 3. three 4. four"
|
115
|
-
assert_equal Hero::Formula[:test_formula].
|
115
|
+
assert_equal Hero::Formula[:test_formula].to_s.gsub(/\n/, ""), expected
|
116
116
|
end
|
117
117
|
|
118
118
|
it "should support logging" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hero
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! ' Simplify your apps with Hero.
|
15
15
|
|
@@ -55,3 +55,4 @@ signing_key:
|
|
55
55
|
specification_version: 3
|
56
56
|
summary: Business process modeling for the Rubyist
|
57
57
|
test_files: []
|
58
|
+
has_rdoc:
|