Skip to content

Commit 633985c

Browse files
committed
Restored routes introspection.
1 parent dfae958 commit 633985c

File tree

3 files changed

+121
-103
lines changed

3 files changed

+121
-103
lines changed

lib/grape/api.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ def middleware
324324

325325
# An array of API routes.
326326
def routes
327-
@routes ||= []
327+
@routes ||= prepare_routes
328328
end
329329

330330
def versions
@@ -333,6 +333,14 @@ def versions
333333

334334
protected
335335

336+
def prepare_routes
337+
routes = []
338+
endpoints.each do |endpoint|
339+
routes.concat(endpoint.routes)
340+
end
341+
routes
342+
end
343+
336344
# Execute first the provided block, then each of the
337345
# block passed in. Allows for simple 'before' setups
338346
# of settings stack pushes.
@@ -364,7 +372,6 @@ def initialize
364372
self.class.endpoints.each do |endpoint|
365373
endpoint.mount_in(@route_set)
366374
end
367-
368375
@route_set.freeze
369376
end
370377

lib/grape/endpoint.rb

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,36 +25,47 @@ def initialize(settings, options = {}, &block)
2525

2626
options[:route_options] ||= {}
2727
end
28+
29+
def routes
30+
@routes ||= prepare_routes
31+
end
2832

2933
def mount_in(route_set)
3034
if options[:app] && options[:app].respond_to?(:endpoints)
3135
options[:app].endpoints.each{|e| e.mount_in(route_set)}
3236
else
33-
options[:method].each do |method|
34-
options[:path].each do |path|
35-
prepared_path = prepare_path(path)
36-
path = compile_path(path, !options[:app])
37-
regex = Rack::Mount::RegexpWithNamedGroups.new(path)
38-
path_params = regex.named_captures.map { |nc| nc[0] } - [ 'version', 'format' ]
39-
path_params |= (options[:route_options][:params] || [])
40-
request_method = (method.to_s.upcase unless method == :any)
41-
42-
# routes << Route.new(route_options.merge({
43-
# :prefix => prefix,
44-
# :version => settings[:version] ? settings[:version].join('|') : nil,
45-
# :namespace => namespace,
46-
# :method => request_method,
47-
# :path => prepared_path,
48-
# :params => path_params})
49-
# )
50-
51-
route_set.add_route(self,
52-
:path_info => path,
53-
:request_method => request_method
54-
)
55-
end
37+
routes.each do |route|
38+
route_set.add_route(self,
39+
:path_info => route.route_compiled,
40+
:request_method => route.route_method
41+
)
42+
end
43+
end
44+
end
45+
46+
def prepare_routes
47+
routes = []
48+
options[:method].each do |method|
49+
options[:path].each do |path|
50+
prepared_path = prepare_path(path)
51+
path = compile_path(path, !options[:app])
52+
regex = Rack::Mount::RegexpWithNamedGroups.new(path)
53+
path_params = regex.named_captures.map { |nc| nc[0] } - [ 'version', 'format' ]
54+
path_params |= (options[:route_options][:params] || [])
55+
request_method = (method.to_s.upcase unless method == :any)
56+
routes << Route.new(options[:route_options].clone.merge({
57+
:prefix => settings[:root_prefix],
58+
:version => settings[:version] ? settings[:version].join('|') : nil,
59+
:namespace => namespace,
60+
:method => request_method,
61+
:path => prepared_path,
62+
:params => path_params,
63+
:compiled => path,
64+
})
65+
)
5666
end
5767
end
68+
routes
5869
end
5970

6071
def prepare_path(path)

spec/grape/api_spec.rb

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -688,84 +688,84 @@ def hello
688688
end
689689
end
690690

