grape 1.5.3 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -0
  3. data/CONTRIBUTING.md +2 -1
  4. data/README.md +150 -21
  5. data/UPGRADING.md +61 -4
  6. data/grape.gemspec +5 -5
  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 +2 -19
  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 +8 -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 +20 -35
  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 +2 -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 +2 -2
  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 +3 -0
  48. data/lib/grape/router/pattern.rb +1 -1
  49. data/lib/grape/router/route.rb +2 -2
  50. data/lib/grape/router.rb +6 -0
  51. data/lib/grape/util/inheritable_setting.rb +1 -3
  52. data/lib/grape/util/json.rb +2 -0
  53. data/lib/grape/util/lazy_value.rb +3 -2
  54. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  55. data/lib/grape/validations/attributes_doc.rb +58 -0
  56. data/lib/grape/validations/params_scope.rb +137 -78
  57. data/lib/grape/validations/types/array_coercer.rb +0 -2
  58. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  59. data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
  60. data/lib/grape/validations/types/json.rb +2 -1
  61. data/lib/grape/validations/types/primitive_coercer.rb +16 -8
  62. data/lib/grape/validations/types/set_coercer.rb +0 -2
  63. data/lib/grape/validations/types.rb +98 -30
  64. data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
  65. data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
  66. data/lib/grape/validations/validators/as_validator.rb +14 -0
  67. data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
  68. data/lib/grape/validations/validators/base.rb +82 -70
  69. data/lib/grape/validations/validators/coerce_validator.rb +75 -0
  70. data/lib/grape/validations/validators/default_validator.rb +51 -0
  71. data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
  72. data/lib/grape/validations/validators/except_values_validator.rb +24 -0
  73. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  74. data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
  75. data/lib/grape/validations/validators/presence_validator.rb +15 -0
  76. data/lib/grape/validations/validators/regexp_validator.rb +16 -0
  77. data/lib/grape/validations/validators/same_as_validator.rb +29 -0
  78. data/lib/grape/validations/validators/values_validator.rb +88 -0
  79. data/lib/grape/validations.rb +16 -6
  80. data/lib/grape/version.rb +1 -1
  81. data/lib/grape.rb +69 -29
  82. data/spec/grape/api/custom_validations_spec.rb +116 -45
  83. data/spec/grape/api/deeply_included_options_spec.rb +3 -5
  84. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
  85. data/spec/grape/api/documentation_spec.rb +59 -0
  86. data/spec/grape/api/inherited_helpers_spec.rb +0 -2
  87. data/spec/grape/api/instance_spec.rb +0 -1
  88. data/spec/grape/api/invalid_format_spec.rb +2 -2
  89. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
  90. data/spec/grape/api/nested_helpers_spec.rb +0 -2
  91. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
  92. data/spec/grape/api/parameters_modification_spec.rb +0 -2
  93. data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
  94. data/spec/grape/api/recognize_path_spec.rb +1 -3
  95. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
  96. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
  97. data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
  98. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
  99. data/spec/grape/api/shared_helpers_spec.rb +0 -2
  100. data/spec/grape/api_remount_spec.rb +16 -16
  101. data/spec/grape/api_spec.rb +457 -231
  102. data/spec/grape/config_spec.rb +0 -2
  103. data/spec/grape/dsl/callbacks_spec.rb +2 -3
  104. data/spec/grape/dsl/configuration_spec.rb +0 -2
  105. data/spec/grape/dsl/desc_spec.rb +0 -2
  106. data/spec/grape/dsl/headers_spec.rb +39 -11
  107. data/spec/grape/dsl/helpers_spec.rb +3 -4
  108. data/spec/grape/dsl/inside_route_spec.rb +16 -16
  109. data/spec/grape/dsl/logger_spec.rb +15 -19
  110. data/spec/grape/dsl/middleware_spec.rb +2 -3
  111. data/spec/grape/dsl/parameters_spec.rb +2 -2
  112. data/spec/grape/dsl/request_response_spec.rb +7 -8
  113. data/spec/grape/dsl/routing_spec.rb +11 -10
  114. data/spec/grape/dsl/settings_spec.rb +0 -2
  115. data/spec/grape/dsl/validations_spec.rb +0 -17
  116. data/spec/grape/endpoint/declared_spec.rb +261 -16
  117. data/spec/grape/endpoint_spec.rb +86 -58
  118. data/spec/grape/entity_spec.rb +22 -23
  119. data/spec/grape/exceptions/base_spec.rb +16 -2
  120. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
  121. data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -24
  122. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
  123. data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
  124. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
  125. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  126. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
  127. data/spec/grape/exceptions/missing_option_spec.rb +1 -3
  128. data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
  129. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
  130. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  131. data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
  132. data/spec/grape/exceptions/validation_spec.rb +5 -5
  133. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
  134. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
  135. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
  136. data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
  137. data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
  138. data/spec/grape/integration/rack_spec.rb +0 -2
  139. data/spec/grape/loading_spec.rb +8 -10
  140. data/spec/grape/middleware/auth/base_spec.rb +0 -1
  141. data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
  142. data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
  143. data/spec/grape/middleware/base_spec.rb +24 -17
  144. data/spec/grape/middleware/error_spec.rb +8 -3
  145. data/spec/grape/middleware/exception_spec.rb +111 -163
  146. data/spec/grape/middleware/formatter_spec.rb +27 -8
  147. data/spec/grape/middleware/globals_spec.rb +7 -6
  148. data/spec/grape/middleware/stack_spec.rb +14 -14
  149. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
  150. data/spec/grape/middleware/versioner/header_spec.rb +30 -15
  151. data/spec/grape/middleware/versioner/param_spec.rb +7 -3
  152. data/spec/grape/middleware/versioner/path_spec.rb +5 -3
  153. data/spec/grape/middleware/versioner_spec.rb +1 -3
  154. data/spec/grape/named_api_spec.rb +0 -2
  155. data/spec/grape/parser_spec.rb +4 -2
  156. data/spec/grape/path_spec.rb +52 -54
  157. data/spec/grape/presenters/presenter_spec.rb +7 -8
  158. data/spec/grape/request_spec.rb +6 -6
  159. data/spec/grape/util/inheritable_setting_spec.rb +7 -8
  160. data/spec/grape/util/inheritable_values_spec.rb +3 -3
  161. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
  162. data/spec/grape/util/stackable_values_spec.rb +7 -6
  163. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
  164. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  165. data/spec/grape/validations/attributes_iterator_spec.rb +0 -2
  166. data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
  167. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
  168. data/spec/grape/validations/params_scope_spec.rb +361 -96
  169. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
  170. data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
  171. data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
  172. data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
  173. data/spec/grape/validations/types_spec.rb +36 -10
  174. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
  175. data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
  176. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
  177. data/spec/grape/validations/validators/coerce_spec.rb +23 -24
  178. data/spec/grape/validations/validators/default_spec.rb +72 -80
  179. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
  180. data/spec/grape/validations/validators/except_values_spec.rb +3 -5
  181. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
  182. data/spec/grape/validations/validators/presence_spec.rb +16 -3
  183. data/spec/grape/validations/validators/regexp_spec.rb +25 -33
  184. data/spec/grape/validations/validators/same_as_spec.rb +14 -22
  185. data/spec/grape/validations/validators/values_spec.rb +182 -179
  186. data/spec/grape/validations_spec.rb +149 -80
  187. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  188. data/spec/integration/multi_json/json_spec.rb +1 -3
  189. data/spec/integration/multi_xml/xml_spec.rb +1 -3
  190. data/spec/shared/versioning_examples.rb +12 -9
  191. data/spec/spec_helper.rb +21 -6
  192. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  193. metadata +126 -117
  194. data/lib/grape/validations/validators/all_or_none.rb +0 -15
  195. data/lib/grape/validations/validators/allow_blank.rb +0 -18
  196. data/lib/grape/validations/validators/as.rb +0 -16
  197. data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
  198. data/lib/grape/validations/validators/coerce.rb +0 -91
  199. data/lib/grape/validations/validators/default.rb +0 -48
  200. data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
  201. data/lib/grape/validations/validators/except_values.rb +0 -22
  202. data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
  203. data/lib/grape/validations/validators/presence.rb +0 -12
  204. data/lib/grape/validations/validators/regexp.rb +0 -13
  205. data/lib/grape/validations/validators/same_as.rb +0 -26
  206. data/lib/grape/validations/validators/values.rb +0 -83
  207. data/spec/support/eager_load.rb +0 -19
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::InvalidAcceptHeader do
6
4
  shared_examples_for 'a valid request' do
