grape 1.3.0 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +119 -1
- data/LICENSE +1 -1
- data/README.md +123 -29
- data/UPGRADING.md +265 -39
- data/lib/grape/api/instance.rb +32 -31
- data/lib/grape/api.rb +5 -5
- data/lib/grape/content_types.rb +34 -0
- data/lib/grape/dsl/callbacks.rb +1 -1
- data/lib/grape/dsl/helpers.rb +2 -1
- data/lib/grape/dsl/inside_route.rb +77 -43
- data/lib/grape/dsl/parameters.rb +12 -8
- data/lib/grape/dsl/routing.rb +12 -11
- data/lib/grape/dsl/validations.rb +18 -1
- data/lib/grape/eager_load.rb +1 -1
- data/lib/grape/endpoint.rb +8 -6
- data/lib/grape/exceptions/base.rb +0 -4
- data/lib/grape/exceptions/validation.rb +1 -1
- data/lib/grape/exceptions/validation_errors.rb +12 -13
- data/lib/grape/http/headers.rb +26 -0
- data/lib/grape/middleware/auth/base.rb +3 -3
- data/lib/grape/middleware/base.rb +4 -5
- data/lib/grape/middleware/error.rb +11 -13
- data/lib/grape/middleware/formatter.rb +3 -3
- data/lib/grape/middleware/stack.rb +10 -2
- data/lib/grape/middleware/versioner/header.rb +4 -4
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
- data/lib/grape/middleware/versioner/path.rb +1 -1
- data/lib/grape/namespace.rb +12 -2
- data/lib/grape/path.rb +13 -3
- data/lib/grape/request.rb +13 -8
- data/lib/grape/router/attribute_translator.rb +26 -5
- data/lib/grape/router/pattern.rb +17 -16
- data/lib/grape/router/route.rb +5 -24
- data/lib/grape/router.rb +26 -30
- data/lib/grape/{serve_file → serve_stream}/file_body.rb +1 -1
- data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +1 -1
- data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +8 -8
- data/lib/grape/util/base_inheritable.rb +15 -8
- data/lib/grape/util/cache.rb +20 -0
- data/lib/grape/util/lazy_object.rb +43 -0
- data/lib/grape/util/lazy_value.rb +1 -0
- data/lib/grape/util/reverse_stackable_values.rb +2 -0
- data/lib/grape/util/stackable_values.rb +7 -20
- data/lib/grape/validations/attributes_iterator.rb +8 -0
- data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
- data/lib/grape/validations/params_scope.rb +10 -8
- data/lib/grape/validations/single_attribute_iterator.rb +1 -1
- data/lib/grape/validations/types/array_coercer.rb +14 -5
- data/lib/grape/validations/types/build_coercer.rb +5 -8
- data/lib/grape/validations/types/custom_type_coercer.rb +16 -2
- data/lib/grape/validations/types/dry_type_coercer.rb +36 -1
- data/lib/grape/validations/types/file.rb +15 -12
- data/lib/grape/validations/types/invalid_value.rb +24 -0
- data/lib/grape/validations/types/json.rb +40 -36
- data/lib/grape/validations/types/primitive_coercer.rb +15 -6
- data/lib/grape/validations/types/set_coercer.rb +6 -4
- data/lib/grape/validations/types/variant_collection_coercer.rb +1 -1
- data/lib/grape/validations/types.rb +7 -9
- data/lib/grape/validations/validator_factory.rb +1 -1
- data/lib/grape/validations/validators/as.rb +1 -1
- data/lib/grape/validations/validators/base.rb +8 -8
- data/lib/grape/validations/validators/coerce.rb +11 -15
- data/lib/grape/validations/validators/default.rb +3 -5
- data/lib/grape/validations/validators/exactly_one_of.rb +4 -2
- data/lib/grape/validations/validators/except_values.rb +1 -1
- data/lib/grape/validations/validators/multiple_params_base.rb +2 -1
- data/lib/grape/validations/validators/regexp.rb +1 -1
- data/lib/grape/validations/validators/values.rb +1 -1
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +5 -5
- data/spec/grape/api/instance_spec.rb +50 -0
- data/spec/grape/api_remount_spec.rb +9 -4
- data/spec/grape/api_spec.rb +82 -6
- data/spec/grape/dsl/inside_route_spec.rb +182 -33
- data/spec/grape/endpoint/declared_spec.rb +601 -0
- data/spec/grape/endpoint_spec.rb +0 -521
- data/spec/grape/entity_spec.rb +7 -1
- data/spec/grape/exceptions/validation_errors_spec.rb +2 -2
- data/spec/grape/integration/rack_sendfile_spec.rb +12 -8
- data/spec/grape/middleware/auth/strategies_spec.rb +1 -1
- data/spec/grape/middleware/error_spec.rb +1 -1
- data/spec/grape/middleware/formatter_spec.rb +3 -3
- data/spec/grape/middleware/stack_spec.rb +10 -0
- data/spec/grape/path_spec.rb +4 -4
- data/spec/grape/request_spec.rb +1 -1
- data/spec/grape/validations/instance_behaivour_spec.rb +1 -1
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +13 -3
- data/spec/grape/validations/params_scope_spec.rb +26 -0
- data/spec/grape/validations/single_attribute_iterator_spec.rb +17 -6
- data/spec/grape/validations/types/array_coercer_spec.rb +35 -0
- data/spec/grape/validations/types/primitive_coercer_spec.rb +135 -0
- data/spec/grape/validations/types/set_coercer_spec.rb +34 -0
- data/spec/grape/validations/types_spec.rb +1 -1
- data/spec/grape/validations/validators/coerce_spec.rb +366 -86
- data/spec/grape/validations/validators/default_spec.rb +170 -0
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +12 -12
- data/spec/grape/validations/validators/except_values_spec.rb +1 -0
- data/spec/grape/validations/validators/values_spec.rb +1 -1
- data/spec/grape/validations_spec.rb +298 -30
- data/spec/integration/eager_load/eager_load_spec.rb +15 -0
- data/spec/shared/versioning_examples.rb +20 -20
- data/spec/spec_helper.rb +3 -10
- data/spec/support/chunks.rb +14 -0
- data/spec/support/eager_load.rb +19 -0
- data/spec/support/versioned_helpers.rb +4 -6
- metadata +27 -10
- data/lib/grape/util/content_types.rb +0 -28
@@ -203,80 +203,229 @@ describe Grape::Endpoint do
|
|
203
203
|
end
|
204
204
|
|
205
205
|
describe '#file' do
|
206
|
+
before do
|
207
|
+
allow(subject).to receive(:warn)
|
208
|
+
end
|
209
|
+
|
206
210
|
describe 'set' do
|
207
211
|
context 'as file path' do
|
208
212
|
let(:file_path) { '/some/file/path' }
|
209
213
|
|
210
|
-
|
211
|
-
|
212
|
-
Grape::ServeFile::FileResponse.new(file_body)
|
213
|
-
end
|
214
|
+
it 'emits a warning that this method is deprecated' do
|
215
|
+
expect(subject).to receive(:warn).with(/Use sendfile or stream/)
|
214
216
|
|
215
|
-
before do
|
216
217
|
subject.file file_path
|
217
218
|
end
|
218
219
|
|
219
|
-
it '
|
220
|
-
expect(subject
|
220
|
+
it 'forwards the call to sendfile' do
|
221
|
+
expect(subject).to receive(:sendfile).with(file_path)
|
222
|
+
|
223
|
+
subject.file file_path
|
221
224
|
end
|
222
225
|
end
|
223
226
|
|
224
227
|
context 'as object (backward compatibility)' do
|
225
|
-
let(:file_object) {
|
228
|
+
let(:file_object) { double('StreamerObject', each: nil) }
|
229
|
+
|
230
|
+
it 'emits a warning that this method is deprecated' do
|
231
|
+
expect(subject).to receive(:warn).with(/Use stream to use a Stream object/)
|
232
|
+
|
233
|
+
subject.file file_object
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'forwards the call to stream' do
|
237
|
+
expect(subject).to receive(:stream).with(file_object)
|
238
|
+
|
239
|
+
subject.file file_object
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe 'get' do
|
245
|
+
it 'emits a warning that this method is deprecated' do
|
246
|
+
expect(subject).to receive(:warn).with(/Use sendfile or stream/)
|
247
|
+
|
248
|
+
subject.file
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'fowards call to sendfile' do
|
252
|
+
expect(subject).to receive(:sendfile)
|
253
|
+
|
254
|
+
subject.file
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
describe '#sendfile' do
|
260
|
+
describe 'set' do
|
261
|
+
context 'as file path' do
|
262
|
+
let(:file_path) { '/some/file/path' }
|
226
263
|
|
227
264
|
let(:file_response) do
|
228
|
-
Grape::
|
265
|
+
file_body = Grape::ServeStream::FileBody.new(file_path)
|
266
|
+
Grape::ServeStream::StreamResponse.new(file_body)
|
229
267
|
end
|
230
268
|
|
231
269
|
before do
|
232
|
-
subject.
|
270
|
+
subject.header 'Cache-Control', 'cache'
|
271
|
+
subject.header 'Content-Length', 123
|
272
|
+
subject.header 'Transfer-Encoding', 'base64'
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'sends no deprecation warnings' do
|
276
|
+
expect(subject).to_not receive(:warn)
|
277
|
+
|
278
|
+
subject.sendfile file_path
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'returns value wrapped in StreamResponse' do
|
282
|
+
subject.sendfile file_path
|
283
|
+
|
284
|
+
expect(subject.sendfile).to eq file_response
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'does not change the Cache-Control header' do
|
288
|
+
subject.sendfile file_path
|
289
|
+
|
290
|
+
expect(subject.header['Cache-Control']).to eq 'cache'
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'does not change the Content-Length header' do
|
294
|
+
subject.sendfile file_path
|
295
|
+
|
296
|
+
expect(subject.header['Content-Length']).to eq 123
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'does not change the Transfer-Encoding header' do
|
300
|
+
subject.sendfile file_path
|
301
|
+
|
302
|
+
expect(subject.header['Transfer-Encoding']).to eq 'base64'
|
233
303
|
end
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'as object' do
|
307
|
+
let(:file_object) { double('StreamerObject', each: nil) }
|
234
308
|
|
235
|
-
it '
|
236
|
-
expect
|
309
|
+
it 'raises an error that only a file path is supported' do
|
310
|
+
expect { subject.sendfile file_object }.to raise_error(ArgumentError, /Argument must be a file path/)
|
237
311
|
end
|
238
312
|
end
|
239
313
|
end
|
240
314
|
|
241
315
|
it 'returns default' do
|
242
|
-
expect(subject.
|
316
|
+
expect(subject.sendfile).to be nil
|
243
317
|
end
|
244
318
|
end
|
245
319
|
|
246
320
|
describe '#stream' do
|
247
321
|
describe 'set' do
|
248
|
-
|
322
|
+
context 'as a file path' do
|
323
|
+
let(:file_path) { '/some/file/path' }
|
249
324
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
subject.stream file_object
|
255
|
-
end
|
325
|
+
let(:file_response) do
|
326
|
+
file_body = Grape::ServeStream::FileBody.new(file_path)
|
327
|
+
Grape::ServeStream::StreamResponse.new(file_body)
|
328
|
+
end
|
256
329
|
|
257
|
-
|
258
|
-
|
259
|
-
|
330
|
+
before do
|
331
|
+
subject.header 'Cache-Control', 'cache'
|
332
|
+
subject.header 'Content-Length', 123
|
333
|
+
subject.header 'Transfer-Encoding', 'base64'
|
334
|
+
end
|
260
335
|
|
261
|
-
|
262
|
-
|
263
|
-
|
336
|
+
it 'emits no deprecation warnings' do
|
337
|
+
expect(subject).to_not receive(:warn)
|
338
|
+
|
339
|
+
subject.stream file_path
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'returns file body wrapped in StreamResponse' do
|
343
|
+
subject.stream file_path
|
344
|
+
|
345
|
+
expect(subject.stream).to eq file_response
|
346
|
+
end
|
347
|
+
|
348
|
+
it 'sets Cache-Control header to no-cache' do
|
349
|
+
subject.stream file_path
|
350
|
+
|
351
|
+
expect(subject.header['Cache-Control']).to eq 'no-cache'
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'does not change Cache-Control header' do
|
355
|
+
subject.stream
|
356
|
+
|
357
|
+
expect(subject.header['Cache-Control']).to eq 'cache'
|
358
|
+
end
|
359
|
+
|
360
|
+
it 'sets Content-Length header to nil' do
|
361
|
+
subject.stream file_path
|
362
|
+
|
363
|
+
expect(subject.header['Content-Length']).to eq nil
|
364
|
+
end
|
365
|
+
|
366
|
+
it 'sets Transfer-Encoding header to nil' do
|
367
|
+
subject.stream file_path
|
264
368
|
|
265
|
-
|
266
|
-
|
369
|
+
expect(subject.header['Transfer-Encoding']).to eq nil
|
370
|
+
end
|
267
371
|
end
|
268
372
|
|
269
|
-
|
270
|
-
|
373
|
+
context 'as a stream object' do
|
374
|
+
let(:stream_object) { double('StreamerObject', each: nil) }
|
375
|
+
|
376
|
+
let(:stream_response) do
|
377
|
+
Grape::ServeStream::StreamResponse.new(stream_object)
|
378
|
+
end
|
379
|
+
|
380
|
+
before do
|
381
|
+
subject.header 'Cache-Control', 'cache'
|
382
|
+
subject.header 'Content-Length', 123
|
383
|
+
subject.header 'Transfer-Encoding', 'base64'
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'emits no deprecation warnings' do
|
387
|
+
expect(subject).to_not receive(:warn)
|
388
|
+
|
389
|
+
subject.stream stream_object
|
390
|
+
end
|
391
|
+
|
392
|
+
it 'returns value wrapped in StreamResponse' do
|
393
|
+
subject.stream stream_object
|
394
|
+
|
395
|
+
expect(subject.stream).to eq stream_response
|
396
|
+
end
|
397
|
+
|
398
|
+
it 'sets Cache-Control header to no-cache' do
|
399
|
+
subject.stream stream_object
|
400
|
+
|
401
|
+
expect(subject.header['Cache-Control']).to eq 'no-cache'
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'sets Content-Length header to nil' do
|
405
|
+
subject.stream stream_object
|
406
|
+
|
407
|
+
expect(subject.header['Content-Length']).to eq nil
|
408
|
+
end
|
409
|
+
|
410
|
+
it 'sets Transfer-Encoding header to nil' do
|
411
|
+
subject.stream stream_object
|
412
|
+
|
413
|
+
expect(subject.header['Transfer-Encoding']).to eq nil
|
414
|
+
end
|
271
415
|
end
|
272
416
|
|
273
|
-
|
274
|
-
|
417
|
+
context 'as a non-stream object' do
|
418
|
+
let(:non_stream_object) { double('NonStreamerObject') }
|
419
|
+
|
420
|
+
it 'raises an error that the object must implement :each' do
|
421
|
+
expect { subject.stream non_stream_object }.to raise_error(ArgumentError, /:each/)
|
422
|
+
end
|
275
423
|
end
|
276
424
|
end
|
277
425
|
|
278
426
|
it 'returns default' do
|
279
|
-
expect(subject.
|
427
|
+
expect(subject.stream).to be nil
|
428
|
+
expect(subject.header['Cache-Control']).to eq nil
|
280
429
|
end
|
281
430
|
end
|
282
431
|
|