Skip to content

Commit 1bf41db

Browse files
author
Michael Bleigh
committed
Added pathless routing, header and status declarers for inside blocks.
1 parent a8d36ad commit 1bf41db

File tree

8 files changed

+118
-16
lines changed

8 files changed

+118
-16
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
gem 'rack'
2-
gem 'rack-mount'
2+
gem 'rack-mount', '~> 0.6.13'
33
gem 'rack-jsonp'
44

55
gem 'multi_json'

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ GEM
2121
multi_xml (0.0.1)
2222
rack (1.2.1)
2323
rack-jsonp (1.0.0)
24-
rack-mount (0.6.9)
24+
rack-mount (0.6.13)
2525
rack (>= 1.0.0)
2626
rack-test (0.5.4)
2727
rack (>= 1.0)
@@ -49,7 +49,7 @@ DEPENDENCIES
4949
multi_xml
5050
rack
5151
rack-jsonp
52-
rack-mount
52+
rack-mount (~> 0.6.13)
5353
rack-test
5454
rake
5555
rspec (>= 2.1.0)

lib/grape/api.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ def compile_path(path)
7474
end
7575

7676
def route(method, path_info, &block)
77-
route_set.add_route(build_endpoint(&block), :path_info => compile_path(path_info))
77+
route_set.add_route(build_endpoint(&block),
78+
:path_info => compile_path(path_info),
79+
:request_method => method
80+
)
7881
end
7982

8083
def build_endpoint(&block)
@@ -88,11 +91,11 @@ def build_endpoint(&block)
8891
b.to_app
8992
end
9093

91-
def get(path_info, &block); route('GET', path_info, &block) end
92-
def post(path_info, &block); route('POST', path_info, &block) end
93-
def put(path_info, &block); route('PUT', path_info, &block) end
94-
def head(path_info, &block); route('HEAD', path_info, &block) end
95-
def delete(path_info, &block); route('DELETE', path_info, &block) end
94+
def get(path_info = '', &block); route('GET', path_info, &block) end
95+
def post(path_info = '', &block); route('POST', path_info, &block) end
96+
def put(path_info = '', &block); route('PUT', path_info, &block) end
97+
def head(path_info = '', &block); route('HEAD', path_info, &block) end
98+
def delete(path_info = '', &block); route('DELETE', path_info, &block) end
9699

97100
def namespace(space = nil, &block)
98101
if space || block_given?

lib/grape/endpoint.rb

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,37 @@ def initialize(&block)
88
end
99

1010
attr_reader :env, :request
11-
11+
12+
def status(status = nil)
13+
if status
14+
@status = status
15+
else
16+
return @status if @status
17+
case request.request_method.to_s.upcase
18+
when 'POST'
19+
201
20+
else
21+
200
22+
end
23+
end
24+
end
25+
26+
def header(key = nil, val = nil)
27+
if key
28+
val ? @header[key.to_s] = val : @header.delete(key.to_s)
29+
else
30+
@header
31+
end
32+
end
33+
1234
def call(env)
1335
@env = env
1436
@request = Rack::Request.new(@env)
15-
@headers = {}
37+
@header = {}
1638

1739
response_text = instance_eval &@block
18-
[200, {}, [response_text]]
40+
41+
[status, header, [response_text]]
1942
end
2043
end
2144
end

lib/grape/middleware/formatter.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,17 @@ def mime_array
7575

7676
def after
7777
status, headers, bodies = *@app_response
78-
bodies.map! do |body|
79-
case env['api.format']
78+
bodymap = []
79+
bodies.each do |body|
80+
bodymap << case env['api.format']
8081
when :json
8182
MultiJson.encode(body)
8283
when :txt
8384
body.to_s
8485
end
8586
end
8687
headers['Content-Type'] = 'application/json'
87-
[status, headers, bodies]
88+
Rack::Response.new(bodymap, status, headers).to_a
8889
end
8990
end
9091
end

spec/grape/api_spec.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,49 @@ def app; subject end
9595
end
9696
end
9797

98+
describe '.route' do
99+
it 'should allow for no path' do
100+
subject.namespace :votes do
101+
get do
102+
"Votes"
103+
end
104+
105+
post do
106+
"Created a Vote"
107+
end
108+
end
109+
110+
get '/votes'
111+
last_response.body.should == 'Votes'
112+
post '/votes'
113+
last_response.body.should == 'Created a Vote'
114+
end
115+
116+
verbs = %w(post get head delete put)
117+
verbs.each do |verb|
118+
it "should allow and properly constrain a #{verb.upcase} method" do
119+
subject.send(verb, '/example') do
120+
verb
121+
end
122+
send(verb, '/example')
123+
last_response.body.should == verb
124+
# Call it with a method other than the properly constrained one.
125+
send(verbs[(verbs.index(verb) + 1) % verbs.size], '/example')
126+
last_response.status.should == 404
127+
end
128+
end
129+
130+
it 'should return a 201 response code for POST by default' do
131+
subject.post('example') do
132+
"Created"
133+
end
134+
135+
post '/example'
136+
last_response.status.should == 201
137+
last_response.body.should == 'Created'
138+
end
139+
end
140+
98141
describe '.basic' do
99142
it 'should protect any resources on the same scope' do
100143
subject.http_basic do |u,p|

spec/grape/endpoint_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
require 'spec_helper'
2+
3+
describe Grape::Endpoint do
4+
subject { Class.new(Grape::API) }
5+
before { subject.default_format :txt }
6+
def app; subject end
7+
8+
describe '#status' do
9+
it 'should be callable from within a block' do
10+
subject.get('/home') do
11+
status 206
12+
"Hello"
13+
end
14+
15+
get '/home'
16+
last_response.status.should == 206
17+
last_response.body.should == "Hello"
18+
end
19+
end
20+
21+
describe '#header' do
22+
it 'should be callable from within a block' do
23+
subject.get('/hey') do
24+
header 'X-Awesome', 'true'
25+
"Awesome"
26+
end
27+
28+
get '/hey'
29+
last_response.headers['X-Awesome'].should == 'true'
30+
end
31+
end
32+
end

spec/grape/middleware/formatter_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
it 'should look at the bodies for possibly serializable data' do
1111
@body = {"abc" => "def"}
1212
status, headers, bodies = *subject.call({'PATH_INFO' => '/somewhere'})
13-
bodies.first.should == MultiJson.encode(@body)
13+
bodies.each{|b| b.should == MultiJson.encode(@body) }
1414
end
1515
end
1616

0 commit comments

Comments
 (0)