grape 1.5.3 → 1.7.1

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.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +92 -0
  3. data/CONTRIBUTING.md +32 -1
  4. data/README.md +176 -25
  5. data/UPGRADING.md +61 -4
  6. data/grape.gemspec +6 -6
  7. data/lib/grape/api/instance.rb +14 -18
  8. data/lib/grape/api.rb +17 -12
  9. data/lib/grape/cookies.rb +2 -0
  10. data/lib/grape/dry_types.rb +12 -0
  11. data/lib/grape/dsl/api.rb +0 -2
  12. data/lib/grape/dsl/callbacks.rb +0 -2
  13. data/lib/grape/dsl/configuration.rb +0 -2
  14. data/lib/grape/dsl/desc.rb +4 -20
  15. data/lib/grape/dsl/headers.rb +5 -2
  16. data/lib/grape/dsl/helpers.rb +7 -7
  17. data/lib/grape/dsl/inside_route.rb +43 -30
  18. data/lib/grape/dsl/middleware.rb +4 -6
  19. data/lib/grape/dsl/parameters.rb +13 -10
  20. data/lib/grape/dsl/request_response.rb +9 -8
  21. data/lib/grape/dsl/routing.rb +6 -4
  22. data/lib/grape/dsl/settings.rb +5 -7
  23. data/lib/grape/dsl/validations.rb +0 -15
  24. data/lib/grape/endpoint.rb +22 -37
  25. data/lib/grape/error_formatter/json.rb +9 -7
  26. data/lib/grape/error_formatter/xml.rb +2 -6
  27. data/lib/grape/exceptions/base.rb +3 -2
  28. data/lib/grape/exceptions/missing_group_type.rb +8 -1
  29. data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
  30. data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
  31. data/lib/grape/exceptions/validation.rb +1 -6
  32. data/lib/grape/formatter/json.rb +1 -0
  33. data/lib/grape/formatter/serializable_hash.rb +2 -1
  34. data/lib/grape/formatter/xml.rb +1 -0
  35. data/lib/grape/locale/en.yml +9 -8
  36. data/lib/grape/middleware/auth/dsl.rb +7 -2
  37. data/lib/grape/middleware/base.rb +3 -1
  38. data/lib/grape/middleware/error.rb +2 -2
  39. data/lib/grape/middleware/formatter.rb +4 -4
  40. data/lib/grape/middleware/stack.rb +3 -3
  41. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  42. data/lib/grape/middleware/versioner/header.rb +6 -4
  43. data/lib/grape/middleware/versioner/param.rb +1 -0
  44. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  45. data/lib/grape/middleware/versioner/path.rb +2 -0
  46. data/lib/grape/path.rb +1 -0
  47. data/lib/grape/request.rb +4 -1
  48. data/lib/grape/router/attribute_translator.rb +1 -1
  49. data/lib/grape/router/pattern.rb +1 -1
  50. data/lib/grape/router/route.rb +2 -2
  51. data/lib/grape/router.rb +6 -0
  52. data/lib/grape/types/invalid_value.rb +8 -0
  53. data/lib/grape/util/cache.rb +1 -1
  54. data/lib/grape/util/inheritable_setting.rb +1 -3
  55. data/lib/grape/util/json.rb +2 -0
  56. data/lib/grape/util/lazy_value.rb +3 -2
  57. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  58. data/lib/grape/validations/attributes_doc.rb +58 -0
  59. data/lib/grape/validations/params_scope.rb +138 -79
  60. data/lib/grape/validations/types/array_coercer.rb +0 -2
  61. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  62. data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
  63. data/lib/grape/validations/types/invalid_value.rb +0 -7
  64. data/lib/grape/validations/types/json.rb +2 -1
  65. data/lib/grape/validations/types/primitive_coercer.rb +16 -8
  66. data/lib/grape/validations/types/set_coercer.rb +0 -2
  67. data/lib/grape/validations/types.rb +98 -30
  68. data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
  69. data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
  70. data/lib/grape/validations/validators/as_validator.rb +14 -0
  71. data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
  72. data/lib/grape/validations/validators/base.rb +82 -70
  73. data/lib/grape/validations/validators/coerce_validator.rb +75 -0
  74. data/lib/grape/validations/validators/default_validator.rb +51 -0
  75. data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
  76. data/lib/grape/validations/validators/except_values_validator.rb +24 -0
  77. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  78. data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
  79. data/lib/grape/validations/validators/presence_validator.rb +15 -0
  80. data/lib/grape/validations/validators/regexp_validator.rb +16 -0
  81. data/lib/grape/validations/validators/same_as_validator.rb +29 -0
  82. data/lib/grape/validations/validators/values_validator.rb +88 -0
  83. data/lib/grape/validations.rb +16 -6
  84. data/lib/grape/version.rb +1 -1
  85. data/lib/grape.rb +77 -29
  86. data/spec/grape/api/custom_validations_spec.rb +116 -45
  87. data/spec/grape/api/deeply_included_options_spec.rb +3 -5
  88. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
  89. data/spec/grape/api/documentation_spec.rb +59 -0
  90. data/spec/grape/api/inherited_helpers_spec.rb +0 -2
  91. data/spec/grape/api/instance_spec.rb +0 -1
  92. data/spec/grape/api/invalid_format_spec.rb +2 -2
  93. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
  94. data/spec/grape/api/nested_helpers_spec.rb +0 -2
  95. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
  96. data/spec/grape/api/parameters_modification_spec.rb +0 -2
  97. data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
  98. data/spec/grape/api/recognize_path_spec.rb +1 -3
  99. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
  100. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
  101. data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
  102. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
  103. data/spec/grape/api/shared_helpers_spec.rb +0 -2
  104. data/spec/grape/api_remount_spec.rb +16 -16
  105. data/spec/grape/api_spec.rb +462 -251
  106. data/spec/grape/config_spec.rb +0 -2
  107. data/spec/grape/dsl/callbacks_spec.rb +2 -3
  108. data/spec/grape/dsl/desc_spec.rb +2 -2
  109. data/spec/grape/dsl/headers_spec.rb +39 -11
  110. data/spec/grape/dsl/helpers_spec.rb +3 -4
  111. data/spec/grape/dsl/inside_route_spec.rb +16 -16
  112. data/spec/grape/dsl/logger_spec.rb +15 -19
  113. data/spec/grape/dsl/middleware_spec.rb +2 -3
  114. data/spec/grape/dsl/parameters_spec.rb +2 -2
  115. data/spec/grape/dsl/request_response_spec.rb +7 -8
  116. data/spec/grape/dsl/routing_spec.rb +11 -10
  117. data/spec/grape/dsl/settings_spec.rb +0 -2
  118. data/spec/grape/dsl/validations_spec.rb +0 -17
  119. data/spec/grape/endpoint/declared_spec.rb +261 -16
  120. data/spec/grape/endpoint_spec.rb +88 -59
  121. data/spec/grape/entity_spec.rb +22 -23
  122. data/spec/grape/exceptions/base_spec.rb +16 -2
  123. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
  124. data/spec/grape/exceptions/invalid_accept_header_spec.rb +64 -24
  125. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
  126. data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
  127. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
  128. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  129. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
  130. data/spec/grape/exceptions/missing_option_spec.rb +1 -3
  131. data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
  132. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
  133. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  134. data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
  135. data/spec/grape/exceptions/validation_spec.rb +5 -5
  136. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
  137. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
  138. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
  139. data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
  140. data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
  141. data/spec/grape/integration/rack_spec.rb +6 -7
  142. data/spec/grape/loading_spec.rb +8 -10
  143. data/spec/grape/middleware/auth/base_spec.rb +0 -1
  144. data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
  145. data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
  146. data/spec/grape/middleware/base_spec.rb +28 -19
  147. data/spec/grape/middleware/error_spec.rb +8 -3
  148. data/spec/grape/middleware/exception_spec.rb +111 -163
  149. data/spec/grape/middleware/formatter_spec.rb +33 -14
  150. data/spec/grape/middleware/globals_spec.rb +7 -6
  151. data/spec/grape/middleware/stack_spec.rb +14 -14
  152. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
  153. data/spec/grape/middleware/versioner/header_spec.rb +30 -15
  154. data/spec/grape/middleware/versioner/param_spec.rb +7 -3
  155. data/spec/grape/middleware/versioner/path_spec.rb +5 -3
  156. data/spec/grape/middleware/versioner_spec.rb +1 -3
  157. data/spec/grape/named_api_spec.rb +0 -2
  158. data/spec/grape/parser_spec.rb +4 -2
  159. data/spec/grape/path_spec.rb +52 -54
  160. data/spec/grape/presenters/presenter_spec.rb +7 -8
  161. data/spec/grape/request_spec.rb +6 -6
  162. data/spec/grape/util/inheritable_setting_spec.rb +7 -8
  163. data/spec/grape/util/inheritable_values_spec.rb +3 -3
  164. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
  165. data/spec/grape/util/stackable_values_spec.rb +7 -6
  166. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
  167. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  168. data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
  169. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
  170. data/spec/grape/validations/params_scope_spec.rb +361 -96
  171. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
  172. data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
  173. data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
  174. data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
  175. data/spec/grape/validations/types_spec.rb +36 -10
  176. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
  177. data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
  178. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
  179. data/spec/grape/validations/validators/coerce_spec.rb +23 -24
  180. data/spec/grape/validations/validators/default_spec.rb +72 -80
  181. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
  182. data/spec/grape/validations/validators/except_values_spec.rb +3 -5
  183. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
  184. data/spec/grape/validations/validators/presence_spec.rb +16 -3
  185. data/spec/grape/validations/validators/regexp_spec.rb +25 -33
  186. data/spec/grape/validations/validators/same_as_spec.rb +14 -22
  187. data/spec/grape/validations/validators/values_spec.rb +201 -179
  188. data/spec/grape/validations_spec.rb +171 -79
  189. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  190. data/spec/integration/multi_json/json_spec.rb +1 -3
  191. data/spec/integration/multi_xml/xml_spec.rb +1 -3
  192. data/spec/shared/versioning_examples.rb +12 -9
  193. data/spec/spec_helper.rb +21 -6
  194. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  195. metadata +41 -29
  196. data/lib/grape/validations/validators/all_or_none.rb +0 -15
  197. data/lib/grape/validations/validators/allow_blank.rb +0 -18
  198. data/lib/grape/validations/validators/as.rb +0 -16
  199. data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
  200. data/lib/grape/validations/validators/coerce.rb +0 -91
  201. data/lib/grape/validations/validators/default.rb +0 -48
  202. data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
  203. data/lib/grape/validations/validators/except_values.rb +0 -22
  204. data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
  205. data/lib/grape/validations/validators/presence.rb +0 -12
  206. data/lib/grape/validations/validators/regexp.rb +0 -13
  207. data/lib/grape/validations/validators/same_as.rb +0 -26
  208. data/lib/grape/validations/validators/values.rb +0 -83
  209. data/spec/grape/dsl/configuration_spec.rb +0 -16
  210. data/spec/grape/validations/attributes_iterator_spec.rb +0 -6
  211. data/spec/support/eager_load.rb +0 -19
