Skip to content

Commit 0123e3b

Browse files
committed
Added support for Multi-parts URL params. Added RSpec test for it
1 parent dd75477 commit 0123e3b

File tree

2 files changed

+73
-44
lines changed

2 files changed

+73
-44
lines changed

lib/grape/api.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def route(methods, paths, &block)
142142

143143
methods.each do |method|
144144
paths.each do |path|
145-
path = Rack::Mount::Strexp.compile(compile_path(path))
145+
path = Rack::Mount::Strexp.compile(compile_path(path), {}, ['/'], true)
146146
route_set.add_route(endpoint,
147147
:path_info => path,
148148
:request_method => (method.to_s.upcase unless method == :any)

spec/grape/api_spec.rb

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ def app; subject end
1414
end
1515

1616
get 'awesome/sauce/hello'
17-
last_response.body.should == "Hello there."
17+
last_response.body.should eql "Hello there."
1818

1919
get '/hello'
20-
last_response.status.should == 404
20+
last_response.status.should eql 404
2121
end
2222
end
2323

@@ -29,7 +29,7 @@ def app; subject end
2929
end
3030

3131
get '/v1/hello'
32-
last_response.body.should == "Version: v1"
32+
last_response.body.should eql "Version: v1"
3333
end
3434

3535
it 'should add the prefix before the API version' do
@@ -40,7 +40,7 @@ def app; subject end
4040
end
4141

4242
get '/api/v1/hello'
43-
last_response.body.should == "Version: v1"
43+
last_response.body.should eql "Version: v1"
4444
end
4545

4646
it 'should be able to specify version as a nesting' do
@@ -56,13 +56,13 @@ def app; subject end
5656
end
5757

5858
get '/v1/awesome'
59-
last_response.status.should == 404
59+
last_response.status.should eql 404
6060
get '/v2/awesome'
61-
last_response.status.should == 200
61+
last_response.status.should eql 200
6262
get '/v1/legacy'
63-
last_response.status.should == 200
63+
last_response.status.should eql 200
6464
get '/v2/legacy'
65-
last_response.status.should == 404
65+
last_response.status.should eql 404
6666
end
6767

6868
it 'should be able to specify multiple versions' do
@@ -72,11 +72,11 @@ def app; subject end
7272
end
7373

7474
get '/v1/awesome'
75-
last_response.status.should == 200
75+
last_response.status.should eql 200
7676
get '/v2/awesome'
77-
last_response.status.should == 200
77+
last_response.status.should eql 200
7878
get '/v3/awesome'
79-
last_response.status.should == 404
79+
last_response.status.should eql 404
8080
end
8181
end
8282

@@ -125,7 +125,7 @@ def app; subject end
125125
%w(group resource resources).each do |als|
126126
it "`.#{als}` should be an alias" do
127127
subject.send(als, :awesome) do
128-
namespace.should == "/awesome"
128+
namespace.should == "/awesome"
129129
end
130130
end
131131
end
@@ -144,9 +144,9 @@ def app; subject end
144144
end
145145

146146
get '/votes'
147-
last_response.body.should == 'Votes'
147+
last_response.body.should eql 'Votes'
148148
post '/votes'
149-
last_response.body.should == 'Created a Vote'
149+
last_response.body.should eql 'Created a Vote'
150150
end
151151

152152
it 'should allow for multiple paths' do
@@ -155,9 +155,9 @@ def app; subject end
155155
end
156156

157157
get '/abc'
158-
last_response.body.should == 'foo'
158+
last_response.body.should eql 'foo'
159159
get '/def'
160-
last_response.body.should == 'foo'
160+
last_response.body.should eql 'foo'
161161
end
162162

163163
it 'should allow for format' do
@@ -166,7 +166,7 @@ def app; subject end
166166
end
167167

168168
get '/abc.json'
169-
last_response.body.should == '"json"'
169+
last_response.body.should eql '"json"'
170170
end
171171

172172
it 'should allow for format in namespace with no path' do
@@ -177,7 +177,7 @@ def app; subject end
177177
end
178178

179179
get '/abc.json'
180-
last_response.body.should == '"json"'
180+
last_response.body.should eql '"json"'
181181
end
182182

183183
it 'should allow for multiple verbs' do
@@ -186,9 +186,38 @@ def app; subject end
186186
end
187187

188188
get '/abc'
189-
last_response.body.should == 'hiya'
189+
last_response.body.should eql 'hiya'
190190
post '/abc'
191-
last_response.body.should == 'hiya'
191+
last_response.body.should eql 'hiya'
192+
end
193+
194+
it 'should allow for multipart paths' do
195+
196+
197+
subject.route([:get, :post], '/:id/first') do
198+
"first"
199+
end
200+
201+
202+
subject.route([:get, :post], '/:id') do
203+
"ola"
204+
end
205+
subject.route([:get, :post], '/:id/first/second') do
206+
"second"
207+
end
208+
209+
210+
get '/1'
211+
last_response.body.should eql 'ola'
212+
post '/1'
213+
last_response.body.should eql 'ola'
214+
get '/1/first'
215+
last_response.body.should eql 'first'
216+
post '/1/first'
217+
last_response.body.should eql 'first'
218+
get '/1/first/second'
219+
last_response.body.should eql 'second'
220+
192221
end
193222

194223
it 'should allow for :any as a verb' do
@@ -198,7 +227,7 @@ def app; subject end
198227

199228
%w(get post put delete).each do |m|
200229
send(m, '/abc')
201-
last_response.body.should == 'lol'
230+
last_response.body.should eql 'lol'
202231
end
203232
end
204233

@@ -209,10 +238,10 @@ def app; subject end
209238
verb
210239
end
211240
send(verb, '/example')
212-
last_response.body.should == verb
241+
last_response.body.should eql verb
213242
# Call it with a method other than the properly constrained one.
214243
send(verbs[(verbs.index(verb) + 1) % verbs.size], '/example')
215-
last_response.status.should == 404
244+
last_response.status.should eql 404
216245
end
217246
end
218247

@@ -222,8 +251,8 @@ def app; subject end
222251
end
223252

224253
post '/example'
225-
last_response.status.should == 201
226-
last_response.body.should == 'Created'
254+
last_response.status.should eql 201
255+
last_response.body.should eql 'Created'
227256
end
228257
end
229258

@@ -244,7 +273,7 @@ def call(env)
244273
describe '.middleware' do
245274
it 'should include middleware arguments from settings' do
246275
subject.stub!(:settings_stack).and_return [{:middleware => [[PhonyMiddleware, 'abc', 123]]}]
247-
subject.middleware.should == [[PhonyMiddleware, 'abc', 123]]
276+
subject.middleware.should eql [[PhonyMiddleware, 'abc', 123]]
248277
end
249278

250279
it 'should include all middleware from stacked settings' do
@@ -253,7 +282,7 @@ def call(env)
253282
{:middleware => [[PhonyMiddleware, 'foo']]}
254283
]
255284

