grape 1.0.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (284) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +346 -39
  3. data/LICENSE +1 -1
  4. data/README.md +658 -90
  5. data/UPGRADING.md +472 -17
  6. data/grape.gemspec +17 -6
  7. data/lib/grape/api/helpers.rb +2 -0
  8. data/lib/grape/api/instance.rb +279 -0
  9. data/lib/grape/api.rb +132 -176
  10. data/lib/grape/config.rb +34 -0
  11. data/lib/grape/content_types.rb +34 -0
  12. data/lib/grape/cookies.rb +4 -0
  13. data/lib/grape/dsl/api.rb +2 -0
  14. data/lib/grape/dsl/callbacks.rb +22 -0
  15. data/lib/grape/dsl/configuration.rb +2 -0
  16. data/lib/grape/dsl/desc.rb +44 -12
  17. data/lib/grape/dsl/headers.rb +2 -0
  18. data/lib/grape/dsl/helpers.rb +11 -6
  19. data/lib/grape/dsl/inside_route.rb +116 -36
  20. data/lib/grape/dsl/logger.rb +2 -0
  21. data/lib/grape/dsl/middleware.rb +12 -3
  22. data/lib/grape/dsl/parameters.rb +34 -16
  23. data/lib/grape/dsl/request_response.rb +13 -8
  24. data/lib/grape/dsl/routing.rb +19 -12
  25. data/lib/grape/dsl/settings.rb +22 -4
  26. data/lib/grape/dsl/validations.rb +24 -4
  27. data/lib/grape/eager_load.rb +20 -0
  28. data/lib/grape/endpoint.rb +66 -57
  29. data/lib/grape/error_formatter/base.rb +2 -0
  30. data/lib/grape/error_formatter/json.rb +6 -4
  31. data/lib/grape/error_formatter/txt.rb +10 -3
  32. data/lib/grape/error_formatter/xml.rb +6 -4
  33. data/lib/grape/error_formatter.rb +4 -2
  34. data/lib/grape/exceptions/base.rb +22 -14
  35. data/lib/grape/exceptions/empty_message_body.rb +11 -0
  36. data/lib/grape/exceptions/incompatible_option_values.rb +2 -1
  37. data/lib/grape/exceptions/invalid_accept_header.rb +2 -1
  38. data/lib/grape/exceptions/invalid_formatter.rb +2 -1
  39. data/lib/grape/exceptions/invalid_message_body.rb +2 -1
  40. data/lib/grape/exceptions/invalid_response.rb +11 -0
  41. data/lib/grape/exceptions/invalid_version_header.rb +2 -1
  42. data/lib/grape/exceptions/invalid_versioner_option.rb +2 -1
  43. data/lib/grape/exceptions/invalid_with_option_for_represent.rb +2 -1
  44. data/lib/grape/exceptions/method_not_allowed.rb +2 -1
  45. data/lib/grape/exceptions/missing_group_type.rb +2 -1
  46. data/lib/grape/exceptions/missing_mime_type.rb +2 -1
  47. data/lib/grape/exceptions/missing_option.rb +2 -1
  48. data/lib/grape/exceptions/missing_vendor_option.rb +2 -1
  49. data/lib/grape/exceptions/unknown_options.rb +2 -1
  50. data/lib/grape/exceptions/unknown_parameter.rb +2 -1
  51. data/lib/grape/exceptions/unknown_validator.rb +2 -1
  52. data/lib/grape/exceptions/unsupported_group_type.rb +2 -1
  53. data/lib/grape/exceptions/validation.rb +5 -4
  54. data/lib/grape/exceptions/validation_array_errors.rb +2 -0
  55. data/lib/grape/exceptions/validation_errors.rb +16 -13
  56. data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +4 -3
  57. data/lib/grape/extensions/deep_mergeable_hash.rb +2 -0
  58. data/lib/grape/extensions/deep_symbolize_hash.rb +2 -0
  59. data/lib/grape/extensions/hash.rb +2 -0
  60. data/lib/grape/extensions/hashie/mash.rb +2 -0
  61. data/lib/grape/formatter/json.rb +3 -0
  62. data/lib/grape/formatter/serializable_hash.rb +4 -1
  63. data/lib/grape/formatter/txt.rb +2 -0
  64. data/lib/grape/formatter/xml.rb +3 -0
  65. data/lib/grape/formatter.rb +5 -3
  66. data/lib/grape/http/headers.rb +50 -18
  67. data/lib/grape/locale/en.yml +3 -1
  68. data/lib/grape/middleware/auth/base.rb +7 -7
  69. data/lib/grape/middleware/auth/dsl.rb +2 -0
  70. data/lib/grape/middleware/auth/strategies.rb +2 -0
  71. data/lib/grape/middleware/auth/strategy_info.rb +2 -0
  72. data/lib/grape/middleware/base.rb +12 -7
  73. data/lib/grape/middleware/error.rb +75 -61
  74. data/lib/grape/middleware/filter.rb +2 -0
  75. data/lib/grape/middleware/formatter.rb +17 -13
  76. data/lib/grape/middleware/globals.rb +2 -0
  77. data/lib/grape/middleware/helpers.rb +12 -0
  78. data/lib/grape/middleware/stack.rb +15 -5
  79. data/lib/grape/middleware/versioner/accept_version_header.rb +5 -5
  80. data/lib/grape/middleware/versioner/header.rb +13 -9
  81. data/lib/grape/middleware/versioner/param.rb +4 -1
  82. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +5 -1
  83. data/lib/grape/middleware/versioner/path.rb +5 -1
  84. data/lib/grape/middleware/versioner.rb +2 -0
  85. data/lib/grape/namespace.rb +15 -3
  86. data/lib/grape/parser/json.rb +3 -1
  87. data/lib/grape/parser/xml.rb +3 -1
  88. data/lib/grape/parser.rb +4 -2
  89. data/lib/grape/path.rb +16 -3
  90. data/lib/grape/presenters/presenter.rb +2 -0
  91. data/lib/grape/request.rb +19 -9
  92. data/lib/grape/router/attribute_translator.rb +41 -8
  93. data/lib/grape/router/pattern.rb +22 -18
  94. data/lib/grape/router/route.rb +16 -30
  95. data/lib/grape/router.rb +37 -28
  96. data/lib/grape/{serve_file → serve_stream}/file_body.rb +3 -1
  97. data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +3 -1
  98. data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +10 -8
  99. data/lib/grape/util/base_inheritable.rb +43 -0
  100. data/lib/grape/util/cache.rb +20 -0
  101. data/lib/grape/util/endpoint_configuration.rb +8 -0
  102. data/lib/grape/util/env.rb +19 -17
  103. data/lib/grape/util/inheritable_setting.rb +3 -3
  104. data/lib/grape/util/inheritable_values.rb +7 -25
  105. data/lib/grape/util/json.rb +2 -0
  106. data/lib/grape/util/lazy_block.rb +27 -0
  107. data/lib/grape/util/lazy_object.rb +43 -0
  108. data/lib/grape/util/lazy_value.rb +99 -0
  109. data/lib/grape/util/registrable.rb +2 -0
  110. data/lib/grape/util/reverse_stackable_values.rb +10 -35
  111. data/lib/grape/util/stackable_values.rb +21 -34
  112. data/lib/grape/util/strict_hash_configuration.rb +2 -0
  113. data/lib/grape/util/xml.rb +2 -0
  114. data/lib/grape/validations/attributes_iterator.rb +16 -6
  115. data/lib/grape/validations/multiple_attributes_iterator.rb +13 -0
  116. data/lib/grape/validations/params_scope.rb +128 -66
  117. data/lib/grape/validations/single_attribute_iterator.rb +24 -0
  118. data/lib/grape/validations/types/array_coercer.rb +65 -0
  119. data/lib/grape/validations/types/build_coercer.rb +52 -46
  120. data/lib/grape/validations/types/custom_type_coercer.rb +30 -51
  121. data/lib/grape/validations/types/custom_type_collection_coercer.rb +56 -0
  122. data/lib/grape/validations/types/dry_type_coercer.rb +76 -0
  123. data/lib/grape/validations/types/file.rb +22 -18
  124. data/lib/grape/validations/types/invalid_value.rb +24 -0
  125. data/lib/grape/validations/types/json.rb +47 -39
  126. data/lib/grape/validations/types/multiple_type_coercer.rb +14 -33
  127. data/lib/grape/validations/types/primitive_coercer.rb +67 -0
  128. data/lib/grape/validations/types/set_coercer.rb +40 -0
  129. data/lib/grape/validations/types/variant_collection_coercer.rb +5 -13
  130. data/lib/grape/validations/types.rb +26 -38
  131. data/lib/grape/validations/validator_factory.rb +8 -11
  132. data/lib/grape/validations/validators/all_or_none.rb +8 -12
  133. data/lib/grape/validations/validators/allow_blank.rb +4 -2
  134. data/lib/grape/validations/validators/as.rb +12 -0
  135. data/lib/grape/validations/validators/at_least_one_of.rb +7 -12
  136. data/lib/grape/validations/validators/base.rb +23 -15
  137. data/lib/grape/validations/validators/coerce.rb +47 -28
  138. data/lib/grape/validations/validators/default.rb +7 -6
  139. data/lib/grape/validations/validators/exactly_one_of.rb +10 -22
  140. data/lib/grape/validations/validators/except_values.rb +4 -2
  141. data/lib/grape/validations/validators/multiple_params_base.rb +19 -10
  142. data/lib/grape/validations/validators/mutual_exclusion.rb +8 -17
  143. data/lib/grape/validations/validators/presence.rb +4 -1
  144. data/lib/grape/validations/validators/regexp.rb +5 -2
  145. data/lib/grape/validations/validators/same_as.rb +27 -0
  146. data/lib/grape/validations/validators/values.rb +29 -9
  147. data/lib/grape/validations.rb +2 -0
  148. data/lib/grape/version.rb +3 -1
  149. data/lib/grape.rb +107 -73
  150. data/spec/grape/api/custom_validations_spec.rb +6 -3
  151. data/spec/grape/api/deeply_included_options_spec.rb +2 -0
  152. data/spec/grape/api/defines_boolean_in_params_spec.rb +39 -0
  153. data/spec/grape/api/inherited_helpers_spec.rb +116 -0
  154. data/spec/grape/api/instance_spec.rb +104 -0
  155. data/spec/grape/api/invalid_format_spec.rb +2 -0
  156. data/spec/grape/api/namespace_parameters_in_route_spec.rb +2 -0
  157. data/spec/grape/api/nested_helpers_spec.rb +2 -0
  158. data/spec/grape/api/optional_parameters_in_route_spec.rb +2 -0
  159. data/spec/grape/api/parameters_modification_spec.rb +3 -1
  160. data/spec/grape/api/patch_method_helpers_spec.rb +2 -0
  161. data/spec/grape/api/recognize_path_spec.rb +2 -0
  162. data/spec/grape/api/required_parameters_in_route_spec.rb +2 -0
  163. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +2 -0
  164. data/spec/grape/api/routes_with_requirements_spec.rb +61 -0
  165. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +49 -0
  166. data/spec/grape/api/shared_helpers_spec.rb +2 -0
  167. data/spec/grape/api_remount_spec.rb +473 -0
  168. data/spec/grape/api_spec.rb +775 -65
  169. data/spec/grape/config_spec.rb +19 -0
  170. data/spec/grape/dsl/callbacks_spec.rb +3 -1
  171. data/spec/grape/dsl/configuration_spec.rb +2 -0
  172. data/spec/grape/dsl/desc_spec.rb +42 -16
  173. data/spec/grape/dsl/headers_spec.rb +2 -0
  174. data/spec/grape/dsl/helpers_spec.rb +23 -2
  175. data/spec/grape/dsl/inside_route_spec.rb +185 -34
  176. data/spec/grape/dsl/logger_spec.rb +2 -0
  177. data/spec/grape/dsl/middleware_spec.rb +11 -1
  178. data/spec/grape/dsl/parameters_spec.rb +12 -9
  179. data/spec/grape/dsl/request_response_spec.rb +2 -0
  180. data/spec/grape/dsl/routing_spec.rb +13 -1
  181. data/spec/grape/dsl/settings_spec.rb +4 -2
  182. data/spec/grape/dsl/validations_spec.rb +2 -0
  183. data/spec/grape/endpoint/declared_spec.rb +848 -0
  184. data/spec/grape/endpoint_spec.rb +75 -515
  185. data/spec/grape/entity_spec.rb +19 -11
  186. data/spec/grape/exceptions/base_spec.rb +67 -0
  187. data/spec/grape/exceptions/body_parse_errors_spec.rb +2 -0
  188. data/spec/grape/exceptions/invalid_accept_header_spec.rb +2 -0
  189. data/spec/grape/exceptions/invalid_formatter_spec.rb +2 -1
  190. data/spec/grape/exceptions/invalid_response_spec.rb +13 -0
  191. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +2 -1
  192. data/spec/grape/exceptions/missing_mime_type_spec.rb +2 -0
  193. data/spec/grape/exceptions/missing_option_spec.rb +2 -1
  194. data/spec/grape/exceptions/unknown_options_spec.rb +3 -2
  195. data/spec/grape/exceptions/unknown_validator_spec.rb +2 -1
  196. data/spec/grape/exceptions/validation_errors_spec.rb +17 -4
  197. data/spec/grape/exceptions/validation_spec.rb +3 -1
  198. data/spec/grape/extensions/param_builders/hash_spec.rb +2 -0
  199. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +2 -0
  200. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +2 -0
  201. data/spec/grape/integration/global_namespace_function_spec.rb +2 -0
  202. data/spec/grape/integration/rack_sendfile_spec.rb +14 -8
  203. data/spec/grape/integration/rack_spec.rb +25 -7
  204. data/spec/grape/loading_spec.rb +2 -0
  205. data/spec/grape/middleware/auth/base_spec.rb +2 -0
  206. data/spec/grape/middleware/auth/dsl_spec.rb +6 -4
  207. data/spec/grape/middleware/auth/strategies_spec.rb +3 -1
  208. data/spec/grape/middleware/base_spec.rb +10 -0
  209. data/spec/grape/middleware/error_spec.rb +4 -3
  210. data/spec/grape/middleware/exception_spec.rb +205 -55
  211. data/spec/grape/middleware/formatter_spec.rb +130 -15
  212. data/spec/grape/middleware/globals_spec.rb +2 -0
  213. data/spec/grape/middleware/stack_spec.rb +15 -1
  214. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -1
  215. data/spec/grape/middleware/versioner/header_spec.rb +10 -2
  216. data/spec/grape/middleware/versioner/param_spec.rb +4 -2
  217. data/spec/grape/middleware/versioner/path_spec.rb +4 -2
  218. data/spec/grape/middleware/versioner_spec.rb +2 -0
  219. data/spec/grape/named_api_spec.rb +21 -0
  220. data/spec/grape/parser_spec.rb +7 -5
  221. data/spec/grape/path_spec.rb +9 -7
  222. data/spec/grape/presenters/presenter_spec.rb +2 -0
  223. data/spec/grape/request_spec.rb +26 -0
  224. data/spec/grape/util/inheritable_setting_spec.rb +4 -2
  225. data/spec/grape/util/inheritable_values_spec.rb +2 -0
  226. data/spec/grape/util/reverse_stackable_values_spec.rb +15 -13
  227. data/spec/grape/util/stackable_values_spec.rb +16 -14
  228. data/spec/grape/util/strict_hash_configuration_spec.rb +3 -1
  229. data/spec/grape/validations/attributes_iterator_spec.rb +2 -0
  230. data/spec/grape/validations/instance_behaivour_spec.rb +5 -3
  231. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +41 -0
  232. data/spec/grape/validations/params_scope_spec.rb +364 -7
  233. data/spec/grape/validations/single_attribute_iterator_spec.rb +58 -0
  234. data/spec/grape/validations/types/array_coercer_spec.rb +35 -0
  235. data/spec/grape/validations/types/primitive_coercer_spec.rb +135 -0
  236. data/spec/grape/validations/types/set_coercer_spec.rb +34 -0
  237. data/spec/grape/validations/types_spec.rb +9 -36
  238. data/spec/grape/validations/validators/all_or_none_spec.rb +140 -30
  239. data/spec/grape/validations/validators/allow_blank_spec.rb +2 -0
  240. data/spec/grape/validations/validators/at_least_one_of_spec.rb +175 -29
  241. data/spec/grape/validations/validators/coerce_spec.rb +558 -133
  242. data/spec/grape/validations/validators/default_spec.rb +212 -0
  243. data/spec/grape/validations/validators/exactly_one_of_spec.rb +204 -38
  244. data/spec/grape/validations/validators/except_values_spec.rb +6 -3
  245. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +186 -27
  246. data/spec/grape/validations/validators/presence_spec.rb +30 -0
  247. data/spec/grape/validations/validators/regexp_spec.rb +2 -0
  248. data/spec/grape/validations/validators/same_as_spec.rb +65 -0
  249. data/spec/grape/validations/validators/values_spec.rb +73 -19
  250. data/spec/grape/validations_spec.rb +403 -53
  251. data/spec/integration/eager_load/eager_load_spec.rb +15 -0
  252. data/spec/integration/multi_json/json_spec.rb +2 -0
  253. data/spec/integration/multi_xml/xml_spec.rb +2 -0
  254. data/spec/shared/versioning_examples.rb +78 -18
  255. data/spec/spec_helper.rb +13 -2
  256. data/spec/support/basic_auth_encode_helpers.rb +3 -1
  257. data/spec/support/chunks.rb +14 -0
  258. data/spec/support/content_type_helpers.rb +3 -1
  259. data/spec/support/eager_load.rb +19 -0
  260. data/spec/support/endpoint_faker.rb +2 -0
  261. data/spec/support/file_streamer.rb +2 -0
  262. data/spec/support/integer_helpers.rb +2 -0
  263. data/spec/support/versioned_helpers.rb +8 -8
  264. metadata +176 -130
  265. data/Appraisals +0 -32
  266. data/Dangerfile +0 -1
  267. data/Gemfile +0 -34
  268. data/Gemfile.lock +0 -229
  269. data/Guardfile +0 -10
  270. data/RELEASING.md +0 -111
  271. data/Rakefile +0 -70
  272. data/benchmark/simple.rb +0 -27
  273. data/benchmark/simple_with_type_coercer.rb +0 -22
  274. data/gemfiles/multi_json.gemfile +0 -36
  275. data/gemfiles/multi_xml.gemfile +0 -36
  276. data/gemfiles/rack_1.5.2.gemfile +0 -36
  277. data/gemfiles/rack_edge.gemfile +0 -36
  278. data/gemfiles/rails_3.gemfile +0 -37
  279. data/gemfiles/rails_4.gemfile +0 -36
  280. data/gemfiles/rails_5.gemfile +0 -36
  281. data/gemfiles/rails_edge.gemfile +0 -36
  282. data/lib/grape/extensions/deep_hash_with_indifferent_access.rb +0 -18
  283. data/lib/grape/util/content_types.rb +0 -26
  284. data/lib/grape/validations/types/virtus_collection_patch.rb +0 -16
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'grape_entity'
3
5
 