7
5
  it 'does return with status 200' do
8
6
  expect(last_response.status).to eq 200
9
7
  end
8
+
10
9
  it 'does return the expected result' do
11
10
  expect(last_response.body).to eq('beer received')
12
11
  end
@@ -20,6 +19,7 @@ describe Grape::Exceptions::InvalidAcceptHeader do
20
19
  it 'does not include the X-Cascade=pass header' do
21
20
  expect(last_response.headers['X-Cascade']).to be_nil
22
21
  end
22
+
23
23
  it 'does not accept the request' do
24
24
  expect(last_response.status).to eq 406
25
25
  end
@@ -28,6 +28,7 @@ describe Grape::Exceptions::InvalidAcceptHeader do
28
28
  it 'does not include the X-Cascade=pass header' do
29
29
  expect(last_response.headers['X-Cascade']).to be_nil
30
30
  end
31
+
31
32
  it 'does show rescue handler processing' do
32
33
  expect(last_response.status).to eq 400
33
34
  expect(last_response.body).to eq('message was processed')
@@ -36,6 +37,7 @@ describe Grape::Exceptions::InvalidAcceptHeader do
36
37
 
37
38
  context 'API with cascade=false and rescue_from :all handler' do
38
39
  subject { Class.new(Grape::API) }
40
+
39
41
  before do
