grape 1.1.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +370 -44
  3. data/CONTRIBUTING.md +32 -1
  4. data/LICENSE +1 -1
  5. data/README.md +683 -87
  6. data/UPGRADING.md +481 -17
  7. data/grape.gemspec +15 -4
  8. data/lib/grape/api/helpers.rb +2 -0
  9. data/lib/grape/api/instance.rb +279 -0
  10. data/lib/grape/api.rb +144 -176
  11. data/lib/grape/config.rb +34 -0
  12. data/lib/grape/content_types.rb +34 -0
  13. data/lib/grape/cookies.rb +4 -0
  14. data/lib/grape/dry_types.rb +12 -0
  15. data/lib/grape/dsl/api.rb +1 -1
  16. data/lib/grape/dsl/callbacks.rb +21 -1
  17. data/lib/grape/dsl/configuration.rb +1 -1
  18. data/lib/grape/dsl/desc.rb +41 -23
  19. data/lib/grape/dsl/headers.rb +7 -2
  20. data/lib/grape/dsl/helpers.rb +10 -7
  21. data/lib/grape/dsl/inside_route.rb +118 -62
  22. data/lib/grape/dsl/logger.rb +2 -0
  23. data/lib/grape/dsl/middleware.rb +11 -4
  24. data/lib/grape/dsl/parameters.rb +33 -19
  25. data/lib/grape/dsl/request_response.rb +12 -9
  26. data/lib/grape/dsl/routing.rb +22 -13
  27. data/lib/grape/dsl/settings.rb +10 -6
  28. data/lib/grape/dsl/validations.rb +19 -14
  29. data/lib/grape/eager_load.rb +20 -0
  30. data/lib/grape/endpoint.rb +67 -58
  31. data/lib/grape/error_formatter/base.rb +2 -0
  32. data/lib/grape/error_formatter/json.rb +11 -7
  33. data/lib/grape/error_formatter/txt.rb +2 -0
  34. data/lib/grape/error_formatter/xml.rb +4 -6
  35. data/lib/grape/error_formatter.rb +4 -2
  36. data/lib/grape/exceptions/base.rb +23 -16
  37. data/lib/grape/exceptions/empty_message_body.rb +11 -0
  38. data/lib/grape/exceptions/incompatible_option_values.rb +2 -0
  39. data/lib/grape/exceptions/invalid_accept_header.rb +2 -0
  40. data/lib/grape/exceptions/invalid_formatter.rb +2 -0
  41. data/lib/grape/exceptions/invalid_message_body.rb +2 -0
  42. data/lib/grape/exceptions/invalid_response.rb +11 -0
  43. data/lib/grape/exceptions/invalid_version_header.rb +2 -0
  44. data/lib/grape/exceptions/invalid_versioner_option.rb +2 -0
  45. data/lib/grape/exceptions/invalid_with_option_for_represent.rb +2 -0
  46. data/lib/grape/exceptions/method_not_allowed.rb +2 -0
  47. data/lib/grape/exceptions/missing_group_type.rb +10 -1
  48. data/lib/grape/exceptions/missing_mime_type.rb +2 -0
  49. data/lib/grape/exceptions/missing_option.rb +2 -0
  50. data/lib/grape/exceptions/missing_vendor_option.rb +2 -0
  51. data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
  52. data/lib/grape/exceptions/unknown_options.rb +2 -0
  53. data/lib/grape/exceptions/unknown_parameter.rb +2 -0
  54. data/lib/grape/exceptions/unknown_validator.rb +2 -0
  55. data/lib/grape/exceptions/unsupported_group_type.rb +10 -1
  56. data/lib/grape/exceptions/validation.rb +5 -8
  57. data/lib/grape/exceptions/validation_array_errors.rb +2 -0
  58. data/lib/grape/exceptions/validation_errors.rb +16 -13
  59. data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +4 -3
  60. data/lib/grape/extensions/deep_mergeable_hash.rb +2 -0
  61. data/lib/grape/extensions/deep_symbolize_hash.rb +2 -0
  62. data/lib/grape/extensions/hash.rb +2 -0
  63. data/lib/grape/extensions/hashie/mash.rb +2 -0
  64. data/lib/grape/formatter/json.rb +3 -0
  65. data/lib/grape/formatter/serializable_hash.rb +4 -1
  66. data/lib/grape/formatter/txt.rb +2 -0
  67. data/lib/grape/formatter/xml.rb +3 -0
  68. data/lib/grape/formatter.rb +5 -3
  69. data/lib/grape/http/headers.rb +50 -18
  70. data/lib/grape/locale/en.yml +11 -8
  71. data/lib/grape/middleware/auth/base.rb +7 -7
  72. data/lib/grape/middleware/auth/dsl.rb +9 -2
  73. data/lib/grape/middleware/auth/strategies.rb +2 -0
  74. data/lib/grape/middleware/auth/strategy_info.rb +2 -0
  75. data/lib/grape/middleware/base.rb +13 -8
  76. data/lib/grape/middleware/error.rb +22 -17
  77. data/lib/grape/middleware/filter.rb +2 -0
  78. data/lib/grape/middleware/formatter.rb +12 -10
  79. data/lib/grape/middleware/globals.rb +2 -0
  80. data/lib/grape/middleware/helpers.rb +12 -0
  81. data/lib/grape/middleware/stack.rb +16 -6
  82. data/lib/grape/middleware/versioner/accept_version_header.rb +5 -5
  83. data/lib/grape/middleware/versioner/header.rb +13 -9
  84. data/lib/grape/middleware/versioner/param.rb +4 -1
  85. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +5 -1
  86. data/lib/grape/middleware/versioner/path.rb +5 -1
  87. data/lib/grape/middleware/versioner.rb +2 -0
  88. data/lib/grape/namespace.rb +14 -2
  89. data/lib/grape/parser/json.rb +3 -1
  90. data/lib/grape/parser/xml.rb +3 -1
  91. data/lib/grape/parser.rb +4 -2
  92. data/lib/grape/path.rb +16 -3
  93. data/lib/grape/presenters/presenter.rb +2 -0
  94. data/lib/grape/request.rb +21 -9
  95. data/lib/grape/router/attribute_translator.rb +41 -8
  96. data/lib/grape/router/pattern.rb +21 -17
  97. data/lib/grape/router/route.rb +15 -29
  98. data/lib/grape/router.rb +36 -29
  99. data/lib/grape/{serve_file → serve_stream}/file_body.rb +3 -1
  100. data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +3 -1
  101. data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +10 -8
  102. data/lib/grape/types/invalid_value.rb +8 -0
  103. data/lib/grape/util/base_inheritable.rb +43 -0
  104. data/lib/grape/util/cache.rb +20 -0
  105. data/lib/grape/util/endpoint_configuration.rb +8 -0
  106. data/lib/grape/util/env.rb +19 -17
  107. data/lib/grape/util/inheritable_setting.rb +3 -3
  108. data/lib/grape/util/inheritable_values.rb +7 -25
  109. data/lib/grape/util/json.rb +4 -0
  110. data/lib/grape/util/lazy_block.rb +27 -0
  111. data/lib/grape/util/lazy_object.rb +43 -0
  112. data/lib/grape/util/lazy_value.rb +99 -0
  113. data/lib/grape/util/registrable.rb +2 -0
  114. data/lib/grape/util/reverse_stackable_values.rb +10 -35
  115. data/lib/grape/util/stackable_values.rb +21 -34
  116. data/lib/grape/util/strict_hash_configuration.rb +3 -1
  117. data/lib/grape/util/xml.rb +2 -0
  118. data/lib/grape/validations/attributes_doc.rb +58 -0
  119. data/lib/grape/validations/attributes_iterator.rb +16 -6
  120. data/lib/grape/validations/multiple_attributes_iterator.rb +13 -0
  121. data/lib/grape/validations/params_scope.rb +174 -94
  122. data/lib/grape/validations/single_attribute_iterator.rb +24 -0
  123. data/lib/grape/validations/types/array_coercer.rb +63 -0
  124. data/lib/grape/validations/types/build_coercer.rb +47 -49
  125. data/lib/grape/validations/types/custom_type_coercer.rb +30 -51
  126. data/lib/grape/validations/types/custom_type_collection_coercer.rb +10 -25
  127. data/lib/grape/validations/types/dry_type_coercer.rb +72 -0
  128. data/lib/grape/validations/types/file.rb +22 -18
  129. data/lib/grape/validations/types/invalid_value.rb +17 -0
  130. data/lib/grape/validations/types/json.rb +47 -39
  131. data/lib/grape/validations/types/multiple_type_coercer.rb +14 -33
  132. data/lib/grape/validations/types/primitive_coercer.rb +75 -0
  133. data/lib/grape/validations/types/set_coercer.rb +38 -0
  134. data/lib/grape/validations/types/variant_collection_coercer.rb +5 -13
  135. data/lib/grape/validations/types.rb +106 -63
  136. data/lib/grape/validations/validator_factory.rb +8 -11
  137. data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
  138. data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
  139. data/lib/grape/validations/validators/as_validator.rb +14 -0
  140. data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
  141. data/lib/grape/validations/validators/base.rb +84 -68
  142. data/lib/grape/validations/validators/coerce_validator.rb +75 -0
  143. data/lib/grape/validations/validators/default_validator.rb +51 -0
  144. data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
  145. data/lib/grape/validations/validators/except_values_validator.rb +24 -0
  146. data/lib/grape/validations/validators/multiple_params_base.rb +27 -16
  147. data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
  148. data/lib/grape/validations/validators/presence_validator.rb +15 -0
  149. data/lib/grape/validations/validators/regexp_validator.rb +16 -0
  150. data/lib/grape/validations/validators/same_as_validator.rb +29 -0
  151. data/lib/grape/validations/validators/values_validator.rb +88 -0
  152. data/lib/grape/validations.rb +18 -6
  153. data/lib/grape/version.rb +3 -1
  154. data/lib/grape.rb +175 -94
  155. data/spec/grape/api/custom_validations_spec.rb +117 -44
  156. data/spec/grape/api/deeply_included_options_spec.rb +4 -4
  157. data/spec/grape/api/defines_boolean_in_params_spec.rb +38 -0
  158. data/spec/grape/api/documentation_spec.rb +59 -0
  159. data/spec/grape/api/inherited_helpers_spec.rb +1 -1
  160. data/spec/grape/api/instance_spec.rb +103 -0
  161. data/spec/grape/api/invalid_format_spec.rb +3 -1
  162. data/spec/grape/api/namespace_parameters_in_route_spec.rb +1 -1
  163. data/spec/grape/api/nested_helpers_spec.rb +1 -1
  164. data/spec/grape/api/optional_parameters_in_route_spec.rb +1 -1
  165. data/spec/grape/api/parameters_modification_spec.rb +2 -2
  166. data/spec/grape/api/patch_method_helpers_spec.rb +1 -1
  167. data/spec/grape/api/recognize_path_spec.rb +2 -2
  168. data/spec/grape/api/required_parameters_in_route_spec.rb +1 -1
  169. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +1 -1
  170. data/spec/grape/api/routes_with_requirements_spec.rb +59 -0
  171. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +10 -16
  172. data/spec/grape/api/shared_helpers_spec.rb +1 -1
  173. data/spec/grape/api_remount_spec.rb +473 -0
  174. data/spec/grape/api_spec.rb +995 -231
  175. data/spec/grape/config_spec.rb +17 -0
  176. data/spec/grape/dsl/callbacks_spec.rb +3 -2
  177. data/spec/grape/dsl/desc_spec.rb +43 -17
  178. data/spec/grape/dsl/headers_spec.rb +40 -10
  179. data/spec/grape/dsl/helpers_spec.rb +6 -5
  180. data/spec/grape/dsl/inside_route_spec.rb +189 -38
  181. data/spec/grape/dsl/logger_spec.rb +17 -19
  182. data/spec/grape/dsl/middleware_spec.rb +11 -2
  183. data/spec/grape/dsl/parameters_spec.rb +3 -1
  184. data/spec/grape/dsl/request_response_spec.rb +8 -7
  185. data/spec/grape/dsl/routing_spec.rb +22 -9
  186. data/spec/grape/dsl/settings_spec.rb +1 -1
  187. data/spec/grape/dsl/validations_spec.rb +1 -16
  188. data/spec/grape/endpoint/declared_spec.rb +846 -0
  189. data/spec/grape/endpoint_spec.rb +136 -577
  190. data/spec/grape/entity_spec.rb +31 -24
  191. data/spec/grape/exceptions/base_spec.rb +81 -0
  192. data/spec/grape/exceptions/body_parse_errors_spec.rb +4 -1
  193. data/spec/grape/exceptions/invalid_accept_header_spec.rb +65 -23
  194. data/spec/grape/exceptions/invalid_formatter_spec.rb +1 -1
  195. data/spec/grape/exceptions/invalid_response_spec.rb +11 -0
  196. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +2 -2
  197. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  198. data/spec/grape/exceptions/missing_mime_type_spec.rb +1 -1
  199. data/spec/grape/exceptions/missing_option_spec.rb +2 -2
  200. data/spec/grape/exceptions/unknown_options_spec.rb +1 -1
  201. data/spec/grape/exceptions/unknown_validator_spec.rb +1 -1
  202. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  203. data/spec/grape/exceptions/validation_errors_spec.rb +21 -15
  204. data/spec/grape/exceptions/validation_spec.rb +6 -4
  205. data/spec/grape/extensions/param_builders/hash_spec.rb +8 -8
  206. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +9 -9
  207. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +9 -9
  208. data/spec/grape/integration/global_namespace_function_spec.rb +2 -2
  209. data/spec/grape/integration/rack_sendfile_spec.rb +14 -10
  210. data/spec/grape/integration/rack_spec.rb +25 -8
  211. data/spec/grape/loading_spec.rb +9 -9
  212. data/spec/grape/middleware/auth/base_spec.rb +2 -1
  213. data/spec/grape/middleware/auth/dsl_spec.rb +19 -10
  214. data/spec/grape/middleware/auth/strategies_spec.rb +62 -22
  215. data/spec/grape/middleware/base_spec.rb +36 -17
  216. data/spec/grape/middleware/error_spec.rb +11 -4
  217. data/spec/grape/middleware/exception_spec.rb +112 -162
  218. data/spec/grape/middleware/formatter_spec.rb +65 -29
  219. data/spec/grape/middleware/globals_spec.rb +8 -5
  220. data/spec/grape/middleware/stack_spec.rb +25 -13
  221. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -2
  222. data/spec/grape/middleware/versioner/header_spec.rb +37 -14
  223. data/spec/grape/middleware/versioner/param_spec.rb +8 -2
  224. data/spec/grape/middleware/versioner/path_spec.rb +6 -2
  225. data/spec/grape/middleware/versioner_spec.rb +2 -2
  226. data/spec/grape/named_api_spec.rb +19 -0
  227. data/spec/grape/parser_spec.rb +10 -6
  228. data/spec/grape/path_spec.rb +53 -53
  229. data/spec/grape/presenters/presenter_spec.rb +8 -7
  230. data/spec/grape/request_spec.rb +29 -3
  231. data/spec/grape/util/inheritable_setting_spec.rb +9 -8
  232. data/spec/grape/util/inheritable_values_spec.rb +5 -3
  233. data/spec/grape/util/reverse_stackable_values_spec.rb +5 -2
  234. data/spec/grape/util/stackable_values_spec.rb +10 -7
  235. data/spec/grape/util/strict_hash_configuration_spec.rb +2 -1
  236. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  237. data/spec/grape/validations/instance_behaivour_spec.rb +13 -14
  238. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +40 -0
  239. data/spec/grape/validations/params_scope_spec.rb +568 -99
  240. data/spec/grape/validations/single_attribute_iterator_spec.rb +57 -0
  241. data/spec/grape/validations/types/array_coercer_spec.rb +33 -0
  242. data/spec/grape/validations/types/primitive_coercer_spec.rb +150 -0
  243. data/spec/grape/validations/types/set_coercer_spec.rb +32 -0
  244. data/spec/grape/validations/types_spec.rb +44 -45
  245. data/spec/grape/validations/validators/all_or_none_spec.rb +134 -32
  246. data/spec/grape/validations/validators/allow_blank_spec.rb +137 -141
  247. data/spec/grape/validations/validators/at_least_one_of_spec.rb +169 -31
  248. data/spec/grape/validations/validators/coerce_spec.rb +491 -151
  249. data/spec/grape/validations/validators/default_spec.rb +242 -78
  250. data/spec/grape/validations/validators/exactly_one_of_spec.rb +198 -40
  251. data/spec/grape/validations/validators/except_values_spec.rb +6 -5
  252. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +181 -30
  253. data/spec/grape/validations/validators/presence_spec.rb +45 -2
  254. data/spec/grape/validations/validators/regexp_spec.rb +27 -33
  255. data/spec/grape/validations/validators/same_as_spec.rb +57 -0
  256. data/spec/grape/validations/validators/values_spec.rb +227 -180
  257. data/spec/grape/validations_spec.rb +502 -72
  258. data/spec/integration/eager_load/eager_load_spec.rb +15 -0
  259. data/spec/integration/multi_json/json_spec.rb +2 -2
  260. data/spec/integration/multi_xml/xml_spec.rb +2 -2
  261. data/spec/shared/versioning_examples.rb +34 -29
  262. data/spec/spec_helper.rb +31 -5
  263. data/spec/support/basic_auth_encode_helpers.rb +3 -1
  264. data/spec/support/chunks.rb +14 -0
  265. data/spec/support/content_type_helpers.rb +2 -0
  266. data/spec/support/endpoint_faker.rb +2 -0
  267. data/spec/support/file_streamer.rb +2 -0
  268. data/spec/support/integer_helpers.rb +2 -0
  269. data/spec/support/versioned_helpers.rb +8 -8
  270. metadata +111 -61
  271. data/Appraisals +0 -32
  272. data/Dangerfile +0 -2
  273. data/Gemfile +0 -33
  274. data/Gemfile.lock +0 -231
  275. data/Guardfile +0 -10
  276. data/RELEASING.md +0 -111
  277. data/Rakefile +0 -25
  278. data/benchmark/simple.rb +0 -27
  279. data/benchmark/simple_with_type_coercer.rb +0 -22
  280. data/gemfiles/multi_json.gemfile +0 -35
  281. data/gemfiles/multi_xml.gemfile +0 -35
  282. data/gemfiles/rack_1.5.2.gemfile +0 -35
  283. data/gemfiles/rack_edge.gemfile +0 -35
  284. data/gemfiles/rails_3.gemfile +0 -36
  285. data/gemfiles/rails_4.gemfile +0 -35
  286. data/gemfiles/rails_5.gemfile +0 -35
  287. data/gemfiles/rails_edge.gemfile +0 -35
  288. data/lib/grape/extensions/deep_hash_with_indifferent_access.rb +0 -18
  289. data/lib/grape/util/content_types.rb +0 -26
  290. data/lib/grape/validations/types/virtus_collection_patch.rb +0 -16
  291. data/lib/grape/validations/validators/all_or_none.rb +0 -20
  292. data/lib/grape/validations/validators/allow_blank.rb +0 -16
  293. data/lib/grape/validations/validators/as.rb +0 -15
  294. data/lib/grape/validations/validators/at_least_one_of.rb +0 -20
  295. data/lib/grape/validations/validators/coerce.rb +0 -74
  296. data/lib/grape/validations/validators/default.rb +0 -48
  297. data/lib/grape/validations/validators/exactly_one_of.rb +0 -29
  298. data/lib/grape/validations/validators/except_values.rb +0 -20
  299. data/lib/grape/validations/validators/mutual_exclusion.rb +0 -25
  300. data/lib/grape/validations/validators/presence.rb +0 -10
  301. data/lib/grape/validations/validators/regexp.rb +0 -11
  302. data/lib/grape/validations/validators/values.rb +0 -71
  303. data/pkg/grape-0.17.0.gem +0 -0
  304. data/pkg/grape-0.19.0.gem +0 -0
  305. data/spec/grape/dsl/configuration_spec.rb +0 -14
  306. data/spec/grape/validations/attributes_iterator_spec.rb +0 -4
