web_pipe 0.13.0 → 0.14.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 +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.
|