web_pipe 0.12.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -1
  3. data/.rubocop.yml +18 -0
  4. data/.travis.yml +3 -2
  5. data/CHANGELOG.md +25 -0
  6. data/Gemfile +5 -0
  7. data/README.md +4 -1
  8. data/docs/extensions/{dry_view.md → hanami_view.md} +16 -14
  9. data/docs/extensions/params.md +4 -3
  10. data/docs/extensions/rails.md +3 -4
  11. data/docs/plugging_operations/inspecting_operations.md +25 -0
  12. data/docs/recipes/dry_rb_integration.md +2 -3
  13. data/docs/testing.md +64 -0
  14. data/docs/using_rack_middlewares/inspecting_middlewares.md +34 -0
  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/flash/flash.rb +1 -0
  27. data/lib/web_pipe/extensions/{dry_view/dry_view.rb → hanami_view/hanami_view.rb} +19 -18
  28. data/lib/web_pipe/extensions/params/params/transf.rb +1 -0
  29. data/lib/web_pipe/extensions/params/params.rb +1 -0
  30. data/lib/web_pipe/extensions/rails/rails.rb +4 -7
  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/lib/web_pipe.rb +2 -2
  39. data/web_pipe.gemspec +3 -2
  40. metadata +45 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 912213d537d97b530b24ba19289e68844c2ee1c46d9a49510167b5ddbef29468
4
- data.tar.gz: e992a632ade636cea6185de8707935c28548d588d264152bac9150a724f80e83
3
+ metadata.gz: 8a8ebc7025774af2e5938efb5c76a0ff120bc386f449900781e3f05d35eb6a15
4
+ data.tar.gz: a6e03d72fb7cb3bd384cea1f51369f21a375b4a009b8409ef3a588600adc07b7
5
5
  SHA512:
6
- metadata.gz: a1f651795c8ea96d8d4d8ac37d452f7e6db6a4835215acad6784a445ecd36fe10c7bad16bc5e7defb9f7130caf8dbce4287ab3f4a0f0a7147f560adeb0a3cc59
7
- data.tar.gz: cea9a48921c145d2fd8c4533e77f59cba2c080c31227943aec69653ca09cb18ff903deee39282594cd66bb2ca91a4d4adb924c03273d70eed4851b22127a1fd2
6
+ metadata.gz: 278d8402ec4ea79266eefd3ee558522af3923bb23232b3fcefd8574d73dc64c8106757f910a1c312ceed57889ee352e5955c19641601dfdcb47bcbbc63673bb8
7
+ data.tar.gz: 99ae42906946fbdda913bbf4f0cdd2cc1a6c3951ffb5972b52bb11b5caf882b6b6c286b68aca9d92ce0e6974d6168178860ae164d3d49af7bcb36556202b70dc
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.5
5
4
  - 2.6
6
5
  - 2.7
6
+ - 3.0
7
7
  before_install:
8
8
  - gem update --system --no-doc
9
9
  script:
10
10
  - bundle exec rspec