@@ -1,4 +1,5 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'grape_entity'
3
4
 
4
5
  describe Grape::Entity do
@@ -30,7 +31,7 @@ describe Grape::Entity do
30
31
  end
31
32
 
32
33
  it 'pulls a representation from the class options if it exists' do
33
- entity = Class.new(Grape::Entity)
34
+ entity = Class.new(described_class)
34
35
  allow(entity).to receive(:represent).and_return('Hiya')
35
36
 
36
37
  subject.represent Object, with: entity
@@ -42,7 +43,7 @@ describe Grape::Entity do
42
43
  end
43
44
 
44
45
  it 'pulls a representation from the class options if the presented object is a collection of objects' do
45
- entity = Class.new(Grape::Entity)
46
+ entity = Class.new(described_class)
46
47
  allow(entity).to receive(:represent).and_return('Hiya')
47
48
 
48
49
  module EntitySpec
@@ -73,7 +74,7 @@ describe Grape::Entity do
73
74
  end
74
75
 
75
76
  it 'pulls a representation from the class ancestor if it exists' do
76
- entity = Class.new(Grape::Entity)
77
+ entity = Class.new(described_class)
77
78
  allow(entity).to receive(:represent).and_return('Hiya')
78
79
 
79
80
  subclass = Class.new(Object)
