ibsciss-middleware 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab6d4d8a9225726d9aa68a41d4be42bcac71bc23
4
- data.tar.gz: 4df6dce76dca18f51c8af01a3be56e5861d8fe4e
3
+ metadata.gz: 45a7f568a5dd19fa3ed4060972af8eab369d6cc7
4
+ data.tar.gz: 9324a50e02d47da8f6a4232db2d0f373dda717f5
5
5
  SHA512:
6
- metadata.gz: e33e2f98cc16cf4dcf6ee076cf1734b1cf8bac3ef17daf7d8aa97636510d739e4af7f851d0adacb75444844e3c9eba401e5f22c787406adac6badab48ffc7ab4
7
- data.tar.gz: c9f1537de72e76797a690c23646640655ca9ed4adfbefae661bef899cac998efb073d199ab9ec3854de9a4cbfa9d4e36322b24d2c201be2530528fcafd9cb734
6
+ metadata.gz: cc1c0601887f79ce0580705cf7031124315cc25109703765f1b92e66147c8c2ef79b2ee9ffca951ff7bb4ef739bebdf8d21f3ec226fab2630852fa073be45204
7
+ data.tar.gz: ad2c8c9a03d3da09664e879322906b405423e0fdb8cd801da3fab30c0cfba90ea0529aeeea330a5c1bb4ff28d4922b20f0b61249ab1c7ab57d6d5c161a9dcd94
@@ -1,5 +1,14 @@
1
+ ## 0.4.0
2
+ - Add a name displayed in the logger & inspect methods
3
+ - Add a logger middleware
4
+ - Fixed rubocop offenses
5
+ - Fix builder#inspect to display class name
6
+
1
7
  ## 0.3.2
2
- - Add CI & Code Climate & Improve documentation
8
+ - Add CI, Code Climate, Gitter & Improve documentation
9
+ - Add `insert_after_each` and `insert_before_each` methods
10
+ - Improve the `inspect` method to a more readable version
11
+ - Enable lambda to receive additional arguments
3
12
 
4
13
  ## 0.3.1
5
14
  - Enable lambda to change the given object
data/README.md CHANGED
@@ -140,18 +140,17 @@ A basic description of the two methods that a middleware must implement:
140
140
  state sent in (defined by the caller, but usually a Hash). This call should also
141
141
  call `app.call(env)` at some point to move on.
142
142
 
143
- This architecture offers the biggest advantage of letting you enhance the env variable before passing it to the next middleware,
144
- and giving you the abilities to change the returned datas, as follow:
143
+ This architecture offers the biggest advantage of letting you enhance the `env` variable before passing it to the next middleware, and giving you the ability to change the returned data, as follows:
145
144
 
146
145
  ```ruby
147
146
  class Greeting
148
- def initialize(app, append = nil)
147
+ def initialize(app, datas = nil)
149
148
  @app = app
150
149
  @datas = datas
151
150
  end
152
151
 
153
152
  def call(env)
154
- env = "#{append} #{env}"
153
+ env = "#{@datas} #{env}"
155
154
  result = @app(env)
156
155
  "#{result} !"
157
156
  end
@@ -205,6 +204,12 @@ end.call()
205
204
  The call method takes an optional parameter which is the state to pass into the
206
205
  initial middleware.
207
206
 
207
+ You can optionally set a name, that will be displayed in inspect and for logging purpose, for the current middleware:
208
+
209
+ ```ruby
210
+ Middleware::Builder.new(name: 'MyPersonalMiddleware')
211
+ ```
212
+
208
213
  ### Manipulating a Stack
209
214
 
210
215
  Stacks also provide a set of methods for manipulating the middleware stack. This
@@ -254,7 +259,7 @@ stack.insert_before_each logger
254
259
  #### Replace
255
260
 
256
261
  ```ruby
257
- # Replace the first middleware
262
+ # Replace the second middleware
258
263
  stack.replace(1, SomeOtherMiddleware)
259
264
 
260
265
  # Replace the Trace middleware
@@ -264,7 +269,7 @@ stack.replace(Trace, SomeOtherMiddleware)
264
269
  #### Delete
265
270
 
266
271
  ```ruby
267
- # Delete the lambda
272
+ # Delete the second middleware
268
273
  stack.delete(1)
269
274
 
270
275
  # Delete the Trace middleware
@@ -304,7 +309,7 @@ Note that you can also pass blocks in using the `use` method.
304
309
 
305
310
  #### Lambda
306
311
 
307
- Lambda work the same with additional arguments:
312
+ Lambda work the same, with additional arguments:
308
313
 
309
314
  ```ruby