@@ -1,74 +1,66 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
- describe Grape::Validations::AtLeastOneOfValidator do
6
- describe '#validate!' do
7
- subject(:validate) { post path, params }
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
- params do
17
- optional :beer, :wine, :grapefruit
18
- at_least_one_of :beer, :wine, :grapefruit
19
- end
20
- post do
21
- end
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
- params do
24
- optional :beer, :wine, :grapefruit, :other
25
- at_least_one_of :beer, :wine, :grapefruit
26
- end
27
- post 'mixed-params' do
28
- end
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
- params do
31
- optional :beer, :wine, :grapefruit
32
- at_least_one_of :beer, :wine, :grapefruit, message: 'you should choose something'
33
- end
34
- post '/custom-message' do
35
- end
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
- params do
38
- requires :item, type: Hash do
39
- optional :beer, :wine, :grapefruit
40
- at_least_one_of :beer, :wine, :grapefruit, message: 'fail'
41
- end
42
- end
43
- post '/nested-hash' do
44
- end
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
- params do
47
- requires :items, type: Array do
48
- optional :beer, :wine, :grapefruit
49
- at_least_one_of :beer, :wine, :grapefruit, message: 'fail'
50
- end
51
- end
52
- post '/nested-array' do
53
- end
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
- params do
56
- requires :items, type: Array do
57
- requires :nested_items, type: Array do
58
- optional :beer, :wine, :grapefruit
59
- at_least_one_of :beer, :wine, :grapefruit, message: 'fail'
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
- def app
70
- ValidationsSpec::AtLeastOneOfValidatorSpec::API
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
- require 'spec_helper'
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 :each do
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('../zh-CN.yml', __FILE__)
32
+ I18n.load_path << File.expand_path('zh-CN.yml', __dir__)
35
33
  I18n.reload!
