Skip to content

Commit

Permalink
Allow inspecting operations
Browse files Browse the repository at this point in the history
Until now, once a `WebPipe` app had been initialized, there was no way
to get an operation by its plug name. This changes with this commit.
`WebPipe#operations` is now a hash mapping the plug name with the final
operation, which can be determined whether by being resolved or
injected.

```ruby
require 'web_pipe'
require 'web_pipe/conn_support/builder'

class MyApp
  include WebPipe

  plug :hello do |conn|
    conn.set_response_body('Hello')
  end
end

conn = WebPipe::ConnSupport::Builder.call(Rack::MockRequest.env_for)
app = MyApp.new
app.operations[:hello].call(conn).response_body # => ['Hello']
```
  • Loading branch information
waiting-for-dev committed Apr 14, 2021
1 parent 054b9c3 commit 352001c
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ Metrics/BlockLength:

Naming/AccessorMethodName:
Enabled: false

Style/HashConversion:
Enabled: false
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extension](docs/extensions/rails.md).
1. [Resolving operations](docs/plugging_operations/resolving_operations.md)
1. [Injecting operations](docs/plugging_operations/injecting_operations.md)
1. [Composing operations](docs/plugging_operations/composing_operations.md)
1. [Inspecting operations](docs/plugging_operations/inspecting_operations.md)
1. [Using rack middlewares](docs/using_rack_middlewares.md)
1. [Injecting middlewares](docs/using_rack_middlewares/injecting_middlewares.md)
1. [Composing middlewares](docs/using_rack_middlewares/composing_middlewares.md)
Expand Down
25 changes: 25 additions & 0 deletions docs/plugging_operations/inspecting_operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Inspecting operations

Once a `WebPipe` class is initialized all its operations get resolved. It
happens because they are whether [resolved](resolving_operations.md) or
[injected](injecting_operations.md). The final result can be accessed through
the `#operations` method:


```ruby
require 'web_pipe'
require 'web_pipe/conn_support/builder'

class MyApp
include WebPipe

plug(:hello) do |conn|
conn.set_response_body('Hello world!')
end
end

app = MyApp.new
conn = WebPipe::ConnSupport::Builder.call(Rack::MockRequest.env_for)
new_conn = app.operations[:hello].call(con)
conn.response_body #=> ['Hello world!']
```
6 changes: 3 additions & 3 deletions lib/web_pipe/dsl/instance_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module InstanceMethods
# @return [RackSupport::AppWithMiddlewares[]]
attr_reader :rack_app

# @return [ConnSupport::Composition::Operation[]]
# @return [Hash<WebPipe::Plug::Name[], ConnSupport::Composition::Operation[]>]
attr_reader :operations

# @return [Array<RackSupport::Middlewares>]
Expand All @@ -58,7 +58,7 @@ def initialize(injects = EMPTY_INJECTIONS)
@operations = Plug.inject_and_resolve(
self.class.plugs, injections[:plugs], container, self
)
app = App.new(operations)
app = App.new(operations.values)
@rack_app = RackSupport::AppWithMiddlewares.new(middlewares, app)
end
# rubocop:enable Metrics/AbcSize
Expand Down Expand Up @@ -105,7 +105,7 @@ def call(env)
# @see ConnSupport::Composition
def to_proc
ConnSupport::Composition
.new(operations)
.new(operations.values)
.method(:call)
.to_proc
end
Expand Down
21 changes: 16 additions & 5 deletions lib/web_pipe/plug.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,26 @@ def call(container, pipe)
# @container container [Types::Container[]]
# @object [Object]
#
# @return [Array<ConnSupport::Composition::Operation[]>]
# @return [Hash<Name[], ConnSupport::Composition::Operation[]>]
def self.inject_and_resolve(plugs, injections, container, object)
plugs.map do |plug|
if injections.key?(plug.name)
plug.with(injections[plug.name])
Hash[
plugs.map do |plug|
inject_and_resolve_plug(plug, injections, container, object)
end
]
end

def self.inject_and_resolve_plug(plug, injections, container, object)
name = plug.name
[
name,
if injections.key?(name)
plug.with(injections[name])
else
plug
end.call(container, object)
end
]
end
private_class_method :inject_and_resolve_plug
end
end
33 changes: 33 additions & 0 deletions spec/integration/inspecting_operations_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require 'spec_helper'
require 'support/conn'

RSpec.describe 'Inspecting operations' do
let(:pipe_class) do
Class.new do
include WebPipe

plug :one, ->(conn) { conn.set_response_body('One') }
end
end

it 'can inspect resolved operations' do
pipe = pipe_class.new
conn = build_conn(default_env)

expect(
pipe.operations[:one].call(conn).response_body
).to eq(['One'])
end

it 'can inspect injected operations' do
two = ->(conn) { conn.set_response_body('Two') }
pipe = pipe_class.new(plugs: { one: two })
conn = build_conn(default_env)

expect(
pipe.operations[:one].call(conn).response_body
).to eq(['Two'])
end
end
5 changes: 3 additions & 2 deletions spec/unit/web_pipe/plug_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def private; end
end

describe '.inject_and_resolve' do
it 'inject specs and resolves resulting list of plugs' do
it 'inject specs and resolves plugs' do
container = {
'op1' => -> { 'op1' },
'op2' => -> { 'op2' }
Expand All @@ -111,7 +111,8 @@ def private; end
plugs, injected, container, Object.new
)

expect(result.map(&:call)).to eq(%w[op1 injected])
expect(result.keys).to eq(%i[op1 op2])
expect(result.values.map(&:call)).to eq(%w[op1 injected])
end
end
end

0 comments on commit 352001c

Please sign in to comment.