40
42
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
41
43
  subject.rescue_from :all do |e|
@@ -52,7 +54,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
52
54
 
53
55
  context 'that received a request with correct vendor and version' do
54
56
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
55
- it_should_behave_like 'a valid request'
57
+
58
+ it_behaves_like 'a valid request'
56
59
  end
57
60
 
58
61
  context 'that receives' do
@@ -61,13 +64,15 @@ describe Grape::Exceptions::InvalidAcceptHeader do
61
64
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
62
65
  'CONTENT_TYPE' => 'application/json'
63
66
  end
64
- it_should_behave_like 'a rescued request'
67
+
68
+ it_behaves_like 'a rescued request'
65
69
  end
66
70
  end
67
71
  end
68
72
 
69
73
  context 'API with cascade=false and without a rescue handler' do
70
74
  subject { Class.new(Grape::API) }
75
+
71
76
  before do
72
77
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
73
78
  subject.get '/beer' do
@@ -81,23 +86,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
81
86
 
82
87
  context 'that received a request with correct vendor and version' do
83
88
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
84
- it_should_behave_like 'a valid request'
89
+
90
+ it_behaves_like 'a valid request'
85
91
  end
86
92
 
87
93
  context 'that receives' do
88
94
  context 'an invalid version in the request' do
89
95
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
90
- it_should_behave_like 'a not-cascaded request'
96
+
97
+ it_behaves_like 'a not-cascaded request'
91
98
  end
99
+
92
100
  context 'an invalid vendor in the request' do
93
101
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
94
- it_should_behave_like 'a not-cascaded request'
102
+
103
+ it_behaves_like 'a not-cascaded request'
95
104
  end
96
105
  end
97
106
  end
98
107
 
99
108
  context 'API with cascade=false and with rescue_from :all handler and http_codes' do
100
109
  subject { Class.new(Grape::API) }
110
+
101
111
  before do
102
112
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
103
113
  subject.rescue_from :all do |e|
@@ -119,7 +129,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
119
129
 
120
130
  context 'that received a request with correct vendor and version' do
121
131
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
122
- it_should_behave_like 'a valid request'
132
+
133
+ it_behaves_like 'a valid request'
123
134
  end
124
135
 
125
136
  context 'that receives' do
@@ -128,13 +139,15 @@ describe Grape::Exceptions::InvalidAcceptHeader do
128
139
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
129
140
  'CONTENT_TYPE' => 'application/json'
130
141
  end
