web_pipe 0.13.0 → 0.16.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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/CHANGELOG.md +29 -0
  4. data/Gemfile +2 -2
  5. data/README.md +18 -11
  6. data/docs/building_a_rack_application.md +1 -1
  7. data/docs/composing_applications.md +4 -4
  8. data/docs/connection_struct/configuring_the_connection_struct.md +4 -4
  9. data/docs/connection_struct/halting_the_pipe.md +17 -19
  10. data/docs/connection_struct/sharing_data_downstream.md +9 -8
  11. data/docs/connection_struct.md +22 -19
  12. data/docs/design_model.md +10 -9
  13. data/docs/dsl_free_usage.md +85 -14
  14. data/docs/extensions/container.md +9 -10
  15. data/docs/extensions/cookies.md +4 -2
  16. data/docs/extensions/dry_schema.md +5 -4
  17. data/docs/extensions/flash.md +9 -11
  18. data/docs/extensions/{dry_view.md → hanami_view.md} +20 -22
  19. data/docs/extensions/not_found.md +40 -0
  20. data/docs/extensions/params.md +6 -4
  21. data/docs/extensions/rails.md +31 -38
  22. data/docs/extensions/redirect.md +5 -4
  23. data/docs/extensions/router_params.md +5 -5
  24. data/docs/extensions/session.md +4 -4
  25. data/docs/extensions/url.md +6 -6
  26. data/docs/extensions.md +5 -6
  27. data/docs/introduction.md +7 -7
  28. data/docs/plugging_operations/composing_operations.md +3 -3
  29. data/docs/plugging_operations/injecting_operations.md +4 -4
  30. data/docs/plugging_operations/inspecting_operations.md +24 -0
  31. data/docs/plugging_operations/resolving_operations.md +3 -3
  32. data/docs/plugging_operations.md +3 -3
  33. data/docs/plugs/config.md +1 -1
  34. data/docs/plugs/content_type.md +2 -1
  35. data/docs/plugs.md +6 -7
  36. data/docs/recipes/hanami_2_and_dry_rb_integration.md +12 -0
  37. data/docs/recipes/hanami_router_integration.md +3 -1
  38. data/docs/recipes/using_all_restful_methods.md +6 -5
  39. data/docs/testing.md +64 -0
  40. data/docs/using_rack_middlewares/composing_middlewares.md +2 -3
  41. data/docs/using_rack_middlewares/injecting_middlewares.md +6 -6
  42. data/docs/using_rack_middlewares/inspecting_middlewares.md +35 -0
  43. data/docs/using_rack_middlewares.md +6 -6
  44. data/lib/web_pipe/app.rb +22 -25
  45. data/lib/web_pipe/conn.rb +0 -1
  46. data/lib/web_pipe/conn_support/builder.rb +0 -7
  47. data/lib/web_pipe/conn_support/composition.rb +3 -26
  48. data/lib/web_pipe/conn_support/errors.rb +5 -5
  49. data/lib/web_pipe/conn_support/headers.rb +1 -50
  50. data/lib/web_pipe/conn_support/types.rb +3 -3
  51. data/lib/web_pipe/dsl/builder.rb +10 -19
  52. data/lib/web_pipe/dsl/class_context.rb +15 -40
  53. data/lib/web_pipe/dsl/instance_context.rb +53 -0
  54. data/lib/web_pipe/extensions/container/container.rb +2 -15
  55. data/lib/web_pipe/extensions/cookies/cookies.rb +2 -31
  56. data/lib/web_pipe/extensions/dry_schema/dry_schema.rb +2 -56
  57. data/lib/web_pipe/extensions/flash/flash.rb +2 -32
  58. data/lib/web_pipe/extensions/hanami_view/hanami_view.rb +67 -0
  59. data/lib/web_pipe/extensions/not_found/not_found.rb +26 -0
  60. data/lib/web_pipe/extensions/params/params.rb +2 -63
  61. data/lib/web_pipe/extensions/rails/rails.rb +2 -123
  62. data/lib/web_pipe/extensions/redirect/redirect.rb +2 -20
  63. data/lib/web_pipe/extensions/router_params/router_params.rb +1 -39
  64. data/lib/web_pipe/extensions/session/session.rb +2 -25
  65. data/lib/web_pipe/extensions/url/url.rb +2 -5
  66. data/lib/web_pipe/pipe.rb +229 -0
  67. data/lib/web_pipe/plug.rb +31 -65
  68. data/lib/web_pipe/plugs/config.rb +0 -2
  69. data/lib/web_pipe/plugs/content_type.rb +0 -2
  70. data/lib/web_pipe/rack_support/app_with_middlewares.rb +3 -26
  71. data/lib/web_pipe/rack_support/middleware.rb +2 -2
  72. data/lib/web_pipe/rack_support/middleware_specification.rb +19 -48
  73. data/lib/web_pipe/test_support.rb +28 -0
  74. data/lib/web_pipe/types.rb +1 -3
  75. data/lib/web_pipe/version.rb +1 -1
  76. data/lib/web_pipe.rb +77 -17
  77. data/web_pipe.gemspec +1 -2
  78. metadata +16 -9
  79. data/docs/recipes/dry_rb_integration.md +0 -18
  80. data/lib/web_pipe/dsl/dsl_context.rb +0 -85
  81. data/lib/web_pipe/dsl/instance_methods.rb +0 -114
  82. data/lib/web_pipe/extensions/dry_view/dry_view.rb +0 -158
