grape 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- data/.yardopts +2 -0
- data/CHANGELOG.markdown +19 -0
- data/Gemfile +2 -0
- data/README.markdown +166 -131
- data/Rakefile +1 -3
- data/lib/grape.rb +0 -3
- data/lib/grape/api.rb +16 -4
- data/lib/grape/cookies.rb +32 -30
- data/lib/grape/endpoint.rb +25 -11
- data/lib/grape/entity.rb +5 -0
- data/lib/grape/error_formatter/base.rb +2 -1
- data/lib/grape/middleware/base.rb +9 -2
- data/lib/grape/middleware/error.rb +11 -11
- data/lib/grape/middleware/formatter.rb +8 -5
- data/lib/grape/middleware/versioner/header.rb +1 -3
- data/lib/grape/middleware/versioner/path.rb +15 -2
- data/lib/grape/util/deep_merge.rb +4 -4
- data/lib/grape/validations.rb +2 -3
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +316 -175
- data/spec/grape/endpoint_spec.rb +159 -57
- data/spec/grape/entity_spec.rb +80 -80
- data/spec/grape/middleware/auth/basic_spec.rb +3 -3
- data/spec/grape/middleware/auth/digest_spec.rb +4 -4
- data/spec/grape/middleware/auth/oauth2_spec.rb +4 -4
- data/spec/grape/middleware/base_spec.rb +9 -9
- data/spec/grape/middleware/error_spec.rb +4 -4
- data/spec/grape/middleware/exception_spec.rb +13 -13
- data/spec/grape/middleware/formatter_spec.rb +25 -25
- data/spec/grape/middleware/versioner/header_spec.rb +23 -23
- data/spec/grape/middleware/versioner/param_spec.rb +8 -8
- data/spec/grape/middleware/versioner/path_spec.rb +8 -8
- data/spec/grape/middleware/versioner_spec.rb +6 -3
- data/spec/grape/util/hash_stack_spec.rb +20 -20
- data/spec/grape/validations/presence_spec.rb +1 -1
- data/spec/grape/validations/regexp_spec.rb +2 -2
- data/spec/grape/validations_spec.rb +4 -4
- data/spec/shared/versioning_examples.rb +48 -20
- metadata +5 -7
- data/.document +0 -5
- data/lib/grape/middleware/prefixer.rb +0 -21
- data/spec/grape/middleware/prefixer_spec.rb +0 -30
data/spec/grape/endpoint_spec.rb
CHANGED
@@ -5,22 +5,25 @@ describe Grape::Endpoint do
|
|
5
5
|
def app; subject end
|
6
6
|
|
7
7
|
describe '#initialize' do
|
8
|
-
it '
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
it 'takes a settings stack, options, and a block' do
|
9
|
+
p = Proc.new {}
|
10
|
+
expect {
|
11
|
+
Grape::Endpoint.new(Grape::Util::HashStack.new, {
|
12
|
+
:path => '/',
|
13
|
+
:method => :get
|
14
|
+
}, &p)
|
15
|
+
}.not_to raise_error
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
16
|
-
it '
|
19
|
+
it 'sets itself in the env upon call' do
|
17
20
|
subject.get('/'){ "Hello world." }
|
18
21
|
get '/'
|
19
22
|
last_request.env['api.endpoint'].should be_kind_of(Grape::Endpoint)
|
20
23
|
end
|
21
24
|
|
22
25
|
describe '#status' do
|
23
|
-
it '
|
26
|
+
it 'is callable from within a block' do
|
24
27
|
subject.get('/home') do
|
25
28
|
status 206
|
26
29
|
"Hello"
|
@@ -33,7 +36,7 @@ describe Grape::Endpoint do
|
|
33
36
|
end
|
34
37
|
|
35
38
|
describe '#header' do
|
36
|
-
it '
|
39
|
+
it 'is callable from within a block' do
|
37
40
|
subject.get('/hey') do
|
38
41
|
header 'X-Awesome', 'true'
|
39
42
|
"Awesome"
|
@@ -45,7 +48,7 @@ describe Grape::Endpoint do
|
|
45
48
|
end
|
46
49
|
|
47
50
|
describe '#cookies' do
|
48
|
-
it '
|
51
|
+
it 'is callable from within a block' do
|
49
52
|
subject.get('/get/cookies') do
|
50
53
|
cookies['my-awesome-cookie1'] = 'is cool'
|
51
54
|
cookies['my-awesome-cookie2'] = {
|
@@ -68,7 +71,7 @@ describe Grape::Endpoint do
|
|
68
71
|
]
|
69
72
|
end
|
70
73
|
|
71
|
-
it
|
74
|
+
it 'sets browser cookies and does not set response cookies' do
|
72
75
|
subject.get('/username') do
|
73
76
|
cookies[:username]
|
74
77
|
end
|
@@ -79,7 +82,7 @@ describe Grape::Endpoint do
|
|
79
82
|
last_response.headers['Set-Cookie'].should_not =~ /sandbox=true/
|
80
83
|
end
|
81
84
|
|
82
|
-
it
|
85
|
+
it 'sets and update browser cookies' do
|
83
86
|
subject.get('/username') do
|
84
87
|
cookies[:sandbox] = true if cookies[:sandbox] == 'false'
|
85
88
|
cookies[:username] += "_test"
|
@@ -90,7 +93,7 @@ describe Grape::Endpoint do
|
|
90
93
|
last_response.headers['Set-Cookie'].should =~ /sandbox=true/
|
91
94
|
end
|
92
95
|
|
93
|
-
it
|
96
|
+
it 'deletes cookie' do
|
94
97
|
subject.get('/test') do
|
95
98
|
sum = 0
|
96
99
|
cookies.each do |name, val|
|
@@ -106,6 +109,23 @@ describe Grape::Endpoint do
|
|
106
109
|
"delete_this_cookie=deleted; expires=Thu, 01-Jan-1970 00:00:00 GMT"
|
107
110
|
]
|
108
111
|
end
|
112
|
+
|
113
|
+
it 'deletes cookies with path' do
|
114
|
+
subject.get('/test') do
|
115
|
+
sum = 0
|
116
|
+
cookies.each do |name, val|
|
117
|
+
sum += val.to_i
|
118
|
+
cookies.delete name, { :path => '/test' }
|
119
|
+
end
|
120
|
+
sum
|
121
|
+
end
|
122
|
+
get('/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2')
|
123
|
+
last_response.body.should == '3'
|
124
|
+
last_response.headers['Set-Cookie'].split("\n").sort.should == [
|
125
|
+
"and_this=deleted; path=/test; expires=Thu, 01-Jan-1970 00:00:00 GMT",
|
126
|
+
"delete_this_cookie=deleted; path=/test; expires=Thu, 01-Jan-1970 00:00:00 GMT"
|
127
|
+
]
|
128
|
+
end
|
109
129
|
end
|
110
130
|
|
111
131
|
describe '#declared' do
|
@@ -118,8 +138,8 @@ describe Grape::Endpoint do
|
|
118
138
|
|
119
139
|
end
|
120
140
|
|
121
|
-
it '
|
122
|
-
subject.get
|
141
|
+
it 'has as many keys as there are declared params' do
|
142
|
+
subject.get '/declared' do
|
123
143
|
declared(params).keys.size.should == 2
|
124
144
|
""
|
125
145
|
end
|
@@ -128,8 +148,8 @@ describe Grape::Endpoint do
|
|
128
148
|
last_response.status.should == 200
|
129
149
|
end
|
130
150
|
|
131
|
-
it '
|
132
|
-
subject.get
|
151
|
+
it 'filters out any additional params that are given' do
|
152
|
+
subject.get '/declared' do
|
133
153
|
declared(params).key?(:other).should == false
|
134
154
|
""
|
135
155
|
end
|
@@ -138,8 +158,8 @@ describe Grape::Endpoint do
|
|
138
158
|
last_response.status.should == 200
|
139
159
|
end
|
140
160
|
|
141
|
-
it '
|
142
|
-
subject.get
|
161
|
+
it 'stringifies if that option is passed' do
|
162
|
+
subject.get '/declared' do
|
143
163
|
declared(params, :stringify => true)["first"].should == "one"
|
144
164
|
""
|
145
165
|
end
|
@@ -148,8 +168,8 @@ describe Grape::Endpoint do
|
|
148
168
|
last_response.status.should == 200
|
149
169
|
end
|
150
170
|
|
151
|
-
it '
|
152
|
-
subject.get
|
171
|
+
it 'does not include missing attributes if that option is passed' do
|
172
|
+
subject.get '/declared' do
|
153
173
|
declared(params, :include_missing => false)[:second].should == nil
|
154
174
|
""
|
155
175
|
end
|
@@ -160,7 +180,7 @@ describe Grape::Endpoint do
|
|
160
180
|
end
|
161
181
|
|
162
182
|
describe '#params' do
|
163
|
-
it '
|
183
|
+
it 'is available to the caller' do
|
164
184
|
subject.get('/hey') do
|
165
185
|
params[:howdy]
|
166
186
|
end
|
@@ -169,7 +189,7 @@ describe Grape::Endpoint do
|
|
169
189
|
last_response.body.should == 'hey'
|
170
190
|
end
|
171
191
|
|
172
|
-
it '
|
192
|
+
it 'parses from path segments' do
|
173
193
|
subject.get('/hey/:id') do
|
174
194
|
params[:id]
|
175
195
|
end
|
@@ -178,7 +198,7 @@ describe Grape::Endpoint do
|
|
178
198
|
last_response.body.should == '12'
|
179
199
|
end
|
180
200
|
|
181
|
-
it '
|
201
|
+
it 'deeply converts nested params' do
|
182
202
|
subject.get '/location' do
|
183
203
|
params[:location][:city]
|
184
204
|
end
|
@@ -187,7 +207,7 @@ describe Grape::Endpoint do
|
|
187
207
|
end
|
188
208
|
|
189
209
|
context 'with special requirements' do
|
190
|
-
it '
|
210
|
+
it 'parses email param with provided requirements for params' do
|
191
211
|
subject.get('/:person_email', :requirements => { :person_email => /.*/ }) do
|
192
212
|
params[:person_email]
|
193
213
|
end
|
@@ -199,7 +219,7 @@ describe Grape::Endpoint do
|
|
199
219
|
last_response.body.should == 'rodzyn@grape.com.pl'
|
200
220
|
end
|
201
221
|
|
202
|
-
it '
|
222
|
+
it 'parses many params with provided regexps' do
|
203
223
|
subject.get('/:person_email/test/:number',
|
204
224
|
:requirements => {
|
205
225
|
:person_email => /rodzyn@(.*).com/,
|
@@ -232,22 +252,22 @@ describe Grape::Endpoint do
|
|
232
252
|
end
|
233
253
|
end
|
234
254
|
|
235
|
-
it '
|
236
|
-
post '/request_body', MultiJson.
|
255
|
+
it 'converts JSON bodies to params' do
|
256
|
+
post '/request_body', MultiJson.dump(:user => 'Bobby T.'), {'CONTENT_TYPE' => 'application/json'}
|
237
257
|
last_response.body.should == 'Bobby T.'
|
238
258
|
end
|
239
259
|
|
240
|
-
it '
|
260
|
+
it 'does not convert empty JSON bodies to params' do
|
241
261
|
put '/request_body', '', {'CONTENT_TYPE' => 'application/json'}
|
242
262
|
last_response.body.should == ''
|
243
263
|
end
|
244
264
|
|
245
|
-
it '
|
265
|
+
it 'converts XML bodies to params' do
|
246
266
|
post '/request_body', '<user>Bobby T.</user>', {'CONTENT_TYPE' => 'application/xml'}
|
247
267
|
last_response.body.should == 'Bobby T.'
|
248
268
|
end
|
249
269
|
|
250
|
-
it '
|
270
|
+
it 'converts XML bodies to params' do
|
251
271
|
put '/request_body', '<user>Bobby T.</user>', {'CONTENT_TYPE' => 'application/xml'}
|
252
272
|
last_response.body.should == 'Bobby T.'
|
253
273
|
end
|
@@ -256,13 +276,20 @@ describe Grape::Endpoint do
|
|
256
276
|
subject.post '/omitted_params' do
|
257
277
|
body_params[:version].should == nil
|
258
278
|
end
|
259
|
-
post '/omitted_params', MultiJson.
|
279
|
+
post '/omitted_params', MultiJson.dump(:user => 'Blah'), {'CONTENT_TYPE' => 'application/json'}
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should return an equivalent hash on subsequenst calls' do
|
283
|
+
subject.post '/two_times' do
|
284
|
+
body_params.should == body_params
|
285
|
+
end
|
286
|
+
post '/two_times', MultiJson.dump(:user => 'Bobby T.'), {'CONTENT_TYPE' => 'application/json'}
|
260
287
|
end
|
261
288
|
end
|
262
289
|
end
|
263
290
|
|
264
291
|
describe '#error!' do
|
265
|
-
it '
|
292
|
+
it 'accepts a message' do
|
266
293
|
subject.get('/hey') do
|
267
294
|
error! "This is not valid."
|
268
295
|
"This is valid."
|
@@ -273,7 +300,7 @@ describe Grape::Endpoint do
|
|
273
300
|
last_response.body.should == "This is not valid."
|
274
301
|
end
|
275
302
|
|
276
|
-
it '
|
303
|
+
it 'accepts a code' do
|
277
304
|
subject.get('/hey') do
|
278
305
|
error! "Unauthorized.", 401
|
279
306
|
end
|
@@ -283,7 +310,7 @@ describe Grape::Endpoint do
|
|
283
310
|
last_response.body.should == "Unauthorized."
|
284
311
|
end
|
285
312
|
|
286
|
-
it '
|
313
|
+
it 'accepts an object and render it in format' do
|
287
314
|
subject.get '/hey' do
|
288
315
|
error!({'dude' => 'rad'}, 403)
|
289
316
|
end
|
@@ -294,8 +321,8 @@ describe Grape::Endpoint do
|
|
294
321
|
end
|
295
322
|
end
|
296
323
|
|
297
|
-
describe
|
298
|
-
it
|
324
|
+
describe '#redirect' do
|
325
|
+
it 'redirects to a url with status 302' do
|
299
326
|
subject.get('/hey') do
|
300
327
|
redirect "/ha"
|
301
328
|
end
|
@@ -305,7 +332,7 @@ describe Grape::Endpoint do
|
|
305
332
|
last_response.body.should eq ""
|
306
333
|
end
|
307
334
|
|
308
|
-
it
|
335
|
+
it 'has status code 303 if it is not get request and it is http 1.1' do
|
309
336
|
subject.post('/hey') do
|
310
337
|
redirect "/ha"
|
311
338
|
end
|
@@ -314,7 +341,7 @@ describe Grape::Endpoint do
|
|
314
341
|
last_response.headers['Location'].should eq "/ha"
|
315
342
|
end
|
316
343
|
|
317
|
-
it
|
344
|
+
it 'support permanent redirect' do
|
318
345
|
subject.get('/hey') do
|
319
346
|
redirect "/ha", :permanent => true
|
320
347
|
end
|
@@ -325,7 +352,7 @@ describe Grape::Endpoint do
|
|
325
352
|
end
|
326
353
|
end
|
327
354
|
|
328
|
-
it '
|
355
|
+
it 'does not persist params between calls' do
|
329
356
|
subject.post('/new') do
|
330
357
|
params[:text]
|
331
358
|
end
|
@@ -337,7 +364,7 @@ describe Grape::Endpoint do
|
|
337
364
|
last_response.body.should == 'def'
|
338
365
|
end
|
339
366
|
|
340
|
-
it '
|
367
|
+
it 'resets all instance variables (except block) between calls' do
|
341
368
|
subject.helpers do
|
342
369
|
def memoized
|
343
370
|
@memoized ||= params[:howdy]
|
@@ -354,7 +381,7 @@ describe Grape::Endpoint do
|
|
354
381
|
last_response.body.should == 'yo'
|
355
382
|
end
|
356
383
|
|
357
|
-
it '
|
384
|
+
it 'allows explicit return calls' do
|
358
385
|
subject.get('/home') do
|
359
386
|
return "Hello"
|
360
387
|
end
|
@@ -364,24 +391,24 @@ describe Grape::Endpoint do
|
|
364
391
|
last_response.body.should == "Hello"
|
365
392
|
end
|
366
393
|
|
367
|
-
describe
|
368
|
-
it
|
394
|
+
describe '.generate_api_method' do
|
395
|
+
it 'raises NameError if the method name is already in use' do
|
369
396
|
expect {
|
370
397
|
Grape::Endpoint.generate_api_method("version", &proc{})
|
371
398
|
}.to raise_error(NameError)
|
372
399
|
end
|
373
|
-
it
|
400
|
+
it 'raises ArgumentError if a block is not given' do
|
374
401
|
expect {
|
375
402
|
Grape::Endpoint.generate_api_method("GET without a block method")
|
376
403
|
}.to raise_error(ArgumentError)
|
377
404
|
end
|
378
|
-
it
|
405
|
+
it 'returns a Proc' do
|
379
406
|
Grape::Endpoint.generate_api_method("GET test for a proc", &proc{}).should be_a Proc
|
380
407
|
end
|
381
408
|
end
|
382
409
|
|
383
410
|
describe '#present' do
|
384
|
-
it '
|
411
|
+
it 'sets the object as the body if no options are provided' do
|
385
412
|
subject.get '/example' do
|
386
413
|
present({:abc => 'def'})
|
387
414
|
body.should == {:abc => 'def'}
|
@@ -389,7 +416,7 @@ describe Grape::Endpoint do
|
|
389
416
|
get '/example'
|
390
417
|
end
|
391
418
|
|
392
|
-
it '
|
419
|
+
it 'calls through to the provided entity class if one is given' do
|
393
420
|
subject.get '/example' do
|
394
421
|
entity_mock = Object.new
|
395
422
|
entity_mock.should_receive(:represent)
|
@@ -398,7 +425,7 @@ describe Grape::Endpoint do
|
|
398
425
|
get '/example'
|
399
426
|
end
|
400
427
|
|
401
|
-
it '
|
428
|
+
it 'pulls a representation from the class options if it exists' do
|
402
429
|
entity = Class.new(Grape::Entity)
|
403
430
|
entity.stub!(:represent).and_return("Hiya")
|
404
431
|
|
@@ -410,7 +437,7 @@ describe Grape::Endpoint do
|
|
410
437
|
last_response.body.should == 'Hiya'
|
411
438
|
end
|
412
439
|
|
413
|
-
it '
|
440
|
+
it 'pulls a representation from the class ancestor if it exists' do
|
414
441
|
entity = Class.new(Grape::Entity)
|
415
442
|
entity.stub!(:represent).and_return("Hiya")
|
416
443
|
|
@@ -424,7 +451,7 @@ describe Grape::Endpoint do
|
|
424
451
|
last_response.body.should == 'Hiya'
|
425
452
|
end
|
426
453
|
|
427
|
-
it '
|
454
|
+
it 'automatically uses Klass::Entity if that exists' do
|
428
455
|
some_model = Class.new
|
429
456
|
entity = Class.new(Grape::Entity)
|
430
457
|
entity.stub!(:represent).and_return("Auto-detect!")
|
@@ -438,18 +465,65 @@ describe Grape::Endpoint do
|
|
438
465
|
last_response.body.should == 'Auto-detect!'
|
439
466
|
end
|
440
467
|
|
441
|
-
it '
|
468
|
+
it 'adds a root key to the output if one is given' do
|
442
469
|
subject.get '/example' do
|
443
470
|
present({:abc => 'def'}, :root => :root)
|
444
471
|
body.should == {:root => {:abc => 'def'}}
|
445
472
|
end
|
446
473
|
get '/example'
|
447
474
|
end
|
475
|
+
|
476
|
+
[ :json, :serializable_hash ].each do |format|
|
477
|
+
|
478
|
+
it 'presents with #{format}' do
|
479
|
+
entity = Class.new(Grape::Entity)
|
480
|
+
entity.root "examples", "example"
|
481
|
+
entity.expose :id
|
482
|
+
|
483
|
+
subject.format format
|
484
|
+
subject.get '/example' do
|
485
|
+
c = Class.new do
|
486
|
+
attr_reader :id
|
487
|
+
def initialize(id)
|
488
|
+
@id = id
|
489
|
+
end
|
490
|
+
end
|
491
|
+
present c.new(1), :with => entity
|
492
|
+
end
|
493
|
+
|
494
|
+
get '/example'
|
495
|
+
last_response.status.should == 200
|
496
|
+
last_response.body.should == '{"example":{"id":1}}'
|
497
|
+
end
|
498
|
+
|
499
|
+
it 'presents with #{format} collection' do
|
500
|
+
entity = Class.new(Grape::Entity)
|
501
|
+
entity.root "examples", "example"
|
502
|
+
entity.expose :id
|
503
|
+
|
504
|
+
subject.format format
|
505
|
+
subject.get '/examples' do
|
506
|
+
c = Class.new do
|
507
|
+
attr_reader :id
|
508
|
+
def initialize(id)
|
509
|
+
@id = id
|
510
|
+
end
|
511
|
+
end
|
512
|
+
examples = [ c.new(1), c.new(2) ]
|
513
|
+
present examples, :with => entity
|
514
|
+
end
|
515
|
+
|
516
|
+
get '/examples'
|
517
|
+
last_response.status.should == 200
|
518
|
+
last_response.body.should == '{"examples":[{"id":1},{"id":2}]}'
|
519
|
+
end
|
520
|
+
|
521
|
+
end
|
448
522
|
end
|
449
523
|
|
450
524
|
context 'filters' do
|
451
525
|
describe 'before filters' do
|
452
|
-
it '
|
526
|
+
it 'runs the before filter if set' do
|
453
527
|
subject.before{ env['before_test'] = "OK" }
|
454
528
|
subject.get('/before_test'){ env['before_test'] }
|
455
529
|
|
@@ -459,14 +533,14 @@ describe Grape::Endpoint do
|
|
459
533
|
end
|
460
534
|
|
461
535
|
describe 'after filters' do
|
462
|
-
it '
|
536
|
+
it 'overrides the response body if it sets it' do
|
463
537
|
subject.after{ body "after" }
|
464
538
|
subject.get('/after_test'){ "during" }
|
465
539
|
get '/after_test'
|
466
540
|
last_response.body.should == 'after'
|
467
541
|
end
|
468
542
|
|
469
|
-
it '
|
543
|
+
it 'does not override the response body with its return' do
|
470
544
|
subject.after{ "after" }
|
471
545
|
subject.get('/after_test'){ "body" }
|
472
546
|
get '/after_test'
|
@@ -479,7 +553,7 @@ describe Grape::Endpoint do
|
|
479
553
|
verbs = %w(post get head delete put options patch)
|
480
554
|
|
481
555
|
verbs.each do |verb|
|
482
|
-
it
|
556
|
+
it 'allows for the anchoring option with a #{verb.upcase} method' do
|
483
557
|
subject.send(verb, '/example', :anchor => true) do
|
484
558
|
verb
|
485
559
|
end
|
@@ -487,7 +561,7 @@ describe Grape::Endpoint do
|
|
487
561
|
last_response.status.should eql 404
|
488
562
|
end
|
489
563
|
|
490
|
-
it
|
564
|
+
it 'anchors paths by default for the #{verb.upcase} method' do
|
491
565
|
subject.send(verb, '/example') do
|
492
566
|
verb
|
493
567
|
end
|
@@ -495,7 +569,7 @@ describe Grape::Endpoint do
|
|
495
569
|
last_response.status.should eql 404
|
496
570
|
end
|
497
571
|
|
498
|
-
it
|
572
|
+
it 'responds to /example/and/some/more for the non-anchored #{verb.upcase} method' do
|
499
573
|
subject.send(verb, '/example', :anchor => false) do
|
500
574
|
verb
|
501
575
|
end
|
@@ -505,4 +579,32 @@ describe Grape::Endpoint do
|
|
505
579
|
end
|
506
580
|
end
|
507
581
|
end
|
582
|
+
|
583
|
+
context 'request' do
|
584
|
+
it 'should be set to the url requested' do
|
585
|
+
subject.get('/url') do
|
586
|
+
request.url
|
587
|
+
end
|
588
|
+
get '/url'
|
589
|
+
last_response.body.should == "http://example.org/url"
|
590
|
+
end
|
591
|
+
it 'should include version' do
|
592
|
+
subject.version 'v1', :using => :path
|
593
|
+
subject.get('/url') do
|
594
|
+
request.url
|
595
|
+
end
|
596
|
+
get '/v1/url'
|
597
|
+
last_response.body.should == "http://example.org/v1/url"
|
598
|
+
end
|
599
|
+
it 'should include prefix' do
|
600
|
+
subject.version 'v1', :using => :path
|
601
|
+
subject.prefix 'api'
|
602
|
+
subject.get('/url') do
|
603
|
+
request.url
|
604
|
+
end
|
605
|
+
get '/api/v1/url'
|
606
|
+
last_response.body.should == "http://example.org/api/v1/url"
|
607
|
+
end
|
608
|
+
end
|
609
|
+
|
508
610
|
end
|