grape 1.5.2 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/CONTRIBUTING.md +2 -1
- data/README.md +152 -21
- data/UPGRADING.md +86 -2
- data/grape.gemspec +5 -5
- data/lib/grape/api/instance.rb +14 -18
- data/lib/grape/api.rb +18 -13
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dry_types.rb +12 -0
- data/lib/grape/dsl/api.rb +0 -2
- data/lib/grape/dsl/callbacks.rb +0 -2
- data/lib/grape/dsl/configuration.rb +0 -2
- data/lib/grape/dsl/desc.rb +2 -19
- data/lib/grape/dsl/headers.rb +5 -2
- data/lib/grape/dsl/helpers.rb +7 -7
- data/lib/grape/dsl/inside_route.rb +43 -30
- data/lib/grape/dsl/middleware.rb +4 -6
- data/lib/grape/dsl/parameters.rb +8 -10
- data/lib/grape/dsl/request_response.rb +9 -8
- data/lib/grape/dsl/routing.rb +6 -4
- data/lib/grape/dsl/settings.rb +5 -7
- data/lib/grape/dsl/validations.rb +0 -15
- data/lib/grape/endpoint.rb +21 -36
- data/lib/grape/error_formatter/json.rb +9 -7
- data/lib/grape/error_formatter/xml.rb +2 -6
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/empty_message_body.rb +11 -0
- data/lib/grape/exceptions/missing_group_type.rb +8 -1
- data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
- data/lib/grape/exceptions/validation.rb +1 -6
- data/lib/grape/formatter/json.rb +1 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -1
- data/lib/grape/formatter/xml.rb +1 -0
- data/lib/grape/locale/en.yml +9 -8
- data/lib/grape/middleware/auth/dsl.rb +7 -2
- data/lib/grape/middleware/base.rb +3 -1
- data/lib/grape/middleware/error.rb +2 -2
- data/lib/grape/middleware/formatter.rb +4 -4
- data/lib/grape/middleware/stack.rb +2 -2
- data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
- data/lib/grape/middleware/versioner/header.rb +6 -4
- data/lib/grape/middleware/versioner/param.rb +1 -0
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
- data/lib/grape/middleware/versioner/path.rb +2 -0
- data/lib/grape/parser/json.rb +1 -1
- data/lib/grape/parser/xml.rb +1 -1
- data/lib/grape/path.rb +1 -0
- data/lib/grape/request.rb +5 -0
- data/lib/grape/router/pattern.rb +1 -1
- data/lib/grape/router/route.rb +2 -2
- data/lib/grape/router.rb +6 -0
- data/lib/grape/util/inheritable_setting.rb +1 -3
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/lazy_value.rb +3 -2
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/attributes_doc.rb +58 -0
- data/lib/grape/validations/params_scope.rb +137 -78
- data/lib/grape/validations/types/array_coercer.rb +0 -2
- data/lib/grape/validations/types/custom_type_coercer.rb +1 -2
- data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
- data/lib/grape/validations/types/json.rb +2 -1
- data/lib/grape/validations/types/primitive_coercer.rb +16 -8
- data/lib/grape/validations/types/set_coercer.rb +0 -2
- data/lib/grape/validations/types.rb +98 -30
- data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
- data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
- data/lib/grape/validations/validators/as_validator.rb +14 -0
- data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
- data/lib/grape/validations/validators/base.rb +82 -70
- data/lib/grape/validations/validators/coerce_validator.rb +75 -0
- data/lib/grape/validations/validators/default_validator.rb +51 -0
- data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
- data/lib/grape/validations/validators/except_values_validator.rb +24 -0
- data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
- data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
- data/lib/grape/validations/validators/presence_validator.rb +15 -0
- data/lib/grape/validations/validators/regexp_validator.rb +16 -0
- data/lib/grape/validations/validators/same_as_validator.rb +29 -0
- data/lib/grape/validations/validators/values_validator.rb +88 -0
- data/lib/grape/validations.rb +16 -6
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +70 -29
- data/spec/grape/api/custom_validations_spec.rb +116 -45
- data/spec/grape/api/deeply_included_options_spec.rb +3 -5
- data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
- data/spec/grape/api/documentation_spec.rb +59 -0
- data/spec/grape/api/inherited_helpers_spec.rb +0 -2
- data/spec/grape/api/instance_spec.rb +0 -1
- data/spec/grape/api/invalid_format_spec.rb +2 -2
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/nested_helpers_spec.rb +0 -2
- data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/parameters_modification_spec.rb +0 -2
- data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
- data/spec/grape/api/recognize_path_spec.rb +1 -3
- data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
- data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
- data/spec/grape/api/shared_helpers_spec.rb +0 -2
- data/spec/grape/api_remount_spec.rb +16 -16
- data/spec/grape/api_spec.rb +527 -224
- data/spec/grape/config_spec.rb +0 -2
- data/spec/grape/dsl/callbacks_spec.rb +2 -3
- data/spec/grape/dsl/configuration_spec.rb +0 -2
- data/spec/grape/dsl/desc_spec.rb +0 -2
- data/spec/grape/dsl/headers_spec.rb +39 -11
- data/spec/grape/dsl/helpers_spec.rb +3 -4
- data/spec/grape/dsl/inside_route_spec.rb +16 -16
- data/spec/grape/dsl/logger_spec.rb +15 -19
- data/spec/grape/dsl/middleware_spec.rb +2 -3
- data/spec/grape/dsl/parameters_spec.rb +2 -2
- data/spec/grape/dsl/request_response_spec.rb +7 -8
- data/spec/grape/dsl/routing_spec.rb +11 -10
- data/spec/grape/dsl/settings_spec.rb +0 -2
- data/spec/grape/dsl/validations_spec.rb +0 -17
- data/spec/grape/endpoint/declared_spec.rb +261 -16
- data/spec/grape/endpoint_spec.rb +98 -57
- data/spec/grape/entity_spec.rb +22 -23
- data/spec/grape/exceptions/base_spec.rb +16 -2
- data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -24
- data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
- data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
- data/spec/grape/exceptions/missing_option_spec.rb +1 -3
- data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
- data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
- data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
- data/spec/grape/exceptions/validation_spec.rb +5 -5
- data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
- data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
- data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
- data/spec/grape/integration/rack_spec.rb +0 -2
- data/spec/grape/loading_spec.rb +8 -10
- data/spec/grape/middleware/auth/base_spec.rb +0 -1
- data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
- data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
- data/spec/grape/middleware/base_spec.rb +24 -17
- data/spec/grape/middleware/error_spec.rb +8 -3
- data/spec/grape/middleware/exception_spec.rb +111 -163
- data/spec/grape/middleware/formatter_spec.rb +27 -8
- data/spec/grape/middleware/globals_spec.rb +7 -6
- data/spec/grape/middleware/stack_spec.rb +14 -14
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
- data/spec/grape/middleware/versioner/header_spec.rb +30 -15
- data/spec/grape/middleware/versioner/param_spec.rb +7 -3
- data/spec/grape/middleware/versioner/path_spec.rb +5 -3
- data/spec/grape/middleware/versioner_spec.rb +1 -3
- data/spec/grape/named_api_spec.rb +0 -2
- data/spec/grape/parser_spec.rb +4 -2
- data/spec/grape/path_spec.rb +52 -54
- data/spec/grape/presenters/presenter_spec.rb +7 -8
- data/spec/grape/request_spec.rb +6 -6
- data/spec/grape/util/inheritable_setting_spec.rb +7 -8
- data/spec/grape/util/inheritable_values_spec.rb +3 -3
- data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
- data/spec/grape/util/stackable_values_spec.rb +7 -6
- data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
- data/spec/grape/validations/attributes_doc_spec.rb +153 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +0 -2
- data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
- data/spec/grape/validations/params_scope_spec.rb +361 -96
- data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
- data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
- data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
- data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
- data/spec/grape/validations/types_spec.rb +36 -10
- data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
- data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
- data/spec/grape/validations/validators/coerce_spec.rb +99 -24
- data/spec/grape/validations/validators/default_spec.rb +72 -80
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
- data/spec/grape/validations/validators/except_values_spec.rb +3 -5
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
- data/spec/grape/validations/validators/presence_spec.rb +16 -3
- data/spec/grape/validations/validators/regexp_spec.rb +25 -33
- data/spec/grape/validations/validators/same_as_spec.rb +14 -22
- data/spec/grape/validations/validators/values_spec.rb +182 -179
- data/spec/grape/validations_spec.rb +149 -80
- data/spec/integration/eager_load/eager_load_spec.rb +2 -2
- data/spec/integration/multi_json/json_spec.rb +1 -3
- data/spec/integration/multi_xml/xml_spec.rb +1 -3
- data/spec/shared/versioning_examples.rb +12 -9
- data/spec/spec_helper.rb +21 -6
- data/spec/support/basic_auth_encode_helpers.rb +1 -1
- metadata +125 -115
- data/lib/grape/validations/validators/all_or_none.rb +0 -15
- data/lib/grape/validations/validators/allow_blank.rb +0 -18
- data/lib/grape/validations/validators/as.rb +0 -16
- data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
- data/lib/grape/validations/validators/coerce.rb +0 -91
- data/lib/grape/validations/validators/default.rb +0 -48
- data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
- data/lib/grape/validations/validators/except_values.rb +0 -22
- data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
- data/lib/grape/validations/validators/presence.rb +0 -12
- data/lib/grape/validations/validators/regexp.rb +0 -13
- data/lib/grape/validations/validators/same_as.rb +0 -26
- data/lib/grape/validations/validators/values.rb +0 -83
- data/spec/support/eager_load.rb +0 -19
@@ -1,74 +1,66 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
module ValidationsSpec
|
10
|
-
module AtLeastOneOfValidatorSpec
|
11
|
-
class API < Grape::API
|
12
|
-
rescue_from Grape::Exceptions::ValidationErrors do |e|
|
13
|
-
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
|
14
|
-
end
|
3
|
+
describe Grape::Validations::Validators::AtLeastOneOfValidator do
|
4
|
+
let_it_be(:app) do
|
5
|
+
Class.new(Grape::API) do
|
6
|
+
rescue_from Grape::Exceptions::ValidationErrors do |e|
|
7
|
+
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
|
8
|
+
end
|
15
9
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
10
|
+
params do
|
11
|
+
optional :beer, :wine, :grapefruit
|
12
|
+
at_least_one_of :beer, :wine, :grapefruit
|
13
|
+
end
|
14
|
+
post do
|
15
|
+
end
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
17
|
+
params do
|
18
|
+
optional :beer, :wine, :grapefruit, :other
|
19
|
+
at_least_one_of :beer, :wine, :grapefruit
|
20
|
+
end
|
21
|
+
post 'mixed-params' do
|
22
|
+
end
|
29
23
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
params do
|
25
|
+
optional :beer, :wine, :grapefruit
|
26
|
+
at_least_one_of :beer, :wine, :grapefruit, message: 'you should choose something'
|
27
|
+
end
|
28
|
+
post '/custom-message' do
|
29
|
+
end
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
31
|
+
params do
|
32
|
+
requires :item, type: Hash do
|
33
|
+
optional :beer, :wine, :grapefruit
|
34
|
+
at_least_one_of :beer, :wine, :grapefruit, message: 'fail'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
post '/nested-hash' do
|
38
|
+
end
|
45
39
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
params do
|
41
|
+
requires :items, type: Array do
|
42
|
+
optional :beer, :wine, :grapefruit
|
43
|
+
at_least_one_of :beer, :wine, :grapefruit, message: 'fail'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
post '/nested-array' do
|
47
|
+
end
|
54
48
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
post '/deeply-nested-array' do
|
49
|
+
params do
|
50
|
+
requires :items, type: Array do
|
51
|
+
requires :nested_items, type: Array do
|
52
|
+
optional :beer, :wine, :grapefruit
|
53
|
+
at_least_one_of :beer, :wine, :grapefruit, message: 'fail'
|
64
54
|
end
|
65
55
|
end
|
66
56
|
end
|
57
|
+
post '/deeply-nested-array' do
|
58
|
+
end
|
67
59
|
end
|
60
|
+
end
|
68
61
|
|
69
|
-
|
70
|
-
|
71
|
-
end
|
62
|
+
describe '#validate!' do
|
63
|
+
subject(:validate) { post path, params }
|
72
64
|
|
73
65
|
context 'when all restricted params are present' do
|
74
66
|
let(:path) { '/' }
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
describe Grape::Validations::CoerceValidator do
|
3
|
+
describe Grape::Validations::Validators::CoerceValidator do
|
6
4
|
subject do
|
7
5
|
Class.new(Grape::API)
|
8
6
|
end
|
@@ -23,7 +21,7 @@ describe Grape::Validations::CoerceValidator do
|
|
23
21
|
end
|
24
22
|
|
25
23
|
context 'i18n' do
|
26
|
-
after
|
24
|
+
after do
|
27
25
|
I18n.available_locales = %i[en]
|
28
26
|
I18n.locale = :en
|
29
27
|
I18n.default_locale = :en
|
@@ -31,9 +29,9 @@ describe Grape::Validations::CoerceValidator do
|
|
31
29
|
|
32
30
|
it 'i18n error on malformed input' do
|
33
31
|
I18n.available_locales = %i[en zh-CN]
|
34
|
-
I18n.load_path << File.expand_path('
|
32
|
+
I18n.load_path << File.expand_path('zh-CN.yml', __dir__)
|
35
33
|
I18n.reload!
|
36
|
-
I18n.locale = 'zh-CN'
|
34
|
+
I18n.locale = :'zh-CN'
|
37
35
|
subject.params do
|
38
36
|
requires :age, type: Integer
|
39
37
|
end
|
@@ -48,7 +46,7 @@ describe Grape::Validations::CoerceValidator do
|
|
48
46
|
|
49
47
|
it 'gives an english fallback error when default locale message is blank' do
|
50
48
|
I18n.available_locales = %i[en pt-BR]
|
51
|
-
I18n.locale = 'pt-BR'
|
49
|
+
I18n.locale = :'pt-BR'
|
52
50
|
subject.params do
|
53
51
|
requires :age, type: Integer
|
54
52
|
end
|
@@ -83,10 +81,11 @@ describe Grape::Validations::CoerceValidator do
|
|
83
81
|
context 'on custom coercion rules' do
|
84
82
|
before do
|
85
83
|
subject.params do
|
86
|
-
requires :a, types: { value: [Boolean, String], message: 'type cast is invalid' }, coerce_with: (lambda do |val|
|
87
|
-
|
84
|
+
requires :a, types: { value: [Grape::API::Boolean, String], message: 'type cast is invalid' }, coerce_with: (lambda do |val|
|
85
|
+
case val
|
86
|
+
when 'yup'
|
88
87
|
true
|
89
|
-
|
88
|
+
when 'false'
|
90
89
|
0
|
91
90
|
else
|
92
91
|
val
|
@@ -170,9 +169,9 @@ describe Grape::Validations::CoerceValidator do
|
|
170
169
|
expect(last_response.body).to eq('BigDecimal 45.1')
|
171
170
|
end
|
172
171
|
|
173
|
-
it 'Boolean' do
|
172
|
+
it 'Grape::API::Boolean' do
|
174
173
|
subject.params do
|
175
|
-
requires :boolean, type: Boolean
|
174
|
+
requires :boolean, type: Grape::API::Boolean
|
176
175
|
end
|
177
176
|
subject.post '/boolean' do
|
178
177
|
params[:boolean]
|
@@ -369,9 +368,9 @@ describe Grape::Validations::CoerceValidator do
|
|
369
368
|
end
|
370
369
|
end
|
371
370
|
|
372
|
-
it 'Boolean' do
|
371
|
+
it 'Grape::API::Boolean' do
|
373
372
|
subject.params do
|
374
|
-
requires :boolean, type: Boolean
|
373
|
+
requires :boolean, type: Grape::API::Boolean
|
375
374
|
end
|
376
375
|
subject.get '/boolean' do
|
377
376
|
params[:boolean].class
|
@@ -650,7 +649,7 @@ describe Grape::Validations::CoerceValidator do
|
|
650
649
|
|
651
650
|
it 'parses parameters with Array[Array[String]] type and coerce_with' do
|
652
651
|
subject.params do
|
653
|
-
requires :values, type: Array[Array[String]], coerce_with: ->(val) { val.is_a?(String) ? [val.split(
|
652
|
+
requires :values, type: Array[Array[String]], coerce_with: ->(val) { val.is_a?(String) ? [val.split(',').map(&:strip)] : val }
|
654
653
|
end
|
655
654
|
subject.post '/coerce_nested_strings' do
|
656
655
|
params[:values]
|
@@ -706,6 +705,44 @@ describe Grape::Validations::CoerceValidator do
|
|
706
705
|
expect(JSON.parse(last_response.body)).to eq([1, 1, 1, 1])
|
707
706
|
end
|
708
707
|
|
708
|
+
context 'Array type and coerce_with should' do
|
709
|
+
before do
|
710
|
+
subject.params do
|
711
|
+
optional :arr, type: Array, coerce_with: (lambda do |val|
|
712
|
+
if val.nil?
|
713
|
+
[]
|
714
|
+
else
|
715
|
+
val
|
716
|
+
end
|
717
|
+
end)
|
718
|
+
end
|
719
|
+
subject.get '/' do
|
720
|
+
params[:arr].class.to_s
|
721
|
+
end
|
722
|
+
end
|
723
|
+
|
724
|
+
it 'coerce nil value to array' do
|
725
|
+
get '/', arr: nil
|
726
|
+
|
727
|
+
expect(last_response.status).to eq(200)
|
728
|
+
expect(last_response.body).to eq('Array')
|
729
|
+
end
|
730
|
+
|
731
|
+
it 'not coerce missing field' do
|
732
|
+
get '/'
|
733
|
+
|
734
|
+
expect(last_response.status).to eq(200)
|
735
|
+
expect(last_response.body).to eq('NilClass')
|
736
|
+
end
|
737
|
+
|
738
|
+
it 'coerce array as array' do
|
739
|
+
get '/', arr: []
|
740
|
+
|
741
|
+
expect(last_response.status).to eq(200)
|
742
|
+
expect(last_response.body).to eq('Array')
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
709
746
|
it 'uses parse where available' do
|
710
747
|
subject.params do
|
711
748
|
requires :ints, type: Array, coerce_with: JSON do
|
@@ -754,13 +791,52 @@ describe Grape::Validations::CoerceValidator do
|
|
754
791
|
expect(last_response.body).to eq('3')
|
755
792
|
end
|
756
793
|
|
794
|
+
context 'Integer type and coerce_with should' do
|
795
|
+
before do
|
796
|
+
subject.params do
|
797
|
+
optional :int, type: Integer, coerce_with: (lambda do |val|
|
798
|
+
if val.nil?
|
799
|
+
0
|
800
|
+
else
|
801
|
+
val.to_i
|
802
|
+
end
|
803
|
+
end)
|
804
|
+
end
|
805
|
+
subject.get '/' do
|
806
|
+
params[:int].class.to_s
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
it 'coerce nil value to integer' do
|
811
|
+
get '/', int: nil
|
812
|
+
|
813
|
+
expect(last_response.status).to eq(200)
|
814
|
+
expect(last_response.body).to eq('Integer')
|
815
|
+
end
|
816
|
+
|
817
|
+
it 'not coerce missing field' do
|
818
|
+
get '/'
|
819
|
+
|
820
|
+
expect(last_response.status).to eq(200)
|
821
|
+
expect(last_response.body).to eq('NilClass')
|
822
|
+
end
|
823
|
+
|
824
|
+
it 'coerce integer as integer' do
|
825
|
+
get '/', int: 1
|
826
|
+
|
827
|
+
expect(last_response.status).to eq(200)
|
828
|
+
expect(last_response.body).to eq('Integer')
|
829
|
+
end
|
830
|
+
end
|
831
|
+
|
757
832
|
context 'Integer type and coerce_with potentially returning nil' do
|
758
833
|
before do
|
759
834
|
subject.params do
|
760
835
|
requires :int, type: Integer, coerce_with: (lambda do |val|
|
761
|
-
|
836
|
+
case val
|
837
|
+
when '0'
|
762
838
|
nil
|
763
|
-
|
839
|
+
when /^-?\d+$/
|
764
840
|
val.to_i
|
765
841
|
else
|
766
842
|
val
|
@@ -940,11 +1016,9 @@ describe Grape::Validations::CoerceValidator do
|
|
940
1016
|
end
|
941
1017
|
|
942
1018
|
context 'multiple types' do
|
943
|
-
Boolean = Grape::API::Boolean
|
944
|
-
|
945
1019
|
it 'coerces to first possible type' do
|
946
1020
|
subject.params do
|
947
|
-
requires :a, types: [Boolean, Integer, String]
|
1021
|
+
requires :a, types: [Grape::API::Boolean, Integer, String]
|
948
1022
|
end
|
949
1023
|
subject.get '/' do
|
950
1024
|
params[:a].class.to_s
|
@@ -965,7 +1039,7 @@ describe Grape::Validations::CoerceValidator do
|
|
965
1039
|
|
966
1040
|
it 'fails when no coercion is possible' do
|
967
1041
|
subject.params do
|
968
|
-
requires :a, types: [Boolean, Integer]
|
1042
|
+
requires :a, types: [Grape::API::Boolean, Integer]
|
969
1043
|
end
|
970
1044
|
subject.get '/' do
|
971
1045
|
params[:a].class.to_s
|
@@ -1124,10 +1198,11 @@ describe Grape::Validations::CoerceValidator do
|
|
1124
1198
|
context 'custom coercion rules' do
|
1125
1199
|
before do
|
1126
1200
|
subject.params do
|
1127
|
-
requires :a, types: [Boolean, String], coerce_with: (lambda do |val|
|
1128
|
-
|
1201
|
+
requires :a, types: [Grape::API::Boolean, String], coerce_with: (lambda do |val|
|
1202
|
+
case val
|
1203
|
+
when 'yup'
|
1129
1204
|
true
|
1130
|
-
|
1205
|
+
when 'false'
|
1131
1206
|
0
|
1132
1207
|
else
|
1133
1208
|
val
|
@@ -1,105 +1,97 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
get '/' do
|
16
|
-
{ id: params[:id], type: params[:type] }
|
17
|
-
end
|
3
|
+
describe Grape::Validations::Validators::DefaultValidator do
|
4
|
+
let_it_be(:app) do
|
5
|
+
Class.new(Grape::API) do
|
6
|
+
default_format :json
|
7
|
+
|
8
|
+
params do
|
9
|
+
optional :id
|
10
|
+
optional :type, default: 'default-type'
|
11
|
+
end
|
12
|
+
get '/' do
|
13
|
+
{ id: params[:id], type: params[:type] }
|
14
|
+
end
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
params do
|
17
|
+
optional :type1, default: 'default-type1'
|
18
|
+
optional :type2, default: 'default-type2'
|
19
|
+
end
|
20
|
+
get '/user' do
|
21
|
+
{ type1: params[:type1], type2: params[:type2] }
|
22
|
+
end
|
26
23
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
params do
|
25
|
+
requires :id
|
26
|
+
optional :type1, default: 'default-type1'
|
27
|
+
optional :type2, default: 'default-type2'
|
28
|
+
end
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
get '/message' do
|
31
|
+
{ id: params[:id], type1: params[:type1], type2: params[:type2] }
|
32
|
+
end
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
params do
|
35
|
+
optional :random, default: -> { Random.rand }
|
36
|
+
optional :not_random, default: Random.rand
|
37
|
+
end
|
38
|
+
get '/numbers' do
|
39
|
+
{ random_number: params[:random], non_random_number: params[:non_random_number] }
|
40
|
+
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
51
|
-
get '/array' do
|
52
|
-
{ array: params[:array] }
|
42
|
+
params do
|
43
|
+
optional :array, type: Array do
|
44
|
+
requires :name
|
45
|
+
optional :with_default, default: 'default'
|
53
46
|
end
|
47
|
+
end
|
48
|
+
get '/array' do
|
49
|
+
{ array: params[:array] }
|
50
|
+
end
|
54
51
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
62
|
-
get '/optional_array' do
|
63
|
-
{ thing1: params[:thing1] }
|
52
|
+
params do
|
53
|
+
requires :thing1
|
54
|
+
optional :more_things, type: Array do
|
55
|
+
requires :nested_thing
|
56
|
+
requires :other_thing, default: 1
|
64
57
|
end
|
58
|
+
end
|
59
|
+
get '/optional_array' do
|
60
|
+
{ thing1: params[:thing1] }
|
61
|
+
end
|
65
62
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
63
|
+
params do
|
64
|
+
requires :root, type: Hash do
|
65
|
+
optional :some_things, type: Array do
|
66
|
+
requires :foo
|
67
|
+
optional :options, type: Array do
|
68
|
+
requires :name, type: String
|
69
|
+
requires :value, type: String
|
74
70
|
end
|
75
71
|
end
|
76
72
|
end
|
77
|
-
|
78
|
-
|
79
|
-
|
73
|
+
end
|
74
|
+
get '/nested_optional_array' do
|
75
|
+
{ root: params[:root] }
|
76
|
+
end
|
80
77
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
78
|
+
params do
|
79
|
+
requires :root, type: Hash do
|
80
|
+
optional :some_things, type: Array do
|
81
|
+
requires :foo
|
82
|
+
optional :options, type: Array do
|
83
|
+
optional :name, type: String
|
84
|
+
optional :value, type: String
|
89
85
|
end
|
90
86
|
end
|
91
87
|
end
|
92
|
-
|
93
|
-
|
94
|
-
|
88
|
+
end
|
89
|
+
get '/another_nested_optional_array' do
|
90
|
+
{ root: params[:root] }
|
95
91
|
end
|
96
92
|
end
|
97
93
|
end
|
98
94
|
|
99
|
-
def app
|
100
|
-
ValidationsSpec::DefaultValidatorSpec::API
|
101
|
-
end
|
102
|
-
|
103
95
|
it 'lets you leave required values nested inside an optional blank' do
|
104
96
|
get '/optional_array', thing1: 'stuff'
|
105
97
|
expect(last_response.status).to eq(200)
|