@@ -88,7 +89,7 @@ describe Grape::Entity do
88
89
 
89
90
  it 'automatically uses Klass::Entity if that exists' do
90
91
  some_model = Class.new
91
- entity = Class.new(Grape::Entity)
92
+ entity = Class.new(described_class)
92
93
  allow(entity).to receive(:represent).and_return('Auto-detect!')
93
94
 
94
95
  some_model.const_set :Entity, entity
@@ -102,7 +103,7 @@ describe Grape::Entity do
102
103
 
103
104
  it 'automatically uses Klass::Entity based on the first object in the collection being presented' do
104
105
  some_model = Class.new
105
- entity = Class.new(Grape::Entity)
106
+ entity = Class.new(described_class)
106
107
  allow(entity).to receive(:represent).and_return('Auto-detect!')
107
108
 
108
109
  some_model.const_set :Entity, entity
@@ -114,8 +115,8 @@ describe Grape::Entity do
114
115
  expect(last_response.body).to eq('Auto-detect!')
115
116
  end
116
117
 
117
- it 'does not run autodetection for Entity when explicitely provided' do
118
- entity = Class.new(Grape::Entity)
118
+ it 'does not run autodetection for Entity when explicitly provided' do
119
+ entity = Class.new(described_class)
119
120
  some_array = []