@@ -114,7 +116,7 @@ describe Grape::Entity do
114
116
  expect(last_response.body).to eq('Auto-detect!')
115
117
  end
116
118
 
117
- it 'does not run autodetection for Entity when explicitely provided' do
119
+ it 'does not run autodetection for Entity when explicitly provided' do
118
120
  entity = Class.new(Grape::Entity)
119
121
  some_array = []
120
122
 
@@ -169,7 +171,7 @@ describe Grape::Entity do
169
171
  expect(inner_body).to eql(root: { abc: 'def' })
170
172
  end
171
173
 
172
- [:json, :serializable_hash].each do |format|
174
+ %i[json serializable_hash].each do |format|
173
175
  it "presents with #{format}" do
174
176
  entity = Class.new(Grape::Entity)
175
177
  entity.root 'examples', 'example'
@@ -179,6 +181,7 @@ describe Grape::Entity do
179
181
  subject.get '/example' do
180
182
  c = Class.new do
181
183
  attr_reader :id
184
+
182
185
  def initialize(id)
183
186
  @id = id
184
187
  end
@@ -200,6 +203,7 @@ describe Grape::Entity do
200
203
  subject.get '/examples' do
201
204
  c = Class.new do
202
205
  attr_reader :id
206
+
203
207
  def initialize(id)
