add multi route extension

This commit is contained in:
Konstantin Haase 2011-09-04 18:13:27 -07:00
parent 6d2c1c69d9
commit 70536c9ff5
5 changed files with 134 additions and 1 deletions

View File

@ -39,6 +39,9 @@ Currently included:
corresponding `Link` HTTP headers. Adds `link`, `stylesheet` and `prefetch`
helper methods.
* `sinatra/multi_route`: Adds ability to define one route block for multiple
routes and multiple or custom HTTP verbs.
* `sinatra/namespace`: Adds namespace support to Sinatra.
* `sinatra/respond_with`: Choose action and/or template depending automatically

View File

@ -8,6 +8,7 @@ module Sinatra
# Sinatra::Application by default.
module Common
register :ConfigFile
register :MultiRoute
register :Namespace
register :RespondWith

View File

@ -0,0 +1,81 @@
require 'sinatra/base'
module Sinatra
# = Sinatra::MultiRoute
#
# Create multiple routes with one statement.
#
# == Usage
#
# Use this extension to create a handler for multiple routes:
#
# get '/foo', '/bar' do
# # ...
# end
#
# Or for multiple verbs:
#
# route :get, :post, '/' do
# # ...
# end
#
# Or even for custom verbs:
#
# route 'LIST', '/' do
# # ...
# end
#
# === Classic Application
#
# To use the extension in a classic application all you need to do is require
# it:
#
# require "sinatra"
# require "sinatra/multi_route"
#
# # Your classic application code goes here...
#
# === Modular Application
#
# To use the extension in a modular application you need to require it, and
# then, tell the application you will use it:
#
# require "sinatra/base"
# require "sinatra/multi_route"
#
# class MyApp < Sinatra::Base
# register Sinatra::MultiRoute
#
# # The rest of your modular application code goes here...
# end
#
module MultiRoute
def head(*args, &block) super(*route_args(args), &block) end
def delete(*args, &block) super(*route_args(args), &block) end
def get(*args, &block) super(*route_args(args), &block) end
def options(*args, &block) super(*route_args(args), &block) end
def patch(*args, &block) super(*route_args(args), &block) end
def post(*args, &block) super(*route_args(args), &block) end
def put(*args, &block) super(*route_args(args), &block) end
def route(*args, &block)
options = Hash === args.last ? args.pop : {}
routes = [*args.pop]
args.each do |verb|
verb = verb.to_s.upcase if Symbol === verb
routes.each do |route|
super(verb, route, options, &block)
end
end
end
private
def route_args(args)
options = Hash === args.last ? args.pop : {}
[args, options]
end
end
register MultiRoute
end

View File

@ -234,7 +234,10 @@ module Sinatra
# Does everything Sinatra::Base#route does, but it also tells the
# +Watcher::List+ for the Sinatra application to watch the defined
# route.
def route(verb, path, options={}, &block)
#
# Note: We are using #compile! so we don't interfere with extensions
# changing #route.
def compile!(verb, path, block, options = {})
source_location = block.respond_to?(:source_location) ?
block.source_location.first : caller_files[1]
signature = super

View File

@ -0,0 +1,45 @@
require 'backports'
require_relative 'spec_helper'
describe Sinatra::MultiRoute do
before do
count = 0
mock_app do
set(:some_condition) { count += 1 }
register Sinatra::MultiRoute
get('/') { 'normal' }
get('/foo', '/bar', :some_condition => true) { 'paths' }
route('PUT', 'POST', '/') { 'verb' }
route(:get, '/baz') { 'symbol as verb' }
end
@count = count
end
it 'does still allow normal routing' do
get('/').should be_ok
body.should be == 'normal'
end
it 'supports multpile routes' do
get('/foo').should be_ok
body.should be == 'paths'
get('/bar').should be_ok
body.should be == 'paths'
end
it 'triggers conditions' do
@count.should be == 4
end
it 'supports multpile verbs' do
post('/').should be_ok
body.should be == 'verb'
put('/').should be_ok
body.should be == 'verb'
end
it 'takes symbols as verbs' do
get('/baz').should be_ok
body.should be == 'symbol as verb'
end
end