ibsciss-middleware 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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