grape 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -3
- data/README.md +56 -8
- data/UPGRADING.md +43 -4
- data/lib/grape/api.rb +2 -2
- data/lib/grape/dsl/helpers.rb +1 -0
- data/lib/grape/dsl/inside_route.rb +26 -38
- data/lib/grape/dsl/routing.rb +2 -4
- data/lib/grape/middleware/base.rb +2 -1
- data/lib/grape/middleware/error.rb +10 -12
- data/lib/grape/middleware/stack.rb +17 -4
- data/lib/grape/request.rb +1 -1
- data/lib/grape/router.rb +1 -1
- data/lib/grape/router/attribute_translator.rb +2 -2
- data/lib/grape/util/base_inheritable.rb +2 -2
- data/lib/grape/util/lazy_value.rb +1 -0
- data/lib/grape/validations/params_scope.rb +2 -1
- data/lib/grape/validations/types/custom_type_coercer.rb +13 -1
- data/lib/grape/validations/validators/as.rb +1 -1
- data/lib/grape/validations/validators/base.rb +2 -4
- data/lib/grape/validations/validators/default.rb +3 -4
- data/lib/grape/validations/validators/except_values.rb +1 -1
- data/lib/grape/validations/validators/values.rb +1 -1
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +10 -0
- data/spec/grape/dsl/inside_route_spec.rb +7 -0
- data/spec/grape/endpoint/declared_spec.rb +590 -0
- data/spec/grape/endpoint_spec.rb +0 -534
- data/spec/grape/entity_spec.rb +6 -0
- data/spec/grape/middleware/error_spec.rb +1 -1
- data/spec/grape/middleware/stack_spec.rb +3 -1
- data/spec/grape/validations/params_scope_spec.rb +26 -0
- data/spec/grape/validations/validators/coerce_spec.rb +24 -0
- data/spec/grape/validations/validators/default_spec.rb +49 -0
- data/spec/grape/validations/validators/except_values_spec.rb +1 -0
- data/spec/spec_helper.rb +0 -10
- data/spec/support/chunks.rb +14 -0
- data/spec/support/versioned_helpers.rb +3 -5
- metadata +9 -5
data/spec/grape/entity_spec.rb
CHANGED
@@ -181,6 +181,7 @@ describe Grape::Entity do
|
|
181
181
|
subject.get '/example' do
|
182
182
|
c = Class.new do
|
183
183
|
attr_reader :id
|
184
|
+
|
184
185
|
def initialize(id)
|
185
186
|
@id = id
|
186
187
|
end
|
@@ -202,6 +203,7 @@ describe Grape::Entity do
|
|
202
203
|
subject.get '/examples' do
|
203
204
|
c = Class.new do
|
204
205
|
attr_reader :id
|
206
|
+
|
205
207
|
def initialize(id)
|
206
208
|
@id = id
|
207
209
|
end
|
@@ -226,6 +228,7 @@ describe Grape::Entity do
|
|
226
228
|
subject.get '/example' do
|
227
229
|
c = Class.new do
|
228
230
|
attr_reader :name
|
231
|
+
|
229
232
|
def initialize(args)
|
230
233
|
@name = args[:name] || 'no name set'
|
231
234
|
end
|
@@ -255,6 +258,7 @@ XML
|
|
255
258
|
subject.get '/example' do
|
256
259
|
c = Class.new do
|
257
260
|
attr_reader :name
|
261
|
+
|
258
262
|
def initialize(args)
|
259
263
|
@name = args[:name] || 'no name set'
|
260
264
|
end
|
@@ -284,6 +288,7 @@ XML
|
|
284
288
|
subject.get '/example' do
|
285
289
|
c = Class.new do
|
286
290
|
attr_reader :name
|
291
|
+
|
287
292
|
def initialize(args)
|
288
293
|
@name = args[:name] || 'no name set'
|
289
294
|
end
|
@@ -302,6 +307,7 @@ XML
|
|
302
307
|
it 'present with multiple entities using optional symbol' do
|
303
308
|
user = Class.new do
|
304
309
|
attr_reader :name
|
310
|
+
|
305
311
|
def initialize(args)
|
306
312
|
@name = args[:name] || 'no name set'
|
307
313
|
end
|
@@ -8,6 +8,7 @@ describe Grape::Middleware::Stack do
|
|
8
8
|
class BarMiddleware; end
|
9
9
|
class BlockMiddleware
|
10
10
|
attr_reader :block
|
11
|
+
|
11
12
|
def initialize(&block)
|
12
13
|
@block = block
|
13
14
|
end
|
@@ -34,7 +35,8 @@ describe Grape::Middleware::Stack do
|
|
34
35
|
expect { subject.use StackSpec::BarMiddleware, false, my_arg: 42 }
|
35
36
|
.to change { subject.size }.by(1)
|
36
37
|
expect(subject.last).to eq(StackSpec::BarMiddleware)
|
37
|
-
expect(subject.last.args).to eq([false
|
38
|
+
expect(subject.last.args).to eq([false])
|
39
|
+
expect(subject.last.opts).to eq(my_arg: 42)
|
38
40
|
end
|
39
41
|
|
40
42
|
it 'pushes a middleware class with block arguments onto the stack' do
|
@@ -633,6 +633,32 @@ describe Grape::Validations::ParamsScope do
|
|
633
633
|
expect(last_response.status).to eq(200)
|
634
634
|
end
|
635
635
|
|
636
|
+
it 'detect unmet nested dependency' do
|
637
|
+
subject.params do
|
638
|
+
requires :a, type: String, allow_blank: false, values: %w[x y z]
|
639
|
+
given a: ->(val) { val == 'z' } do
|
640
|
+
requires :inner3, type: Array, allow_blank: false do
|
641
|
+
requires :bar, type: String, allow_blank: false
|
642
|
+
given bar: ->(val) { val == 'b' } do
|
643
|
+
requires :baz, type: Array do
|
644
|
+
optional :baz_category, type: String
|
645
|
+
end
|
646
|
+
end
|
647
|
+
given bar: ->(val) { val == 'c' } do
|
648
|
+
requires :baz, type: Array do
|
649
|
+
requires :baz_category, type: String
|
650
|
+
end
|
651
|
+
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
end
|
655
|
+
subject.get('/nested-dependency') { declared(params).to_json }
|
656
|
+
|
657
|
+
get '/nested-dependency', a: 'z', inner3: [{ bar: 'c', baz: [{ unrelated: 'nope' }] }]
|
658
|
+
expect(last_response.status).to eq(400)
|
659
|
+
expect(last_response.body).to eq 'inner3[0][baz][0][baz_category] is missing'
|
660
|
+
end
|
661
|
+
|
636
662
|
it 'includes the parameter within #declared(params)' do
|
637
663
|
get '/test', a: true, b: true
|
638
664
|
|
@@ -620,6 +620,30 @@ describe Grape::Validations::CoerceValidator do
|
|
620
620
|
expect(JSON.parse(last_response.body)).to eq(%w[a b c d])
|
621
621
|
end
|
622
622
|
|
623
|
+
it 'parses parameters with Array[Array[String]] type and coerce_with' do
|
624
|
+
subject.params do
|
625
|
+
requires :values, type: Array[Array[String]], coerce_with: ->(val) { val.is_a?(String) ? [val.split(/,/).map(&:strip)] : val }
|
626
|
+
end
|
627
|
+
subject.post '/coerce_nested_strings' do
|
628
|
+
params[:values]
|
629
|
+
end
|
630
|
+
|
631
|
+
post '/coerce_nested_strings', ::Grape::Json.dump(values: 'a,b,c,d'), 'CONTENT_TYPE' => 'application/json'
|
632
|
+
expect(last_response.status).to eq(201)
|
633
|
+
expect(JSON.parse(last_response.body)).to eq([%w[a b c d]])
|
634
|
+
|
635
|
+
post '/coerce_nested_strings', ::Grape::Json.dump(values: [%w[a c], %w[b]]), 'CONTENT_TYPE' => 'application/json'
|
636
|
+
expect(last_response.status).to eq(201)
|
637
|
+
expect(JSON.parse(last_response.body)).to eq([%w[a c], %w[b]])
|
638
|
+
|
639
|
+
post '/coerce_nested_strings', ::Grape::Json.dump(values: [[]]), 'CONTENT_TYPE' => 'application/json'
|
640
|
+
expect(last_response.status).to eq(201)
|
641
|
+
expect(JSON.parse(last_response.body)).to eq([[]])
|
642
|
+
|
643
|
+
post '/coerce_nested_strings', ::Grape::Json.dump(values: [['a', { bar: 0 }], ['b']]), 'CONTENT_TYPE' => 'application/json'
|
644
|
+
expect(last_response.status).to eq(400)
|
645
|
+
end
|
646
|
+
|
623
647
|
it 'parses parameters with Array[Integer] type' do
|
624
648
|
subject.params do
|
625
649
|
requires :values, type: Array[Integer], coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) }
|
@@ -419,4 +419,53 @@ describe Grape::Validations::DefaultValidator do
|
|
419
419
|
end
|
420
420
|
end
|
421
421
|
end
|
422
|
+
|
423
|
+
context 'array with default values and given conditions' do
|
424
|
+
subject do
|
425
|
+
Class.new(Grape::API) do
|
426
|
+
default_format :json
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def app
|
431
|
+
subject
|
432
|
+
end
|
433
|
+
|
434
|
+
it 'applies the default values only if the conditions are met' do
|
435
|
+
subject.params do
|
436
|
+
requires :ary, type: Array do
|
437
|
+
requires :has_value, type: Grape::API::Boolean
|
438
|
+
given has_value: ->(has_value) { has_value } do
|
439
|
+
optional :type, type: String, values: %w[str int], default: 'str'
|
440
|
+
given type: ->(type) { type == 'str' } do
|
441
|
+
optional :str, type: String, default: 'a'
|
442
|
+
end
|
443
|
+
given type: ->(type) { type == 'int' } do
|
444
|
+
optional :int, type: Integer, default: 1
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
subject.post('/nested_given_and_default') { declared(self.params) }
|
450
|
+
|
451
|
+
params = {
|
452
|
+
ary: [
|
453
|
+
{ has_value: false },
|
454
|
+
{ has_value: true, type: 'int', int: 123 },
|
455
|
+
{ has_value: true, type: 'str', str: 'b' }
|
456
|
+
]
|
457
|
+
}
|
458
|
+
expected = {
|
459
|
+
'ary' => [
|
460
|
+
{ 'has_value' => false, 'type' => nil, 'int' => nil, 'str' => nil },
|
461
|
+
{ 'has_value' => true, 'type' => 'int', 'int' => 123, 'str' => nil },
|
462
|
+
{ 'has_value' => true, 'type' => 'str', 'int' => nil, 'str' => 'b' }
|
463
|
+
]
|
464
|
+
}
|
465
|
+
|
466
|
+
post '/nested_given_and_default', params
|
467
|
+
expect(last_response.status).to eq(201)
|
468
|
+
expect(JSON.parse(last_response.body)).to eq(expected)
|
469
|
+
end
|
470
|
+
end
|
422
471
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -20,17 +20,7 @@ eager_load!
|
|
20
20
|
# so it should be set to true here as well to reflect that.
|
21
21
|
I18n.enforce_available_locales = true
|
22
22
|
|
23
|
-
module Chunks
|
24
|
-
def read_chunks(body)
|
25
|
-
buffer = []
|
26
|
-
body.each { |chunk| buffer << chunk }
|
27
|
-
|
28
|
-
buffer
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
23
|
RSpec.configure do |config|
|
33
|
-
config.include Chunks
|
34
24
|
config.include Rack::Test::Methods
|
35
25
|
config.include Spec::Support::Helpers
|
36
26
|
config.raise_errors_for_deprecations!
|
@@ -6,7 +6,7 @@ module Spec
|
|
6
6
|
module Helpers
|
7
7
|
# Returns the path with options[:version] prefixed if options[:using] is :path.
|
8
8
|
# Returns normal path otherwise.
|
9
|
-
def versioned_path(options
|
9
|
+
def versioned_path(**options)
|
10
10
|
case options[:using]
|
11
11
|
when :path
|
12
12
|
File.join('/', options[:prefix] || '', options[:version], options[:path])
|
@@ -43,13 +43,11 @@ module Spec
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
def versioned_get(path, version_name, version_options
|
46
|
+
def versioned_get(path, version_name, **version_options)
|
47
47
|
path = versioned_path(version_options.merge(version: version_name, path: path))
|
48
48
|
headers = versioned_headers(**version_options.merge(version: version_name))
|
49
49
|
params = {}
|
50
|
-
if version_options[:using] == :param
|
51
|
-
params = { version_options[:parameter] => version_name }
|
52
|
-
end
|
50
|
+
params = { version_options[:parameter] => version_name } if version_options[:using] == :param
|
53
51
|
get path, params, headers
|
54
52
|
end
|
55
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -282,6 +282,7 @@ files:
|
|
282
282
|
- spec/grape/dsl/routing_spec.rb
|
283
283
|
- spec/grape/dsl/settings_spec.rb
|
284
284
|
- spec/grape/dsl/validations_spec.rb
|
285
|
+
- spec/grape/endpoint/declared_spec.rb
|
285
286
|
- spec/grape/endpoint_spec.rb
|
286
287
|
- spec/grape/entity_spec.rb
|
287
288
|
- spec/grape/exceptions/base_spec.rb
|
@@ -356,6 +357,7 @@ files:
|
|
356
357
|
- spec/shared/versioning_examples.rb
|
357
358
|
- spec/spec_helper.rb
|
358
359
|
- spec/support/basic_auth_encode_helpers.rb
|
360
|
+
- spec/support/chunks.rb
|
359
361
|
- spec/support/content_type_helpers.rb
|
360
362
|
- spec/support/eager_load.rb
|
361
363
|
- spec/support/endpoint_faker.rb
|
@@ -367,9 +369,9 @@ licenses:
|
|
367
369
|
- MIT
|
368
370
|
metadata:
|
369
371
|
bug_tracker_uri: https://github.com/ruby-grape/grape/issues
|
370
|
-
changelog_uri: https://github.com/ruby-grape/grape/blob/v1.
|
371
|
-
documentation_uri: https://www.rubydoc.info/gems/grape/1.
|
372
|
-
source_code_uri: https://github.com/ruby-grape/grape/tree/v1.
|
372
|
+
changelog_uri: https://github.com/ruby-grape/grape/blob/v1.5.0/CHANGELOG.md
|
373
|
+
documentation_uri: https://www.rubydoc.info/gems/grape/1.5.0
|
374
|
+
source_code_uri: https://github.com/ruby-grape/grape/tree/v1.5.0
|
373
375
|
post_install_message:
|
374
376
|
rdoc_options: []
|
375
377
|
require_paths:
|
@@ -397,6 +399,7 @@ test_files:
|
|
397
399
|
- spec/shared/versioning_examples.rb
|
398
400
|
- spec/support/basic_auth_encode_helpers.rb
|
399
401
|
- spec/support/endpoint_faker.rb
|
402
|
+
- spec/support/chunks.rb
|
400
403
|
- spec/support/file_streamer.rb
|
401
404
|
- spec/support/versioned_helpers.rb
|
402
405
|
- spec/support/content_type_helpers.rb
|
@@ -470,6 +473,7 @@ test_files:
|
|
470
473
|
- spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb
|
471
474
|
- spec/grape/parser_spec.rb
|
472
475
|
- spec/grape/request_spec.rb
|
476
|
+
- spec/grape/endpoint/declared_spec.rb
|
473
477
|
- spec/grape/api/parameters_modification_spec.rb
|
474
478
|
- spec/grape/api/patch_method_helpers_spec.rb
|
475
479
|
- spec/grape/api/required_parameters_with_invalid_method_spec.rb
|