204
208
  @id = id
205
209
  end
@@ -224,6 +228,7 @@ describe Grape::Entity do
224
228
  subject.get '/example' do
225
229
  c = Class.new do
226
230
  attr_reader :name
231
+
227
232
  def initialize(args)
228
233
  @name = args[:name] || 'no name set'
229
234
  end
@@ -233,14 +238,14 @@ describe Grape::Entity do
233
238
  get '/example'
234
239
  expect(last_response.status).to eq(200)
235
240
  expect(last_response.headers['Content-type']).to eq('application/xml')
236
- expect(last_response.body).to eq <<-XML
237
- <?xml version="1.0" encoding="UTF-8"?>
238
- <hash>
239
- <example>
240
- <name>johnnyiller</name>
241
- </example>
242
- </hash>
243
- XML
241
+ expect(last_response.body).to eq <<~XML
242
+ <?xml version="1.0" encoding="UTF-8"?>
243
+ <hash>
244
+ <example>
245
+ <name>johnnyiller</name>
246
+ </example>
247
+ </hash>
248
+ XML
244
249
  end
245
250
 
246
251
  it 'presents with json' do
@@ -253,6 +258,7 @@ XML
253
258
  subject.get '/example' do
254
259
  c = Class.new do
255
260
  attr_reader :name