131
- it_should_behave_like 'a rescued request'
142
+
143
+ it_behaves_like 'a rescued request'
132
144
  end
133
145
  end
134
146
  end
135
147
 
136
148
  context 'API with cascade=false, http_codes but without a rescue handler' do
137
149
  subject { Class.new(Grape::API) }
150
+
138
151
  before do
139
152
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
140
153
  subject.desc 'Get beer' do
@@ -153,23 +166,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
153
166
 
154
167
  context 'that received a request with correct vendor and version' do
155
168
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
156
- it_should_behave_like 'a valid request'
169
+
170
+ it_behaves_like 'a valid request'
157
171
  end
158
172
 
159
173
  context 'that receives' do
160
174
  context 'an invalid version in the request' do
161
175
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
162
- it_should_behave_like 'a not-cascaded request'
176
+
177
+ it_behaves_like 'a not-cascaded request'
163
178
  end
179
+
164
180
  context 'an invalid vendor in the request' do
165
181
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
166
- it_should_behave_like 'a not-cascaded request'
182
+
183
+ it_behaves_like 'a not-cascaded request'
167
184
  end
168
185
  end
169
186
  end
170
187
 
171
188
  context 'API with cascade=true and rescue_from :all handler' do
172
189
  subject { Class.new(Grape::API) }
190
+
173
191
  before do
174
192
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
175
193
  subject.rescue_from :all do |e|
@@ -186,7 +204,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
186
204
 
187
205
  context 'that received a request with correct vendor and version' do
188
206
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
189
- it_should_behave_like 'a valid request'
207
+
208
+ it_behaves_like 'a valid request'
190
209
  end
191
210
 
192
211
  context 'that receives' do
@@ -195,20 +214,24 @@ describe Grape::Exceptions::InvalidAcceptHeader do
195
214
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
196
215
  'CONTENT_TYPE' => 'application/json'
197
216
  end
198
- it_should_behave_like 'a cascaded request'
217
+
218
+ it_behaves_like 'a cascaded request'
199
219
  end
220
+
200
221
  context 'an invalid vendor in the request' do
201
222
  before do
202
223
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
203
224
  'CONTENT_TYPE' => 'application/json'
204
225
  end
205
- it_should_behave_like 'a cascaded request'
226
+
227
+ it_behaves_like 'a cascaded request'
206
228
  end
207
229
  end
208
230
  end
209
231
 
210
232
  context 'API with cascade=true and without a rescue handler' do
211
233
  subject { Class.new(Grape::API) }
234
+
212
235
  before do
213
236
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
214
237
  subject.get '/beer' do
@@ -222,23 +245,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
222
245
 
223
246
  context 'that received a request with correct vendor and version' do
224
247
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
225
- it_should_behave_like 'a valid request'
248
+
249
+ it_behaves_like 'a valid request'
226
250
  end
227
251
 
228
252
  context 'that receives' do
229
253
  context 'an invalid version in the request' do
230
254
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
231
- it_should_behave_like 'a cascaded request'
255
+
256
+ it_behaves_like 'a cascaded request'
232
257
  end
258
+
233
259
  context 'an invalid vendor in the request' do
234
260
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
235
- it_should_behave_like 'a cascaded request'
261
+
262
+ it_behaves_like 'a cascaded request'
236
263
  end
237
264
  end
238
265
  end
239
266
 
240
267
  context 'API with cascade=true and with rescue_from :all handler and http_codes' do
241
268
  subject { Class.new(Grape::API) }
269
+
242
270
  before do
243
271
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
244
272
  subject.rescue_from :all do |e|
@@ -260,7 +288,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
260
288
 
261
289
  context 'that received a request with correct vendor and version' do
262
290
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
263
- it_should_behave_like 'a valid request'
291
+
292
+ it_behaves_like 'a valid request'
264
293
  end
265
294
 
266
295
  context 'that receives' do
@@ -269,20 +298,24 @@ describe Grape::Exceptions::InvalidAcceptHeader do
269
298
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
270
299
  'CONTENT_TYPE' => 'application/json'
271
300
  end
272
- it_should_behave_like 'a cascaded request'
301
+
302
+ it_behaves_like 'a cascaded request'
273
303
  end