36
- I18n.locale = 'zh-CN'.to_sym
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'.to_sym
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
- if val == 'yup'
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
- elsif val == 'false'
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(/,/).map(&:strip)] : val }
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]
@@ -834,9 +833,10 @@ describe Grape::Validations::CoerceValidator do
834
833
  before do
835
834
  subject.params do
836
835
  requires :int, type: Integer, coerce_with: (lambda do |val|
837
- if val == '0'
836
+ case val
837
+ when '0'
838
838
  nil
839
- elsif val.match?(/^-?\d+$/)
839
+ when /^-?\d+$/
840
840
  val.to_i
841
841
  else
842
842
  val
@@ -1016,11 +1016,9 @@ describe Grape::Validations::CoerceValidator do
1016
1016
  end
1017
1017
 
1018
1018
  context 'multiple types' do
1019
- Boolean = Grape::API::Boolean
1020
-
1021
1019
  it 'coerces to first possible type' do
1022
1020
  subject.params do
1023
- requires :a, types: [Boolean, Integer, String]
1021
+ requires :a, types: [Grape::API::Boolean, Integer, String]
1024
1022
  end
1025
1023
  subject.get '/' do
1026
1024
  params[:a].class.to_s
@@ -1041,7 +1039,7 @@ describe Grape::Validations::CoerceValidator do
1041
1039
 
1042
1040
  it 'fails when no coercion is possible' do
1043
1041
  subject.params do
1044
- requires :a, types: [Boolean, Integer]
1042
+ requires :a, types: [Grape::API::Boolean, Integer]
1045
1043
  end
1046
1044
  subject.get '/' do
1047
1045
  params[:a].class.to_s
@@ -1200,10 +1198,11 @@ describe Grape::Validations::CoerceValidator do
1200
1198
  context 'custom coercion rules' do
1201
1199
  before do
1202
1200
  subject.params do
1203
- requires :a, types: [Boolean, String], coerce_with: (lambda do |val|
1204
- if val == 'yup'
1201
+ requires :a, types: [Grape::API::Boolean, String], coerce_with: (lambda do |val|
1202
+ case val
1203
+ when 'yup'
1205
1204
  true
1206
- elsif val == 'false'
1205
+ when 'false'
1207
1206
  0
1208
1207
  else
1209
1208
  val
@@ -1,105 +1,97 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
- describe Grape::Validations::DefaultValidator do
6
- module ValidationsSpec
7
- module DefaultValidatorSpec
8
- class API < Grape::API
9
- default_format :json
10
-
11
- params do
12
- optional :id
13
- optional :type, default: 'default-type'
14
- end
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
- params do
20
- optional :type1, default: 'default-type1'
21
- optional :type2, default: 'default-type2'
22
- end
23
- get '/user' do
24
- { type1: params[:type1], type2: params[:type2] }
25
- end
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
- params do
28
- requires :id
29
- optional :type1, default: 'default-type1'
30
- optional :type2, default: 'default-type2'
31
- end
24
+ params do
25
+ requires :id
26
+ optional :type1, default: 'default-type1'
27
+ optional :type2, default: 'default-type2'
28
+ end
32
29
 
33
- get '/message' do
34
- { id: params[:id], type1: params[:type1], type2: params[:type2] }
35
- end
30
+ get '/message' do
31
+ { id: params[:id], type1: params[:type1], type2: params[:type2] }
32
+ end
36
33
 
37
- params do
38
- optional :random, default: -> { Random.rand }
39
- optional :not_random, default: Random.rand
40
- end
41
- get '/numbers' do
42
- { random_number: params[:random], non_random_number: params[:non_random_number] }
43
- end
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
- params do
46
- optional :array, type: Array do
47
- requires :name
48
- optional :with_default, default: 'default'
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
- params do
56
- requires :thing1
57
- optional :more_things, type: Array do
58
- requires :nested_thing
59
- requires :other_thing, default: 1
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
- params do
67
- requires :root, type: Hash do
68
- optional :some_things, type: Array do
69
- requires :foo
70
- optional :options, type: Array do
71
- requires :name, type: String
72
- requires :value, type: String
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
- get '/nested_optional_array' do
78
- { root: params[:root] }
79
- end
73
+ end
74
+ get '/nested_optional_array' do
75
+ { root: params[:root] }
76
+ end
80
77
 
81
- params do
82
- requires :root, type: Hash do
83
- optional :some_things, type: Array do
84
- requires :foo
85
- optional :options, type: Array do
86
- optional :name, type: String
87
- optional :value, type: String
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
- get '/another_nested_optional_array' do
93
- { root: params[:root] }
94
- end
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)
@@ -1,96 +1,88 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
- describe Grape::Validations::ExactlyOneOfValidator do
6
- describe '#validate!' do
7
- subject(:validate) { post path, params }
8
-
9
- module ValidationsSpec
10
- module ExactlyOneOfValidatorSpec
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::ExactlyOneOfValidator 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
- params do
17
- optional :beer
18
- optional :wine
19
- optional :grapefruit
20
- exactly_one_of :beer, :wine, :grapefruit
21
- end
22
- post do
23
- end
10
+ params do
11
+ optional :beer
12
+ optional :wine
13
+ optional :grapefruit
14
+ exactly_one_of :beer, :wine, :grapefruit
15
+ end
16
+ post do
17
+ end
24
18
 
25
- params do
26
- optional :beer
27
- optional :wine
28
- optional :grapefruit
29
- optional :other
30
- exactly_one_of :beer, :wine, :grapefruit
31
- end
32
- post 'mixed-params' do
33
- end
19
+ params do
20
+ optional :beer
21
+ optional :wine
22
+ optional :grapefruit
23
+ optional :other
24
+ exactly_one_of :beer, :wine, :grapefruit
25
+ end
26
+ post 'mixed-params' do
27
+ end
34
28
 
35
- params do
36
- optional :beer
37
- optional :wine
38
- optional :grapefruit
39
- exactly_one_of :beer, :wine, :grapefruit, message: 'you should choose one'
40
- end
41
- post '/custom-message' do
42
- end
29
+ params do
30
+ optional :beer
31
+ optional :wine
32
+ optional :grapefruit
33
+ exactly_one_of :beer, :wine, :grapefruit, message: 'you should choose one'
34
+ end
35
+ post '/custom-message' do
36
+ end
43
37
 
44
- params do
45
- requires :item, type: Hash do
46
- optional :beer
47
- optional :wine
48
- optional :grapefruit
49
- exactly_one_of :beer, :wine, :grapefruit
50
- end
51
- end
52
- post '/nested-hash' do
53
- end
38
+ params do
39
+ requires :item, type: Hash do
40
+ optional :beer
41
+ optional :wine
42
+ optional :grapefruit
43
+ exactly_one_of :beer, :wine, :grapefruit
44
+ end
45
+ end
46
+ post '/nested-hash' do
47
+ end
54
48
 
55
- params do
56
- optional :item, type: Hash do
57
- optional :beer
58
- optional :wine
59
- optional :grapefruit
60
- exactly_one_of :beer, :wine, :grapefruit
61
- end
62
- end
63
- post '/nested-optional-hash' do
64
- end
49
+ params do
50
+ optional :item, type: Hash do
51
+ optional :beer
52
+ optional :wine
53
+ optional :grapefruit
54
+ exactly_one_of :beer, :wine, :grapefruit
55
+ end
56
+ end
57
+ post '/nested-optional-hash' do
58
+ end
65
59
 
66
- params do
67
- requires :items, type: Array do
68
- optional :beer
69
- optional :wine
70
- optional :grapefruit
71
- exactly_one_of :beer, :wine, :grapefruit
72
- end
73
- end
74
- post '/nested-array' do
75
- end
60
+ params do
61
+ requires :items, type: Array do
62
+ optional :beer
63
+ optional :wine
64
+ optional :grapefruit
65
+ exactly_one_of :beer, :wine, :grapefruit
66
+ end
67
+ end
68
+ post '/nested-array' do
69
+ end
76
70
 
77
- params do
78
- requires :items, type: Array do
79
- requires :nested_items, type: Array do
80
- optional :beer, :wine, :grapefruit, type: Boolean
81
- exactly_one_of :beer, :wine, :grapefruit
82
- end
83
- end
84
- end
85
- post '/deeply-nested-array' do
71
+ params do
72
+ requires :items, type: Array do
73
+ requires :nested_items, type: Array do
74
+ optional :beer, :wine, :grapefruit, type: Grape::API::Boolean
75
+ exactly_one_of :beer, :wine, :grapefruit
86
76
  end
87
77
  end
88
78
  end
79
+ post '/deeply-nested-array' do
80
+ end
89
81
  end
82
+ end
90
83
 
91
- def app
92
- ValidationsSpec::ExactlyOneOfValidatorSpec::API
93
- end
84
+ describe '#validate!' do
85
+ subject(:validate) { post path, params }
94
86
 
95
87
  context 'when all params are present' do
96
88
  let(:path) { '/' }
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
- describe Grape::Validations::ExceptValuesValidator do
3
+ describe Grape::Validations::Validators::ExceptValuesValidator do
6
4
  module ValidationsSpec
7
5
  class ExceptValuesModel
8
- DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze
6
+ DEFAULT_EXCEPTS = %w[invalid-type1 invalid-type2 invalid-type3].freeze
9
7
  class << self
10
8
  attr_accessor :excepts
11
9
 
@@ -170,7 +168,7 @@ describe Grape::Validations::ExceptValuesValidator do
170
168
  it 'raises IncompatibleOptionValues when type is incompatible with values array' do
171
169
  subject = Class.new(Grape::API)
172
170
  expect do
173
- subject.params { optional :type, except_values: ['valid-type1', 'valid-type2', 'valid-type3'], type: Symbol }
171
+ subject.params { optional :type, except_values: %w[valid-type1 valid-type2 valid-type3], type: Symbol }
174
172
  end.to raise_error Grape::Exceptions::IncompatibleOptionValues
175
173
  end
176
174