261
+
256
262
  def initialize(args)
257
263
  @name = args[:name] || 'no name set'
258
264
  end
@@ -282,6 +288,7 @@ XML
282
288
  subject.get '/example' do
283
289
  c = Class.new do
284
290
  attr_reader :name
291
+
285
292
  def initialize(args)
286
293
  @name = args[:name] || 'no name set'
287
294
  end
@@ -300,6 +307,7 @@ XML
300
307
  it 'present with multiple entities using optional symbol' do
301
308
  user = Class.new do
302
309
  attr_reader :name
310
+
303
311
  def initialize(args)
304
312
  @name = args[:name] || 'no name set'
305
313
  end
@@ -318,7 +326,7 @@ XML
318
326
  end
319
327
  get '/example'
320
328
  expect_response_json = {
321
- 'page' => 1,
329
+ 'page' => 1,
322
330
  'user1' => { 'name' => 'user1' },
323
331
  'user2' => { 'name' => 'user2' }
324
332
  }
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Grape::Exceptions::Base do
6
+ describe '#compose_message' do
7
+ subject { described_class.new.send(:compose_message, key, **attributes) }
8
+
9
+ let(:key) { :invalid_formatter }
10
+ let(:attributes) { { klass: String, to_format: 'xml' } }
11
+
12
+ after do
13
+ I18n.enforce_available_locales = true
14
+ I18n.available_locales = %i[en]
15
+ I18n.locale = :en
16
+ I18n.default_locale = :en
17
+ I18n.reload!
18
+ end
19
+
20
+ context 'when I18n enforces available locales' do
21
+ before { I18n.enforce_available_locales = true }
22
+
23
+ context 'when the fallback locale is available' do
24
+ before do
25
+ I18n.available_locales = %i[de en]
26
+ I18n.default_locale = :de
27
+ end
28
+
29
+ it 'returns the translated message' do
30
+ expect(subject).to eq('cannot convert String to xml')
31
+ end
32
+ end
33
+
34
+ context 'when the fallback locale is not available' do
35
+ before do
36
+ I18n.available_locales = %i[de jp]
37
+ I18n.locale = :de
38
+ I18n.default_locale = :de
39
+ end
40
+
41
+ it 'returns the translation string' do
42
+ expect(subject).to eq("grape.errors.messages.#{key}")
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'when I18n does not enforce available locales' do
48
+ before { I18n.enforce_available_locales = false }
49
+
50
+ context 'when the fallback locale is available' do
51
+ before { I18n.available_locales = %i[de en] }
52
+
53
+ it 'returns the translated message' do
54
+ expect(subject).to eq('cannot convert String to xml')
55
+ end
56
+ end
57
+
58
+ context 'when the fallback locale is not available' do
59
+ before { I18n.available_locales = %i[de jp] }
60
+
61
+ it 'returns the translated message' do
62
+ expect(subject).to eq('cannot convert String to xml')
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Exceptions::ValidationErrors do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Exceptions::InvalidAcceptHeader do
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'spec_helper'
3
4
 