120
121
 
121
122
  subject.get '/example' do
@@ -127,7 +128,7 @@ describe Grape::Entity do
127
128
  end
128
129
 
129
130
  it 'does not use #first method on ActiveRecord::Relation to prevent needless sql query' do
130
- entity = Class.new(Grape::Entity)
131
+ entity = Class.new(described_class)
131
132
  some_relation = Class.new
132
133
  some_model = Class.new
133
134
 
@@ -171,7 +172,7 @@ describe Grape::Entity do
171
172
 
172
173
  %i[json serializable_hash].each do |format|
173
174
  it "presents with #{format}" do
174
- entity = Class.new(Grape::Entity)
175
+ entity = Class.new(described_class)
175
176
  entity.root 'examples', 'example'
176
177
  entity.expose :id
177
178
 
@@ -179,6 +180,7 @@ describe Grape::Entity do
179
180
  subject.get '/example' do
180
181
  c = Class.new do
181
182
  attr_reader :id
183
+
182
184
  def initialize(id)
183
185
  @id = id
184
186
  end
@@ -192,7 +194,7 @@ describe Grape::Entity do
192
194
  end
193
195
 
194
196
  it "presents with #{format} collection" do
195
- entity = Class.new(Grape::Entity)
197
+ entity = Class.new(described_class)
196
198
  entity.root 'examples', 'example'