304
+
274
305
  context 'an invalid vendor in the request' do
275
306
  before do
276
307
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
277
308
  'CONTENT_TYPE' => 'application/json'
278
309
  end
279
- it_should_behave_like 'a cascaded request'
310
+
311
+ it_behaves_like 'a cascaded request'
280
312
  end
281
313
  end
282
314
  end
283
315
 
284
316
  context 'API with cascade=true, http_codes but without a rescue handler' do
285
317
  subject { Class.new(Grape::API) }
318
+
286
319
  before do
287
320
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
288
321
  subject.desc 'Get beer' do
@@ -301,17 +334,21 @@ describe Grape::Exceptions::InvalidAcceptHeader do
301
334
 
302
335
  context 'that received a request with correct vendor and version' do
303
336
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
304
- it_should_behave_like 'a valid request'
337
+
338
+ it_behaves_like 'a valid request'
305
339
  end
306
340
 
307
341
  context 'that receives' do
308
342
  context 'an invalid version in the request' do
309
343
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
310
- it_should_behave_like 'a cascaded request'
344
+
345
+ it_behaves_like 'a cascaded request'
311
346
  end
347
+
312
348
  context 'an invalid vendor in the request' do
313
349
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
314
- it_should_behave_like 'a cascaded request'
350
+
351
+ it_behaves_like 'a cascaded request'
315
352
  end
316
353
  end
317
354
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::InvalidFormatter do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::InvalidResponse do
6
4
  describe '#message' do
7
5
  let(:error) { described_class.new }
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::InvalidVersionerOption do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -10,7 +8,7 @@ describe Grape::Exceptions::InvalidVersionerOption do
10
8
 
11
9
  it 'contains the problem in the message' do
12
10
  expect(error.message).to include(
13
- 'Unknown :using for versioner: headers'
11
+ 'unknown :using for versioner: headers'
14
12
  )
15
13
  end
16
14
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Grape::Exceptions::MissingGroupType do
4
+ describe '#message' do
5
+ subject { described_class.new.message }
6
+
7
+ it { is_expected.to include 'group type is required' }
8
+ end
9
+
10
+ describe 'deprecated Grape::Exceptions::MissingGroupTypeError' do
11
+ subject { Grape::Exceptions::MissingGroupTypeError.new }
12
+
13
+ it 'puts a deprecation warning' do
14
+ expect(Warning).to receive(:warn) do |message|
15
+ expect(message).to include('`Grape::Exceptions::MissingGroupTypeError` is deprecated')
16
+ end
17
+
18
+ subject
19
+ end
20
+ end
21
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::MissingMimeType do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::MissingOption do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -10,7 +8,7 @@ describe Grape::Exceptions::MissingOption do
10
8
 
11
9
  it 'contains the problem in the message' do
12
10
  expect(error.message).to include(
13
- 'You must specify :path options.'
11
+ 'you must specify :path options'
14
12
  )
15
13
  end
16
14
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::UnknownOptions do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::UnknownValidator do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Grape::Exceptions::UnsupportedGroupType do
4
+ subject { described_class.new }
5
+
6
+ describe '#message' do
7
+ subject { described_class.new.message }
8
+
9
+ it { is_expected.to include 'group type must be Array, Hash, JSON or Array[JSON]' }
10
+ end
11
+
12
+ describe 'deprecated Grape::Exceptions::UnsupportedGroupTypeError' do
13
+ subject { Grape::Exceptions::UnsupportedGroupTypeError.new }
14
+
15
+ it 'puts a deprecation warning' do
16
+ expect(Warning).to receive(:warn) do |message|
17
+ expect(message).to include('`Grape::Exceptions::UnsupportedGroupTypeError` is deprecated')
18
+ end
19
+
20
+ subject
21
+ end
22
+ end
23
+ end
@@ -1,34 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  require 'ostruct'
5
4
 
6
5
  describe Grape::Exceptions::ValidationErrors do
7
6
  let(:validation_message) { 'FooBar is invalid' }
8
- let(:validation_error) { OpenStruct.new(params: [validation_message]) }
7
+ let(:validation_error) { instance_double Grape::Exceptions::Validation, params: [validation_message], message: '' }
9
8
 