4
5
  describe Grape::Exceptions::InvalidFormatter do
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Grape::Exceptions::InvalidResponse do
6
+ describe '#message' do
7
+ let(:error) { described_class.new }
8
+
9
+ it 'contains the problem in the message' do
10
+ expect(error.message).to include('Invalid response')
11
+ end
12
+ end
13
+ end
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'spec_helper'
3
4
 
4
5
  describe Grape::Exceptions::InvalidVersionerOption do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Exceptions::MissingMimeType do
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'spec_helper'
3
4
 
4
5
  describe Grape::Exceptions::MissingOption do
@@ -1,10 +1,11 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'spec_helper'
3
4
 
4
5
  describe Grape::Exceptions::UnknownOptions do
5
6
  describe '#message' do
6
7
  let(:error) do
7
- described_class.new([:a, :b])
8
+ described_class.new(%i[a b])
8
9
  end
9
10
 
10
11
  it 'contains the problem in the message' do
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'spec_helper'
3
4
 
4
5
  describe Grape::Exceptions::UnknownValidator do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'ostruct'
3
5
 
@@ -43,6 +45,15 @@ describe Grape::Exceptions::ValidationErrors do
43
45
  expect(subject).to contain_exactly('id is missing', 'name is missing')
44
46
  end
45
47
  end