197
199
  entity.expose :id
198
200
 
@@ -200,6 +202,7 @@ describe Grape::Entity do
200
202
  subject.get '/examples' do
201
203
  c = Class.new do
202
204
  attr_reader :id
205
+
203
206
  def initialize(id)
204
207
  @id = id
205
208
  end
@@ -215,7 +218,7 @@ describe Grape::Entity do
215
218
  end
216
219
 
217
220
  it 'presents with xml' do
218
- entity = Class.new(Grape::Entity)
221
+ entity = Class.new(described_class)
219
222
  entity.root 'examples', 'example'
220
223
  entity.expose :name
221
224
 
@@ -224,6 +227,7 @@ describe Grape::Entity do
224
227
  subject.get '/example' do
225
228
  c = Class.new do
226
229
  attr_reader :name
230
+
227
231
  def initialize(args)
228
232
  @name = args[:name] || 'no name set'
229
233
  end
@@ -233,18 +237,18 @@ describe Grape::Entity do
233
237
  get '/example'
234
238
  expect(last_response.status).to eq(200)
235
239
  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
240
+ expect(last_response.body).to eq <<~XML
241
+ <?xml version="1.0" encoding="UTF-8"?>
242
+ <hash>
243
+ <example>
244
+ <name>johnnyiller</name>
245
+ </example>
246
+ </hash>
247
+ XML
244
248
  end
245
249
 
246
250
  it 'presents with json' do
247
- entity = Class.new(Grape::Entity)
251
+ entity = Class.new(described_class)
248
252
  entity.root 'examples', 'example'
249
253
  entity.expose :name
250
254
 
@@ -253,6 +257,7 @@ XML
253
257
  subject.get '/example' do
254
258
  c = Class.new do
255
259
  attr_reader :name
260
+
256
261
  def initialize(args)
257
262
  @name = args[:name] || 'no name set'
258
263
  end