11
+ - bundle exec rubocop
data/CHANGELOG.md CHANGED
@@ -4,6 +4,31 @@ 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.15.0] - 2021-09-12
8
+ - **BREAKING**. Switch `dry_view` extension with `hanami_view`.
9
+ [#45](https://github.com/waiting-for-dev/web_pipe/pull/45)
10
+
11
+ ### Added
12
+ ## [0.14.0] - 2021-04-14
13
+ ### Added
14
+ - Inspecting operations
15
+ [#42](https://github.com/waiting-for-dev/web_pipe/pull/42)
16
+ - Inspecting middlewares
17
+ [#43](https://github.com/waiting-for-dev/web_pipe/pull/43)
18
+ - Testing support
19
+ [#44](https://github.com/waiting-for-dev/web_pipe/pull/44)
20
+
21
+ ## [0.13.0] - 2021-01-15
22
+ ### Added
23
+ - **BREAKING**. Ruby 2.5 deprecated.
24
+ [#40](https://github.com/waiting-for-dev/web_pipe/pull/40)
25
+ - Ruby 3.0 supported.
26
+ [#41](https://github.com/waiting-for-dev/web_pipe/pull/41)
27
+
28
+ ## [0.12.1] - 2019-03-18
29
+ ### Fixed
30
+ - Update rake to fix security alert
31
+
7
32
  ## [0.12.0] - 2019-12-30
8
33
  ### Added
9
34
  - **BREAKING**. Ruby 2.4 deprecated.
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
+ group :development do
11
+ # TODO: Move to gemspec when hanami-view 2.0 is available
12
+ gem 'hanami-view', github: 'hanami/view', tag: 'v2.0.0.alpha2'
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,12 +34,13 @@ 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)
38
41
  1. [Flash](docs/extensions/flash.md)
39
42
  1. [Dry Schema](docs/extensions/dry_schema.md)
40
- 1. [Dry View](docs/extensions/dry_view.md)
43
+ 1. [Hanami View](docs/extensions/hanami_view.md)
41
44
  1. [Params](docs/extensions/params.md)
42
45
  1. [Rails](docs/extensions/rails.md)
43
46
  1. [Redirect](docs/extensions/redirect.md)
@@ -1,8 +1,10 @@
1
- # Dry View
1
+ # Hanami View
2
2
 
3
- This extensions integrates with
4
- [dry-view](https://dry-rb.org/gems/dry-view/) rendering system to
5
- set a dry-view output as response body.
3
+ > This extension currently works with `hanami-view` v2.0.0.alpha2, which is not
4
+ still released but it's available on the gem repository.
5
+
6
+ This extensions integrates with [hanami-view](https://github.com/hanami/view)
7
+ rendering system to set a hanami-view output as response body.
6
8
 
7
9
  `WebPipe::Conn#view` method is at the core of this extension. In its basic
8
10
  behaviour, you provide to it a view instance you want to render and any
@@ -10,12 +12,12 @@ exposures or options it may need:
10
12
 
11
13
  ```ruby
12
14
  require 'web_pipe'
13
- require 'dry/view'
15
+ require 'hanami/view'
14
16
  require 'my_context'
15
17
 
16
- WebPipe.load_extensions(:dry_view)
18
+ WebPipe.load_extensions(:hanami_view)
17
19
 
18
- class SayHelloView < Dry::View
20
+ class SayHelloView < Hanami::View
19
21
  config.paths = [File.join(__dir__, '..', 'templates')]
20
22
  config.template = 'say_hello'
21
23
  config.default_context = MyContext
@@ -40,12 +42,12 @@ However, you can resolve a view from a container if you also use (`:container`
40
42
  extension)[container.md]:
41
43
 
42
44
  ```ruby
43
- require 'dry_view'
45
+ require 'hanami_view'
44
46
  require 'my_container'
45
47
  require 'web_pipe'
46
48
  require 'web_pipe/plugs/config'
47
49
 
48
- WebPipe.load_extensions(:dry_view, :container)
50
+ WebPipe.load_extensions(:hanami_view, :container)
49
51
 
50
52
  class MyApp
51
53
  include WebPipe
@@ -61,20 +63,20 @@ class MyApp
61
63
  end
62
64
  ```
63
65
 
64
- As in a standard call to `Dry::View#call`, you can override the context
65
- (`Dry::View::Context`) to use through `context:` option. However, it is still
66
+ As in a standard call to `Hanami::View#call`, you can override the context
67
+ (`Hanami::View::Context`) to use through `context:` option. However, it is still
66
68
  possible to leverage configured default context while being able to inject
67
69
  request specific data to it.
68
70
 
69
71
  For that to work, you have to specify required dependencies (in this case,
70
- request specific data) to your dry-view's context. A very convenient way to do
72
+ request specific data) to your hanami-view's context. A very convenient way to do
71
73
  that is with [`dry-auto_inject`](https://dry-rb.org/gems/dry-auto_inject):
72
74
 
73
75
  ```ruby
74
- require 'dry/view/context'
76
+ require 'hanami/view/context'
75
77
  require 'my_import'
76
78
 
77
- class MyContext < Dry::View::Context
79
+ class MyContext < Hanami::View::Context
78
80
  include MyImport::Import[:current_path]
79
81
 
80
82
  # Without `dry-auto_inject` you have to manually specify dependencies and
@@ -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:
@@ -31,10 +31,9 @@ It's quite possible that you don't need more than that in terms of rails
31
31
  integration. Of course, surely you want something more elaborate to generate
32
32
  responses. For that, you can use the view or template system you like. One
33
33
  option that will play specially well here is
34
- [`dry-view`](https://dry-rb.org/gems/dry-view/), which
35
- [integrates](https://github.com/dry-rb/dry-view/tree/master/examples/rails)
36
- itself easily with Rails. Furthermore, we have a tailored `dry_view`
37
- [extension](https://waiting-for-dev.github.io/web_pipe/docs/extensions/dry_view.html).
34
+ [`hanami-view`](https://github.com/hanami/view). Furthermore, we have a
35
+ tailored `hanami_view`
36
+ [extension](https://waiting-for-dev.github.io/web_pipe/docs/extensions/hanami_view.html).
38
37
 
39
38
  You need to use `:rails` extension if:
40
39
 
@@ -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
+ ```
@@ -3,9 +3,8 @@
3
3
  `web_pipe` has been designed to integrate smoothly with
4
4
  [dry-rb](https://dry-rb.org/) ecosystem. It shares same design
5
5
  principles and it ships with some extensions which even make this
6
- integration tighter (like
7
- [`:dry-view`](../extensions/dry_view.md) or
8
- [`:dry-schema`](../extensions/dry_schema.md) extensions).
6
+ integration tighter (like [`:dry-schema`](../extensions/dry_schema.md)
7
+ extension).
9
8
 
10
9
  If you want to use `web_pipe` with the rest of dry-rb libraries,
11
10
  your best bet is to use
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
+ ```
@@ -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
  #
@@ -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
  #
@@ -2,18 +2,19 @@
2
2
 
3
3
  require 'web_pipe/types'
4
4
  require 'web_pipe/conn'
5
- require 'dry/view'
5
+ require 'hanami/view'
6
6
 
7
+ #:nodoc:
7
8
  module WebPipe
8
- # Integration with `dry-view` rendering system.
9
+ # Integration with `hanami-view` rendering system.
9
10
  #
10
11
  # This extensions adds a {#view} method to {WebPipe::Conn} which
11
- # sets the string output of a `dry-view` view as response body.
12
+ # sets the string output of a `hanami-view` view as response body.
12
13
  #
13
14
  # @example
14
- # WebPipe.load_extensions(:dry_view)
15
+ # WebPipe.load_extensions(:hanami_view)
15
16
  #
16
- # class SayHelloView < Dry::View
17
+ # class SayHelloView < Hanami::View
17
18
  # config.paths = [File.join(__dir__, '..', 'templates')]
18
19
  # config.template = 'say_hello'
19
20
  #
@@ -34,7 +35,7 @@ module WebPipe
34
35
  # instance can be resolved from it.
35
36
  #
36
37
  # @example
37
- # WebPipe.load_extensions(:dry_view, :container)
38
+ # WebPipe.load_extensions(:hanami_view, :container)
38
39
  #
39
40
  # class App
40
41
  # include WebPipe
@@ -49,18 +50,18 @@ module WebPipe
49
50
  # end
50
51
  # end
51
52
  #
52
- # Context ({Dry::View::Context}) for the view can be set explicetly
53
+ # Context ({Hanami::View::Context}) for the view can be set explicetly
53
54
  # through the `context:` argument, as in a standard call to
54
- # {Dry::View#call}. However, it is possible to leverage configured
55
+ # {Hanami::View#call}. However, it is possible to leverage configured
55
56
  # default context while still being able to inject request specific
56
57
  # context. For that to work, `:view_context` should be present in
57
58
  # {WebPipe::Conn#config}. Its value must be a lambda accepting the
58
59
  # {Conn} instance and returning a hash, which will be passed to
59
- # {Dry::View::Context#with} to create the final context at the
60
+ # {Hanami::View::Context#with} to create the final context at the
60
61
  # moment {#view} is called.
61
62
  #
62
63
  # @example
63
- # class MyContext < Dry::View::Context
64
+ # class MyContext < Hanami::View::Context
64
65
  # attr_reader :current_path
65
66
  #
66
67
  # def initialize(current_path: nil, **options)
@@ -69,7 +70,7 @@ module WebPipe
69
70
  # end
70
71
  # end
71
72
  #
72
- # class SayHelloView < Dry::View
73
+ # class SayHelloView < Hanami::View
73
74
  # config.paths = [File.join(__dir__, '..', 'templates')]
74
75
  # config.template = 'say_hello'
75
76
  # config.default_context = MyContext.new
@@ -95,7 +96,7 @@ module WebPipe
95
96
  # end
96
97
  # end
97
98
  #
98
- # @see https://dry-rb.org/gems/dry-view/
99
+ # @see https://github.com/hanami/view
99
100
  # @see WebPipe::Container
100
101
  module DryView
101
102
  # Where to find in {#config} request's view context generator.
@@ -106,17 +107,17 @@ module WebPipe
106
107
 
107
108
  # Sets string output of a view as response body.
108
109
  #
109
- # If the view is not a {Dry::View} instance, it is resolved from
110
+ # If the view is not a {Hanami::View} instance, it is resolved from
110
111
  # the configured container.
111
112
  #
112
113
  # `kwargs` is used as the input for the view (the arguments that
113
- # {Dry::View#call} receives). If they doesn't contain an explicit
114
+ # {Hanami::View#call} receives). If they doesn't contain an explicit
114
115
  # `context:` key, it can be added through the injection of the
115
116
  # result of a lambda present in context's `:view_context`.(see
116
- # {Dry::View::Context#with}).
117
+ # {Hanami::View::Context#with}).
117
118
  #
118
- # @param view_spec [Dry::View, Any]
119
- # @param kwargs [Hash] Arguments to pass along to `Dry::View#call`
119
+ # @param view_spec [Hanami::View, Any]
120
+ # @param kwargs [Hash] Arguments to pass along to `Hanami::View#call`
120
121
  #
121
122
  # @return WebPipe::Conn
122
123
  def view(view_spec, **kwargs)
@@ -133,7 +134,7 @@ module WebPipe
133
134
  private
134
135
 
135
136
  def view_instance(view_spec)
136
- return view_spec if view_spec.is_a?(Dry::View)
137
+ return view_spec if view_spec.is_a?(Hanami::View)
137
138
 
138
139
  fetch_config(:container)[view_spec]
139
140
  end
@@ -4,6 +4,7 @@ require 'dry/transformer'
4
4
 
5
5
  module WebPipe
6
6
  module Params
7
+ # Parameter transformations from dry-transformer.
7
8
  module Transf
8
9
  extend Dry::Transformer::Registry
9
10
 
@@ -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.
@@ -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
  #
@@ -36,9 +37,8 @@ module WebPipe
36
37
  # It's quite possible that you don't need more than that in terms of rails
37
38
  # integration. Of course, surely you want something more elaborate to generate
38
39
  # responses. For that, you can use the view or template system you like. One
39
- # option that will play specially well here is `dry-view`, which integrates
40
- # itself easily with Rails. Furthermore, we have a tailored `dry_view`
41
- # extension.
40
+ # option that will play specially well here is `hanami-view`. Furthermore, we
41
+ # have a tailored `hanami_view` extension.
42
42
  #
43
43
  # You need to use `:rails` extension if:
44
44
  #
@@ -73,7 +73,7 @@ module WebPipe
73
73
  # class ApplicationController < ActionController::Base
74
74
  # # By default uses the layout in `layouts/application`
75
75
  # end
76
- #
76
+ #
77
77
  # # app/controllers/articles_index.rb
78
78
  # require 'web_pipe/plugs/config'
79
79
  #
@@ -117,9 +117,6 @@ module WebPipe
117
117
  # https://github.com/waiting-for-dev/rails-web_pipe
118
118
  #
119
119
  # @see https://guides.rubyonrails.org/routing.html#routing-to-rack-applications
120
- # @see https://dry-rb.org/gems/dry-view/
121
- # @see https://github.com/dry-rb/dry-view/tree/master/examples/rails
122
- # @see https://waiting-for-dev.github.io/web_pipe/docs/extensions/dry_view.html
123
120
  # @see https://api.rubyonrails.org/v6.0.1/classes/ActionController/Renderer.html
124
121
  # @see https://api.rubyonrails.org/v6.0.1/classes/ActionController/Renderer.html
125
122
  # @see https://api.rubyonrails.org/v6.0.1/classes/ActionView/Helpers/UrlHelper.html
@@ -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.12.0'
4
+ VERSION = '0.15.0'
5
5
  end
data/lib/web_pipe.rb CHANGED
@@ -27,8 +27,8 @@ module WebPipe
27
27
  require 'web_pipe/extensions/dry_schema/plugs/sanitize_params'
28
28
  end
29
29
 
30
- register_extension :dry_view do
31
- require 'web_pipe/extensions/dry_view/dry_view'
30
+ register_extension :hanami_view do
31
+ require 'web_pipe/extensions/hanami_view/hanami_view'
32
32
  end
33
33
 
34
34
  register_extension :container do
data/web_pipe.gemspec CHANGED
@@ -43,12 +43,13 @@ Gem::Specification.new do |spec|
43
43
  spec.add_development_dependency 'bundler'
44
44
  spec.add_development_dependency 'dry-schema', '~> 1.0'
45
45
  spec.add_development_dependency 'dry-transformer', '~> 0.1'
46
- spec.add_development_dependency 'dry-view', '~> 0.7'
47
46
  spec.add_development_dependency 'pry-byebug'
48
47
  spec.add_development_dependency 'rack-flash3', '~> 1.0'
49
48
  spec.add_development_dependency 'rack-test', '~> 1.1'
50
- spec.add_development_dependency 'rake', '~> 10.0'
49
+ spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
51
50
  spec.add_development_dependency 'redcarpet', '~> 3.4'
52
51
  spec.add_development_dependency 'rspec', '~> 3.0'
53
52
  spec.add_development_dependency 'yard', '~> 0.9', '>= 0.9.20'
53
+ spec.add_development_dependency 'rubocop', '~> 1.8'
54
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.1'
54
55
  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.12.0
4
+ version: 0.15.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: 1970-01-01 00:00:00.000000000 Z
11
+ date: 2021-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-monads
@@ -108,20 +108,6 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.1'
111
- - !ruby/object:Gem::Dependency
112
- name: dry-view
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '0.7'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '0.7'
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
@@ -256,8 +277,8 @@ files:
256
277
  - docs/extensions/container.md
257
278
  - docs/extensions/cookies.md
258
279
  - docs/extensions/dry_schema.md
259
- - docs/extensions/dry_view.md
260
280
  - docs/extensions/flash.md
281
+ - docs/extensions/hanami_view.md
261
282
  - docs/extensions/params.md
262
283
  - docs/extensions/rails.md
263
284
  - docs/extensions/redirect.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
@@ -294,8 +318,8 @@ files:
294
318
  - lib/web_pipe/extensions/cookies/cookies.rb
295
319
  - lib/web_pipe/extensions/dry_schema/dry_schema.rb
296
320
  - lib/web_pipe/extensions/dry_schema/plugs/sanitize_params.rb
297
- - lib/web_pipe/extensions/dry_view/dry_view.rb
298
321
  - lib/web_pipe/extensions/flash/flash.rb
322
+ - lib/web_pipe/extensions/hanami_view/hanami_view.rb
299
323
  - lib/web_pipe/extensions/params/params.rb
300
324
  - lib/web_pipe/extensions/params/params/transf.rb
301
325
  - lib/web_pipe/extensions/rails/rails.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