hero 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -36,7 +36,7 @@ you have a lump of spaghetti that's difficult to maintain and even harder to imp
36
36
 
37
37
  Hero provides a simple pattern that encourages you to
38
38
  <a href="http://en.wikipedia.org/wiki/Decomposition_(computer_science)">decompose</a>
39
- these processes into managable chunks. And the best part... the components can be easily tested.
39
+ these processes into managable chunks.
40
40
 
41
41
  ---
42
42
 
@@ -48,6 +48,8 @@ gem install hero
48
48
 
49
49
  Lets model a business process for collecting the top news stories from Hacker News, Reddit, & Google and then emailing the results to someone.
50
50
 
51
+ ---
52
+
51
53
  Gather News
52
54
 
53
55
  - Get news from Hacker News
@@ -55,28 +57,30 @@ Gather News
55
57
  - Get news from Google
56
58
  - Email Results
57
59
 
60
+ ---
61
+
58
62
  Now that we have the basic requirements, lets model it with Hero.
59
63
 
60
64
  ```ruby
61
- Hero::Formula[:gather_news].add_step :hacker_news do |context|
65
+ Hero::Formula[:gather_news].add_step :hacker_news do |context, options|
62
66
  # make api call
63
67
  # parse results
64
68
  # append results to context
65
69
  end
66
70
 
67
- Hero::Formula[:gather_news].add_step :reddit do |context|
71
+ Hero::Formula[:gather_news].add_step :reddit do |context, options|
68
72
  # make api call
69
73
  # parse results
70
74
  # append results to context
71
75
  end
72
76
 
73
- Hero::Formula[:gather_news].add_step :google do |context|
77
+ Hero::Formula[:gather_news].add_step :google do |context, options|
74
78
  # make api call
75
79
  # parse results
76
80
  # append results to context
77
81
  end
78
82
 
79
- Hero::Formula[:gather_news].add_step :email do |context|
83
+ Hero::Formula[:gather_news].add_step :email do |context, options|
80
84
  # format news for email
81
85
  # compose the email
82
86
  # send the email
@@ -108,14 +112,16 @@ And we're done.
108
112
 
109
113
  ### Key take aways
110
114
 
111
- - **The implementation aligns perfectly with the requirements.**
112
- *This means that developers and business folks can talk the same lingo.*
115
+ - The implementation aligns perfectly with the requirements.
116
+ *Developers and business folks can talk the same lingo.*
117
+
118
+ - The formula is composed of smaller steps that are interchangable.
119
+ *We are poised for changing requirements.*
120
+
121
+ - Steps can be tested independently.
113
122
 
114
- - **The formula is composed of smaller steps that are interchangable.**
115
- *This means we are poised for changing requirements.*
123
+ - Each step implements the interface: `def call(context, options)`
116
124
 
117
- - **Each step implements the interface `def call(context)`**
118
- *This means we can create step classes to simplify the app structure.*
119
125
 
120
126
  ## Next Steps
121
127
 
@@ -124,7 +130,7 @@ Here's an example.
124
130
 
125
131
  ```ruby
126
132
  # this
127
- Hero::Formula[:gather_news].add_step :hacker_news do |context|
133
+ Hero::Formula[:gather_news].add_step :hacker_news do |context, options|
128
134
  # make api call
129
135
  # parse results
130
136
  # append results to context
@@ -134,7 +140,7 @@ end
134
140
  module GatherNews
135
141
  class HackerNews
136
142
 
137
- def call(context)
143
+ def call(context, options)
138
144
  # make api call
139
145
  # parse results
140
146
  # append results to context
@@ -169,7 +175,7 @@ Hero::Formula[:gather_news].add_step :google, GatherNews::Google.new
169
175
  Hero::Formula[:gather_news].add_step :email, GatherNews::Email.new
170
176
  ```
171
177
 
172
- Now we have a well structured application that is ready to grow.
178
+ Now we have a well structured application thats ready to grow.
173
179
  Notice how well organized everything is.
174
180
 
175
181
  Also note that we can write tests for each step independent of anything else.
data/lib/hero/observer.rb CHANGED
@@ -59,13 +59,18 @@ module Hero
59
59
  # @param optional [Hash] options An option Hash to be passed to each step.
60
60
  def update(context=nil, options={})
61
61
  steps.each do |step|
62
- log_step(:before, step, context, options)
63
- step.last.call(context, options)
64
- log_step(:after, step, context, options)
62
+ log_step(:info, :before, step, context, options)
63
+ begin
64
+ step.last.call(context, options)
65
+ rescue Exception => ex
66
+ log_step(:error, :after, step, context, options)
67
+ raise ex
68
+ end
69
+ log_step(:info, :after, step, context, options)
65
70
  end
66
71
  end
67
72
 
68
- private
73
+ private
69
74
 
70
75
  # Logs a step to the registered Hero.logger.
71
76
  # @note Users info for the log level.
@@ -73,9 +78,9 @@ module Hero
73
78
  # @param [Object] step
74
79
  # @param [Object] context
75
80
  # @param [Object] options
76
- def log_step(id, step, context, options)
81
+ def log_step(level, id, step, context, options)
77
82
  return unless Hero.logger
78
- Hero.logger.info "HERO #{id.to_s.ljust(6)} #{formula_name} -> #{step.first} Context: #{context.inspect} Options: #{options.inspect}"
83
+ Hero.logger.send level, "HERO #{id.to_s.ljust(6)} #{formula_name} -> #{step.first} Context: #{context.inspect} Options: #{options.inspect}"
79
84
  end
80
85
 
81
86
  end
data/spec/formula_spec.rb CHANGED
@@ -118,10 +118,9 @@ describe Hero::Formula do
118
118
  it "should support logging" do
119
119
  class TestLogger
120
120
  attr_reader :buffer
121
- def info(value)
122
- @buffer ||= []
123
- @buffer << value
124
- end
121
+ def initialize; @buffer = []; end
122
+ def info(value); @buffer << value; end
123
+ alias :error :info
125
124
  end
126
125
  Hero.logger = TestLogger.new
127
126
 
@@ -136,6 +135,21 @@ describe Hero::Formula do
136
135
  assert_equal "HERO after test_formula -> two Context: [1, 2] Options: {:step=>2}", Hero.logger.buffer[3]
137
136
  end
138
137
 
138
+ it "should support logging errors" do
139
+ class TestLogger
140
+ attr_reader :info_count, :error_count, :buffer
141
+ def initialize; @info_count = 0; @error_count = 0; @buffer = []; end
142
+ def info(value); @info_count += 1; @buffer << value; end
143
+ def error(value); @error_count += 1; @buffer << value; end
144
+ end
145
+ Hero.logger = TestLogger.new
146
+ Hero::Formula[:test_formula].add_step(:one) { |list, opts| raise Exception.new("fubar") }
147
+ assert_raise(Exception) { Hero::Formula[:test_formula].run }
148
+ assert_equal Hero.logger.buffer.length, 2
149
+ assert_equal Hero.logger.info_count, 1
150
+ assert_equal Hero.logger.error_count, 1
151
+ end
152
+
139
153
  end
140
154
 
141
155
  end
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.7
4
+ version: 0.0.8
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-26 00:00:00.000000000 Z
12
+ date: 2012-08-27 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! ' Simplify your apps with Hero.
15
15