@@ -269,7 +274,7 @@ XML
269
274
  # Include JSONP middleware
270
275
  subject.use Rack::JSONP
271
276
 
272
- entity = Class.new(Grape::Entity)
277
+ entity = Class.new(described_class)
273
278
  entity.root 'examples', 'example'
274
279
  entity.expose :name
275
280
 
@@ -282,6 +287,7 @@ XML
282
287
  subject.get '/example' do
283
288
  c = Class.new do
284
289
  attr_reader :name
290
+
285
291
  def initialize(args)
286
292
  @name = args[:name] || 'no name set'
287
293
  end
@@ -300,6 +306,7 @@ XML
300
306
  it 'present with multiple entities using optional symbol' do
301
307
  user = Class.new do
302
308
  attr_reader :name
309
+
303
310
  def initialize(args)
304
311
  @name = args[:name] || 'no name set'
305
312
  end
@@ -307,7 +314,7 @@ XML
307
314
  user1 = user.new(name: 'user1')
308
315
  user2 = user.new(name: 'user2')
309
316
 
310
- entity = Class.new(Grape::Entity)
317
+ entity = Class.new(described_class)
311
318
  entity.expose :name
312
319
 
313
320
  subject.format :json
@@ -318,7 +325,7 @@ XML
318
325
  end
319
326
  get '/example'
320
327
  expect_response_json = {
321
- 'page' => 1,
328
+ 'page' => 1,
322
329
  'user1' => { 'name' => 'user1' },
323
330
  'user2' => { 'name' => 'user2' }
324
331
  }
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Grape::Exceptions::Base do
4
+ describe '#to_s' do
5
+ subject { described_class.new(message: message).to_s }
6
+
7
+ let(:message) { 'a_message' }
8
+
9
+ it { is_expected.to eq(message) }
10
+ end
11
+
12
+ describe '#message' do
13
+ subject { described_class.new(message: message).message }
14
+
15
+ let(:message) { 'a_message' }
16
+
17
+ it { is_expected.to eq(message) }
18
+ end
19
+
20
+ describe '#compose_message' do
21
+ subject { described_class.new.send(:compose_message, key, **attributes) }
22
+
23
+ let(:key) { :invalid_formatter }
24
+ let(:attributes) { { klass: String, to_format: 'xml' } }
25
+
26
+ after do
27
+ I18n.enforce_available_locales = true
28
+ I18n.available_locales = %i[en]
29
+ I18n.locale = :en
30
+ I18n.default_locale = :en
31
+ I18n.reload!
32
+ end
33
+
34
+ context 'when I18n enforces available locales' do
35
+ before { I18n.enforce_available_locales = true }
36
+
37
+ context 'when the fallback locale is available' do
38
+ before do
39
+ I18n.available_locales = %i[de en]
40
+ I18n.default_locale = :de
41
+ end
42
+
43
+ it 'returns the translated message' do
44
+ expect(subject).to eq('cannot convert String to xml')
45
+ end
46
+ end
47
+
48
+ context 'when the fallback locale is not available' do
49
+ before do
50
+ I18n.available_locales = %i[de jp]
51
+ I18n.locale = :de
52
+ I18n.default_locale = :de
53
+ end
54
+
55
+ it 'returns the translation string' do
56
+ expect(subject).to eq("grape.errors.messages.#{key}")
57
+ end
58
+ end
59
+ end
60
+
61
+ context 'when I18n does not enforce available locales' do
62
+ before { I18n.enforce_available_locales = false }
63
+
64
+ context 'when the fallback locale is available' do
65
+ before { I18n.available_locales = %i[de en] }
66
+
67
+ it 'returns the translated message' do
68
+ expect(subject).to eq('cannot convert String to xml')
69
+ end
70
+ end
71
+
72
+ context 'when the fallback locale is not available' do
73
+ before { I18n.available_locales = %i[de jp] }
74
+
75
+ it 'returns the translated message' do
76
+ expect(subject).to eq('cannot convert String to xml')
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -1,8 +1,9 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe Grape::Exceptions::ValidationErrors do
4
4
  context 'api with rescue_from :all handler' do
5
5
  subject { Class.new(Grape::API) }
6
+
6
7
  before do
7
8
  subject.rescue_from :all do |_e|
8
9
  rack_response 'message was processed', 400
@@ -54,6 +55,7 @@ describe Grape::Exceptions::ValidationErrors do
54
55
 
55
56
  context 'api with rescue_from :grape_exceptions handler' do
56
57
  subject { Class.new(Grape::API) }
58
+
57
59
  before do
58
60
  subject.rescue_from :all do |_e|
59
61
  rack_response 'message was processed', 400
@@ -91,6 +93,7 @@ describe Grape::Exceptions::ValidationErrors do
91
93
 
92
94
  context 'api without a rescue handler' do
93
95
  subject { Class.new(Grape::API) }
96
+
94
97
  before do
95
98
  subject.params do
96
99
  requires :beer
@@ -1,31 +1,37 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe Grape::Exceptions::InvalidAcceptHeader do
4
4
  shared_examples_for 'a valid request' do
5
5
  it 'does return with status 200' do
6
6
  expect(last_response.status).to eq 200
7
7
  end
8
+
8
9
  it 'does return the expected result' do
9
10
  expect(last_response.body).to eq('beer received')
10
11
  end