48
+
49
+ 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
+ subject { described_class.new(errors: [validation_error]).full_messages }
52
+
53
+ it 'returns an array with an error full message' do
54
+ expect(subject.first).to eq('admin_field Can not set admin-only field')
55
+ end
56
+ end
46
57
  end
47
58
 
48
59
  context 'api' do
@@ -68,10 +79,12 @@ describe Grape::Exceptions::ValidationErrors do
68
79
  end
69
80
  get '/exactly_one_of', beer: 'string', wine: 'anotherstring'
70
81
  expect(last_response.status).to eq(400)
71
- expect(JSON.parse(last_response.body)).to eq([
72
- 'params' => %w(beer wine),
73
- 'messages' => ['are mutually exclusive']
74
- ])
82
+ expect(JSON.parse(last_response.body)).to eq(
83
+ [
84
+ 'params' => %w[beer wine],
85
+ 'messages' => ['are mutually exclusive']
86
+ ]
87
+ )
75
88
  end
76
89
  end
77
90
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Exceptions::Validation do
4
6
  it 'fails when params are missing' do
5
- expect { Grape::Exceptions::Validation.new(message: 'presence') }.to raise_error(ArgumentError, 'missing keyword: params')
7
+ expect { Grape::Exceptions::Validation.new(message: 'presence') }.to raise_error(ArgumentError, /missing keyword:.+?params/)
6
8
  end