310
315
  Middleware::Builder.new { |b|
@@ -324,8 +329,50 @@ Middleware::Builder.new { |b|
324
329
  }.inspect
325
330
  ```
326
331
 
327
- the output will be
332
+ It will output:
333
+
334
+ ```ruby
335
+ Middleware[Trace(), Echo("Hello, World!")]
336
+ ```
337
+
338
+ _If you have set a name, it will be displayed instead of `Middleware`_.
339
+
340
+ #### Logging
341
+
342
+ A built-in logging mechanism is provided, it will output for each provider of the stack:
343
+
344
+ - The provided arguments
345
+ - The returned values (the first 255 chars) and the time (in milliseconds) elapsed in the call method
346
+
347
+ To initialize the logging you must provide a valid logger instance to `#inject_logger`.
348
+
349
+ It is also recommended to give a name to your middleware stack.
328
350
 
329
351
  ```ruby
330
- [Trace(), Echo("Hello, World!")]
331
- ```
352
+ require 'logger'
353
+
354
+ class UpperCaseMiddleware
355
+ def initialize app
356
+ @app = app
357
+ end
358
+
359
+ def call env
360
+ sleep(1)
361
+ env.upcase
362
+ end
363
+ end
364
+
365
+ # Build the middleware:
366
+ Middleware::Builder.new(name: 'MyMiddleware') { |b|
367
+ b.use UpperCaseMiddleware
368
+ }.inject_logger(Logger.new(STDOUT)).call('a message')
369
+ ```
370
+
371
+ It will output something like:
372
+
373
+ ```
374
+ INFO -- MyMiddleware: UpperCaseMiddleware has been called with: "a message"
375
+ INFO -- MyMiddleware: UpperCaseMiddleware finished in 1001 ms and returned: "A MESSAGE"
376
+ ```
377
+
378
+ _Note: the provided logger instance must respond to `#call(level severity, message, app name)`_
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
- require "rspec/core/rake_task"
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
4
 
5
5
  # RSpec test task
6
6
  RSpec::Core::RakeTask.new
7
7
 
8
8
  # Make sure the default is to run RSpec
9
- task :default => "spec"
9
+ task default: 'spec'
@@ -1,2 +1,2 @@
1
- require "middleware/builder"
2
- require "middleware/runner"
1
+ require 'middleware/builder'
2
+ require 'middleware/runner'
@@ -17,6 +17,7 @@ module Middleware
17
17
  # app.call(7)
18
18
  #
19
19
  class Builder
20
+
20
21
  # Initializes the builder. An optional block can be passed which
21
22
  # will either yield the builder or be evaluated in the context of the instance.
22
23
  #
@@ -37,9 +38,10 @@ module Middleware
37
38
  # in which knows how to run them.
38
39
  # @yield [] Evaluated in this instance which allows you to use methods
39
40
  # like {#use} and such.
40
- def initialize(opts=nil, &block)
41
+ def initialize(opts = nil, &block)
41
42
  opts ||= {}
42
43
  @runner_class = opts[:runner_class] || Runner
44
+ @middleware_name = opts[:name] || 'Middleware'
43
45
 
44
46
  if block_given?
45
47
  if block.arity == 1
@@ -50,12 +52,17 @@ module Middleware
50
52
  end
51
53
  end
52
54
 
55
+ # Returns the name of the current middleware
56
+ def name
57
+ @middleware_name
58
+ end
59
+
53
60
  # Returns a mergeable version of the builder. If `use` is called with
54
61
  # the return value of this method, then the stack will merge, instead
55
62
  # of being treated as a separate single middleware.
56
63
  def flatten
57
64
  lambda do |env|
58
- self.call(env)
65
+ call(env)
59
66
  end
60
67
  end
61
68
 
@@ -65,11 +72,11 @@ module Middleware
65
72
  #
66
73
  # @param [Class] middleware The middleware class
67
74
  def use(middleware, *args, &block)
68
- if middleware.kind_of?(Builder)
75
+ if middleware.is_a?(Builder)
69
76
  # Merge in the other builder's stack into our own
70
- self.stack.concat(middleware.stack)
77
+ stack.concat(middleware.stack)
71
78
  else
72
- self.stack << [middleware, args, block]
79
+ stack << [middleware, args, block]
73
80
  end
74
81
 
75
82
  self
@@ -79,7 +86,7 @@ module Middleware
79
86
  # given middleware object.
80
87
  def insert(index, middleware, *args, &block)
81
88
  index = self.index(index) unless index.is_a?(Integer)
82
- raise "no such middleware to insert before: #{index.inspect}" unless index
89
+ fail "no such middleware to insert before: #{index.inspect}" unless index
83
90
  stack.insert(index, [middleware, args, block])
84
91
  end
85
92
 
@@ -88,7 +95,7 @@ module Middleware
88
95
  # Inserts a middleware after the given index or middleware object.
89
96
  def insert_after(index, middleware, *args, &block)
90
97
  index = self.index(index) unless index.is_a?(Integer)
91
- raise "no such middleware to insert after: #{index.inspect}" unless index
98
+ fail "no such middleware to insert after: #{index.inspect}" unless index
92
99
  insert(index + 1, middleware, *args, &block)
93
100
  end
94
101
 
@@ -125,14 +132,22 @@ module Middleware
125
132
  end
126
133
 
127
134
  # Runs the builder stack with the given environment.
128
- def call(env=nil)
135
+ def call(env = nil)
129
136
  to_app.call(env)
130
137
  end
131
138
 
132
139
  def inspect
133
- "[" + stack.reduce([]) { |carry, middleware|
134
- carry << "#{middleware[0].class.name}(#{middleware[1].join(', ')})"
135
- }.join(', ') + "]"
140
+ name+'[' + stack.reduce([]) do |carry, middleware|
141
+ name = middleware[0].is_a?(Proc) ? 'Proc' : middleware[0].name
142
+
143
+ carry << "#{name}(#{middleware[1].join(', ')})"
144
+ end.join(', ') + ']'
145
+ end
146
+
147
+ def inject_logger logger
148
+ insert_before_each Middleware::Logger, logger, name
149
+
150
+ self
136
151
  end
137
152
 
138
153
  protected
@@ -160,9 +175,7 @@ module Middleware
160
175
  # you shouldn't use this method
161
176
  #
162
177
  # @return [Array]
163
- def stack= stack
164
- @stack = stack
165
- end
178
+ attr_writer :stack
166
179
 
167
180
  # Converts the builder stack to a runnable action sequence.
168
181
  #
@@ -170,6 +183,5 @@ module Middleware
170
183
  def to_app
171
184
  @runner_class.new(stack.dup)
172
185
  end
173
-
174
186
  end
175
187
  end
@@ -0,0 +1,49 @@
1
+ require 'logger'
2
+ require 'pp'
3
+
4
+ module Middleware
5
+
6
+ class Logger
7
+ def initialize app, logger, name = nil
8
+ @app = app
9
+ @write_to = logger
10
+ @middleware_name = name
11
+ end
12
+
13
+ def call env
14
+ write(
15
+ way_in_message(
16
+ next_middleware_name, env
17
+ ))
18
+
19
+ time = Time.now
20
+
21
+ @app.call(env).tap { |env|
22
+ write(
23
+ way_out_message(
24
+ next_middleware_name, (Time.now - time) * 1000.0, env
25
+ ))
26
+ }
27
+ end
28
+
29
+ def next_middleware_name
30
+ @app.class.name
31
+ end
32
+
33
+ def pretty_print item
34
+ ->(out){ PP.pp(item, out) }.('')
35
+ end
36
+
37
+ def way_in_message name, env
38
+ ' %s has been called with: %s' % [name, pretty_print(env)]
39
+ end
40
+
41
+ def way_out_message name, time, value
42
+ ' %s finished in %.0f ms and returned: %s' % [name, time, pretty_print(value)]
43
+ end
44
+
45
+ def write msg
46
+ @write_to.add(::Logger::INFO, msg.slice(0, 255).strip!, @middleware_name)
47
+ end
48
+ end
49
+ end
@@ -4,7 +4,7 @@ module Middleware
4
4
  # in order, then reversing the order.
5
5
  class Runner
6
6
  # A middleware which does nothing
7
- EMPTY_MIDDLEWARE = lambda { |env| env }
7
+ EMPTY_MIDDLEWARE = ->(env) { env }
8
8
 
9
9
  # Build a new middleware runner with the given middleware
10
10
  # stack.
@@ -60,7 +60,7 @@ module Middleware
60
60
  next_middleware.call(klass.call(env, *args))
61
61
  end
62
62
  else
63
- raise "Invalid middleware, doesn't respond to `call`: #{klass.inspect}"
63
+ fail "Invalid middleware, doesn't respond to `call`: #{klass.inspect}"
64
64
  end
65
65
  end
66
66
  end
@@ -1,23 +1,23 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  Gem::Specification.new do |gem|
4
- gem.authors = ["Mitchell Hashimoto", "Arnaud Lemaire"]
5
- gem.email = ["mitchell.hashimoto@gmail.com", "alemaire@ibsciss.com"]
6
- gem.description = %q{Generalized implementation of the rack middleware abstraction for Ruby.}
7
- gem.summary = %q{Generalized implementation of the rack middleware abstraction for Ruby (chain of responsibility design pattern).}
8
- gem.homepage = "https://github.com/ibsciss/ruby-middleware"
9
- gem.license = "MIT"
4
+ gem.authors = ['Mitchell Hashimoto', 'Arnaud Lemaire']
5
+ gem.email = ['mitchell.hashimoto@gmail.com', 'alemaire@ibsciss.com']
6
+ gem.description = 'Generalized implementation of the rack middleware abstraction for Ruby.'
7
+ gem.summary = 'Generalized implementation of the rack middleware abstraction for Ruby (chain of responsibility design pattern).'
8
+ gem.homepage = 'https://github.com/ibsciss/ruby-middleware'
9
+ gem.license = 'MIT'
10
10
 
11
- gem.add_development_dependency "rake", "~> 10.4.2"
12
- gem.add_development_dependency "rspec-core", "~> 3.2"
13
- gem.add_development_dependency "rspec-expectations", "~> 3.2"
14
- gem.add_development_dependency "rspec-mocks", "~> 3.2"
11
+ gem.add_development_dependency 'rake', '~> 10.4.2'
12
+ gem.add_development_dependency 'rspec-core', '~> 3.2'
13
+ gem.add_development_dependency 'rspec-expectations', '~> 3.2'
14
+ gem.add_development_dependency 'rspec-mocks', '~> 3.2'
15
15
  gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.7'
16
16
 
17
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
18
18
  gem.files = `git ls-files`.split("\n")
19
19
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
- gem.name = "ibsciss-middleware"
21
- gem.require_paths = ["lib"]
22
- gem.version = '0.3.2'
20
+ gem.name = 'ibsciss-middleware'
21
+ gem.require_paths = ['lib']
22
+ gem.version = '0.4.0'
23
23
  end
@@ -1,20 +1,20 @@
1
- require "middleware"
1
+ require 'middleware'
2
2
 
3
3
  describe Middleware::Builder do
4
- let(:data) { { :data => [] } }
4
+ let(:data) { { data: [] } }
5
5
  let(:instance) { described_class.new }
6
6
 
7
7
  # This returns a proc that can be used with the builder
8
8
  # that simply appends data to an array in the env.
9
9
  def appender_proc(data)
10
- Proc.new { |obj| obj.tap { |env| env[:data] << data }}
10
+ proc { |obj| obj.tap { |env| env[:data] << data } }
11
11
  end
12
12
 
13
- context "initialized with a block" do
14
- context "without explicit receiver" do
15
- it "instance evals the block" do
13
+ context 'initialized with a block' do
14
+ context 'without explicit receiver' do
15
+ it 'instance evals the block' do
16
16
  data = {}
17
- proc = Proc.new { |env| env[:data] = true }
17
+ proc = proc { |env| env[:data] = true }
18
18
 
19
19
  app = described_class.new do
20
20
  use proc
@@ -26,10 +26,10 @@ describe Middleware::Builder do
26
26
  end
27
27
  end
28
28
 
29
- context "with explicit receiver" do
30
- it "yields self to the block" do
29
+ context 'with explicit receiver' do
30
+ it 'yields self to the block' do
31
31
  data = {}
32
- proc = Proc.new { |env| env[:data] = true }
32
+ proc = proc { |env| env[:data] = true }
33
33
 
34
34
  app = described_class.new do |b|
35
35
  b.use proc
@@ -42,10 +42,10 @@ describe Middleware::Builder do
42
42
  end
43
43
  end
44
44
 
45
- context "basic `use`" do
46
- it "should add items to the stack and make them callable" do
45
+ context 'basic `use`' do
46
+ it 'should add items to the stack and make them callable' do
47
47
  data = {}
48
- proc = Proc.new { |env| env[:data] = true }
48
+ proc = proc { |env| env[:data] = true }
49
49
 
50
50
  instance.use proc
51
51
  instance.call(data)
@@ -53,10 +53,10 @@ describe Middleware::Builder do
53
53
  expect(data[:data]).to be_truthy
54
54
  end
55
55
 
56
- it "should be able to add multiple items" do
56
+ it 'should be able to add multiple items' do
57
57
  data = {}
58
- proc1 = Proc.new { |env| env.tap { |obj| obj[:one] = true }}
59
- proc2 = Proc.new { |env| env.tap { |obj| obj[:two] = true }}
58
+ proc1 = proc { |env| env.tap { |obj| obj[:one] = true } }
59
+ proc2 = proc { |env| env.tap { |obj| obj[:two] = true } }
60
60
 
61
61
  instance.use proc1
62
62
  instance.use proc2
@@ -66,16 +66,16 @@ describe Middleware::Builder do
66
66
  expect(data[:two]).to be_truthy
67
67
  end
68
68
 
69
- it "should be able to add another builder" do
69
+ it 'should be able to add another builder' do
70
70
  data = {}
71
- proc1 = Proc.new { |env| env[:one] = true }
71
+ proc1 = proc { |env| env[:one] = true }
72
72
 
73
73
  # Build the first builder
74
74
  one = described_class.new
75
75
  one.use proc1
76
76
 
77
77
  # Add it to this builder
78
- two = described_class.new
78
+ two = described_class.new
79
79
  two.use one
80
80
 
81
81
  # Call the 2nd and verify results
@@ -83,19 +83,19 @@ describe Middleware::Builder do
83
83
  expect(data[:one]).to be_truthy
84
84
  end
85
85
 
86
- it "should default the env to `nil` if not given" do
86
+ it 'should default the env to `nil` if not given' do
87
87
  result = false
88
- proc = Proc.new { |env| result = env.nil? }
88
+ proc = proc { |env| result = env.nil? }
89
89
 
90
90
  instance.use proc
91
91
  instance.call
92
92
 
93
93
  expect(result).to be_truthy
94
- end
94
+ end
95
95
  end
96
96
 
97
- context "inserting" do
98
- it "can insert at an index" do
97
+ context 'inserting' do
98
+ it 'can insert at an index' do
99
99
  instance.use appender_proc(1)
100
100
  instance.insert(0, appender_proc(2))
101
101
  instance.call(data)
@@ -103,7 +103,7 @@ describe Middleware::Builder do
103
103
  expect(data[:data]).to eq [2, 1]
104
104
  end
105
105
 
106
- it "can insert next to a previous object" do
106
+ it 'can insert next to a previous object' do
107
107
  proc2 = appender_proc(2)
108
108
  instance.use appender_proc(1)
109
109
  instance.use proc2
@@ -113,7 +113,7 @@ describe Middleware::Builder do
113
113
  expect(data[:data]).to eq [1, 3, 2]
114
114
  end
115
115
 
116
- it "can insert before" do
116
+ it 'can insert before' do
117
117
  instance.use appender_proc(1)
118
118
  instance.insert_before 0, appender_proc(2)
119
119
  instance.call(data)
@@ -121,12 +121,12 @@ describe Middleware::Builder do
121
121
  expect(data[:data]).to eq [2, 1]
122
122
  end
123
123
 
124
- it "raises an exception if attempting to insert before an invalid object" do
125
- expect { instance.insert "object", appender_proc(1) }.
126
- to raise_error(RuntimeError)
124
+ it 'raises an exception if attempting to insert before an invalid object' do
125
+ expect { instance.insert 'object', appender_proc(1) }
126
+ .to raise_error(RuntimeError)
127
127
  end
128
128
 
129
- it "can insert after each" do
129
+ it 'can insert after each' do
130
130
  instance.use appender_proc(1)
131
131
  instance.use appender_proc(2)
132
132
  instance.use appender_proc(3)
@@ -135,7 +135,7 @@ describe Middleware::Builder do
135
135
  expect(data[:data]).to eq [1, 9, 2, 9, 3, 9]
136
136
  end
137
137
 
138
- it "can insert before each" do
138
+ it 'can insert before each' do
139
139
  instance.use appender_proc(1)
140
140
  instance.use appender_proc(2)
141
141
  instance.use appender_proc(3)
@@ -144,14 +144,14 @@ describe Middleware::Builder do
144
144
  expect(data[:data]).to eq [9, 1, 9, 2, 9, 3]
145
145
  end
146
146
 
147
- it "raises an exception if attempting to insert after an invalid object" do
148
- expect { instance.insert_after "object", appender_proc(1) }.
149
- to raise_error(RuntimeError)
147
+ it 'raises an exception if attempting to insert after an invalid object' do
148
+ expect { instance.insert_after 'object', appender_proc(1) }
149
+ .to raise_error(RuntimeError)
150
150
  end
151
151
  end
152
152
 
153
- context "replace" do
154
- it "can replace an object" do
153
+ context 'replace' do
154
+ it 'can replace an object' do
155
155
  proc1 = appender_proc(1)
156
156
  proc2 = appender_proc(2)
157
157
 
@@ -162,7 +162,7 @@ describe Middleware::Builder do
162
162
  expect(data[:data]).to eq [2]
163
163
  end
164
164
 
165
- it "can replace by index" do
165
+ it 'can replace by index' do
166
166
  proc1 = appender_proc(1)
167
167
  proc2 = appender_proc(2)
168
168
 
@@ -174,8 +174,8 @@ describe Middleware::Builder do
174
174
  end
175
175
  end
176
176
 
177
- context "deleting" do
178
- it "can delete by object" do
177
+ context 'deleting' do
178
+ it 'can delete by object' do
179
179
  proc1 = appender_proc(1)
180
180
 
181
181
  instance.use proc1
@@ -186,7 +186,7 @@ describe Middleware::Builder do
186
186
  expect(data[:data]).to eq [2]
187
187
  end
188
188
 
189
- it "can delete by index" do
189
+ it 'can delete by index' do
190
190
  proc1 = appender_proc(1)
191
191
 
192
192
  instance.use proc1
@@ -198,11 +198,45 @@ describe Middleware::Builder do
198
198
  end
199
199
  end
200
200
 
201
- context "debugging" do
202
- it "has an inspect method" do
201
+ context 'debugging' do
202
+ class Echo
203
+ def initialize app
204
+ @app = app
205
+ end
206
+
207
+ def call env
208
+ @app.call(env)
209
+ end
210
+ end
211
+
212
+ it 'has an inspect method' do
203
213
  instance.use appender_proc(1)
204
214
  instance.use appender_proc(1), 2
205
- expect(instance.inspect).to eq '[Proc(), Proc(2)]'
215
+ instance.use Echo, 'Hi, how are you?'
216
+ expect(instance.inspect).to eq 'Middleware[Proc(), Proc(2), Echo(Hi, how are you?)]'
217
+ end
218
+
219
+ it 'displays his name in the inspect' do
220
+ middleware = described_class.new(name: 'Dumb') { |b|
221
+ b.use appender_proc(1)
222
+ }
223
+ expect(middleware.inspect).to eq 'Dumb[Proc()]'
224
+ end
225
+
226
+ it "can have a name" do
227
+ expect(described_class.new(name: 'Name').name).to eq 'Name'
228
+ end
229
+
230
+ it "can have a Logger" do
231
+ mocked_logger = instance_double(Logger)
232
+ expect(mocked_logger).to receive(:add).exactly(4).times
233
+
234
+ described_class.new(name: 'Dumb') { |b|
235
+ b.use Echo
236
+ b.use Echo
237
+ }.inject_logger(mocked_logger)
238
+ .call()
206
239
  end
207
240
  end
208
- end
241
+
242
+ end
@@ -0,0 +1,58 @@
1
+ require_relative '../../lib/middleware/logger'
2
+ require 'logger'
3
+
4
+ class NEXT_Middleware
5
+ def initialize app
6
+ @app = app
7
+ end
8
+
9
+ def call env
10
+ env
11
+ end
12
+ end
13
+
14
+ #Middleware.new('tchoutchou_orchestrator') {
15
+ #}.inject_logger(Logger.new IO::String(''))
16
+
17
+ describe Middleware::Logger do
18
+
19
+ it 'wrote the names of the next middleware in the logger' do
20
+ mocked_logger = instance_double('Logger');
21
+ expect(mocked_logger).to receive(:add).twice
22
+
23
+ described_class.new(NEXT_Middleware.new(nil), mocked_logger, 'dump_middleware').call(1)
24
+ end
25
+
26
+ describe '#next_middleware_name' do
27
+ context 'when the next middleware is a Class' do
28
+ it 'extracts the next middleware name from the class name' do
29
+ expect(described_class.new(NEXT_Middleware.new(nil), nil).next_middleware_name).to eq 'NEXT_Middleware'
30
+ end
31
+ end
32
+
33
+ context 'when the next middleware is a Lambda' do
34
+ it 'gives "Proc" for the next middleware' do
35
+ expect(described_class.new(->(env){env}, nil).next_middleware_name).to eq 'Proc'
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#way_out_message' do
41
+ it 'returns a formatted message' do
42
+ expect(described_class.new(nil, nil).way_out_message('Dumb', 2400, [1, 2])).to eq " Dumb finished in 2400 ms and returned: [1, 2]\n"
43
+ end
44
+ end
45
+
46
+ describe '#way_in_message' do
47
+ it 'returns a formatted message' do
48
+ expect(described_class.new(nil, nil).way_in_message('Dumb', [1, 2])).to eq " Dumb has been called with: [1, 2]\n"
49
+ end
50
+ end
51
+
52
+ describe '#pretty_print' do
53
+ it 'pretty prints given var' do
54
+ expect(described_class.new(nil, nil).pretty_print([1, 2, 3, 4, 5])).to eq "[1, 2, 3, 4, 5]\n"
55
+ end
56
+ end
57
+
58
+ end
@@ -1,21 +1,21 @@
1
- require "middleware"
1
+ require 'middleware'
2
2
 
3
3
  describe Middleware::Runner do
4
- it "should work with an empty stack" do
4
+ it 'should work with an empty stack' do
5
5
  instance = described_class.new([])
6
6
  expect { instance.call({}) }.to_not raise_error
7
7
  end
8
8
 
9
- it "should call classes in the proper order" do
9
+ it 'should call classes in the proper order' do
10
10
  a = Class.new do
11
11
  def initialize(app)
12
12
  @app = app
13
13
  end
14
14
 
15
15
  def call(env)
16
- env[:result] << "A"
16
+ env[:result] << 'A'
17
17
  @app.call(env)
18
- env[:result] << "A"
18
+ env[:result] << 'A'
19
19
  end
20
20
  end
21
21
 
@@ -25,40 +25,40 @@ describe Middleware::Runner do
25
25
  end
26
26
 
27
27
  def call(env)
28
- env[:result] << "B"
28
+ env[:result] << 'B'
29
29
  @app.call(env)
30
- env[:result] << "B"
30
+ env[:result] << 'B'
31
31
  end
32
32
  end
33
33
 
34
- env = { :result => [] }
34
+ env = { result: [] }
35
35
  instance = described_class.new([a, b])
36
36
  instance.call(env)
37
- expect(env[:result]).to eq ["A", "B", "B", "A"]
37
+ expect(env[:result]).to eq %w(A B B A)
38
38
  end
39
39
 
40
- it "should call lambdas in the proper order" do
40
+ it 'should call lambdas in the proper order' do
41
41
  data = []
42
- a = lambda { |env| data << "A" }
43
- b = lambda { |env| data << "B" }
42
+ a = ->(_env) { data << 'A' }
43
+ b = ->(_env) { data << 'B' }
44
44
 
45
45
  instance = described_class.new([a, b])
46
46
  instance.call({})
47
47
 
48
- expect(data).to eq ["A", "B"]
48
+ expect(data).to eq %w(A B)
49
49
  end
50
50
 
51
- it "should let lambdas to change the given argument" do
52
- a = lambda { |env| env + 1 }
53
- b = lambda { |env| env + 2 }
51
+ it 'should let lambdas to change the given argument' do
52
+ a = ->(env) { env + 1 }
53
+ b = ->(env) { env + 2 }
54
54
 
55
55
  instance = described_class.new([a, b])
56
56
  expect(instance.call(1)).to eq 4
57
57
  end
58
58
 
59
- it "passes in arguments to lambda if given" do
59
+ it 'passes in arguments to lambda if given' do
60
60
  data = []
61
- a = lambda { |env, arg| data << arg }
61
+ a = ->(_env, arg) { data << arg }
62
62
 
63
63
  instance = described_class.new([[a, 1]])
64
64
  instance.call(nil)
@@ -66,7 +66,7 @@ describe Middleware::Runner do
66
66
  expect(data).to eq [1]
67
67
  end
68
68
 
69
- it "passes in arguments if given" do
69
+ it 'passes in arguments if given' do
70
70
  a = Class.new do
71
71
  def initialize(app, value)
72
72
  @app = app
@@ -85,9 +85,9 @@ describe Middleware::Runner do
85
85
  expect(env[:result]).to eq 42
86
86
  end
87
87
 
88
- it "passes in a block if given" do
88
+ it 'passes in a block if given' do
89
89
  a = Class.new do
90
- def initialize(app, &block)
90
+ def initialize(_app, &block)
91
91
  @block = block
92
92
  end
93
93
 
@@ -96,7 +96,7 @@ describe Middleware::Runner do
96
96
  end
97
97
  end
98
98
 
99
- block = Proc.new { 42 }
99
+ block = proc { 42 }
100
100
  env = {}
101
101
  instance = described_class.new([[a, nil, block]])
102
102
  instance.call(env)
@@ -104,7 +104,7 @@ describe Middleware::Runner do
104
104
  expect(env[:result]).to eq 42
105
105
  end
106
106
 
107
- it "should raise an error if an invalid middleware is given" do
107
+ it 'should raise an error if an invalid middleware is given' do
108
108
  expect { described_class.new([27]) }.to raise_error(/Invalid middleware/)
109
109
  end
110
110
 
@@ -112,24 +112,26 @@ describe Middleware::Runner do
112
112
  # A does not call B, so B should never execute
113
113
  data = []
114
114
  a = Class.new do
115
- def initialize(app); @app = app; end
115
+ def initialize(app)
116
+ @app = app
117
+ end
116
118
 
117
- define_method :call do |env|
118
- data << "a"
119
+ define_method :call do |_env|
120
+ data << 'a'
119
121
  end
120
122
  end
121
123
 
122
- b = lambda { |env| data << "b" }
124
+ b = ->(_env) { data << 'b' }
123
125
 
124
126
  env = {}
125
127
  instance = described_class.new([a, b])
126
128
  instance.call(env)
127
129
 
128
- expect(data).to eq ["a"]
130
+ expect(data).to eq ['a']
129
131
  end
130
132
 
131
- describe "exceptions" do
132
- it "should propagate the exception up the middleware chain" do
133
+ describe 'exceptions' do
134
+ it 'should propagate the exception up the middleware chain' do
133
135
  # This tests a few important properties:
134
136
  # * Exceptions propagate multiple middlewares
135
137
  # - C raises an exception, which raises through B to A.
@@ -141,70 +143,76 @@ describe Middleware::Runner do
141
143
  end
142
144
 
143
145
  define_method :call do |env|
144
- data << "a"
146
+ data << 'a'
145
147
  begin
146
148
  @app.call(env)
147
- data << "never"
149
+ data << 'never'
148
150
  rescue Exception => e
149
- data << "e"
151
+ data << 'e'
150
152
  raise
151
153
  end
152
154
  end
153
155
  end
154
156
 
155
157
  b = Class.new do
156
- def initialize(app); @app = app; end
158
+ def initialize(app)
159
+ @app = app
160
+ end
157
161
 
158
162
  define_method :call do |env|
159
- data << "b"
163
+ data << 'b'
160
164
  @app.call(env)
161
165
  end
162
166
  end
163
167
 
164
- c = lambda { |env| raise "ERROR" }
168
+ c = ->(_env) { fail 'ERROR' }
165
169
 
166
170
  env = {}
167
171
  instance = described_class.new([a, b, c])
168
172
  expect { instance.call(env) }.to raise_error 'ERROR'
169
173
 
170
- expect(data).to eq ["a", "b", "e"]
174
+ expect(data).to eq %w(a b e)
171
175
  end
172
176
 
173
- it "should stop propagation if rescued" do
177
+ it 'should stop propagation if rescued' do
174
178
  # This test mainly tests that if there is a sequence A, B, C, and
175
179
  # an exception is raised in C, that if B rescues this, then the chain
176
180
  # continues fine backwards.
177
181
  data = []
178
182
  a = Class.new do
179
- def initialize(app); @app = app; end
183
+ def initialize(app)
184
+ @app = app
185
+ end
180
186
 
181
187
  define_method :call do |env|
182
- data << "in_a"
188
+ data << 'in_a'
183
189
  @app.call(env)
184
- data << "out_a"
190
+ data << 'out_a'
185
191
  end
186
192
  end
187
193
 
188
194
  b = Class.new do
189
- def initialize(app); @app = app; end
195
+ def initialize(app)
196
+ @app = app
197
+ end
190
198
 
191
199
  define_method :call do |env|
192
- data << "in_b"
200
+ data << 'in_b'
193
201
  @app.call(env) rescue nil
194
- data << "out_b"
202
+ data << 'out_b'
195
203
  end
196
204
  end
197
205
 
198
- c = lambda do |env|
199
- data << "in_c"
200
- raise "BAD"
206
+ c = lambda do |_env|
207
+ data << 'in_c'
208
+ fail 'BAD'
201
209
  end
202
210
 
203
211
  env = {}
204
212
  instance = described_class.new([a, b, c])
205
213
  instance.call(env)
206
214
 
207
- expect(data).to eq ["in_a", "in_b", "in_c", "out_b", "out_a"]
215
+ expect(data).to eq %w(in_a in_b in_c out_b out_a)
208
216
  end
209
217
  end
210
218
  end
@@ -1,4 +1,4 @@
1
- require "codeclimate-test-reporter"
1
+ require 'codeclimate-test-reporter'
2
2
  CodeClimate::TestReporter.start
3
3
  # This file was generated by the `rspec --init` command. Conventionally, all
4
4
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
@@ -42,50 +42,48 @@ RSpec.configure do |config|
42
42
 
43
43
  # The settings below are suggested to provide a good initial experience
44
44
  # with RSpec, but feel free to customize to your heart's content.
45
- =begin
46
- # These two settings work together to allow you to limit a spec run
47
- # to individual examples or groups you care about by tagging them with
48
- # `:focus` metadata. When nothing is tagged with `:focus`, all examples
49
- # get run.
50
- config.filter_run :focus
51
- config.run_all_when_everything_filtered = true
52
-
53
- # Limits the available syntax to the non-monkey patched syntax that is recommended.
54
- # For more details, see:
55
- # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
56
- # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
57
- # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
58
- config.disable_monkey_patching!
59
-
60
- # This setting enables warnings. It's recommended, but in some cases may
61
- # be too noisy due to issues in dependencies.
62
- config.warnings = true
63
-
64
- # Many RSpec users commonly either run the entire suite or an individual
65
- # file, and it's useful to allow more verbose output when running an
66
- # individual spec file.
67
- if config.files_to_run.one?
68
- # Use the documentation formatter for detailed output,
69
- # unless a formatter has already been configured
70
- # (e.g. via a command-line flag).
71
- config.default_formatter = 'doc'
72
- end
73
-
74
- # Print the 10 slowest examples and example groups at the
75
- # end of the spec run, to help surface which specs are running
76
- # particularly slow.
77
- config.profile_examples = 10
78
-
79
- # Run specs in random order to surface order dependencies. If you find an
80
- # order dependency and want to debug it, you can fix the order by providing
81
- # the seed, which is printed after each run.
82
- # --seed 1234
83
- config.order = :random
84
-
85
- # Seed global randomization in this process using the `--seed` CLI option.
86
- # Setting this allows you to use `--seed` to deterministically reproduce
87
- # test failures related to randomization by passing the same `--seed` value
88
- # as the one that triggered the failure.
89
- Kernel.srand config.seed
90
- =end
45
+ # # These two settings work together to allow you to limit a spec run
46
+ # # to individual examples or groups you care about by tagging them with
47
+ # # `:focus` metadata. When nothing is tagged with `:focus`, all examples
48
+ # # get run.
49
+ # config.filter_run :focus
50
+ # config.run_all_when_everything_filtered = true
51
+ #
52
+ # # Limits the available syntax to the non-monkey patched syntax that is recommended.
53
+ # # For more details, see:
54
+ # # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
55
+ # # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
56
+ # # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
57
+ # config.disable_monkey_patching!
58
+ #
59
+ # # This setting enables warnings. It's recommended, but in some cases may
60
+ # # be too noisy due to issues in dependencies.
61
+ # config.warnings = true
62
+ #
63
+ # # Many RSpec users commonly either run the entire suite or an individual
64
+ # # file, and it's useful to allow more verbose output when running an
65
+ # # individual spec file.
66
+ # if config.files_to_run.one?
67
+ # # Use the documentation formatter for detailed output,
68
+ # # unless a formatter has already been configured
69
+ # # (e.g. via a command-line flag).
70
+ # config.default_formatter = 'doc'
71
+ # end
72
+ #
73
+ # # Print the 10 slowest examples and example groups at the
74
+ # # end of the spec run, to help surface which specs are running
75
+ # # particularly slow.
76
+ # config.profile_examples = 10
77
+ #
78
+ # # Run specs in random order to surface order dependencies. If you find an
79
+ # # order dependency and want to debug it, you can fix the order by providing
80
+ # # the seed, which is printed after each run.
81
+ # # --seed 1234
82
+ # config.order = :random
83
+ #
84
+ # # Seed global randomization in this process using the `--seed` CLI option.
85
+ # # Setting this allows you to use `--seed` to deterministically reproduce
86
+ # # test failures related to randomization by passing the same `--seed` value
87
+ # # as the one that triggered the failure.
88
+ # Kernel.srand config.seed
91
89
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ibsciss-middleware
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mitchell Hashimoto
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-08-21 00:00:00.000000000 Z
12
+ date: 2015-11-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -98,9 +98,11 @@ files:
98
98
  - Rakefile
99
99
  - lib/middleware.rb
100
100
  - lib/middleware/builder.rb
101
+ - lib/middleware/logger.rb
101
102
  - lib/middleware/runner.rb
102
103
  - middleware.gemspec
103
104
  - spec/middleware/builder_spec.rb
105
+ - spec/middleware/logger_spec.rb
104
106
  - spec/middleware/runner_spec.rb
105
107
  - spec/spec_helper.rb
106
108
  homepage: https://github.com/ibsciss/ruby-middleware
@@ -130,5 +132,6 @@ summary: Generalized implementation of the rack middleware abstraction for Ruby
130
132
  of responsibility design pattern).
131
133
  test_files:
132
134
  - spec/middleware/builder_spec.rb
135
+ - spec/middleware/logger_spec.rb
133
136
  - spec/middleware/runner_spec.rb
134
137
  - spec/spec_helper.rb