11
12
  end
13
+
12
14
  shared_examples_for 'a cascaded request' do
13
15
  it 'does not find a matching route' do
14
16
  expect(last_response.status).to eq 404
15
17
  end
16
18
  end
19
+
17
20
  shared_examples_for 'a not-cascaded request' do
18
21
  it 'does not include the X-Cascade=pass header' do
19
22
  expect(last_response.headers['X-Cascade']).to be_nil
20
23
  end
24
+
21
25
  it 'does not accept the request' do
22
26
  expect(last_response.status).to eq 406
23
27
  end
24
28
  end
29
+
25
30
  shared_examples_for 'a rescued request' do
26
31
  it 'does not include the X-Cascade=pass header' do
27
32
  expect(last_response.headers['X-Cascade']).to be_nil
28
33
  end
34
+
29
35
  it 'does show rescue handler processing' do
30
36
  expect(last_response.status).to eq 400
31
37
  expect(last_response.body).to eq('message was processed')
@@ -34,6 +40,7 @@ describe Grape::Exceptions::InvalidAcceptHeader do
34
40
 
35
41
  context 'API with cascade=false and rescue_from :all handler' do
36
42
  subject { Class.new(Grape::API) }
43
+
37
44
  before do
38
45
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
39
46
  subject.rescue_from :all do |e|
@@ -50,7 +57,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
50
57
 
51
58
  context 'that received a request with correct vendor and version' do
52
59
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
53
- it_should_behave_like 'a valid request'
60
+
61
+ it_behaves_like 'a valid request'
54
62
  end
55
63
 
56
64
  context 'that receives' do
@@ -59,13 +67,15 @@ describe Grape::Exceptions::InvalidAcceptHeader do
59
67
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
60
68
  'CONTENT_TYPE' => 'application/json'
61
69
  end
62
- it_should_behave_like 'a rescued request'
70
+
71
+ it_behaves_like 'a rescued request'
63
72
  end
64
73
  end
65
74
  end
66
75
 
67
76
  context 'API with cascade=false and without a rescue handler' do
68
77
  subject { Class.new(Grape::API) }
78
+
69
79
  before do
70
80
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
71
81
  subject.get '/beer' do
@@ -79,23 +89,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
79
89
 
80
90
  context 'that received a request with correct vendor and version' do
81
91
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
82
- it_should_behave_like 'a valid request'
92
+
93
+ it_behaves_like 'a valid request'
83
94
  end
84
95
 
85
96
  context 'that receives' do
86
97
  context 'an invalid version in the request' do
87
98
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
88
- it_should_behave_like 'a not-cascaded request'
99
+
100
+ it_behaves_like 'a not-cascaded request'
89
101
  end
102
+
90
103
  context 'an invalid vendor in the request' do
91
104
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
92
- it_should_behave_like 'a not-cascaded request'
105
+
106
+ it_behaves_like 'a not-cascaded request'
93
107
  end
94
108
  end
95
109
  end
96
110
 
97
111
  context 'API with cascade=false and with rescue_from :all handler and http_codes' do
98
112
  subject { Class.new(Grape::API) }
113
+
99
114
  before do
100
115
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
101
116
  subject.rescue_from :all do |e|
@@ -117,7 +132,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
117
132
 
118
133
  context 'that received a request with correct vendor and version' do
119
134
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
120
- it_should_behave_like 'a valid request'
135
+
136
+ it_behaves_like 'a valid request'
121
137
  end
122
138
 
123
139
  context 'that receives' do
@@ -126,13 +142,15 @@ describe Grape::Exceptions::InvalidAcceptHeader do
126
142
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
127
143
  'CONTENT_TYPE' => 'application/json'
128
144
  end
129
- it_should_behave_like 'a rescued request'
145
+
146
+ it_behaves_like 'a rescued request'
130
147
  end
131
148
  end
132
149
  end
133
150
 
134
151
  context 'API with cascade=false, http_codes but without a rescue handler' do
135
152
  subject { Class.new(Grape::API) }
153
+
136
154
  before do
137
155
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
138
156
  subject.desc 'Get beer' do
@@ -151,23 +169,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
151
169
 
152
170
  context 'that received a request with correct vendor and version' do
153
171
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
154
- it_should_behave_like 'a valid request'
172
+
173
+ it_behaves_like 'a valid request'
155
174
  end
156
175
 
157
176
  context 'that receives' do
158
177
  context 'an invalid version in the request' do
159
178
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
160
- it_should_behave_like 'a not-cascaded request'
179
+
180
+ it_behaves_like 'a not-cascaded request'
161
181
  end
182
+
162
183
  context 'an invalid vendor in the request' do
163
184
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
164
- it_should_behave_like 'a not-cascaded request'
185
+
186
+ it_behaves_like 'a not-cascaded request'
165
187
  end
166
188
  end
167
189
  end
168
190
 
169
191
  context 'API with cascade=true and rescue_from :all handler' do
170
192
  subject { Class.new(Grape::API) }
193
+
171
194
  before do
172
195
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
173
196
  subject.rescue_from :all do |e|
@@ -184,7 +207,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
184
207
 
185
208
  context 'that received a request with correct vendor and version' do
186
209
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
187
- it_should_behave_like 'a valid request'
210
+
211
+ it_behaves_like 'a valid request'
188
212
  end
