ibsciss-middleware 0.3.1 → 0.3.2

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: 2885d91b0fe8a07086ee6e68f40194cce36747c9
4
- data.tar.gz: d4b6288f7aec993be1640244c6b5d193b27e2ffe
3
+ metadata.gz: ab6d4d8a9225726d9aa68a41d4be42bcac71bc23
4
+ data.tar.gz: 4df6dce76dca18f51c8af01a3be56e5861d8fe4e
5
5
  SHA512:
6
- metadata.gz: 8e3fa59de3b97d5f38e0b8a4588a1e3babca6bdb885eecb6351ff960e1e485e7763e3a6803949e98448a7ddbc19e756af64f8f2a6abacfa1329c64f72679c6ae
7
- data.tar.gz: 57e79ebd22365b169dff558b248fc50bd05b425b2ba609a9bc654b426111ae0822e78ce6dcc51c3cf5194a78c868cbe4518b7995ddd5aa5da6e952a82fb9c0cd
6
+ metadata.gz: e33e2f98cc16cf4dcf6ee076cf1734b1cf8bac3ef17daf7d8aa97636510d739e4af7f851d0adacb75444844e3c9eba401e5f22c787406adac6badab48ffc7ab4
7
+ data.tar.gz: c9f1537de72e76797a690c23646640655ca9ed4adfbefae661bef899cac998efb073d199ab9ec3854de9a4cbfa9d4e36322b24d2c201be2530528fcafd9cb734
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.3.2
2
+ - Add CI & Code Climate & Improve documentation
3
+
4
+ ## 0.3.1
5
+ - Enable lambda to change the given object
6
+
1
7
  ## 0.3.0
2
8
  - Apply https://github.com/Ibsciss/ruby-middleware/commit/01f75d8e4137b39ea907f13756f21cba4edffaa7
3
9
  - Apply https://github.com/Ibsciss/ruby-middleware/commit/00aa09353f7ee2b801bdb446418a936640ae56d7
data/LICENSE CHANGED
@@ -1,3 +1,4 @@
1
+ Copyright (c) 2015 Arnaud LEMAIRE
1
2
  Copyright (c) 2012 Mitchell Hashimoto
2
3
 
3
4
  MIT License
