web_pipe 0.10.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -1
  3. data/.rubocop.yml +18 -0
  4. data/.travis.yml +5 -4
  5. data/CHANGELOG.md +37 -0
  6. data/Gemfile +5 -0
  7. data/README.md +6 -4
  8. data/docs/connection_struct.md +11 -0
  9. data/docs/extensions/params.md +4 -3
  10. data/docs/extensions/rails.md +4 -3
  11. data/docs/plugging_operations/inspecting_operations.md +25 -0
  12. data/docs/testing.md +64 -0
  13. data/docs/using_rack_middlewares/inspecting_middlewares.md +34 -0
  14. data/lib/web_pipe.rb +2 -2
  15. data/lib/web_pipe/conn_support/builder.rb +2 -1
  16. data/lib/web_pipe/conn_support/composition.rb +2 -2
  17. data/lib/web_pipe/conn_support/errors.rb +6 -6
  18. data/lib/web_pipe/conn_support/headers.rb +2 -4
  19. data/lib/web_pipe/dsl/builder.rb +1 -0
  20. data/lib/web_pipe/dsl/class_context.rb +1 -0
  21. data/lib/web_pipe/dsl/dsl_context.rb +1 -1
  22. data/lib/web_pipe/dsl/instance_methods.rb +7 -5
  23. data/lib/web_pipe/extensions/container/container.rb +1 -0
  24. data/lib/web_pipe/extensions/cookies/cookies.rb +1 -0
  25. data/lib/web_pipe/extensions/dry_schema/dry_schema.rb +1 -0
  26. data/lib/web_pipe/extensions/dry_view/dry_view.rb +5 -2
  27. data/lib/web_pipe/extensions/flash/flash.rb +1 -0
  28. data/lib/web_pipe/extensions/params/params.rb +4 -3
  29. data/lib/web_pipe/extensions/params/params/transf.rb +4 -3
  30. data/lib/web_pipe/extensions/rails/rails.rb +6 -4
  31. data/lib/web_pipe/extensions/redirect/redirect.rb +1 -0
  32. data/lib/web_pipe/extensions/session/session.rb +1 -0
  33. data/lib/web_pipe/extensions/url/url.rb +1 -0
  34. data/lib/web_pipe/plug.rb +19 -8
  35. data/lib/web_pipe/rack_support/middleware_specification.rb +22 -12
  36. data/lib/web_pipe/test_support.rb +28 -0
  37. data/lib/web_pipe/version.rb +1 -1
  38. data/web_pipe.gemspec +7 -4
  39. metadata +51 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb774cbbdd90831e9ffcd5dba76265c37585b65f56618aff8cfa311b78d2bea8
4
- data.tar.gz: c456b68f6995308a740dacf97bb7177f140c51757fa6f680ecc7e515036d37a0
3
+ metadata.gz: 248232882dde49a235e15080f2c9c2abb1188e29e10f228f43d0c30c6c5f116f
4
+ data.tar.gz: ad6afa0399cdb99d80ef46fb1bcdde037e987e8fe01756f2c667301a9f622d5e
5
5
  SHA512:
6
- metadata.gz: 118d6af2b98c082fa174b33e092744d82a5e2667e20bc717ef996fa9da1b934d44a618331527d2c328d02ce2ea0dc62b3649800f326cfc7516f9ba3ba23c8797
7
- data.tar.gz: 32cb91bec0de9aaab6f48d48f4c68334a64fc3c5e944be4f6c20fccaacf1dab928b59809b0e50c129306d43951f0ef028812ab6196503cfff1d830cf8b5e658a
6
+ metadata.gz: 399f912c144ac66bd1bfeaf58708a8e52ed7e296f5e592c9f9422fd3fd6553a4e3c16c0fec2986cf4fd278857d5acd1078d7b1a7e9e0e07ad9f18824303953ba
7
+ data.tar.gz: 41c539bee15aa9d3f8ae23bc88cd02ba5dc113ad9245290c330a269917716d12da5637852153d2f9bd7b324e8101f2a1329b267e5ebc409ae0c5cb419cd932f8
data/.gitignore CHANGED
@@ -10,4 +10,8 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
 