10
9
  context 'initialize' do
10
+ subject do
11
+ described_class.new(errors: [validation_error], headers: headers)
12
+ end
13
+
11
14
  let(:headers) do
12
15
  {
13
16
  'A-Header-Key' => 'A-Header-Value'
14
17
  }
15
18
  end
16
19
 
17
- subject do
18
- described_class.new(errors: [validation_error], headers: headers)
19
- end
20
-
21
- it 'should assign headers through base class' do
20
+ it 'assigns headers through base class' do
22
21
  expect(subject.headers).to eq(headers)
23
22
  end
24
23
  end
25
24
 
26
25
  context 'message' do
27
26
  context 'is not repeated' do
27
+ subject(:message) { error.message.split(',').map(&:strip) }
28
+
28
29
  let(:error) do
29
30
  described_class.new(errors: [validation_error, validation_error])
30
31
  end
31
- subject(:message) { error.message.split(',').map(&:strip) }
32
32
 
33
33
  it { expect(message).to include validation_message }
34
34
  it { expect(message.size).to eq 1 }
@@ -37,9 +37,10 @@ describe Grape::Exceptions::ValidationErrors do
37
37
 
38
38
  describe '#full_messages' do
39
39
  context 'with errors' do
40
+ subject { described_class.new(errors: [validation_error_1, validation_error_2]).full_messages }
41
+
40
42
  let(:validation_error_1) { Grape::Exceptions::Validation.new(params: ['id'], message: :presence) }
41
43
  let(:validation_error_2) { Grape::Exceptions::Validation.new(params: ['name'], message: :presence) }
42
- subject { described_class.new(errors: [validation_error_1, validation_error_2]).full_messages }
43
44
 
44
45
  it 'returns an array with each errors full message' do
45
46
  expect(subject).to contain_exactly('id is missing', 'name is missing')
@@ -47,9 +48,10 @@ describe Grape::Exceptions::ValidationErrors do
47
48
  end
48
49
 
49
50
  context 'when attributes is an array of symbols' do
50
- let(:validation_error) { Grape::Exceptions::Validation.new(params: [:admin_field], message: 'Can not set admin-only field') }
51
51
  subject { described_class.new(errors: [validation_error]).full_messages }
52
52
 
53
+ let(:validation_error) { Grape::Exceptions::Validation.new(params: [:admin_field], message: 'Can not set admin-only field') }
54
+
53
55
  it 'returns an array with an error full message' do
54
56
  expect(subject.first).to eq('admin_field Can not set admin-only field')
55
57
  end
@@ -65,7 +67,7 @@ describe Grape::Exceptions::ValidationErrors do
65
67
 
66
68
  it 'can return structured json with separate fields' do
67
69
  subject.format :json
68
- subject.rescue_from Grape::Exceptions::ValidationErrors do |e|
70
+ subject.rescue_from described_class do |e|
69
71
  error!(e, 400)
70
72
  end
71
73
  subject.params do
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::Validation do
6
4
  it 'fails when params are missing' do
7
- expect { Grape::Exceptions::Validation.new(message: 'presence') }.to raise_error(ArgumentError, /missing keyword:.+?params/)
5
+ expect { described_class.new(message: 'presence') }.to raise_error(ArgumentError, /missing keyword:.+?params/)
8
6
  end
7
+
9
8
  context 'when message is a symbol' do
10
9
  it 'stores message_key' do
11
- expect(Grape::Exceptions::Validation.new(params: ['id'], message: :presence).message_key).to eq(:presence)
10
+ expect(described_class.new(params: ['id'], message: :presence).message_key).to eq(:presence)
12
11
  end
13
12
  end
13
+
14
14
  context 'when message is a String' do
15
15
  it 'does not store the message_key' do
16
- expect(Grape::Exceptions::Validation.new(params: ['id'], message: 'presence').message_key).to eq(nil)
16
+ expect(described_class.new(params: ['id'], message: 'presence').message_key).to be_nil
17
17
  end
18
18
  end