189
213
 
190
214
  context 'that receives' do
@@ -193,20 +217,24 @@ describe Grape::Exceptions::InvalidAcceptHeader do
193
217
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
194
218
  'CONTENT_TYPE' => 'application/json'
195
219
  end
196
- it_should_behave_like 'a cascaded request'
220
+
221
+ it_behaves_like 'a cascaded request'
197
222
  end
223
+
198
224
  context 'an invalid vendor in the request' do
199
225
  before do
200
226
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
201
227
  'CONTENT_TYPE' => 'application/json'
202
228
  end
203
- it_should_behave_like 'a cascaded request'
229
+
230
+ it_behaves_like 'a cascaded request'
204
231
  end
205
232
  end
206
233
  end
207
234
 
208
235
  context 'API with cascade=true and without a rescue handler' do
209
236
  subject { Class.new(Grape::API) }
237
+
210
238
  before do
211
239
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
212
240
  subject.get '/beer' do
@@ -220,23 +248,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
220
248
 
221
249
  context 'that received a request with correct vendor and version' do
222
250
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
223
- it_should_behave_like 'a valid request'
251
+
252
+ it_behaves_like 'a valid request'
224
253
  end
225
254
 
226
255
  context 'that receives' do
227
256
  context 'an invalid version in the request' do
228
257
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
229
- it_should_behave_like 'a cascaded request'
258
+
259
+ it_behaves_like 'a cascaded request'
230
260
  end
261
+
231
262
  context 'an invalid vendor in the request' do
232
263
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
233
- it_should_behave_like 'a cascaded request'
264
+
265
+ it_behaves_like 'a cascaded request'
234
266
  end
235
267
  end
236
268
  end
237
269
 
238
270
  context 'API with cascade=true and with rescue_from :all handler and http_codes' do
239
271
  subject { Class.new(Grape::API) }
272
+
240
273
  before do
241
274
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
242
275
  subject.rescue_from :all do |e|
@@ -258,7 +291,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
258
291
 
259
292
  context 'that received a request with correct vendor and version' do
260
293
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
261
- it_should_behave_like 'a valid request'
294
+
295
+ it_behaves_like 'a valid request'
262
296
  end
263
297
 
264
298
  context 'that receives' do
@@ -267,20 +301,24 @@ describe Grape::Exceptions::InvalidAcceptHeader do
267
301
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
268
302
  'CONTENT_TYPE' => 'application/json'
269
303
  end
270
- it_should_behave_like 'a cascaded request'
304
+
305
+ it_behaves_like 'a cascaded request'
271
306
  end
307
+
272
308
  context 'an invalid vendor in the request' do
273
309
  before do
274
310
  get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
275
311
  'CONTENT_TYPE' => 'application/json'
276
312
  end
277
- it_should_behave_like 'a cascaded request'
313
+
314
+ it_behaves_like 'a cascaded request'
278
315
  end
279
316
  end
280
317
  end
281
318
 
282
319
  context 'API with cascade=true, http_codes but without a rescue handler' do
283
320
  subject { Class.new(Grape::API) }
321
+
284
322
  before do
285
323
  subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
286
324
  subject.desc 'Get beer' do
@@ -299,17 +337,21 @@ describe Grape::Exceptions::InvalidAcceptHeader do
299
337
 
300
338
  context 'that received a request with correct vendor and version' do
301
339
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
302
- it_should_behave_like 'a valid request'
340
+
341
+ it_behaves_like 'a valid request'
303
342
  end
304
343
 
305
344
  context 'that receives' do
306
345
  context 'an invalid version in the request' do
307
346
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
308
- it_should_behave_like 'a cascaded request'
347
+
348
+ it_behaves_like 'a cascaded request'
309
349
  end
350
+
310
351
  context 'an invalid vendor in the request' do
311
352
  before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
312
- it_should_behave_like 'a cascaded request'
353
+
354
+ it_behaves_like 'a cascaded request'
313
355
  end
314
356
  end
315
357
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe Grape::Exceptions::InvalidFormatter do
4
4
  describe '#message' do
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Grape::Exceptions::InvalidResponse do
4
+ describe '#message' do
5
+ let(:error) { described_class.new }
6
+
7
+ it 'contains the problem in the message' do
8
+ expect(error.message).to include('Invalid response')
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe Grape::Exceptions::InvalidVersionerOption do
4
4
  describe '#message' do
@@ -8,7 +8,7 @@ describe Grape::Exceptions::InvalidVersionerOption do
8
8
 
9
9
  it 'contains the problem in the message' do
10
10
  expect(error.message).to include(
11
- 'Unknown :using for versioner: headers'
11
+ 'unknown :using for versioner: headers'
12
12
  )
13
13
  end
14
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,4 +1,4 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe Grape::Exceptions::MissingMimeType do
4
4
  describe '#message' do
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe Grape::Exceptions::MissingOption do
4
4
  describe '#message' do
@@ -8,7 +8,7 @@ describe Grape::Exceptions::MissingOption do
8
8
 
9
9
  it 'contains the problem in the message' do
10
10
  expect(error.message).to include(
11
- 'You must specify :path options.'
11
+ 'you must specify :path options'
12
12
  )
13
13
  end
14
14
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe Grape::Exceptions::UnknownOptions do
4
4
  describe '#message' do