@@ -1,21 +1,23 @@
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 available on the gem repository.
5
+
6
+ This extension integrates with [hanami-view](https://github.com/hanami/view)
7
+ rendering system to set a hanami-view output as the response body.
6
8
 
7
9
  `WebPipe::Conn#view` method is at the core of this extension. In its basic
8
- behaviour, you provide to it a view instance you want to render and any
10
+ behavior, you provide to it a view instance you want to render and any
9
11
  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
@@ -35,17 +37,16 @@ class MyApp
35
37
  end
36
38
  end
37
39
  ```
38
-
39
- However, you can resolve a view from a container if you also use (`:container`
40
- extension)[container.md]:
40
+ However, you can resolve a view from a container if you also use the
41
+ (`:container` extension)[container.md]:
41
42
 
42
43
  ```ruby
43
- require 'dry_view'
44
+ require 'hanami_view'
44
45
  require 'my_container'
45
46
  require 'web_pipe'
46
47
  require 'web_pipe/plugs/config'
47
48
 
48
- WebPipe.load_extensions(:dry_view, :container)
49
+ WebPipe.load_extensions(:hanami_view, :container)
49
50
 
50
51
  class MyApp
51
52
  include WebPipe
@@ -61,20 +62,17 @@ class MyApp
61
62
  end
62
63
  ```
63
64
 
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
- possible to leverage configured default context while being able to inject
67
- request specific data to it.
65
+ As in a standard call to `Hanami::View#call`, you can override the context
66
+ (`Hanami::View::Context`) to use through the `context:` option. However, it is still possible to leverage the configured default context while injecting specific data to it.
68
67
 
69
- 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
71
- that is with [`dry-auto_inject`](https://dry-rb.org/gems/dry-auto_inject):
68
+ To work, you have to specify required dependencies (in this case,
69
+ request specific data) to your hanami-view's context. A very convenient way to do that is with [`dry-auto_inject`](https://dry-rb.org/gems/dry-auto_inject):
72
70
 
73
71
  ```ruby
74
- require 'dry/view/context'
72
+ require 'hanami/view/context'
75
73
  require 'my_import'
76
74
 
77
- class MyContext < Dry::View::Context
75
+ class MyContext < Hanami::View::Context
78
76
  include MyImport::Import[:current_path]
79
77
 
80
78
  # Without `dry-auto_inject` you have to manually specify dependencies and
@@ -0,0 +1,40 @@
1
+ # Not found
2
+
3
+ This extension helps to build a not-found response in a single method
4
+ invocation. The `WebPipe::Conn#not_found` method will:
5
+
6
+ - Set 404 as response status.
7
+ - Set 'Not found' as the response body, or instead run a step configured in
8
+ `:not_found_body_step` config key.
9
+ - Halt the connection struct.
10
+
11
+ ```ruby
12
+ require 'web_pipe'
13
+ require 'web_pipe/plugs/config'
14
+
15
+ WebPipe.load_extensions(:params, :not_found)
16
+
17
+ class ShowItem
18
+ include 'web_pipe'
19
+
20
+ plug :config, WebPipe::Plugs::Config.(
21
+ not_found_body_step: ->(conn) { conn.set_response_body('Nothing') }
22
+ )
23
+
24
+ plug :fetch_item do |conn|
25
+ conn.add(:item, Item[params['id']])
26
+ end
27
+
28
+ plug :check_item do |conn|
29
+ if conn.fetch(:item)
30
+ conn
31
+ else
32
+ conn.not_found
33
+ end
34
+ end
35
+
36
+ plug :render do |conn|
37
+ conn.set_response_body(conn.fetch(:item).name)
38
+ end
39
+ end
40
+ ```
@@ -1,10 +1,11 @@
1
1
  # Params
2
2
 
3
3
  This extension adds a `WebPipe::Conn#params` method which returns
4
- request parameters as a Hash where any number of transformations
5
- can be configured.
4
+ request parameters as a Hash. Then, any number of transformations on it can be
5
+ configured.
6
6
 
7
- When no transformations are configured, `#params` just returns GET and POST parameters as a hash:
7
+ When no transformations are configured, `#params` returns GET and POST
8
+ parameters as a hash:
8
9
 
9
10
  ```ruby
10
11
  # http://www.example.com?foo=bar
@@ -102,7 +103,8 @@ plug(:this) do |conn|
102
103
  end
103
104
  # ...
104
105
  ```
105
- Finally, you can override configured transformations injecting another set at the moment of calling `#params`:
106
+ Finally, you can override the configured transformations injecting another set
107
+ at the moment of calling `#params`:
106
108
 
107
109
  ```ruby
108
110
  # ...
@@ -1,8 +1,8 @@
1
1
  # Rails
2
2
 
3
- The first two things to keep in mind in order to integrate with Rails is
3
+ The first two things to keep in mind to integrate with Rails are
4
4
  that `WebPipe` instances are Rack applications and that rails router can
5
- perfectly [dispatch to a rack application](https://guides.rubyonrails.org/routing.html#routing-to-rack-applications). For example:
5
+ perfectly [dispatch to a rack application](https://guides.rubyonrails.org/routing.html#routing-to-rack-applications).
6
6
 
7
7
  ```ruby
8
8
  # config/routes.rb
@@ -22,31 +22,29 @@ class MyRoute
22
22
  end
23
23
  ```
24
24
 
25
- In order to do something like the previous example you don't need to enable
26
- this extension. Notice that rails took care of dispatching the request to our
27
- `WebPipe` rack application, which was then responsible for generating the
28
- response. In this case, it used a simple call to `#set_response_body`.
25
+ To do something like the previous example, you don't need to enable this
26
+ extension. Notice that rails dispatched the request to our `WebPipe` rack
27
+ application, which was then responsible for generating the response. In this
28
+ case, it used a simple call to `#set_response_body`.
29
29
 
30
30
  It's quite possible that you don't need more than that in terms of rails
31
- integration. Of course, surely you want something more elaborate to generate
31
+ integration. Of course, you want something more elaborate to generate
32
32
  responses. For that, you can use the view or template system you like. One
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).
33
+ option that will play especially well here is
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
- You need to use `:rails` extension if:
38
+ You need to use the `:rails` extension if:
40
39
 
41
- - You want to use `action_view` as rendering system.
42
- - You want to use rails url helpers from your `WebPipe` application.
40
+ - You want to use `action_view` as a rendering system.
41
+ - You want to use rails URL helpers from your `WebPipe` application.
43
42
  - You want to use controller helpers from your `WebPipe` application.
44
43
 
45
- Rails responsibilities for controlling the request/response cycle and the
46
- rendering process are a little bit tangled. For this reason, even if you
47
- want to use `WebPipe` applications instead of Rails controller actions you
48
- still have to use the typical top `ApplicationController` in order to define
49
- some behaviour for the view layer:
44
+ Rails' responsibilities for controlling the request/response cycle are coupled
45
+ to the rendering process. For this reason, even if you want to use `WebPipe`
46
+ applications instead of Rails controller actions you still have to use the
47
+ typical top `ApplicationController` to define some behavior for the view layer:
50
48
 
51
49
  - Which layout is applied to the template.
52
50
  - Which helpers will become available to the templates.
@@ -56,11 +54,11 @@ no layout is applied and only built-in helpers (for example,
56
54
  `number_as_currency`) are available. You can change it via the
57
55
  `:rails_controller` configuration option.
58
56
 
59
- The main method that this extension adds to `WebPipe::Conn` is `#render`,
60
- which just delegates to the [Rails
61
- implementation](https://api.rubyonrails.org/v6.0.1/classes/ActionController/Renderer.html)
62
- as you'd do in a typical rails controller. Remember that you can provide
63
- template instance variables through the keyword `:assigns`.
57
+ The main method that this extension adds to `WebPipe::Conn` is `#render`, which
58
+ delegates to the [Rails implementation]
59
+ (https://api.rubyonrails.org/v6.0.1/classes/ActionController/Renderer.html) as
60
+ you'd do in a typical rails controller. Remember that you can provide template
61
+ instance variables through the keyword `:assigns`.
64
62
 
65
63
  ```ruby
66
64
  # config/routes.rb
@@ -93,10 +91,10 @@ end
93
91
  ```
94
92
 
95
93
  Notice that we used the keyword `template:` instead of taking advantage of
96
- automatic template lookup. We did that way so that we don't have to create also
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 })`.
94
+ automatic template lookup. We did that way so that we don't have to create an
95
+ `ArticlesController`, but it's up to you. In the case of having an
96
+ `ArticlesController`, we could do `conn.render(:index, assigns: { articles:
97
+ Article.all })`.
100
98
 
101
99
  Besides, this extension provides with two other methods:
102
100
 
@@ -105,12 +103,7 @@ Besides, this extension provides with two other methods:
105
103
  - `helpers` returns the associated [controller
106
104
  helpers](https://api.rubyonrails.org/classes/ActionController/Helpers.html).
107
105
 
108
- In all the examples we have supposed that we are putting `WebPipe` applications
109
- within `app/controllers/` directory. However, remember you can put them
110
- wherever you like as long as you respect rails [`autoload_paths`](https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoload-paths).
111
-
112
- Here you have a link to a very simple and contrived example of a rails
113
- application integrating `web_pipe`:
114
-
115
- https://github.com/waiting-for-dev/rails-web_pipe
116
-
106
+ We have placed `WebPipe` applications within `app/controllers/` directory in
107
+ all the examples. However, remember you can put them wherever you like as long
108
+ as you respect rails
109
+ [`autoload_paths`](https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoload-paths).
@@ -1,14 +1,15 @@
1
1
  # Redirect
2
2
 
3
- This extension helps with creating a redirect response.
3
+ This extension helps create a redirect response.
4
4
 
5
5
  Redirect responses consist of two pieces:
6
6
 
7
- - `Location` response header with the URL to which browsers should redirect.
7
+ - The `Location` response header with the URL to which browsers should
8
+ redirect.
8
9
  - A 3xx status code.
9
10
 
10
- A `#redirect(location, code)` method is added to `WebPipe::Conn` which takes
11
- care of both steps. `code` argument is optional, defaulting to `302`.
11
+ A `#redirect(location, code)` method is added to `WebPipe::Conn`, which takes
12
+ care of both steps. The `code` argument is optional, defaulting to `302`.
12
13
 
13
14
  ```ruby
14
15
  require 'web_pipe'
@@ -1,12 +1,12 @@
1
1
  # Router params
2
2
 
3
- This extension can be used in order to merge placeholder parameters
3
+ This extension can be used to merge placeholder parameters
4
4
  that usually routers support (like `get /users/:id`) to the parameters hash
5
- added through [`:params` extension](params.md) (which is
6
- automatically loaded).
5
+ added through the [`:params` extension](params.md) (which is
6
+ automatically loaded if using `:router_params`).
7
7
 
8
- What this extension does is adding a transformation function to the registry
9
- with name `:router_params`. Internally, it merges what is present in rack env's
8
+ This extension adds a transformation function named `:router_params`to the
9
+ registry. Internally, it merges what is present in rack env's
10
10
  `router.params` key.
11
11
 
12
12
  It automatically integrates with
@@ -1,11 +1,11 @@
1
1
  # Session
2
2
 
3
- Wrapper around `Rack::Session` middleware to help working with
4
- sessions in your plugged operations.
3
+ Wrapper around `Rack::Session` middleware to help work with sessions in your
4
+ plugged operations.
5
5
 
6
- It depends on `Rack::Session` middleware, which is shipped by rack.
6
+ It depends on the `Rack::Session` middleware, which is shipped by rack.
7
7
 
8
- It adds following methods to `WebPipe::Conn`:
8
+ It adds the following methods to `WebPipe::Conn`:
9
9
 
10
10
  - `#fetch_session(key)`, `#fetch_session(key, default)` or
11
11
  `#fetch_session(key) { default }`. Returns what is stored under
@@ -1,11 +1,11 @@
1
1
  # URL
2
2
 
3
- `:url` extension just adds a few methods which cook raw request information
4
- about the URL into something more digestible.
3
+ The `:url` extension adds a few methods that process the raw URL information
4
+ into something more digestable.
5
5
 
6
6
  Specifically, it adds:
7
7
 
8
- - `#base_url`: Which is schema + host + port (unless it is the default for the scheme). I.e. `'https://example.org'` or `'http://example.org:8000'`.
9
- - `#path`: Which is script name (if any) + path information. I.e. `'index.rb/users/1'` or `'users/1'`.
10
- - `#full_path`: Which is path + query string (if any). I.e. `'users/1?view=table'`.
11
- - `#url`: Which is base url + full path. I.e. `'http://example.org:8000/users/1?view=table'`.
8
+ - `#base_url`: That's schema + host + port (unless it is the default for the scheme). E.g. `'https://example.org'` or `'http://example.org:8000'`.
9
+ - `#path`: That's script name (if any) + path information. E.g. `'index.rb/users/1'` or `'users/1'`.
10
+ - `#full_path`: That's path + query string (if any). E.g. `'users/1?view=table'`.
11
+ - `#url`: That's base url + full path. E.g. `'http://example.org:8000/users/1?view=table'`.
data/docs/extensions.md CHANGED
@@ -1,12 +1,11 @@
1
1
  # Extensions
2
2
 
3
- `WebPipe::Conn` features are by default raw: the very minimal you
4
- need to be able to build a web application. However, there are
5
- several extensions to progressively add just the ingredients you
6
- want to use.
3
+ `WebPipe::Conn` features are bare-bones by default: the very minimal you need
4
+ to be able to build a web application. However, there are several extensions to
5
+ add just the ingredients you want to use progressively.
7
6
 
8
- In order to load the extensions, you have to call
9
- `#load_extensions` method in `WebPipe`:
7
+ To load the extensions, you have to call `#load_extensions` method in
8
+ `WebPipe`:
10
9
 
11
10
  ```ruby
12
11
  WebPipe.load_extensions(:params, :cookies)
data/docs/introduction.md CHANGED
@@ -6,10 +6,10 @@ It means that with it and a rack router (like
6
6
  [`hanami-router`](https://github.com/hanami/router),
7
7
  [`http_router`](https://github.com/joshbuddy/http_router) or plain
8
8
  [rack](https://github.com/rack/rack) routing methods you can build a complete
9
- web application. However, the idea behind `web_pipe` is being a decoupled
10
- component within a web framework. For this reason, it plays extremely well
11
- with [dry-rb](https://dry-rb.org/) ecosystem. If it helps, you can think of it
12
- as a decoupled web controller (as the C in MVC).
9
+ web application. However, the idea behind `web_pipe` is for it to be a
10
+ decoupled component within a web framework. For this reason, it plays
11
+ extremely well with [dry-rb](https://dry-rb.org/) ecosystem. If it helps, you
12
+ can think of it as a decoupled web controller (as the C in MVC).
13
13
 
14
14
  `web_pipe` applications are built as a [pipe of
15
15
  operations](design_model.md) on an [immutable
@@ -28,9 +28,9 @@ Following there is a simple example. It is a web application that will check
28
28
  the value of a `user` parameter. When it is `Alice` or `Joe`, it will kindly
29
29
  say hello. Otherwise, it will unauthorize:
30
30
 
31
- > In order to try this example you can paste it to a file with name `config.ru`
32
- and launch the rack command `rackup` within the same directory. The application
33
- will be available in `http://localhost:9292`.
31
+ > To try this example, you can paste it to a file with the name `config.ru` and
32
+ launch the rack command `rackup` within the same directory. The application
33
+ will be available at `http://localhost:9292`.
34
34
 
35
35
  ```ruby
36
36
  require 'web_pipe'
@@ -5,9 +5,9 @@ and returning a connection struct. As a result, a composition of operations is
5
5
  an operation in itself (as it also takes a connection struct and returns a
6
6
  connection struct).
7
7
 
8
- This can be leveraged to plug a whole `web_pipe` application as an operation
9
- to another application. Doing so, you are plugging an operation which is the
10
- composition of all operations for given application.
8
+ We can leverage that to plug a whole `web_pipe` application as an operation to
9
+ another application. By doing so, you are plugging an operation which is the
10
+ composition of all operations for a given application.
11
11
 
12
12
  ```ruby
13
13
  class HtmlApp
@@ -1,12 +1,12 @@
1
1
  # Injecting operations
2
2
 
3
- Operations can be injected at the moment an application is initialized,
4
- which allows you to override what the definition declares.
3
+ You can inject operations at the moment an application is initialized. It
4
+ allows you to override what the definition declares.
5
5
 
6
6
  To this effect, you must use `plugs:` keyword argument. It must be a hash where
7
- operations are matched by the name you gave them in its definition.
7
+ the operations are matched by the name you gave them in its definition.
8
8
 
9
- This is mainly useful for testing purposes, where you can switch a heavy
9
+ That is mainly useful for testing purposes, where you can switch a heavy
10
10
  operation and use another lighter one.
11
11
 
12
12
  In the following example, the response body of the application will be
@@ -0,0 +1,24 @@
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
+ ```ruby
9
+ require 'web_pipe'
10
+ require 'web_pipe/conn_support/builder'
11
+
12
+ class MyApp
13
+ include WebPipe
14
+
15
+ plug(:hello) do |conn|
16
+ conn.set_response_body('Hello world!')
17
+ end
18
+ end
19
+
20
+ app = MyApp.new
21
+ conn = WebPipe::ConnSupport::Builder.call(Rack::MockRequest.env_for)
22
+ new_conn = app.operations[:hello].call(con)
23
+ conn.response_body #=> ['Hello world!']
24
+ ```
@@ -1,6 +1,6 @@
1
1
  # Resolving operations
2
2
 
3
- There are several ways you can specify how an operation is resolved.
3
+ There are several ways you can specify how to resolve an operation.
4
4
 
5
5
  ## Instance method
6
6
 
@@ -53,8 +53,8 @@ end
53
53
  Operations can be resolved from a dependency injection container.
54
54
 
55
55
  A container is anything that responds to `#[]` (accepting `Symbol` or `String`
56
- as argument) in order to resolve a dependency. It can be configured at the
57
- moment `WebPipe` module is included:
56
+ as argument) to resolve a dependency. It can be configured at the
57
+ moment you include the `WebPipe` module:
58
58
 