7
9
  context 'when message is a symbol' do
8
10
  it 'stores message_key' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Extensions::Hash::ParamBuilder do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Extensions::Hashie::Mash::ParamBuilder do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # see https://github.com/ruby-grape/grape/issues/1348
2
4
 
3
5
  require 'spec_helper'
@@ -1,13 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Rack::Sendfile do
4
6
  subject do
5
- send_file = file_streamer
7
+ content_object = file_object
6
8
  app = Class.new(Grape::API) do
7
9
  use Rack::Sendfile
8
10
  format :json
9
11
  get do
10
- file send_file
12
+ if content_object.is_a?(String)
13
+ sendfile content_object
14
+ else
15
+ stream content_object
16
+ end
11
17
  end
12
18
  end
13
19
 
@@ -20,9 +26,9 @@ describe Rack::Sendfile do
20
26
  app.call(env)
21
27
  end
22
28
 
23
- context do
24
- let(:file_streamer) do
25
- double(:file_streamer, to_path: '/accel/mapping/some/path')
29
+ context 'when calling sendfile' do
30
+ let(:file_object) do
31
+ '/accel/mapping/some/path'
26
32
  end
27
33
 
28
34
  it 'contains Sendfile headers' do
@@ -31,9 +37,9 @@ describe Rack::Sendfile do
31
37
  end
32
38
  end
33
39
 
34
- context do
35
- let(:file_streamer) do
36
- double(:file_streamer)
40
+ context 'when streaming non file content' do
41
+ let(:file_object) do
42
+ double(:file_object, each: nil)
37
43
  end
38
44
 
39
45
  it 'not contains Sendfile headers' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Rack do
@@ -19,16 +21,32 @@ describe Rack do
19
21
  }
20
22
  env = Rack::MockRequest.env_for('/', options)
21
23
 
22
- unless RUBY_PLATFORM == 'java'
23
- major, minor, patch = Rack.release.split('.').map(&:to_i)
24
- patch ||= 0 # rack <= 1.5.2 does not specify patch version
25
- pending 'Rack 1.5.3 or 1.6.1 required' unless major >= 2 || (major >= 1 && ((minor == 5 && patch >= 3) || (minor >= 6)))
26
- end
27
-
28
- expect(JSON.parse(app.call(env)[2].body.first)['params_keys']).to match_array('test')
24
+ expect(JSON.parse(read_chunks(app.call(env)[2]).join)['params_keys']).to match_array('test')
29
25
  ensure