data/README.md CHANGED
@@ -1,11 +1,21 @@
1
+ [![Code Climate](https://codeclimate.com/github/Ibsciss/ruby-middleware/badges/gpa.svg)](https://codeclimate.com/github/Ibsciss/ruby-middleware)
2
+ [![Test Coverage](https://codeclimate.com/github/Ibsciss/ruby-middleware/badges/coverage.svg)](https://codeclimate.com/github/Ibsciss/ruby-middleware)
3
+ [![Build Status](https://semaphoreci.com/api/v1/projects/c5797935-6c93-4596-a8a8-bd45c8c584e9/393201/shields_badge.svg)](https://semaphoreci.com/lilobase/ruby-middleware)
4
+
1
5
  # Middleware
2
6
 
3
- `middleware` is a library which provides a generalized implementation
4
- of the middleware pattern for Ruby. The middleware pattern is a useful
7
+ [![Join the chat at https://gitter.im/Ibsciss/ruby-middleware](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Ibsciss/ruby-middleware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8
+
9
+ `Middleware` is a library which provides a generalized implementation
10
+ of the [chain of responsibility pattern](http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern) for Ruby.
11
+
12
+ This pattern is used in `Rack::Builder` or `ActionDispatch::MiddlewareStack` to manage a stack of middlewares. This gem is a generic implementation for any Ruby project.
13
+
14
+ The middleware pattern is a useful
5
15
  abstraction tool in various cases, but is specifically useful for splitting
6
16
  large sequential chunks of logic into small pieces.
7
17
 
8
- This library was created by Mitchell Hashimoto, original repository: https://github.com/mitchellh/middleware
18
+ This is an updated version of the original Mitchell Hashimoto's library: https://github.com/mitchellh/middleware
9
19
 
10
20
  ## Installing
11
21
 
@@ -15,6 +25,18 @@ Middleware is distributed as a RubyGem, so simply gem install:
15
25
  $ gem install ibsciss-middleware
16
26
  ```
17
27
 
28
+ Or, in your Gemfile:
29
+
30
+ ```
31
+ gem 'ibsciss-middleware', '~> 0.3'
32
+ ```
33
+
34
+ Then, you can add it to your project:
35
+
36
+ ```ruby
37
+ require 'middleware'
38
+ ```
39
+
18
40
  ## A Basic Example
19
41
 
20
42
  Below is a basic example of the library in use. If you don't understand
@@ -61,7 +83,6 @@ And the output:
61
83
  ```
62
84
 
63
85
 
64
-
65
86
  ## Middleware
66
87
 
67
88
  ### What is it?
@@ -103,9 +124,9 @@ class Trace
103
124
  end
104
125
 
105
126
  def call(env)
106
- puts "Trace up"
127
+ puts "Before next middleware execution"
107
128
  @app.call(env)
108
- puts "Trace down"
129
+ puts "After next middleware execution"
109
130
  end
110
131
  end
111
132
  ```
@@ -119,14 +140,39 @@ A basic description of the two methods that a middleware must implement:
119
140
  state sent in (defined by the caller, but usually a Hash). This call should also
120
141
  call `app.call(env)` at some point to move on.
121
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:
145
+
146
+ ```ruby
147
+ class Greeting
148
+ def initialize(app, append = nil)
149
+ @app = app
150
+ @datas = datas
151
+ end
152
+
153
+ def call(env)
154
+ env = "#{append} #{env}"
155
+ result = @app(env)
156
+ "#{result} !"
157
+ end
158
+ end
159
+
160
+ Middleware::Builder.new { |b|
161
+ b.use Greeting, 'Hello'
162
+ }.call('John') #return "Hello John !"
163
+ ```
164
+
122
165
  ### Middleware Lambdas
123
166
 
124
167
  A middleware can also be a simple lambda. The downside of using a lambda is that
125
168
  it only has access to the state on the initial call, there is no "post" step for
126
- lambdas. A basic example, in the context of a web request:
169
+ lambdas:
127
170
 
128
171
  ```ruby
129
- lambda { |env| puts "You requested: #{env["http.request_url"]}" }
172
+ Middleware::Builder.new { |b|
173
+ b.use lambda { |env| env + 3 }
174
+ b.use lambda { |env| env * 2 }
175
+ }.call(1) #return 8
130
176
  ```
131
177
 
132
178
  ## Middleware Stacks
@@ -148,10 +194,12 @@ end
148
194
  ```
149
195
 
150
196
  This `stack` variable itself is now a valid middleware and has the same interface,
151
- so to execute the stack, just call `call` on it:
197
+ so to execute the stack, just call `call` on it, so can compose middleware stack between them:
152
198
 
153
199
  ```ruby
154
- stack.call
200
+ Middleware::Builder.new do |d|
201
+ d.use stack
202
+ end.call()
155
203
  ```
156
204
 
157
205
  The call method takes an optional parameter which is the state to pass into the
@@ -165,15 +213,62 @@ created. Given the `stack` variable created above, we can manipulate it as
165
213
  follows. Please imagine that each example runs with the original `stack` variable,
166
214
  so that the order of the examples doesn't actually matter:
167
215
 
216
+ #### Insert before
217
+
218
+ ```ruby
219
+ # Insert a new item before the Trace middleware
220
+ stack.insert_before Trace, SomeOtherMiddleware
221
+
222
+ # Insert a new item at the top of the middleware stack
223
+ stack.insert_before 0, SomeOtherMiddleware
224
+ ```
225
+
226
+ #### Insert after
227
+
168
228
  ```ruby
169
229
  # Insert a new item after the Trace middleware
170
230
  stack.insert_after(Trace, SomeOtherMiddleware)
171
231
 
172
- # Replace the lambda
232
+ # Insert a new item after the first middleware
233
+ stack.insert_after(0, SomeOtherMiddleware)
234
+ ```
235
+
236
+ #### Insert after each
237
+
238
+ ```ruby
239
+ logger = lambda { |env| p env }
240
+
241
+ # Insert the middleware (can be also a middleware object) after each existing middleware
242
+ stack.insert_after_each logger
243
+ ```
244
+
245
+ #### Insert before each
246
+
247
+ ```ruby
248
+ logger = lambda { |env| p env }
249
+
250
+ # Insert the middleware (can be also a middleware object) before each existing middleware
251
+ stack.insert_before_each logger
252
+ ```
253
+
254
+ #### Replace
255
+
256
+ ```ruby
257
+ # Replace the first middleware
173
258
  stack.replace(1, SomeOtherMiddleware)
174
259
 
260
+ # Replace the Trace middleware
261
+ stack.replace(Trace, SomeOtherMiddleware)
262
+ ```
263
+
264
+ #### Delete
265
+
266
+ ```ruby
175
267
  # Delete the lambda
176
268
  stack.delete(1)
269
+
270
+ # Delete the Trace middleware
271
+ stack.delete(Trace)
177
272
  ```
178
273
 
179
274
  ### Passing Additional Constructor Arguments
@@ -206,3 +301,31 @@ end
206
301
  Then when the stack is called, it will output "Hello, World!"
207
302
 
208
303
  Note that you can also pass blocks in using the `use` method.
304
+
305
+ #### Lambda
306
+
307
+ Lambda work the same with additional arguments:
308
+
309
+ ```ruby
310
+ Middleware::Builder.new { |b|
311
+ # arrow syntax for lambda construction
312
+ b.use ->(env, msg) { puts msg }, 'some message'
313
+ }.call(1) #will print "some message"
314
+ ```
315
+
316
+ ### Debug
317
+
318
+ You can see the content of a given stack using the `inspect` method
319
+
320
+ ```ruby
321
+ Middleware::Builder.new { |b|
322
+ b.use Trace
323
+ b.use Echo, "Hello, World!"
324
+ }.inspect
325
+ ```
326
+
327
+ the output will be
328
+
329
+ ```ruby
330
+ [Trace(), Echo("Hello, World!")]
331
+ ```
@@ -92,6 +92,20 @@ module Middleware
92
92
  insert(index + 1, middleware, *args, &block)
93
93
  end
94
94
 
95
+ # Inserts a middleware before each middleware object
96
+ def insert_before_each(middleware, *args, &block)
97
+ self.stack = stack.reduce([]) do |carry, item|
98
+ carry.push([middleware, args, block], item)
99
+ end
100
+ end
101
+
102
+ # Inserts a middleware after each middleware object
103
+ def insert_after_each(middleware, *args, &block)
104
+ self.stack = stack.reduce([]) do |carry, item|
105
+ carry.push(item, [middleware, args, block])
106
+ end
107
+ end
108
+
95
109
  # Replaces the given middleware object or index with the new
96
110
  # middleware.
97
111
  def replace(index, middleware, *args, &block)
@@ -115,6 +129,12 @@ module Middleware
115
129
  to_app.call(env)
116
130
  end
117
131
 
132
+ def inspect
133
+ "[" + stack.reduce([]) { |carry, middleware|
134
+ carry << "#{middleware[0].class.name}(#{middleware[1].join(', ')})"
135
+ }.join(', ') + "]"
136
+ end
137
+
118
138
  protected
119
139
 
120
140
  # Returns the numeric index for the given middleware object.
@@ -137,11 +157,19 @@ module Middleware
137
157
  @stack ||= []
138
158
  end
139
159
 
160
+ # you shouldn't use this method
161
+ #
162
+ # @return [Array]
163
+ def stack= stack
164
+ @stack = stack
165
+ end
166
+
140
167
  # Converts the builder stack to a runnable action sequence.
141
168
  #
142
169
  # @return [Object] A callable object
143
170
  def to_app
144
171
  @runner_class.new(stack.dup)
145
172
  end
173
+
146
174
  end
147
175
  end
@@ -57,7 +57,7 @@ module Middleware
57
57
  # Make it a lambda which calls the item then forwards up
58
58
  # the chain.
59
59
  lambda do |env|
60
- next_middleware.call(klass.call(env))
60
+ next_middleware.call(klass.call(env, *args))
61
61
  end
62
62
  else
63
63
  raise "Invalid middleware, doesn't respond to `call`: #{klass.inspect}"
data/middleware.gemspec CHANGED
@@ -8,15 +8,16 @@ Gem::Specification.new do |gem|
8
8
  gem.homepage = "https://github.com/ibsciss/ruby-middleware"
9
9
  gem.license = "MIT"
10
10
 
11
- gem.add_development_dependency "rake", "~> 1.6"
11
+ gem.add_development_dependency "rake", "~> 10.4.2"
12
12
  gem.add_development_dependency "rspec-core", "~> 3.2"
13
13
  gem.add_development_dependency "rspec-expectations", "~> 3.2"
14
14
  gem.add_development_dependency "rspec-mocks", "~> 3.2"
15
+ gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.7'
15
16
 
16
17
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
18
  gem.files = `git ls-files`.split("\n")
18
19
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
20
  gem.name = "ibsciss-middleware"
20
21
  gem.require_paths = ["lib"]
21
- gem.version = '0.3.1'
22
+ gem.version = '0.3.2'
22
23
  end
@@ -126,13 +126,22 @@ describe Middleware::Builder do
126
126
  to raise_error(RuntimeError)
127
127
  end
128
128
 
129
- it "can insert after" do
129
+ it "can insert after each" do
130
130
  instance.use appender_proc(1)
131
+ instance.use appender_proc(2)
131
132
  instance.use appender_proc(3)
132
- instance.insert_after 0, appender_proc(2)
133
+ instance.insert_after_each appender_proc(9)
133
134
  instance.call(data)
135
+ expect(data[:data]).to eq [1, 9, 2, 9, 3, 9]
136
+ end
134
137
 
135
- expect(data[:data]).to eq [1, 2, 3]
138
+ it "can insert before each" do
139
+ instance.use appender_proc(1)
140
+ instance.use appender_proc(2)
141
+ instance.use appender_proc(3)
142
+ instance.insert_before_each appender_proc(9)
143
+ instance.call(data)
144
+ expect(data[:data]).to eq [9, 1, 9, 2, 9, 3]
136
145
  end
137
146
 
138
147
  it "raises an exception if attempting to insert after an invalid object" do
@@ -188,4 +197,12 @@ describe Middleware::Builder do
188
197
  expect(data[:data]).to eq [2]
189
198
  end
190
199
  end
200
+
201
+ context "debugging" do
202
+ it "has an inspect method" do
203
+ instance.use appender_proc(1)
204
+ instance.use appender_proc(1), 2
205
+ expect(instance.inspect).to eq '[Proc(), Proc(2)]'
206
+ end
207
+ end
191
208
  end
@@ -49,7 +49,6 @@ describe Middleware::Runner do
49
49
  end
50
50
 
51
51
  it "should let lambdas to change the given argument" do
52
- data = []
53
52
  a = lambda { |env| env + 1 }
54
53
  b = lambda { |env| env + 2 }
55
54
 
@@ -57,6 +56,16 @@ describe Middleware::Runner do
57
56
  expect(instance.call(1)).to eq 4
58
57
  end
59
58
 
59
+ it "passes in arguments to lambda if given" do
60
+ data = []
61
+ a = lambda { |env, arg| data << arg }
62
+
63
+ instance = described_class.new([[a, 1]])
64
+ instance.call(nil)
65
+
66
+ expect(data).to eq [1]
67
+ end
68
+
60
69
  it "passes in arguments if given" do
61
70
  a = Class.new do
62
71
  def initialize(app, value)
@@ -156,7 +165,7 @@ describe Middleware::Runner do
156
165
 
157
166
  env = {}
158
167
  instance = described_class.new([a, b, c])
159
- expect { instance.call(env) }.to raise_error
168
+ expect { instance.call(env) }.to raise_error 'ERROR'
160
169
 
161
170
  expect(data).to eq ["a", "b", "e"]
162
171
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
1
3
  # This file was generated by the `rspec --init` command. Conventionally, all
2
4
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
5
  # The generated `.rspec` file contains `--require spec_helper` which will cause this
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.1
4
+ version: 0.3.2
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-04-07 00:00:00.000000000 Z
12
+ date: 2015-08-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '1.6'
20
+ version: 10.4.2
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '1.6'
27
+ version: 10.4.2
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rspec-core
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -67,6 +67,20 @@ dependencies:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '3.2'
70
+ - !ruby/object:Gem::Dependency
71
+ name: codeclimate-test-reporter
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 0.4.7
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 0.4.7
70
84
  description: Generalized implementation of the rack middleware abstraction for Ruby.
71
85
  email:
72
86
  - mitchell.hashimoto@gmail.com
@@ -77,7 +91,6 @@ extra_rdoc_files: []
77
91
  files:
78
92
  - ".gitignore"
79
93
  - ".rspec"
80
- - ".travis.yml"
81
94
  - CHANGELOG.md
82
95
  - Gemfile
83
96
  - LICENSE
data/.travis.yml DELETED
@@ -1,11 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.8.7
4
- - 1.9.2
5
- - 1.9.3
6
- - jruby-18mode
7
- - rbx-18mode
8
- - rbx-19mode
9
- - ruby-head
10
- - jruby-head
11
- - ree