ibsciss-middleware 0.3.1 → 0.3.2

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: 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