Skip to content

Commit

Permalink
Merge branch 'master' of github.com:lotus/controller
Browse files Browse the repository at this point in the history
  • Loading branch information
jodosha committed Jan 27, 2015
2 parents 1263241 + b594792 commit af1ed16
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 36 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2014 Luca Guidi
Copyright © 2014-2015 Luca Guidi

MIT License

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1064,4 +1064,4 @@ __Lotus::Controller__ uses [Semantic Versioning 2.0.0](http://semver.org)

## Copyright

Copyright 2014 Luca Guidi – Released under MIT License
Copyright © 2014-2015 Luca Guidi – Released under MIT License
41 changes: 18 additions & 23 deletions lib/lotus/action/rack.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'securerandom'
require 'lotus/action/request'
require 'lotus/action/rack/callable'

module Lotus
module Action
Expand Down Expand Up @@ -53,24 +54,34 @@ def self.included(base)
end

module ClassMethods
# Use a Rack middleware as a before callback.
# Build rack builder
#
# The middleware will be used as it is, no matter if it's a class or an
# instance. If it needs to be initialized, please do it before to pass
# it as the argument of this method.
# @return [Rack::Builder]
def rack_builder
@rack_builder ||= begin
extend Lotus::Action::Rack::Callable
rack_builder = ::Rack::Builder.new
rack_builder.run ->(env) { self.new.call(env) }
rack_builder
end
end
# Use a Rack middleware
#
# The middleware will be used as it is.
#
# At the runtime, the middleware be invoked with the raw Rack env.
#
# Multiple middlewares can be employed, just by using multiple times
# this method.
#
# @param middleware [#call] A Rack middleware
# @param args [Array] Array arguments for middleware
#
# @since 0.2.0
#
# @see Lotus::Action::Callbacks::ClassMethods#before
#
# @example Class Middleware
# @example Middleware
# require 'lotus/controller'
#
# module Sessions
Expand All @@ -83,24 +94,8 @@ module ClassMethods
# end
# end
# end
#
# @example Instance Middleware
# require 'lotus/controller'
#
# module Sessions
# class Create
# include Lotus::Controller
# use XMiddleware.new('x', 123)
#
# def call(params)
# # ...
# end
# end
# end
def use(middleware)
before do |params|
middleware.call(params.env)
end
def use(middleware, *args)
rack_builder.use middleware, *args
end
end

Expand Down
47 changes: 47 additions & 0 deletions lib/lotus/action/rack/callable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

module Lotus
module Action
module Rack
module Callable
# Callable module for actions. With this module, actions with middlewares
# will be able to work with rack builder.
#
# @param env [Hash] the full Rack env or the params. This value may vary,
# see the examples below.
#
# @since x.x.x
#
# @see Lotus::Action::Rack::ClassMethods#rack_builder
# @see Lotus::Action::Rack::ClassMethods#use
#
# @example
# require 'lotus/controller'
#
# class MyMiddleware
# def initialize(app)
# @app = app
# end
#
# def call(env)
# #...
# end
# end
#
# class Show
# include Lotus::Action
# use MyMiddleware
#
# def call(params)
# # ...
# puts params # => { id: 23 } extracted from Rack env
# end
# end
#
# Show.respond_to?(:call) # => true
def call(env)
rack_builder.call(env)
end
end
end
end
end
50 changes: 43 additions & 7 deletions test/fixtures.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,19 +170,55 @@ def call(params)
end
end

class YMiddleware
def initialize(app)
@app = app
end

def call(env)
code, headers, body = @app.call(env)
[code, headers.merge!('Y-Middleware' => 'OK'), body]
end
end

class XMiddleware
def self.call(env)
env['X-Middleware'] = 'OK'
def initialize(app)
@app = app
end

def call(env)
code, headers, body = @app.call(env)
[code, headers.merge!('X-Middleware' => 'OK'), body]
end
end

class UseAction
include Lotus::Action
module UseAction
class Index
include Lotus::Action
use XMiddleware

def call(params)
self.body = 'Hello from UseAction::Index'
end
end

use XMiddleware
class Show
include Lotus::Action
use YMiddleware

def call(params)
headers['X-Middleware'] = params.env.fetch('X-Middleware')
def call(params)
self.body = 'Hello from UseAction::Show'
end
end
end

module NoUseAction
class Index
include Lotus::Action

def call(params)
self.body = 'Hello from NoUseAction::Index'
end
end
end

Expand Down
54 changes: 50 additions & 4 deletions test/integration/use_test.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,59 @@
require 'test_helper'
require 'rack/test'

describe 'Rack middleware integration' do
include Rack::Test::Methods

def response
last_response
end

describe '.use' do
let(:app) { UseActionApplication }

it 'uses the specified Rack middleware' do
response = Rack::MockRequest.new(UseAction.new).get('/')
status, headers, _ = response
router = Lotus::Router.new do
get '/', to: 'use_action#index'
get '/show', to: 'use_action#show'
end

UseActionApplication = Rack::Builder.new do
run router
end.to_app

get '/'

response.status.must_equal 200
response.headers.fetch('X-Middleware').must_equal 'OK'
response.headers['Y-Middleware'].must_be_nil
response.body.must_equal 'Hello from UseAction::Index'

get '/show'

response.status.must_equal 200
response.headers.fetch('Y-Middleware').must_equal 'OK'
response.headers['X-Middleware'].must_be_nil
response.body.must_equal 'Hello from UseAction::Show'
end
end

describe 'not using .use' do
let(:app) { NoUseActionApplication }

it "action doens't use a middleware" do
router = Lotus::Router.new do
get '/', to: 'no_use_action#index'
end

NoUseActionApplication = Rack::Builder.new do
run router
end.to_app

get '/'

status.must_equal 200
headers['X-Middleware'].must_equal 'OK'
response.status.must_equal 200
response.headers['X-Middleware'].must_be_nil
response.body.must_equal 'Hello from NoUseAction::Index'
end
end
end

0 comments on commit af1ed16

Please sign in to comment.