19
19
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Extensions::Hash::ParamBuilder do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -10,10 +8,10 @@ describe Grape::Extensions::Hash::ParamBuilder do
10
8
  end
11
9
 
12
10
  describe 'in an endpoint' do
13
- context '#params' do
11
+ describe '#params' do
14
12
  before do
15
13
  subject.params do
16
- build_with Grape::Extensions::Hash::ParamBuilder
14
+ build_with Grape::Extensions::Hash::ParamBuilder # rubocop:disable RSpec/DescribedClass
17
15
  end
18
16
 
19
17
  subject.get do
@@ -21,7 +19,7 @@ describe Grape::Extensions::Hash::ParamBuilder do
21
19
  end
22
20
  end
23
21
 
24
- it 'should be of type Hash' do
22
+ it 'is of type Hash' do
25
23
  get '/'
26
24
  expect(last_response.status).to eq(200)
27
25
  expect(last_response.body).to eq('Hash')
@@ -31,17 +29,17 @@ describe Grape::Extensions::Hash::ParamBuilder do
31
29
 
32
30
  describe 'in an api' do
33
31
  before do
34
- subject.send(:include, Grape::Extensions::Hash::ParamBuilder)
32
+ subject.send(:include, Grape::Extensions::Hash::ParamBuilder) # rubocop:disable RSpec/DescribedClass
35
33
  end
36
34
 
37
- context '#params' do
35
+ describe '#params' do
38
36
  before do
39
37
  subject.get do
40
38
  params.class
41
39
  end
42
40
  end
43
41
 
44
- it 'should be Hash' do
42
+ it 'is Hash' do
45
43
  get '/'
46
44
  expect(last_response.status).to eq(200)
47
45
  expect(last_response.body).to eq('Hash')
@@ -69,7 +67,7 @@ describe Grape::Extensions::Hash::ParamBuilder do
69
67
 
70
68
  it 'symbolizes the params' do
71
69
  subject.params do
72
- build_with Grape::Extensions::Hash::ParamBuilder
70
+ build_with Grape::Extensions::Hash::ParamBuilder # rubocop:disable RSpec/DescribedClass
73
71
  requires :a, type: String
74
72
  end
75
73
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -10,10 +8,10 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
10
8
  end
11
9
 
12
10
  describe 'in an endpoint' do
13
- context '#params' do
11
+ describe '#params' do
14
12
  before do
15
13
  subject.params do
16
- build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
14
+ build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder # rubocop:disable RSpec/DescribedClass
17
15
  end
18
16
 
19
17
  subject.get do
@@ -21,7 +19,7 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
21
19
  end
22
20
  end
23
21
 
24
- it 'should be of type Hash' do
22
+ it 'is of type Hash' do
25
23
  get '/'
26
24
  expect(last_response.status).to eq(200)
27
25
  expect(last_response.body).to eq('ActiveSupport::HashWithIndifferentAccess')
@@ -31,10 +29,10 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
31
29
 
32
30
  describe 'in an api' do
33
31
  before do
34
- subject.send(:include, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder)
32
+ subject.send(:include, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder) # rubocop:disable RSpec/DescribedClass
35
33
  end
36
34
 
37
- context '#params' do
35
+ describe '#params' do
38
36
  before do
39
37
  subject.get do
40
38
  params.class
@@ -49,7 +47,7 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
49
47
 
50
48
  it 'parses sub hash params' do
51
49
  subject.params do
52
- build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
50
+ build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder # rubocop:disable RSpec/DescribedClass
53
51
 
54
52
  optional :a, type: Hash do
55
53
  optional :b, type: Hash do
@@ -70,7 +68,7 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
70
68
 
71
69
  it 'params are indifferent to symbol or string keys' do
72
70
  subject.params do
73
- build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
71
+ build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder # rubocop:disable RSpec/DescribedClass
74
72
  optional :a, type: Hash do
75
73
  optional :b, type: Hash do
76
74
  optional :c, type: String
@@ -90,7 +88,7 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
90
88
 
91
89
  it 'responds to string keys' do
92
90
  subject.params do
93
- build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
91
+ build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder # rubocop:disable RSpec/DescribedClass
94
92
  requires :a, type: String
95
93
  end
96
94