13
- Gemfile.lock
13
+ Gemfile.lock
14
+
15
+ Dockerfile
16
+ docker-compose.yml
17
+ .dockerignore
data/.rubocop.yml ADDED
@@ -0,0 +1,18 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7.2
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+ Exclude:
6
+ - "*.gemspec"
7
+ - vendor/**/*
8
+ - Gemfile
9
+
10
+ Metrics/BlockLength:
11
+ Exclude:
12
+ - spec/**/*
13
+
14
+ Naming/AccessorMethodName:
15
+ Enabled: false
16
+
17
+ Style/HashConversion:
18
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,10 +1,11 @@
1
- sudo: false
2
1
  language: ruby
2
+ cache: bundler
3
3
  rvm:
4
- - 2.4
5
- - 2.5
6
4
  - 2.6
5
+ - 2.7
6
+ - 3.0
7
7
  before_install:
8
8
  - gem update --system --no-doc
9
9
  script:
10
- - bundle exec rspec
10
+ - bundle exec rspec
11
+ - bundle exec rubocop
data/CHANGELOG.md CHANGED
@@ -4,6 +4,43 @@ 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
+
16
+ ## [0.13.0] - 2021-01-15
17
+ ### Added
18
+ - **BREAKING**. Ruby 2.5 deprecated.
19
+ [#40](https://github.com/waiting-for-dev/web_pipe/pull/40)
20
+ - Ruby 3.0 supported.
21
+ [#41](https://github.com/waiting-for-dev/web_pipe/pull/41)
22
+
23
+ ## [0.12.1] - 2019-03-18
24
+ ### Fixed
25
+ - Update rake to fix security alert
26
+
27
+ ## [0.12.0] - 2019-12-30
28
+ ### Added
29
+ - **BREAKING**. Ruby 2.4 deprecated.
30
+ - Ruby 2.7 supported.
31
+
32
+ ### Fixed
33
+ - Ruby 2.7 argument warnings.
34
+ [[#38]](https://github.com/waiting-for-dev/web_pipe/pull/38)
35
+
36
+ ## [0.11.0] - 2019-12-28
37
+ ### Added
38
+ - **BREAKING**. `dry-transformer` (former `transproc`) dependency is now
39
+ optional.
40
+ [[#37]](https://github.com/waiting-for-dev/web_pipe/pull/37)
41
+ - Switch `transproc` dependency to `dry-transformer`.
42
+ [[#37]](https://github.com/waiting-for-dev/web_pipe/pull/37)
43
+
7
44
  ## [0.10.0] - 2019-11-15
8
45
  ### Added
9
46
  - `:rails` extension integrating with Ruby On Rails.
data/Gemfile CHANGED
@@ -6,3 +6,8 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
 
7
7
  # Specify your gem's dependencies in web_pipe.gemspec
8
8
  gemspec
9
+
10
+ # TODO: Remove when dry-rb 0.8 is released (ruby 3.0 support)
11
+ group :development do
12
+ gem 'dry-view', github: 'dry-rb/dry-view', ref: 'a048e32'
13
+ end
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)
@@ -92,10 +95,9 @@ run HelloApp.new
92
95
 
93
96
  ## Current status
94
97
 
95
- `web_pipe` is in active development. The very basic features to build
96
- a rack application are all available. However, very necessary
97
- conveniences to build a production application, for example a session
98
- mechanism, are still missing.
98
+ `web_pipe` is in active development but ready to be used in any environment.
99
+ Common needs are covered and while you can expect some API changes, they won't
100
+ be very important and everything will be properly documented.
99
101
 
100
102
  ## Contributing
101
103
 
@@ -75,3 +75,14 @@ Immutability is a core design principle in `web_pipe`. All methods in
75
75
  `WebPipe::Conn` which are used to add data to it (both in core behaviour and
76
76
  extensions) return a fresh new instance. It also makes possible chaining
77
77
  methods in a very readable way.
78
+
79
+ You can use ruby 2.7 pattern matching on a `WebPipe::Conn` struct, as in:
80
+
81
+ ```ruby
82
+ # GET http://example.org
83
+ conn in { request_method:, host: }
84
+ request_method
85
+ # :get
86
+ host
87
+ # 'example.org'
88
+ ```
@@ -12,9 +12,10 @@ conn.params # => { 'foo' => 'bar' }
12
12
  ```
13
13
 
14
14
  You can configure a stack of transformations to be applied to the
15
- parameter hash. For that, we lean on [`transproc`
16
- gem](https://github.com/solnic/transproc) (you have to add it yourself to your
17
- Gemfile). All hash transformations in `transproc` are available by default.
15
+ parameter hash. For that, we lean on [`dry-transformer`
16
+ gem](https://github.com/dry-rb/dry-transformer) (you have to add it yourself to
17
+ your Gemfile). All hash transformations in `dry-transformer` are available by
18
+ default.
18
19
 
19
20
  Transformations must be configured under `:param_transformations`
20
21
  key:
@@ -36,7 +36,7 @@ option that will play specially well here is
36
36
  itself easily with Rails. Furthermore, we have a tailored `dry_view`
37
37
  [extension](https://waiting-for-dev.github.io/web_pipe/docs/extensions/dry_view.html).
38
38
 
39
- You need to use this extension if:
39
+ You need to use `:rails` extension if:
40
40
 
41
41
  - You want to use `action_view` as rendering system.
42
42
  - You want to use rails url helpers from your `WebPipe` application.
@@ -50,7 +50,6 @@ some behaviour for the view layer:
50
50
 
51
51
  - Which layout is applied to the template.
52
52
  - Which helpers will become available to the templates.
53
- - Where within `app/views/` templates are looked up.
54
53
 
55
54
  By default, the controller in use is `ActionController::Base`, which means that
56
55
  no layout is applied and only built-in helpers (for example,
@@ -95,7 +94,9 @@ end
95
94
 
96
95
  Notice that we used the keyword `template:` instead of taking advantage of
97
96
  automatic template lookup. We did that way so that we don't have to create also
98
- an `ArticlesController`, but it's up to you.
97
+ an `ArticlesController`, but it's up to you. In the case of having an
98
+ `ArticlesController` we could just do `conn.render(:index, assigns: {
99
+ articles: Article.all })`.
99
100
 
100
101
  Besides, this extension provides with two other methods:
101
102
 
@@ -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
+ ```
data/lib/web_pipe.rb CHANGED
@@ -14,8 +14,8 @@ module WebPipe
14
14
  klass.include(call)
15
15
  end
16
16
 
17
- def self.call(*args)
18
- DSL::Builder.new(*args)
17
+ def self.call(**opts)
18
+ DSL::Builder.new(**opts)
19
19
  end
20
20
 
21
21
  register_extension :cookies do
@@ -15,12 +15,12 @@ module WebPipe
15
15
  # @param env [Types::Env] Rack's env
16
16
  #
17
17
  # @return [Conn::Ongoing]
18
+ # rubocop:disable Metrics/MethodLength
18
19
  def self.call(env)
19
20
  rr = Rack::Request.new(env)
20
21
  Conn::Ongoing.new(
21
22
  request: rr,
22
23
  env: env,
23
-
24
24
  scheme: rr.scheme.to_sym,
25
25
  request_method: rr.request_method.downcase.to_sym,
26
26
  host: rr.host,
@@ -33,6 +33,7 @@ module WebPipe
33
33
  request_headers: Headers.extract(env)
34
34
  )
35
35
  end
36
+ # rubocop:enable Metrics/MethodLength
36
37
  end
37
38
  end
38
39
  end
@@ -28,11 +28,11 @@ module WebPipe
28
28
  # @param returned [Any] What was returned from the {Operation}
29
29
  def initialize(returned)
30
30
  super(
31
- <<~eos
31
+ <<~MSG
32
32
  An operation returned +#{returned.inspect}+. To be valid,
33
33
  an operation must return whether a
34
34
  WebPipe::Conn::Ongoing or a WebPipe::Conn::Halted.
35
- eos
35
+ MSG
36
36
  )
37
37
  end
38
38
  end
@@ -8,9 +8,9 @@ module WebPipe
8
8
  # @param key [Any] Key not found in the bag
9
9
  def initialize(key)
10
10
  super(
11
- <<~eos
11
+ <<~MSG
12
12
  Bag does not contain a key with name +#{key}+.
13
- eos
13
+ MSG
14
14
  )
15
15
  end
16
16
  end
@@ -21,9 +21,9 @@ module WebPipe
21
21
  # @param key [Any] Key not found in config
22
22
  def initialize(key)
23
23
  super(
24
- <<~eos
24
+ <<~MSG
25
25
  Config does not contain a key with name +#{key}+.
26
- eos
26
+ MSG
27
27
  )
28
28
  end
29
29
  end
@@ -36,10 +36,10 @@ module WebPipe
36
36
  # @param gem [String] Gem name for the middleware
37
37
  def initialize(feature, middleware, gem)
38
38
  super(
39
- <<~eos
39
+ <<~MSG
40
40
  In order to use #{feature} you must use #{middleware} middleware:
41
41
  https://rubygems.org/gems/#{gem}
42
- eos
42
+ MSG
43
43
  )
44
44
  end
45
45
  end
@@ -25,7 +25,7 @@ module WebPipe
25
25
  Hash[
26
26
  env
27
27
  .select { |k, _v| k.start_with?('HTTP_') }
28
- .map { |k, v| pair(k[5..-1], v) }
28
+ .map { |k, v| pair(k[5..], v) }
29
29
  .concat(
30
30
  env
31
31
  .select { |k, _v| HEADERS_AS_CGI.include?(k) }
@@ -99,9 +99,7 @@ module WebPipe
99
99
  #
100
100
  # @see #normalize_key
101
101
  def self.normalize(headers)
102
- Hash[
103
- headers.map { |k, v| [normalize_key(k), v] }
104
- ]
102
+ headers.transform_keys { |k| normalize_key(k) }
105
103
  end
106
104
  end
107
105
  end
@@ -25,6 +25,7 @@ module WebPipe
25
25
  def initialize(container: EMPTY_CONTAINER)
26
26
  @container = Types::Container[container]
27
27
  @class_context = ClassContext.new(container: container)
28
+ super()
28
29
  end
29
30
 
30
31
  def included(klass)
@@ -33,6 +33,7 @@ module WebPipe
33
33
  @dsl_context = DSLContext.new([], [])
34
34
  define_container
35
35
  define_dsl
36
+ super()
36
37
  end
37
38
 
38
39
  private
@@ -66,7 +66,7 @@ module WebPipe
66
66
  spec
67
67
  else
68
68
  block_spec
69
- end
69
+ end
70
70
 
71
71
  plugs << Plug.new(name: name, spec: plug_spec)
72
72
  end
@@ -42,12 +42,13 @@ 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
+ # rubocop:disable Metrics/AbcSize
51
52
  def initialize(injects = EMPTY_INJECTIONS)
52
53
  @injections = Injections[injects]
53
54
  container = self.class.container
@@ -57,9 +58,10 @@ module WebPipe
57
58
  @operations = Plug.inject_and_resolve(
58
59
  self.class.plugs, injections[:plugs], container, self
59
60
  )
60
- app = App.new(operations)
61
- @rack_app = RackSupport::AppWithMiddlewares.new(middlewares, app)
61
+ app = App.new(operations.values)
62
+ @rack_app = RackSupport::AppWithMiddlewares.new(middlewares.values.flatten, app)
62
63
  end
64
+ # rubocop:enable Metrics/AbcSize
63
65
 
64
66
  # Expected interface for rack.
65
67
  #
@@ -103,7 +105,7 @@ module WebPipe
103
105
  # @see ConnSupport::Composition
104
106
  def to_proc
105
107
  ConnSupport::Composition
106
- .new(operations)
108
+ .new(operations.values)
107
109
  .method(:call)
108
110
  .to_proc
109
111
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'web_pipe'
4
4
 
5
+ #:nodoc:
5
6
  module WebPipe
6
7
  # Extension adding a `#container` method which returns {Conn#config}
7
8
  # `:container` key.
@@ -4,6 +4,7 @@ require 'web_pipe'
4
4
  require 'web_pipe/types'
5
5
  require 'rack/utils'
6
6
 
7
+ #:nodoc:
7
8
  module WebPipe
8
9
  # Extension to help dealing with request and response cookies.
9
10
  #
@@ -4,6 +4,7 @@ require 'web_pipe'
4
4
 
5
5
  WebPipe.load_extensions(:params)
6
6
 
7
+ #:nodoc:
7
8
  module WebPipe
8
9
  # Integration with `dry-schema` validation library.
9
10
  #
@@ -4,6 +4,7 @@ require 'web_pipe/types'
4
4
  require 'web_pipe/conn'
5
5
  require 'dry/view'
6
6
 
7
+ #:nodoc:
7
8
  module WebPipe
8
9
  # Integration with `dry-view` rendering system.
9
10
  #
@@ -125,7 +126,7 @@ module WebPipe
125
126
 
126
127
  set_response_body(
127
128
  view_instance.call(
128
- view_input
129
+ **view_input
129
130
  ).to_str
130
131
  )
131
132
  end
@@ -145,7 +146,9 @@ module WebPipe
145
146
  .config
146
147
  .default_context
147
148
  .with(
148
- fetch_config(VIEW_CONTEXT_KEY, DEFAULT_VIEW_CONTEXT).call(self)
149
+ **fetch_config(
150
+ VIEW_CONTEXT_KEY, DEFAULT_VIEW_CONTEXT
151
+ ).call(self)
149
152
  )
150
153
  kwargs.merge(context: context)
151
154
  end
@@ -3,6 +3,7 @@
3
3
  require 'web_pipe/conn'
4
4
  require 'web_pipe/conn_support/errors'
5
5
 
6
+ #:nodoc:
6
7
  module WebPipe
7
8
  # Provides with a typical flash messages functionality.
8
9
  #
@@ -3,6 +3,7 @@
3
3
  require 'web_pipe/types'
4
4
  require 'web_pipe/extensions/params/params/transf'
5
5
 
6
+ #:nodoc:
6
7
  module WebPipe
7
8
  # Adds a {Conn#params} method which can perform any number of
8
9
  # transformations to the request parameters.
@@ -14,9 +15,9 @@ module WebPipe
14
15
  # # http://www.example.com?foo=bar
15
16
  # conn.params #=> { 'foo' => 'bar' }
16
17
  #
17
- # Further processing can be specified thanks to `transproc` gem (you
18
+ # Further processing can be specified thanks to `dry-transformer` gem (you
18
19
  # need to add it yourself to the Gemfile). All hash transformations
19
- # in `transproc` are available:
20
+ # in `dry-transformer` are available:
20
21
  #
21
22
  # @example
22
23
  # # http://www.example.com?foo=bar
@@ -65,7 +66,7 @@ module WebPipe
65
66
  # conn.
66
67
  # params(fake) #=> { fake: :params }
67
68
  #
68
- # @see https://github.com/solnic/transproc
69
+ # @see https://github.com/dry-rb/dry-transformer
69
70
  module Params
70
71
  # Key where configured transformations are set
71
72
  PARAM_TRANSFORMATION_KEY = :param_transformations
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'transproc'
3
+ require 'dry/transformer'
4
4
 
5
5
  module WebPipe
6
6
  module Params
7
+ # Parameter transformations from dry-transformer.
7
8
  module Transf
8
- extend Transproc::Registry
9
+ extend Dry::Transformer::Registry
9
10
 
10
- import Transproc::HashTransformations
11
+ import Dry::Transformer::HashTransformations
11
12
 
12
13
  def self.id(params)
13
14
  params
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'web_pipe/conn'
4
4
 
5
+ #:nodoc:
5
6
  module WebPipe
6
7
  # Integrates with Rails framework.
7
8
  #
@@ -40,7 +41,7 @@ module WebPipe
40
41
  # itself easily with Rails. Furthermore, we have a tailored `dry_view`
41
42
  # extension.
42
43
  #
43
- # You need to use this extension if:
44
+ # You need to use `:rails` extension if:
44
45
  #
45
46
  # - You want to use `action_view` as rendering system.
46
47
  # - You want to use rails url helpers from your {WebPipe} application.
@@ -54,7 +55,6 @@ module WebPipe
54
55
  #
55
56
  # - Which layout is applied to the template.
56
57
  # - Which helpers will become available to the templates.
57
- # - Where within `app/views/` templates are looked up.
58
58
  #
59
59
  # By default, the controller in use is `ActionController::Base`, which means
60
60
  # that no layout is applied and only built-in helpers (for example,
@@ -74,7 +74,7 @@ module WebPipe
74
74
  # class ApplicationController < ActionController::Base
75
75
  # # By default uses the layout in `layouts/application`
76
76
  # end
77
- #
77
+ #
78
78
  # # app/controllers/articles_index.rb
79
79
  # require 'web_pipe/plugs/config'
80
80
  #
@@ -99,7 +99,9 @@ module WebPipe
99
99
  #
100
100
  # Notice that we used the keyword `template:` instead of taking advantage of
101
101
  # automatic template lookup. We did that way so that we don't have to create
102
- # also an `ArticlesController`, but it's up to you.
102
+ # also an `ArticlesController`, but it's up to you. In the case of having an
103
+ # `ArticlesController` we could just do `conn.render(:index, assigns: {
104
+ # articles: Article.all })`.
103
105
  #
104
106
  # Besides, this extension provides with two other methods:
105
107
  #
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'web_pipe/types'
4
4
 
5
+ #:nodoc:
5
6
  module WebPipe
6
7
  # Helper method to create redirect responses.
7
8
  #
@@ -4,6 +4,7 @@ require 'web_pipe/conn'
4
4
  require 'web_pipe/types'
5
5
  require 'rack'
6
6
 
7
+ #:nodoc:
7
8
  module WebPipe
8
9
  # Wrapper around Rack::Session middlewares.
9
10
  #
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ #:nodoc:
3
4
  module WebPipe
4
5
  # Adds helper methods related to the request URL.
5
6
  #
data/lib/web_pipe/plug.rb CHANGED
@@ -25,11 +25,11 @@ module WebPipe
25
25
  # @param name [Any] Name for the plug that can't be resolved
26
26
  def initialize(name)
27
27
  super(
28
- <<~eos
28
+ <<~MSG
29
29
  Plug with name +#{name}+ is invalid. It must be something
30
30
  callable, an instance method when no operation is given,
31
31
  or something callable registered in the container."
32
- eos
32
+ MSG
33
33
  )
34
34
  end
35
35
  end
@@ -83,7 +83,7 @@ module WebPipe
83
83
  spec
84
84
  elsif spec.nil?
85
85
  pipe.method(name)
86
- elsif container[spec]&.respond_to?(:call)
86
+ elsif container[spec].respond_to?(:call)
87
87
  container[spec]
88
88
  else
89
89
  raise InvalidPlugError, name
@@ -97,15 +97,26 @@ module WebPipe
97
97
  # @container container [Types::Container[]]
98
98
  # @object [Object]
99
99
  #
100
- # @return [Array<ConnSupport::Composition::Operation[]>]
100
+ # @return [Hash<Name[], ConnSupport::Composition::Operation[]>]
101
101
  def self.inject_and_resolve(plugs, injections, container, object)
102
- plugs.map do |plug|
103
- if injections.key?(plug.name)
104
- plug.with(injections[plug.name])
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
- end
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,26 +42,38 @@ 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
- middleware_specifications.map do |spec|
50
- if injections.key?(spec.name)
51
- spec.with(injections[spec.name])
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
- spec
61
+ middleware_spec
54
62
  end.call
55
- end.flatten
63
+ ]
56
64
  end
65
+ private_class_method :inject_and_resolve_middleware
57
66
 
58
67
  # Resolves {RackSupport::Middlewares} from given specification.
59
68
  #
60
69
  # @return [Array<RackSupport::Middleware>]
61
70
  def call
62
71
  klass = spec[0]
63
- options = spec[1..-1] || Types::EMPTY_ARRAY
64
- if klass.is_a?(WebPipe)
65
- klass.middlewares
66
- elsif klass.is_a?(Class)
72
+ options = spec[1..] || Types::EMPTY_ARRAY
73
+ case klass
74
+ when WebPipe
75
+ klass.middlewares.values
76
+ when Class
67
77
  [Middleware.new(middleware: klass, options: options)]
68
78
  end
69
79
  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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebPipe
4
- VERSION = '0.10.0'
4
+ VERSION = '0.14.0'
5
5
  end
data/web_pipe.gemspec CHANGED
@@ -39,16 +39,19 @@ Gem::Specification.new do |spec|
39
39
  spec.add_runtime_dependency 'dry-struct', '~> 1.0'
40
40
  spec.add_runtime_dependency 'dry-types', '~> 1.1'
41
41
  spec.add_runtime_dependency 'rack', '~> 2.0'
42
- spec.add_runtime_dependency 'transproc', '~> 1.1'
43
42
 
44
- spec.add_development_dependency 'bundler', '~> 1.17'
43
+ spec.add_development_dependency 'bundler'
45
44
  spec.add_development_dependency 'dry-schema', '~> 1.0'
46
- spec.add_development_dependency 'dry-view', '~> 0.7'
45
+ spec.add_development_dependency 'dry-transformer', '~> 0.1'
46
+ # TODO: Readd when dry-rb 0.8 is released (ruby 3.0 support)
47
+ # spec.add_development_dependency 'dry-view', '~> 0.8'
47
48
  spec.add_development_dependency 'pry-byebug'
48
49
  spec.add_development_dependency 'rack-flash3', '~> 1.0'
49
50
  spec.add_development_dependency 'rack-test', '~> 1.1'
50
- spec.add_development_dependency 'rake', '~> 10.0'
51
+ spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
51
52
  spec.add_development_dependency 'redcarpet', '~> 3.4'
52
53
  spec.add_development_dependency 'rspec', '~> 3.0'
53
54
  spec.add_development_dependency 'yard', '~> 0.9', '>= 0.9.20'
55
+ spec.add_development_dependency 'rubocop', '~> 1.8'
56
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.1'
54
57
  end
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.10.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: 2019-11-15 00:00:00.000000000 Z
11
+ date: 2021-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-monads
@@ -66,34 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.0'
69
- - !ruby/object:Gem::Dependency
70
- name: transproc
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '1.1'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.1'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: bundler
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
- - - "~>"
73
+ - - ">="
88
74
  - !ruby/object:Gem::Version
89
- version: '1.17'
75
+ version: '0'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
- - - "~>"
80
+ - - ">="
95
81
  - !ruby/object:Gem::Version
96
- version: '1.17'
82
+ version: '0'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: dry-schema
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -109,19 +95,19 @@ dependencies:
109
95
  - !ruby/object:Gem::Version
110
96
  version: '1.0'
111
97
  - !ruby/object:Gem::Dependency
112
- name: dry-view
98
+ name: dry-transformer
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
101
  - - "~>"
116
102
  - !ruby/object:Gem::Version
117
- version: '0.7'
103
+ version: '0.1'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
108
  - - "~>"
123
109
  - !ruby/object:Gem::Version
124
- version: '0.7'
110
+ version: '0.1'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: pry-byebug
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -170,14 +156,20 @@ dependencies:
170
156
  requirements:
171
157
  - - "~>"
172
158
  - !ruby/object:Gem::Version
173
- version: '10.0'
159
+ version: '12.3'
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 12.3.3
174
163
  type: :development
175
164
  prerelease: false
176
165
  version_requirements: !ruby/object:Gem::Requirement
177
166
  requirements:
178
167
  - - "~>"
179
168
  - !ruby/object:Gem::Version
180
- version: '10.0'
169
+ version: '12.3'
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 12.3.3
181
173
  - !ruby/object:Gem::Dependency
182
174
  name: redcarpet
183
175
  requirement: !ruby/object:Gem::Requirement
@@ -226,6 +218,34 @@ dependencies:
226
218
  - - ">="
227
219
  - !ruby/object:Gem::Version
228
220
  version: 0.9.20
221
+ - !ruby/object:Gem::Dependency
222
+ name: rubocop
223
+ requirement: !ruby/object:Gem::Requirement
224
+ requirements:
225
+ - - "~>"
226
+ - !ruby/object:Gem::Version
227
+ version: '1.8'
228
+ type: :development
229
+ prerelease: false
230
+ version_requirements: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - "~>"
233
+ - !ruby/object:Gem::Version
234
+ version: '1.8'
235
+ - !ruby/object:Gem::Dependency
236
+ name: rubocop-rspec
237
+ requirement: !ruby/object:Gem::Requirement
238
+ requirements:
239
+ - - "~>"
240
+ - !ruby/object:Gem::Version
241
+ version: '2.1'
242
+ type: :development
243
+ prerelease: false
244
+ version_requirements: !ruby/object:Gem::Requirement
245
+ requirements:
246
+ - - "~>"
247
+ - !ruby/object:Gem::Version
248
+ version: '2.1'
229
249
  description:
230
250
  email:
231
251
  - marc@lamarciana.com
@@ -235,6 +255,7 @@ extra_rdoc_files: []
235
255
  files:
236
256
  - ".gitignore"
237
257
  - ".rspec"
258
+ - ".rubocop.yml"
238
259
  - ".travis.yml"
239
260
  - ".yardopts"
240
261
  - CHANGELOG.md
@@ -268,6 +289,7 @@ files:
268
289
  - docs/plugging_operations.md
269
290
  - docs/plugging_operations/composing_operations.md
270
291
  - docs/plugging_operations/injecting_operations.md
292
+ - docs/plugging_operations/inspecting_operations.md
271
293
  - docs/plugging_operations/resolving_operations.md
272
294
  - docs/plugs.md
273
295
  - docs/plugs/config.md
@@ -275,9 +297,11 @@ files:
275
297
  - docs/recipes/dry_rb_integration.md
276
298
  - docs/recipes/hanami_router_integration.md
277
299
  - docs/recipes/using_all_restful_methods.md
300
+ - docs/testing.md
278
301
  - docs/using_rack_middlewares.md
279
302
  - docs/using_rack_middlewares/composing_middlewares.md
280
303
  - docs/using_rack_middlewares/injecting_middlewares.md
304
+ - docs/using_rack_middlewares/inspecting_middlewares.md
281
305
  - lib/web_pipe.rb
282
306
  - lib/web_pipe/app.rb
283
307
  - lib/web_pipe/conn.rb
@@ -310,6 +334,7 @@ files:
310
334
  - lib/web_pipe/rack_support/app_with_middlewares.rb
311
335
  - lib/web_pipe/rack_support/middleware.rb
312
336
  - lib/web_pipe/rack_support/middleware_specification.rb
337
+ - lib/web_pipe/test_support.rb
313
338
  - lib/web_pipe/types.rb
314
339
  - lib/web_pipe/version.rb
315
340
  - web_pipe.gemspec
@@ -335,8 +360,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
335
360
  - !ruby/object:Gem::Version
336
361
  version: '0'
337
362
  requirements: []
338
- rubyforge_project:
339
- rubygems_version: 2.7.8
363
+ rubygems_version: 3.1.2
340
364
  signing_key:
341
365
  specification_version: 4
342
366
  summary: Rack application builder through a pipe of operations on an immutable struct.