grape 1.5.3 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
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,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ describe Grape::Validations::Validators::ValuesValidator do
4
+ let_it_be(:values_model) do
5
+ Class.new do
6
+ DEFAULT_VALUES = %w[valid-type1 valid-type2 valid-type3].freeze
7
+ DEFAULT_EXCEPTS = %w[invalid-type1 invalid-type2 invalid-type3].freeze
4
8
 
5
- describe Grape::Validations::ValuesValidator do
6
- module ValidationsSpec
7
- class ValuesModel
8
- DEFAULT_VALUES = ['valid-type1', 'valid-type2', 'valid-type3'].freeze
9
- DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze
10
9
  class << self
11
10
  def values
12
11
  @values ||= []
@@ -27,214 +26,226 @@ describe Grape::Validations::ValuesValidator do
27
26
  @excepts ||= []
28
27
  @excepts << except
29
28
  end
29
+
30
+ def include?(value)
31
+ values.include?(value)
32
+ end
30
33
  end
31
34
  end
35
+ end
32
36
 
33
- module ValuesValidatorSpec
34
- class API < Grape::API
35
- default_format :json
36
-
37
- resources :custom_message do
38
- params do
39
- requires :type, values: { value: ValuesModel.values, message: 'value does not include in values' }
40
- end
41
- get '/' do
42
- { type: params[:type] }
43
- end
44
-
45
- params do
46
- optional :type, values: { value: -> { ValuesModel.values }, message: 'value does not include in values' }, default: 'valid-type2'
47
- end
48
- get '/lambda' do
49
- { type: params[:type] }
50
- end
51
-
52
- params do
53
- requires :type, values: { except: ValuesModel.excepts, except_message: 'value is on exclusions list', message: 'default exclude message' }
54
- end
55
- get '/exclude/exclude_message'
56
-
57
- params do
58
- requires :type, values: { except: -> { ValuesModel.excepts }, except_message: 'value is on exclusions list' }
59
- end
60
- get '/exclude/lambda/exclude_message'
61
-
62
- params do
63
- requires :type, values: { except: ValuesModel.excepts, message: 'default exclude message' }
64
- end
65
- get '/exclude/fallback_message'
66
- end
37
+ before do
38
+ stub_const('ValuesModel', values_model)
39
+ end
67
40
 
41
+ let_it_be(:app) do
42
+ ValuesModel = values_model
43
+ Class.new(Grape::API) do
44
+ default_format :json
45
+
46
+ resources :custom_message do
68
47
  params do
69
- requires :type, values: ValuesModel.values
48
+ requires :type, values: { value: ValuesModel.values, message: 'value does not include in values' }
70
49
  end
71
50
  get '/' do
72
51
  { type: params[:type] }
73
52
  end
74
53
 
75
54
  params do
76
- requires :type, values: []
55
+ optional :type, values: { value: -> { ValuesModel.values }, message: 'value does not include in values' }, default: 'valid-type2'
77
56
  end
78
- get '/empty'
79
-
80
- params do
81
- optional :type, values: { value: ValuesModel.values }, default: 'valid-type2'
82
- end
83
- get '/default/hash/valid' do
57
+ get '/lambda' do
84
58
  { type: params[:type] }
85
59
  end
86
60
 
87
61
  params do
88
- optional :type, values: ValuesModel.values, default: 'valid-type2'
89
- end
90
- get '/default/valid' do
91
- { type: params[:type] }
62
+ requires :type, values: { except: ValuesModel.excepts, except_message: 'value is on exclusions list', message: 'default exclude message' }
92
63
  end
64
+ get '/exclude/exclude_message'
93
65
 
94
66
  params do
95
- optional :type, values: { except: ValuesModel.excepts }, default: 'valid-type2'
96
- end
97
- get '/default/except' do
98
- { type: params[:type] }
67
+ requires :type, values: { except: -> { ValuesModel.excepts }, except_message: 'value is on exclusions list' }
99
68
  end
69
+ get '/exclude/lambda/exclude_message'
100
70
 
101
71
  params do
102
- optional :type, values: -> { ValuesModel.values }, default: 'valid-type2'
103
- end
104
- get '/lambda' do
105
- { type: params[:type] }
72
+ requires :type, values: { except: ValuesModel.excepts, message: 'default exclude message' }
106
73
  end
74
+ get '/exclude/fallback_message'
75
+ end
107
76
 