256-
subject.middleware.should == [
285+
subject.middleware.should eql [
257286
[PhonyMiddleware, 123],
258287
[PhonyMiddleware, 'abc'],
259288
[PhonyMiddleware, 'foo']
@@ -264,7 +293,7 @@ def call(env)
264293
describe '.use' do
265294
it 'should add middleware' do
266295
subject.use PhonyMiddleware, 123
267-
subject.middleware.should == [[PhonyMiddleware, 123]]
296+
subject.middleware.should eql [[PhonyMiddleware, 123]]
268297
end
269298

270299
it 'should not show up outside the namespace' do
@@ -274,7 +303,7 @@ def call(env)
274303
middleware.should == [[PhonyMiddleware, 123],[PhonyMiddleware, 'abc']]
275304
end
276305

277-
subject.middleware.should == [[PhonyMiddleware, 123]]
306+
subject.middleware.should eql [[PhonyMiddleware, 123]]
278307
end
279308

280309
it 'should actually call the middleware' do
@@ -284,7 +313,7 @@ def call(env)
284313
end
285314

286315
get '/'
287-
last_response.body.should == 'hello'
316+
last_response.body.should eql 'hello'
288317
end
289318
end
290319
end
@@ -295,9 +324,9 @@ def call(env)
295324
end
296325
subject.get(:hello){ "Hello, world."}
297326
get '/hello'
298-
last_response.status.should == 401
327+
last_response.status.should eql 401
299328
get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic('allow','whatever')
300-
last_response.status.should == 200
329+
last_response.status.should eql 200
301330
end
302331

303332
it 'should be scopable' do
@@ -311,9 +340,9 @@ def call(env)
311340
end
312341

313342
get '/hello'
314-
last_response.status.should == 200
343+
last_response.status.should eql 200
315344
get '/admin/hello'
316-
last_response.status.should == 401
345+
last_response.status.should eql 401
317346
end
318347

319348
it 'should be callable via .auth as well' do
@@ -323,9 +352,9 @@ def call(env)
323352

324353
subject.get(:hello){ "Hello, world."}
325354
get '/hello'
326-
last_response.status.should == 401
355+
last_response.status.should eql 401
327356
get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic('allow','whatever')
328-
last_response.status.should == 200
357+
last_response.status.should eql 200
329358
end
330359
end
331360

@@ -342,7 +371,7 @@ def hello
342371
end
343372

344373
get '/howdy'
345-
last_response.body.should == 'Hello, world.'
374+
last_response.body.should eql 'Hello, world.'
346375
end
347376

348377
it 'should be scopable' do
@@ -369,9 +398,9 @@ def secret
369398
end
370399

371400
get '/generic'
372-
last_response.body.should == 'always there:false'
401+
last_response.body.should eql 'always there:false'
373402
get '/admin/secret'
374-
last_response.body.should == 'always there:only in admin'
403+
last_response.body.should eql 'always there:only in admin'
375404
end
376405

377406
it 'should be reopenable' do
@@ -412,13 +441,13 @@ def two
412441
end
413442

414443
get '/v2/abc'
415-
last_response.status.should == 404
444+
last_response.status.should eql 404
416445
get '/v1/abc'
417-
last_response.status.should == 200
446+
last_response.status.should eql 200
418447
get '/v1/def'
419-
last_response.status.should == 404
448+
last_response.status.should eql 404
420449
get '/v2/def'
421-
last_response.status.should == 200
450+
last_response.status.should eql 200
422451
end
423452
end
424453
end

0 commit comments

Comments
 (0)