59
59
  ```ruby
60
60
  MyContainer = Hash[
@@ -1,10 +1,10 @@
1
1
  # Plugging operations
2
2
 
3
- You can plug operations to your application with the DSL method `plug`. The
3
+ You can plug operations into your application with the DSL method `plug`. The
4
4
  first argument it always takes is a symbol with the name you want
5
5
  to give to the operation (which is needed to allow
6
- [injection](plugging_operations/injecting_operations.md) on
7
- initialization).
6
+ [injection](plugging_operations/injecting_operations.md) at
7
+ initialization time).
8
8
 
9
9
  ```ruby
10
10
  class MyApp
data/docs/plugs/config.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Config
2
2
 
3
- `Config` plug helps in the addition of configuration settings (`#config` hash
3
+ The `Config` plug helps in adding configuration settings (`#config` hash
4
4
  attribute) to an instance of `WebPipe::Conn`.
5
5
 
6
6
  ```ruby
@@ -1,6 +1,7 @@
1
1
  # ContentType
2
2
 
3
- `ContentType` plug is just a helper to set `Content-Type` response header.
3
+ The `ContentType` plug is just a helper to set the `Content-Type` response
4
+ header.
4
5
 
5
6
  Example:
6
7
 
data/docs/plugs.md CHANGED
@@ -1,13 +1,12 @@
1
1
  # Plugs
2
2
 
3
- Some group of operations can be generalized as following same pattern. For
3
+ Some groups of operations can be generalized as following the same pattern. For
4
4
  example, an operation setting `Content-Type` header to `text/html` is very
5
- similar to another one setting same header to `application/json`. We name plugs
6
- to this level of abstraction on top of operations: plugs are operation
7
- builders. In other words, they are higher order functions which return
8
- functions.
5
+ similar to setting the same header to `application/json`. We name plugs to this
6
+ level of abstraction on top of operations: plugs are operation builders. In
7
+ other words, they are higher-order functions that return functions.
9
8
 
10
- Being just functions, we take as convention that plugs respond to `#call` in
11
- order to create an operation.
9
+ Being just functions, we take as a convention that plugs respond to `#call` to
10
+ create an operation.
12
11
 
13
12
  This library ships with some useful plugs.
@@ -0,0 +1,12 @@
1
+ # Hanami 2 and dry-rb integration
2
+
3
+ `web_pipe` has been designed to integrate smoothly with
4
+ the [hanami](https://hanamirb.org/) & [dry-rb](https://dry-rb.org/) ecosystems. It shares the same design
5
+ principles, and it ships with some extensions that even make this
6
+ integration painless (like [`:dry-schema`](../extensions/dry_schema.md)
7
+ extension or [`:hanami_view`](../extensions/hanami_view.md)).
8
+
9
+ If you want to use `web_pipe` within a hanami 2 application, you can take
10
+ inspiration from this sample todo app:
11
+
12
+ https://github.com/waiting-for-dev/hanami_2_web_pipe_todo_app
@@ -22,4 +22,6 @@ end
22
22
  run router
23
23
  ```
24
24
 
25
- In order to perform [string matching with variables](https://github.com/hanami/router#string-matching-with-variables) you just need to load [`:router_params` extension](../extensions/router_params.md).
25
+ To perform [string matching with
26
+ variables](https://github.com/hanami/router#string-matching-with-variables) you
27
+ just need to load [`:router_params` extension](../extensions/router_params.md).
@@ -1,6 +1,6 @@
1
1
  # Using all RESTful methods
2
2
 
3
- As you probably know, a lot of browsers don't support some RESTful
3
+ As you probably know, most browsers don't support some RESTful
4
4
  methods like `PATCH` or `PUT`. [Rack's `MethodOverride`
5
5
  middleware](https://github.com/rack/rack/blob/master/lib/rack/method_override.rb)
6
6
  provides a workaround for this limitation, allowing to override
@@ -9,12 +9,13 @@ request method in rack's env if a magical `_method` parameter or
9
9
 
10
10
  You have to be aware that if you use this middleware within a
11
11
  `web_pipe` application (through [`use` DSL
12
- method](../using_rack_middlewares.md)) it will have no effect.
13
- When your `web_pipe` application takes control of the request it
14
- has already gone through the router, which is the one who should
12
+ method](../using_rack_middlewares.md)), it will have no effect.
13
+ When your `web_pipe` application takes control of the request, it
14
+ has already gone through the router, which is the one that should
15
15
  read the request method set by rack.
16
16
 
17
- The solution for this is very simple. Just use `MethodOverride` middleware before your router does its work. For example, in `config.ru`:
17
+ The solution for this is straightforward. Just use `MethodOverride` middleware
18
+ before your router does its work. For example, in `config.ru`:
18
19
 
19
20
  ```ruby
20
21
  # config.ru
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).
@@ -3,9 +3,8 @@
3
3
  In a similar way that you compose plugged operations, you can also compose rack
4
4
  middlewares from another application.
5
5
 
6
- For that, you just need to `use` another application. When you do so, all the
7
- middlewares for that application will be added to the stack in the same order
8
- they had there.
6
+ For that, you just need to `use` another application. All the middlewares for
7
+ that application will be added to the stack in the same order.
9
8
 
10
9
  ```ruby
11
10
  class HtmlApp