108
- params do
109
- requires :type, values: ->(v) { ValuesModel.values.include? v }
110
- end
111
- get '/lambda_val' do
112
- { type: params[:type] }
113
- end
77
+ params do
78
+ requires :type, values: ValuesModel.values
79
+ end
80
+ get '/' do
81
+ { type: params[:type] }
82
+ end
114
83
 
115
- params do
116
- requires :number, type: Integer, values: ->(v) { v > 0 }
117
- end
118
- get '/lambda_int_val' do
119
- { number: params[:number] }
120
- end
84
+ params do
85
+ requires :type, values: []
86
+ end
87
+ get '/empty'
121
88
 
122
- params do
123
- requires :type, values: -> { [] }
124
- end
125
- get '/empty_lambda'
89
+ params do
90
+ optional :type, values: { value: ValuesModel.values }, default: 'valid-type2'
91
+ end
92
+ get '/default/hash/valid' do
93
+ { type: params[:type] }
94
+ end
126
95
 
127
- params do
128
- optional :type, values: ValuesModel.values, default: -> { ValuesModel.values.sample }
129
- end
130
- get '/default_lambda' do
131
- { type: params[:type] }
132
- end
96
+ params do
97
+ optional :type, values: ValuesModel.values, default: 'valid-type2'
98
+ end
99
+ get '/default/valid' do
100
+ { type: params[:type] }
101
+ end
133
102
 
134
- params do
135
- optional :type, values: -> { ValuesModel.values }, default: -> { ValuesModel.values.sample }
136
- end
137
- get '/default_and_values_lambda' do
138
- { type: params[:type] }
139
- end
103
+ params do
104
+ optional :type, values: { except: ValuesModel.excepts }, default: 'valid-type2'
105
+ end
106
+ get '/default/except' do
107
+ { type: params[:type] }
108
+ end
140
109
 
141
- params do
142
- optional :type, type: Boolean, desc: 'A boolean', values: [true]
143
- end
144
- get '/values/optional_boolean' do
145
- { type: params[:type] }
146
- end
110
+ params do
111
+ optional :type, values: -> { ValuesModel.values }, default: 'valid-type2'
112
+ end
113
+ get '/lambda' do
114
+ { type: params[:type] }
115
+ end
147
116
 
148
- params do
149
- requires :type, type: Integer, desc: 'An integer', values: [10, 11], default: 10
150
- end
151
- get '/values/coercion' do
152
- { type: params[:type] }
153
- end
117
+ params do
118
+ optional :type, type: Integer, values: 1..
119
+ end
120
+ get '/endless' do
121
+ { type: params[:type] }
122
+ end
154
123
 
155
- params do
156
- requires :type, type: Array[Integer], desc: 'An integer', values: [10, 11], default: 10
157
- end
158
- get '/values/array_coercion' do
159
- { type: params[:type] }
160
- end
124
+ params do
125
+ requires :type, values: ->(v) { ValuesModel.include? v }
126
+ end
127
+ get '/lambda_val' do
128
+ { type: params[:type] }
129
+ end
161
130
 
162
- params do
163
- optional :optional, type: Array do
164
- requires :type, values: %w[a b]
165
- end
166
- end
167
- get '/optional_with_required_values'
131
+ params do
132
+ requires :number, type: Integer, values: ->(v) { v > 0 }
133
+ end
134
+ get '/lambda_int_val' do
135
+ { number: params[:number] }
136
+ end
168
137
 
169
- params do
170
- requires :type, values: { except: ValuesModel.excepts }
171
- end
172
- get '/except/exclusive' do
173
- { type: params[:type] }
174
- end
138
+ params do
139
+ requires :type, values: -> { [] }
140
+ end
141
+ get '/empty_lambda'
175
142
 
176
- params do
177
- requires :type, type: String, values: { except: ValuesModel.excepts }
178
- end
179
- get '/except/exclusive/type' do
180
- { type: params[:type] }
181
- end
143
+ params do
144
+ optional :type, values: ValuesModel.values, default: -> { ValuesModel.values.sample }
145
+ end
146
+ get '/default_lambda' do
147
+ { type: params[:type] }
148
+ end
182
149
 
183
- params do
184
- requires :type, values: { except: -> { ValuesModel.excepts } }
185
- end
186
- get '/except/exclusive/lambda' do
187
- { type: params[:type] }
188
- end
150
+ params do
151
+ optional :type, values: -> { ValuesModel.values }, default: -> { ValuesModel.values.sample }
152
+ end
153
+ get '/default_and_values_lambda' do
154
+ { type: params[:type] }
155
+ end
189
156
 
