web_pipe 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +9 -0
- data/README.md +3 -0
- data/docs/plugging_operations/inspecting_operations.md +25 -0
- data/docs/testing.md +64 -0
- data/docs/using_rack_middlewares/inspecting_middlewares.md +34 -0
- data/lib/web_pipe/dsl/instance_methods.rb +5 -5
- data/lib/web_pipe/plug.rb +16 -5
- data/lib/web_pipe/rack_support/middleware_specification.rb +18 -9
- data/lib/web_pipe/test_support.rb +28 -0
- data/lib/web_pipe/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 248232882dde49a235e15080f2c9c2abb1188e29e10f228f43d0c30c6c5f116f
|
4
|
+
data.tar.gz: ad6afa0399cdb99d80ef46fb1bcdde037e987e8fe01756f2c667301a9f622d5e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 399f912c144ac66bd1bfeaf58708a8e52ed7e296f5e592c9f9422fd3fd6553a4e3c16c0fec2986cf4fd278857d5acd1078d7b1a7e9e0e07ad9f18824303953ba
|
7
|
+
data.tar.gz: 41c539bee15aa9d3f8ae23bc88cd02ba5dc113ad9245290c330a269917716d12da5637852153d2f9bd7b324e8101f2a1329b267e5ebc409ae0c5cb419cd932f8
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
|
+
## [0.14.0] - 2021-04-14
|
8
|
+
### Added
|
9
|
+
- Inspecting operations
|
10
|
+
[#42](https://github.com/waiting-for-dev/web_pipe/pull/42)
|
11
|
+
- Inspecting middlewares
|
12
|
+
[#43](https://github.com/waiting-for-dev/web_pipe/pull/43)
|
13
|
+
- Testing support
|
14
|
+
[#44](https://github.com/waiting-for-dev/web_pipe/pull/44)
|
15
|
+
|
7
16
|
## [0.13.0] - 2021-01-15
|
8
17
|
### Added
|
9
18
|
- **BREAKING**. Ruby 2.5 deprecated.
|
data/README.md
CHANGED
@@ -20,9 +20,11 @@ extension](docs/extensions/rails.md).
|
|
20
20
|
1. [Resolving operations](docs/plugging_operations/resolving_operations.md)
|
21
21
|
1. [Injecting operations](docs/plugging_operations/injecting_operations.md)
|
22
22
|
1. [Composing operations](docs/plugging_operations/composing_operations.md)
|
23
|
+
1. [Inspecting operations](docs/plugging_operations/inspecting_operations.md)
|
23
24
|
1. [Using rack middlewares](docs/using_rack_middlewares.md)
|
24
25
|
1. [Injecting middlewares](docs/using_rack_middlewares/injecting_middlewares.md)
|
25
26
|
1. [Composing middlewares](docs/using_rack_middlewares/composing_middlewares.md)
|
27
|
+
1. [Inspecting middlewares](docs/using_rack_middlewares/inspecting_middlewares.md)
|
26
28
|
1. [Composing applications](docs/composing_applications.md)
|
27
29
|
1. [Connection struct](docs/connection_struct.md)
|
28
30
|
1. [Sharing data downstream](docs/connection_struct/sharing_data_downstream.md)
|
@@ -32,6 +34,7 @@ extension](docs/extensions/rails.md).
|
|
32
34
|
1. [Plugs](docs/plugs.md)
|
33
35
|
1. [Config](docs/plugs/config.md)
|
34
36
|
1. [ContentType](docs/plugs/content_type.md)
|
37
|
+
1. [Testing](docs/testing.md)
|
35
38
|
1. [Extensions](docs/extensions.md)
|
36
39
|
1. [Container](docs/extensions/container.md)
|
37
40
|
1. [Cookies](docs/extensions/cookies.md)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Inspecting operations
|
2
|
+
|
3
|
+
Once a `WebPipe` class is initialized all its operations get resolved. It
|
4
|
+
happens because they are whether [resolved](resolving_operations.md) or
|
5
|
+
[injected](injecting_operations.md). The final result can be accessed through
|
6
|
+
the `#operations` method:
|
7
|
+
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
require 'web_pipe'
|
11
|
+
require 'web_pipe/conn_support/builder'
|
12
|
+
|
13
|
+
class MyApp
|
14
|
+
include WebPipe
|
15
|
+
|
16
|
+
plug(:hello) do |conn|
|
17
|
+
conn.set_response_body('Hello world!')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
app = MyApp.new
|
22
|
+
conn = WebPipe::ConnSupport::Builder.call(Rack::MockRequest.env_for)
|
23
|
+
new_conn = app.operations[:hello].call(con)
|
24
|
+
conn.response_body #=> ['Hello world!']
|
25
|
+
```
|
data/docs/testing.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Testing
|
2
|
+
|
3
|
+
## Testing the rack application
|
4
|
+
|
5
|
+
A `WebPipe` instance is a just a rack application, so you can test it as such:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
require 'web_pipe'
|
9
|
+
require 'rack/mock'
|
10
|
+
require 'rspec'
|
11
|
+
|
12
|
+
class MyApp
|
13
|
+
include WebPipe
|
14
|
+
|
15
|
+
plug :response
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def response(conn)
|
20
|
+
conn
|
21
|
+
.set_response_body('Hello!')
|
22
|
+
.set_status(200)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.describe MyApp do
|
27
|
+
it 'responds with 200 status code' do
|
28
|
+
env = Rack::MockRequest.env_for
|
29
|
+
|
30
|
+
status, _headers, _body = described_class.new.call(env)
|
31
|
+
|
32
|
+
expect(status).to be(200)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
## Testing individual operations
|
38
|
+
|
39
|
+
Each operation in a pipe is an isolated function that takes a connection struct
|
40
|
+
as argument. You can leverage [the inspection of
|
41
|
+
operations](docs/plugging_operations/inspecting_operations.md) to unit test them.
|
42
|
+
|
43
|
+
There's also a `WebPipe::TestSupport` module that you can include to get a
|
44
|
+
helper method `#build_conn` to easily create a connection struct.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
RSpec.describe MyApp do
|
48
|
+
include WebPipe::TestSupport
|
49
|
+
|
50
|
+
describe '#response' do
|
51
|
+
it 'responds with 200 status code' do
|
52
|
+
conn = build_conn
|
53
|
+
operation = described_class.new.operations[:response]
|
54
|
+
|
55
|
+
new_conn = operation.call(conn)
|
56
|
+
|
57
|
+
expect(new_conn.status).to be(200)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Check the API documentation for the options you can provide to
|
64
|
+
[`#build_conn`](https://www.rubydoc.info/github/waiting-for-dev/web_pipe/master/WebPipe/TestSupport#build_conn).
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Inspecting middlewares
|
2
|
+
|
3
|
+
Once a `WebPipe` class is initialized all its middlewares get resolved. They
|
4
|
+
can be accessed through the `#middlewares` method.
|
5
|
+
|
6
|
+
Each middleware is represented by a
|
7
|
+
`WebPipe::RackSupport::MiddlewareSpecification` instance, which contains two
|
8
|
+
accessors: `middleware` returns the middleware class, while `options` returns
|
9
|
+
an array with the arguments that are provided to the middleware on initialization.
|
10
|
+
|
11
|
+
Kepp in mind that every middleware is resolved as an array. This is because it
|
12
|
+
can in fact be composed by an chain of middlewares built through
|
13
|
+
[composition](composing_middlewares.md).
|
14
|
+
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
require 'web_pipe'
|
18
|
+
require 'rack/session'
|
19
|
+
|
20
|
+
class MyApp
|
21
|
+
include WebPipe
|
22
|
+
|
23
|
+
use :session, Rack::Session::Cookie, key: 'my_app.session', secret: 'long'
|
24
|
+
|
25
|
+
plug(:hello) do |conn|
|
26
|
+
conn.set_response_body('Hello world!')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
app = MyApp.new
|
31
|
+
session_middleware = app.middlewares[:session][0]
|
32
|
+
session_middleware.middleware # => Rack::Session::Cookie
|
33
|
+
session_middleware.options # => [{ key: 'my_app.session', secret: 'long' }]
|
34
|
+
```
|
@@ -42,10 +42,10 @@ module WebPipe
|
|
42
42
|
# @return [RackSupport::AppWithMiddlewares[]]
|
43
43
|
attr_reader :rack_app
|
44
44
|
|
45
|
-
# @return [ConnSupport::Composition::Operation[]]
|
45
|
+
# @return [Hash<Plug::Name[], ConnSupport::Composition::Operation[]>]
|
46
46
|
attr_reader :operations
|
47
47
|
|
48
|
-
# @return [Array<RackSupport::Middlewares>]
|
48
|
+
# @return [Hash<RackSupport::MiddlewareSpecification::Name[], Array<RackSupport::Middlewares>]
|
49
49
|
attr_reader :middlewares
|
50
50
|
|
51
51
|
# rubocop:disable Metrics/AbcSize
|
@@ -58,8 +58,8 @@ module WebPipe
|
|
58
58
|
@operations = Plug.inject_and_resolve(
|
59
59
|
self.class.plugs, injections[:plugs], container, self
|
60
60
|
)
|
61
|
-
app = App.new(operations)
|
62
|
-
@rack_app = RackSupport::AppWithMiddlewares.new(middlewares, app)
|
61
|
+
app = App.new(operations.values)
|
62
|
+
@rack_app = RackSupport::AppWithMiddlewares.new(middlewares.values.flatten, app)
|
63
63
|
end
|
64
64
|
# rubocop:enable Metrics/AbcSize
|
65
65
|
|
@@ -105,7 +105,7 @@ module WebPipe
|
|
105
105
|
# @see ConnSupport::Composition
|
106
106
|
def to_proc
|
107
107
|
ConnSupport::Composition
|
108
|
-
.new(operations)
|
108
|
+
.new(operations.values)
|
109
109
|
.method(:call)
|
110
110
|
.to_proc
|
111
111
|
end
|
data/lib/web_pipe/plug.rb
CHANGED
@@ -97,15 +97,26 @@ module WebPipe
|
|
97
97
|
# @container container [Types::Container[]]
|
98
98
|
# @object [Object]
|
99
99
|
#
|
100
|
-
# @return [
|
100
|
+
# @return [Hash<Name[], ConnSupport::Composition::Operation[]>]
|
101
101
|
def self.inject_and_resolve(plugs, injections, container, object)
|
102
|
-
|
103
|
-
|
104
|
-
plug
|
102
|
+
Hash[
|
103
|
+
plugs.map do |plug|
|
104
|
+
inject_and_resolve_plug(plug, injections, container, object)
|
105
|
+
end
|
106
|
+
]
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.inject_and_resolve_plug(plug, injections, container, object)
|
110
|
+
name = plug.name
|
111
|
+
[
|
112
|
+
name,
|
113
|
+
if injections.key?(name)
|
114
|
+
plug.with(injections[name])
|
105
115
|
else
|
106
116
|
plug
|
107
117
|
end.call(container, object)
|
108
|
-
|
118
|
+
]
|
109
119
|
end
|
120
|
+
private_class_method :inject_and_resolve_plug
|
110
121
|
end
|
111
122
|
end
|
@@ -15,8 +15,6 @@ module WebPipe
|
|
15
15
|
# - A single element array where it is an instance of a class
|
16
16
|
# including {WebPipe}. This specifies all {RackSupport::Middlewares} for
|
17
17
|
# that {WebPipe}.
|
18
|
-
#
|
19
|
-
# @api private
|
20
18
|
class MiddlewareSpecification < Dry::Struct
|
21
19
|
# Type for the name given to a middleware.
|
22
20
|
Name = Types::Strict::Symbol.constructor(&:to_sym)
|
@@ -44,16 +42,27 @@ module WebPipe
|
|
44
42
|
# @param middleware_specifications [Array<MiddlewareSpecification>]
|
45
43
|
# @param injections [Injections[]]
|
46
44
|
#
|
47
|
-
# @return [Array<RackSupport::Middleware>]
|
45
|
+
# @return [Hash<Name[], Array<RackSupport::Middleware>]
|
48
46
|
def self.inject_and_resolve(middleware_specifications, injections)
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
Hash[
|
48
|
+
middleware_specifications.map do |middleware_spec|
|
49
|
+
inject_and_resolve_middleware(middleware_spec, injections)
|
50
|
+
end
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.inject_and_resolve_middleware(middleware_spec, injections)
|
55
|
+
name = middleware_spec.name
|
56
|
+
[
|
57
|
+
name,
|
58
|
+
if injections.key?(name)
|
59
|
+
middleware_spec.with(injections[name])
|
52
60
|
else
|
53
|
-
|
61
|
+
middleware_spec
|
54
62
|
end.call
|
55
|
-
|
63
|
+
]
|
56
64
|
end
|
65
|
+
private_class_method :inject_and_resolve_middleware
|
57
66
|
|
58
67
|
# Resolves {RackSupport::Middlewares} from given specification.
|
59
68
|
#
|
@@ -63,7 +72,7 @@ module WebPipe
|
|
63
72
|
options = spec[1..] || Types::EMPTY_ARRAY
|
64
73
|
case klass
|
65
74
|
when WebPipe
|
66
|
-
klass.middlewares
|
75
|
+
klass.middlewares.values
|
67
76
|
when Class
|
68
77
|
[Middleware.new(middleware: klass, options: options)]
|
69
78
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'web_pipe/conn_support/builder'
|
4
|
+
require 'rack/mock'
|
5
|
+
|
6
|
+
module WebPipe
|
7
|
+
# Test helper methods.
|
8
|
+
#
|
9
|
+
# This module is meant to be included in a test file to provide helper
|
10
|
+
# methods.
|
11
|
+
module TestSupport
|
12
|
+
# Builds a {WebPipe::Conn}
|
13
|
+
#
|
14
|
+
# @param uri [String] URI that will be used to populate the request
|
15
|
+
# attributes
|
16
|
+
# @param attributes [Hash<Symbol, Any>] Manually set attributes for the
|
17
|
+
# struct. It overrides what is taken from the `uri` parameter
|
18
|
+
# @param env_opts [Hash] Options to be added to the `env` from which the
|
19
|
+
# connection struct is created. See {Rack::MockRequest.env_for}.
|
20
|
+
# @return [Conn]
|
21
|
+
def build_conn(uri = '', attributes: {}, env_opts: {})
|
22
|
+
env = Rack::MockRequest.env_for(uri, env_opts)
|
23
|
+
ConnSupport::Builder
|
24
|
+
.call(env)
|
25
|
+
.new(attributes)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/web_pipe/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: web_pipe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Busqué
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-monads
|
@@ -289,6 +289,7 @@ files:
|
|
289
289
|
- docs/plugging_operations.md
|
290
290
|
- docs/plugging_operations/composing_operations.md
|
291
291
|
- docs/plugging_operations/injecting_operations.md
|
292
|
+
- docs/plugging_operations/inspecting_operations.md
|
292
293
|
- docs/plugging_operations/resolving_operations.md
|
293
294
|
- docs/plugs.md
|
294
295
|
- docs/plugs/config.md
|
@@ -296,9 +297,11 @@ files:
|
|
296
297
|
- docs/recipes/dry_rb_integration.md
|
297
298
|
- docs/recipes/hanami_router_integration.md
|
298
299
|
- docs/recipes/using_all_restful_methods.md
|
300
|
+
- docs/testing.md
|
299
301
|
- docs/using_rack_middlewares.md
|
300
302
|
- docs/using_rack_middlewares/composing_middlewares.md
|
301
303
|
- docs/using_rack_middlewares/injecting_middlewares.md
|
304
|
+
- docs/using_rack_middlewares/inspecting_middlewares.md
|
302
305
|
- lib/web_pipe.rb
|
303
306
|
- lib/web_pipe/app.rb
|
304
307
|
- lib/web_pipe/conn.rb
|
@@ -331,6 +334,7 @@ files:
|
|
331
334
|
- lib/web_pipe/rack_support/app_with_middlewares.rb
|
332
335
|
- lib/web_pipe/rack_support/middleware.rb
|
333
336
|
- lib/web_pipe/rack_support/middleware_specification.rb
|
337
|
+
- lib/web_pipe/test_support.rb
|
334
338
|
- lib/web_pipe/types.rb
|
335
339
|
- lib/web_pipe/version.rb
|
336
340
|
- web_pipe.gemspec
|
@@ -356,7 +360,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
356
360
|
- !ruby/object:Gem::Version
|
357
361
|
version: '0'
|
358
362
|
requirements: []
|
359
|
-
rubygems_version: 3.2
|
363
|
+
rubygems_version: 3.1.2
|
360
364
|
signing_key:
|
361
365
|
specification_version: 4
|
362
366
|
summary: Rack application builder through a pipe of operations on an immutable struct.
|