30
26
  input.close
31
27
  input.unlink
32
28
  end
33
29
  end
30
+
31
+ context 'when the app is mounted' do
32
+ def app
33
+ @main_app ||= Class.new(Grape::API) do
34
+ get 'ping'
35
+ end
36
+ end
37
+
38
+ let!(:base) do
39
+ app_to_mount = app
40
+ Class.new(Grape::API) do
41
+ namespace 'namespace' do
42
+ mount app_to_mount
43
+ end
44
+ end
45
+ end
46
+
47
+ it 'finds the app on the namespace' do
48
+ get '/namespace/ping'
49
+ expect(last_response.status).to eq 200
50
+ end
51
+ end
34
52
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::API do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'base64'
3
5
 
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Middleware::Auth::DSL do
4
6
  subject { Class.new(Grape::API) }
5
7
 
6
- let(:block) { ->() {} }
8
+ let(:block) { -> {} }
7
9
  let(:settings) do
8
10
  {
9
11
  opaque: 'secret',
@@ -15,15 +17,15 @@ describe Grape::Middleware::Auth::DSL do
15
17
 
16
18
  describe '.auth' do
17
19
  it 'stets auth parameters' do
18
- expect(subject).to receive(:use).with(Grape::Middleware::Auth::Base, settings)
20
+ expect(subject.base_instance).to receive(:use).with(Grape::Middleware::Auth::Base, settings)
19
21
 
20
22
  subject.auth :http_digest, realm: settings[:realm], opaque: settings[:opaque], &settings[:proc]
21
23
  expect(subject.auth).to eq(settings)
22
24
  end
23
25
 
24
26
  it 'can be called multiple times' do
25
- expect(subject).to receive(:use).with(Grape::Middleware::Auth::Base, settings)
26
- expect(subject).to receive(:use).with(Grape::Middleware::Auth::Base, settings.merge(realm: 'super_secret'))
27
+ expect(subject.base_instance).to receive(:use).with(Grape::Middleware::Auth::Base, settings)
28
+ expect(subject.base_instance).to receive(:use).with(Grape::Middleware::Auth::Base, settings.merge(realm: 'super_secret'))
27
29
 
28
30
  subject.auth :http_digest, realm: settings[:realm], opaque: settings[:opaque], &settings[:proc]
29
31
  first_settings = subject.auth
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  require 'base64'
@@ -34,7 +36,7 @@ describe Grape::Middleware::Auth::Strategies do
34
36
  RSpec::Matchers.define :be_challenge do
35
37
  match do |actual_response|
36
38
  actual_response.status == 401 &&
37
- actual_response['WWW-Authenticate'] =~ /^Digest / &&
39
+ actual_response['WWW-Authenticate'].start_with?('Digest ') &&
38
40
  actual_response.body.empty?
39
41
  end
40
42
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Middleware::Base do
@@ -114,6 +116,14 @@ describe Grape::Middleware::Base do
114
116
  end
115
117
  end
116
118
 
119
+ describe '#context' do
120
+ subject { Grape::Middleware::Base.new(blank_app) }
121
+ it 'allows access to response context' do
122
+ subject.call(Grape::Env::API_ENDPOINT => { header: 'some header' })
123
+ expect(subject.context).to eq(header: 'some header')
124
+ end
125
+ end
126
+
117
127
  context 'options' do
118
128
  it 'persists options passed at initialization' do
119
129
  expect(Grape::Middleware::Base.new(blank_app, abc: true).options[:abc]).to be true
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'grape-entity'
3
5
 
@@ -14,8 +16,7 @@ describe Grape::Middleware::Error do
14
16
 
15
17
  class ErrApp
16
18
  class << self
17
- attr_accessor :error
18
- attr_accessor :format
19
+ attr_accessor :error, :format
19
20
 
20
21
  def call(_env)
21
22
  throw :error, error
@@ -28,7 +29,7 @@ describe Grape::Middleware::Error do
28
29
  opts = options
29
30
  Rack::Builder.app do
30
31
  use Spec::Support::EndpointFaker
31
- use Grape::Middleware::Error, opts
32
+ use Grape::Middleware::Error, **opts
32
33
  run ErrorSpec::ErrApp
33
34
  end
34
35
  end