190
- params do
191
- requires :type, type: String, values: { except: -> { ValuesModel.excepts } }
192
- end
193
- get '/except/exclusive/lambda/type' do
194
- { type: params[:type] }
195
- end
157
+ params do
158
+ optional :type, type: Grape::API::Boolean, desc: 'A boolean', values: [true]
159
+ end
160
+ get '/values/optional_boolean' do
161
+ { type: params[:type] }
162
+ end
196
163
 
197
- params do
198
- requires :type, type: Integer, values: { except: -> { [3, 4, 5] } }
199
- end
200
- get '/except/exclusive/lambda/coercion' do
201
- { type: params[:type] }
202
- end
164
+ params do
165
+ requires :type, type: Integer, desc: 'An integer', values: [10, 11], default: 10
166
+ end
167
+ get '/values/coercion' do
168
+ { type: params[:type] }
169
+ end
203
170
 
204
- params do
205
- requires :type, type: Integer, values: { value: 1..5, except: [3] }
206
- end
207
- get '/mixed/value/except' do
208
- { type: params[:type] }
209
- end
171
+ params do
172
+ requires :type, type: Array[Integer], desc: 'An integer', values: [10, 11], default: 10
173
+ end
174
+ get '/values/array_coercion' do
175
+ { type: params[:type] }
176
+ end
210
177
 
211
- params do
212
- optional :optional, type: Array[String], values: %w[a b c]
178
+ params do
179
+ optional :optional, type: Array do
180
+ requires :type, values: %w[a b]
213
181
  end
214
- put '/optional_with_array_of_string_values'
182
+ end
183
+ get '/optional_with_required_values'
215
184
 
216
- params do
217
- requires :type, values: { proc: ->(v) { ValuesModel.values.include? v } }
218
- end
219
- get '/proc' do
220
- { type: params[:type] }
221
- end
185
+ params do
186
+ requires :type, values: { except: ValuesModel.excepts }
187
+ end
188
+ get '/except/exclusive' do
189
+ { type: params[:type] }
190
+ end
222
191
 
223
- params do
224
- requires :type, values: { proc: ->(v) { ValuesModel.values.include? v }, message: 'failed check' }
225
- end
226
- get '/proc/message'
192
+ params do
193
+ requires :type, type: String, values: { except: ValuesModel.excepts }
194
+ end
195
+ get '/except/exclusive/type' do
196
+ { type: params[:type] }
197
+ end
227
198
 
228
- params do
229
- optional :name, type: String, values: %w[a b], allow_blank: true
230
- end
231
- get '/allow_blank'
199
+ params do
200
+ requires :type, values: { except: -> { ValuesModel.excepts } }
201
+ end
202
+ get '/except/exclusive/lambda' do
203
+ { type: params[:type] }
204
+ end
205
+
206
+ params do
207
+ requires :type, type: String, values: { except: -> { ValuesModel.excepts } }
208
+ end
209
+ get '/except/exclusive/lambda/type' do
210
+ { type: params[:type] }
211
+ end
212
+
213
+ params do
214
+ requires :type, type: Integer, values: { except: -> { [3, 4, 5] } }
215
+ end
216
+ get '/except/exclusive/lambda/coercion' do
217
+ { type: params[:type] }
218
+ end
219
+
220
+ params do
221
+ requires :type, type: Integer, values: { value: 1..5, except: [3] }
222
+ end
223
+ get '/mixed/value/except' do
224
+ { type: params[:type] }
232
225
  end
233
- end
234
- end
235
226
 
236
- def app
237
- ValidationsSpec::ValuesValidatorSpec::API
227
+ params do
228
+ optional :optional, type: Array[String], values: %w[a b c]
229
+ end
230
+ put '/optional_with_array_of_string_values'
231
+
232
+ params do
233
+ requires :type, values: { proc: ->(v) { ValuesModel.include? v } }
234
+ end
235
+ get '/proc' do
236
+ { type: params[:type] }
237
+ end
238
+
239
+ params do
240
+ requires :type, values: { proc: ->(v) { ValuesModel.include? v }, message: 'failed check' }
241
+ end
242
+ get '/proc/message'
243
+
244
+ params do
245
+ optional :name, type: String, values: %w[a b], allow_blank: true
246
+ end
247
+ get '/allow_blank'
248
+ end
238
249
  end
239
250
 
240
251
  context 'with a custom validation message' do