691-
# context "routes" do
692-
# describe "empty api structure" do
693-
# it "returns an empty array of routes" do
694-
# subject.routes.should == []
695-
# end
696-
# end
697-
# describe "single method api structure" do
698-
# before(:each) do
699-
# subject.get :ping do
700-
# 'pong'
701-
# end
702-
# end
703-
# it "returns one route" do
704-
# subject.routes.size.should == 1
705-
# route = subject.routes[0]
706-
# route.route_version.should be_nil
707-
# route.route_path.should == "/ping(.:format)"
708-
# route.route_method.should == "GET"
709-
# end
710-
# end
711-
# describe "api structure with two versions and a namespace" do
712-
# class TwitterAPI < Grape::API
713-
# # version v1
714-
# version 'v1', :using => :path
715-
# get "version" do
716-
# api.version
717-
# end
718-
# # version v2
719-
# version 'v2', :using => :path
720-
# prefix 'p'
721-
# namespace "n1" do
722-
# namespace "n2" do
723-
# get "version" do
724-
# api.version
725-
# end
726-
# end
727-
# end
728-
# end
729-
# it "should return versions" do
730-
# TwitterAPI::versions.should == [ 'v1', 'v2' ]
731-
# end
732-
# it "should set route paths" do
733-
# TwitterAPI::routes.size.should >= 2
734-
# TwitterAPI::routes[0].route_path.should == "/:version/version(.:format)"
735-
# TwitterAPI::routes[1].route_path.should == "/p/:version/n1/n2/version(.:format)"
736-
# end
737-
# it "should set route versions" do
738-
# TwitterAPI::routes[0].route_version.should == 'v1'
739-
# TwitterAPI::routes[1].route_version.should == 'v2'
740-
# end
741-
# it "should set a nested namespace" do
742-
# TwitterAPI::routes[1].route_namespace.should == "/n1/n2"
743-
# end
744-
# it "should set prefix" do
745-
# TwitterAPI::routes[1].route_prefix.should == 'p'
746-
# end
747-
# end
748-
# describe "api structure with additional parameters" do
749-
# before(:each) do
750-
# subject.get 'split/:string', { :params => [ "token" ], :optional_params => [ "limit" ] } do
751-
# params[:string].split(params[:token], (params[:limit] || 0).to_i)
752-
# end
753-
# end
754-
# it "should split a string" do
755-
# get "/split/a,b,c.json", :token => ','
756-
# last_response.body.should == '["a","b","c"]'
757-
# end
758-
# it "should split a string with limit" do
759-
# get "/split/a,b,c.json", :token => ',', :limit => '2'
760-
# last_response.body.should == '["a","b,c"]'
761-
# end
762-
# it "should set route_params" do
763-
# subject.routes.size.should == 1
764-
# subject.routes[0].route_params.should == [ "string", "token" ]
765-
# subject.routes[0].route_optional_params.should == [ "limit" ]
766-
# end
767-
# end
768-
# end
691+
context "routes" do
692+
describe "empty api structure" do
693+
it "returns an empty array of routes" do
694+
subject.routes.should == []
695+
end
696+
end
697+
describe "single method api structure" do
698+
before(:each) do
699+
subject.get :ping do
700+
'pong'
701+
end
702+
end
703+
it "returns one route" do
704+
subject.routes.size.should == 1
705+
route = subject.routes[0]
706+
route.route_version.should be_nil
707+
route.route_path.should == "/ping(.:format)"
708+
route.route_method.should == "GET"
709+
end
710+
end
711+
describe "api structure with two versions and a namespace" do
712+
class TwitterAPI < Grape::API
713+
# version v1
714+
version 'v1', :using => :path
715+
get "version" do
716+
api.version
717+
end
718+
# version v2
719+
version 'v2', :using => :path
720+
prefix 'p'
721+
namespace "n1" do
722+
namespace "n2" do
723+
get "version" do
724+
api.version
725+
end
726+
end
727+
end
728+
end
729+
it "should return versions" do
730+
TwitterAPI::versions.should == [ 'v1', 'v2' ]
731+
end
732+
it "should set route paths" do
733+
TwitterAPI::routes.size.should >= 2
734+
TwitterAPI::routes[0].route_path.should == "/:version/version(.:format)"
735+
TwitterAPI::routes[1].route_path.should == "/p/:version/n1/n2/version(.:format)"
736+
end
737+
it "should set route versions" do
738+
TwitterAPI::routes[0].route_version.should == 'v1'
739+
TwitterAPI::routes[1].route_version.should == 'v2'
740+
end
741+
it "should set a nested namespace" do
742+
TwitterAPI::routes[1].route_namespace.should == "/n1/n2"
743+
end
744+
it "should set prefix" do
745+
TwitterAPI::routes[1].route_prefix.should == 'p'
746+
end
747+
end
748+
describe "api structure with additional parameters" do
749+
before(:each) do
750+
subject.get 'split/:string', { :params => [ "token" ], :optional_params => [ "limit" ] } do
751+
params[:string].split(params[:token], (params[:limit] || 0).to_i)
752+
end
753+
end
754+
it "should split a string" do
755+
get "/split/a,b,c.json", :token => ','
756+
last_response.body.should == '["a","b","c"]'
757+
end
758+
it "should split a string with limit" do
759+
get "/split/a,b,c.json", :token => ',', :limit => '2'
760+
last_response.body.should == '["a","b,c"]'
761+
end
762+
it "should set route_params" do
763+
subject.routes.size.should == 1
764+
subject.routes[0].route_params.should == [ "string", "token" ]
765+
subject.routes[0].route_optional_params.should == [ "limit" ]
766+
end
767+
end
768+
end
769769

770770
describe ".rescue_from klass, block" do
771771
it 'should rescue Exception' do

0 commit comments

Comments
 (0)