@@ -251,7 +262,7 @@ describe Grape::Validations::ValuesValidator do
251
262
  end
252
263
 
253
264
  it 'validates against values in a proc' do
254
- ValidationsSpec::ValuesModel.add_value('valid-type4')
265
+ ValuesModel.add_value('valid-type4')
255
266
 
256
267
  get('/custom_message/lambda', type: 'valid-type4')
257
268
  expect(last_response.status).to eq 200
@@ -350,15 +361,14 @@ describe Grape::Validations::ValuesValidator do
350
361
  end
351
362
 
352
363
  it 'does not validate updated values without proc' do
353
- ValidationsSpec::ValuesModel.add_value('valid-type4')
354
-
364
+ ValuesModel.add_value('valid-type4')
355
365
  get('/', type: 'valid-type4')
356
366
  expect(last_response.status).to eq 400
357
367
  expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
358
368
  end
359
369
 
360
370
  it 'validates against values in a proc' do
361
- ValidationsSpec::ValuesModel.add_value('valid-type4')
371
+ ValuesModel.add_value('valid-type4')
362
372
 
363
373
  get('/lambda', type: 'valid-type4')
364
374
  expect(last_response.status).to eq 200
@@ -371,6 +381,18 @@ describe Grape::Validations::ValuesValidator do
371
381
  expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
372
382
  end
373
383
 
384
+ it 'validates against values in an endless range', if: ActiveSupport::VERSION::MAJOR >= 6 do
385
+ get('/endless', type: 10)
386
+ expect(last_response.status).to eq 200
387
+ expect(last_response.body).to eq({ type: 10 }.to_json)
388
+ end
389
+
390
+ it 'does not allow an invalid value for a parameter using an endless range', if: ActiveSupport::VERSION::MAJOR >= 6 do
391
+ get('/endless', type: 0)
392
+ expect(last_response.status).to eq 400
393
+ expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
394
+ end
395
+
374
396
  it 'does not allow non-numeric string value for int value using lambda' do
375
397
  get('/lambda_int_val', number: 'foo')
376
398
  expect(last_response.status).to eq 400
@@ -420,21 +442,21 @@ describe Grape::Validations::ValuesValidator do
420
442
  it 'raises IncompatibleOptionValues on an invalid default value from proc' do
421
443
  subject = Class.new(Grape::API)
422
444
  expect do
423
- subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], default: ValidationsSpec::ValuesModel.values.sample + '_invalid' }
445
+ subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], default: "#{ValuesModel.values.sample}_invalid" }
424
446
  end.to raise_error Grape::Exceptions::IncompatibleOptionValues
425
447
  end
426
448
 
427
449
  it 'raises IncompatibleOptionValues on an invalid default value' do
428
450
  subject = Class.new(Grape::API)
429
451
  expect do
430
- subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], default: 'invalid-type' }
452
+ subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], default: 'invalid-type' }
431
453
  end.to raise_error Grape::Exceptions::IncompatibleOptionValues
432
454
  end
433
455
 
434
456
  it 'raises IncompatibleOptionValues when type is incompatible with values array' do
435
457
  subject = Class.new(Grape::API)
436
458
  expect do
437
- subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], type: Symbol }
459
+ subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], type: Symbol }
438
460
  end.to raise_error Grape::Exceptions::IncompatibleOptionValues
439
461
  end
440
462
 
@@ -648,9 +670,9 @@ describe Grape::Validations::ValuesValidator do
648
670
  end
649
671
 
650
672
  it 'accepts multiple valid values' do
651
- get '/proc', type: ['valid-type1', 'valid-type3']
673
+ get '/proc', type: %w[valid-type1 valid-type3]
652
674
  expect(last_response.status).to eq 200
653
- expect(last_response.body).to eq({ type: ['valid-type1', 'valid-type3'] }.to_json)
675
+ expect(last_response.body).to eq({ type: %w[valid-type1 valid-type3] }.to_json)
654
676
  end
655
677
 
656
678
  it 'rejects a single invalid value' do
@@ -660,7 +682,7 @@ describe Grape::Validations::ValuesValidator do
660
682
  end
661
683
 
662
684
  it 'rejects an invalid value among valid ones' do
663
- get '/proc', type: ['valid-type1', 'invalid-type1', 'valid-type3']
685
+ get '/proc', type: %w[valid-type1 invalid-type1 valid-type3]
664
686
  expect(last_response.status).to eq 400
665
687
  expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
666
688
  end