grape 1.5.3 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +92 -0
  3. data/CONTRIBUTING.md +32 -1
  4. data/README.md +176 -25
  5. data/UPGRADING.md +61 -4
  6. data/grape.gemspec +6 -6
  7. data/lib/grape/api/instance.rb +14 -18
  8. data/lib/grape/api.rb +17 -12
  9. data/lib/grape/cookies.rb +2 -0
  10. data/lib/grape/dry_types.rb +12 -0
  11. data/lib/grape/dsl/api.rb +0 -2
  12. data/lib/grape/dsl/callbacks.rb +0 -2
  13. data/lib/grape/dsl/configuration.rb +0 -2
  14. data/lib/grape/dsl/desc.rb +4 -20
  15. data/lib/grape/dsl/headers.rb +5 -2
  16. data/lib/grape/dsl/helpers.rb +7 -7
  17. data/lib/grape/dsl/inside_route.rb +43 -30
  18. data/lib/grape/dsl/middleware.rb +4 -6
  19. data/lib/grape/dsl/parameters.rb +13 -10
  20. data/lib/grape/dsl/request_response.rb +9 -8
  21. data/lib/grape/dsl/routing.rb +6 -4
  22. data/lib/grape/dsl/settings.rb +5 -7
  23. data/lib/grape/dsl/validations.rb +0 -15
  24. data/lib/grape/endpoint.rb +22 -37
  25. data/lib/grape/error_formatter/json.rb +9 -7
  26. data/lib/grape/error_formatter/xml.rb +2 -6
  27. data/lib/grape/exceptions/base.rb +3 -2
  28. data/lib/grape/exceptions/missing_group_type.rb +8 -1
  29. data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
  30. data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
  31. data/lib/grape/exceptions/validation.rb +1 -6
  32. data/lib/grape/formatter/json.rb +1 -0
  33. data/lib/grape/formatter/serializable_hash.rb +2 -1
  34. data/lib/grape/formatter/xml.rb +1 -0
  35. data/lib/grape/locale/en.yml +9 -8
  36. data/lib/grape/middleware/auth/dsl.rb +7 -2
  37. data/lib/grape/middleware/base.rb +3 -1
  38. data/lib/grape/middleware/error.rb +2 -2
  39. data/lib/grape/middleware/formatter.rb +4 -4
  40. data/lib/grape/middleware/stack.rb +3 -3
  41. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  42. data/lib/grape/middleware/versioner/header.rb +6 -4
  43. data/lib/grape/middleware/versioner/param.rb +1 -0
  44. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  45. data/lib/grape/middleware/versioner/path.rb +2 -0
  46. data/lib/grape/path.rb +1 -0
  47. data/lib/grape/request.rb +4 -1
  48. data/lib/grape/router/attribute_translator.rb +1 -1
  49. data/lib/grape/router/pattern.rb +1 -1
  50. data/lib/grape/router/route.rb +2 -2
  51. data/lib/grape/router.rb +6 -0
  52. data/lib/grape/types/invalid_value.rb +8 -0
  53. data/lib/grape/util/cache.rb +1 -1
  54. data/lib/grape/util/inheritable_setting.rb +1 -3
  55. data/lib/grape/util/json.rb +2 -0
  56. data/lib/grape/util/lazy_value.rb +3 -2
  57. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  58. data/lib/grape/validations/attributes_doc.rb +58 -0
  59. data/lib/grape/validations/params_scope.rb +138 -79
  60. data/lib/grape/validations/types/array_coercer.rb +0 -2
  61. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  62. data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
  63. data/lib/grape/validations/types/invalid_value.rb +0 -7
  64. data/lib/grape/validations/types/json.rb +2 -1
  65. data/lib/grape/validations/types/primitive_coercer.rb +16 -8
  66. data/lib/grape/validations/types/set_coercer.rb +0 -2
  67. data/lib/grape/validations/types.rb +98 -30
  68. data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
  69. data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
  70. data/lib/grape/validations/validators/as_validator.rb +14 -0
  71. data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
  72. data/lib/grape/validations/validators/base.rb +82 -70
  73. data/lib/grape/validations/validators/coerce_validator.rb +75 -0
  74. data/lib/grape/validations/validators/default_validator.rb +51 -0
  75. data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
  76. data/lib/grape/validations/validators/except_values_validator.rb +24 -0
  77. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  78. data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
  79. data/lib/grape/validations/validators/presence_validator.rb +15 -0
  80. data/lib/grape/validations/validators/regexp_validator.rb +16 -0
  81. data/lib/grape/validations/validators/same_as_validator.rb +29 -0
  82. data/lib/grape/validations/validators/values_validator.rb +88 -0
  83. data/lib/grape/validations.rb +16 -6
  84. data/lib/grape/version.rb +1 -1
  85. data/lib/grape.rb +77 -29
  86. data/spec/grape/api/custom_validations_spec.rb +116 -45
  87. data/spec/grape/api/deeply_included_options_spec.rb +3 -5
  88. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
  89. data/spec/grape/api/documentation_spec.rb +59 -0
  90. data/spec/grape/api/inherited_helpers_spec.rb +0 -2
  91. data/spec/grape/api/instance_spec.rb +0 -1
  92. data/spec/grape/api/invalid_format_spec.rb +2 -2
  93. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
  94. data/spec/grape/api/nested_helpers_spec.rb +0 -2
  95. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
  96. data/spec/grape/api/parameters_modification_spec.rb +0 -2
  97. data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
  98. data/spec/grape/api/recognize_path_spec.rb +1 -3
  99. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
  100. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
  101. data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
  102. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
  103. data/spec/grape/api/shared_helpers_spec.rb +0 -2
  104. data/spec/grape/api_remount_spec.rb +16 -16
  105. data/spec/grape/api_spec.rb +462 -251
  106. data/spec/grape/config_spec.rb +0 -2
  107. data/spec/grape/dsl/callbacks_spec.rb +2 -3
  108. data/spec/grape/dsl/desc_spec.rb +2 -2
  109. data/spec/grape/dsl/headers_spec.rb +39 -11
  110. data/spec/grape/dsl/helpers_spec.rb +3 -4
  111. data/spec/grape/dsl/inside_route_spec.rb +16 -16
  112. data/spec/grape/dsl/logger_spec.rb +15 -19
  113. data/spec/grape/dsl/middleware_spec.rb +2 -3
  114. data/spec/grape/dsl/parameters_spec.rb +2 -2
  115. data/spec/grape/dsl/request_response_spec.rb +7 -8
  116. data/spec/grape/dsl/routing_spec.rb +11 -10
  117. data/spec/grape/dsl/settings_spec.rb +0 -2
  118. data/spec/grape/dsl/validations_spec.rb +0 -17
  119. data/spec/grape/endpoint/declared_spec.rb +261 -16
  120. data/spec/grape/endpoint_spec.rb +88 -59
  121. data/spec/grape/entity_spec.rb +22 -23
  122. data/spec/grape/exceptions/base_spec.rb +16 -2
  123. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
  124. data/spec/grape/exceptions/invalid_accept_header_spec.rb +64 -24
  125. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
  126. data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
  127. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
  128. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  129. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
  130. data/spec/grape/exceptions/missing_option_spec.rb +1 -3
  131. data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
  132. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
  133. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  134. data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
  135. data/spec/grape/exceptions/validation_spec.rb +5 -5
  136. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
  137. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
  138. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
  139. data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
  140. data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
  141. data/spec/grape/integration/rack_spec.rb +6 -7
  142. data/spec/grape/loading_spec.rb +8 -10
  143. data/spec/grape/middleware/auth/base_spec.rb +0 -1
  144. data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
  145. data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
  146. data/spec/grape/middleware/base_spec.rb +28 -19
  147. data/spec/grape/middleware/error_spec.rb +8 -3
  148. data/spec/grape/middleware/exception_spec.rb +111 -163
  149. data/spec/grape/middleware/formatter_spec.rb +33 -14
  150. data/spec/grape/middleware/globals_spec.rb +7 -6
  151. data/spec/grape/middleware/stack_spec.rb +14 -14
  152. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
  153. data/spec/grape/middleware/versioner/header_spec.rb +30 -15
  154. data/spec/grape/middleware/versioner/param_spec.rb +7 -3
  155. data/spec/grape/middleware/versioner/path_spec.rb +5 -3
  156. data/spec/grape/middleware/versioner_spec.rb +1 -3
  157. data/spec/grape/named_api_spec.rb +0 -2
  158. data/spec/grape/parser_spec.rb +4 -2
  159. data/spec/grape/path_spec.rb +52 -54
  160. data/spec/grape/presenters/presenter_spec.rb +7 -8
  161. data/spec/grape/request_spec.rb +6 -6
  162. data/spec/grape/util/inheritable_setting_spec.rb +7 -8
  163. data/spec/grape/util/inheritable_values_spec.rb +3 -3
  164. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
  165. data/spec/grape/util/stackable_values_spec.rb +7 -6
  166. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
  167. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  168. data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
  169. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
  170. data/spec/grape/validations/params_scope_spec.rb +361 -96
  171. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
  172. data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
  173. data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
  174. data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
  175. data/spec/grape/validations/types_spec.rb +36 -10
  176. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
  177. data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
  178. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
  179. data/spec/grape/validations/validators/coerce_spec.rb +23 -24
  180. data/spec/grape/validations/validators/default_spec.rb +72 -80
  181. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
  182. data/spec/grape/validations/validators/except_values_spec.rb +3 -5
  183. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
  184. data/spec/grape/validations/validators/presence_spec.rb +16 -3
  185. data/spec/grape/validations/validators/regexp_spec.rb +25 -33
  186. data/spec/grape/validations/validators/same_as_spec.rb +14 -22
  187. data/spec/grape/validations/validators/values_spec.rb +201 -179
  188. data/spec/grape/validations_spec.rb +171 -79
  189. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  190. data/spec/integration/multi_json/json_spec.rb +1 -3
  191. data/spec/integration/multi_xml/xml_spec.rb +1 -3
  192. data/spec/shared/versioning_examples.rb +12 -9
  193. data/spec/spec_helper.rb +21 -6
  194. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  195. metadata +41 -29
  196. data/lib/grape/validations/validators/all_or_none.rb +0 -15
  197. data/lib/grape/validations/validators/allow_blank.rb +0 -18
  198. data/lib/grape/validations/validators/as.rb +0 -16
  199. data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
  200. data/lib/grape/validations/validators/coerce.rb +0 -91
  201. data/lib/grape/validations/validators/default.rb +0 -48
  202. data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
  203. data/lib/grape/validations/validators/except_values.rb +0 -22
  204. data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
  205. data/lib/grape/validations/validators/presence.rb +0 -12
  206. data/lib/grape/validations/validators/regexp.rb +0 -13
  207. data/lib/grape/validations/validators/same_as.rb +0 -26
  208. data/lib/grape/validations/validators/values.rb +0 -83
  209. data/spec/grape/dsl/configuration_spec.rb +0 -16
  210. data/spec/grape/validations/attributes_iterator_spec.rb +0 -6
  211. data/spec/support/eager_load.rb +0 -19
@@ -1,20 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Validations do
6
- context 'using a custom length validator' do
7
- before do
8
- module CustomValidationsSpec
9
- class DefaultLength < Grape::Validations::Base
10
- def validate_param!(attr_name, params)
11
- @option = params[:max].to_i if params.key?(:max)
12
- return if params[attr_name].length <= @option
13
- raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long")
14
- end
4
+ context 'deprecated Grape::Validations::Base' do
5
+ subject do
6
+ Class.new(Grape::API) do
7
+ params do
8
+ requires :text, validator_with_old_base: true
9
+ end
10
+ get do
11
+ end
12
+ end
13
+ end
14
+
15
+ let(:validator_with_old_base) do
16
+ Class.new(Grape::Validations::Base) do
17
+ def validate_param!(_attr_name, _params)
18
+ true
15
19
  end
16
20
  end
17
21
  end
22
+
23
+ before do
24
+ described_class.register_validator('validator_with_old_base', validator_with_old_base)
25
+ allow(Warning).to receive(:warn)
26
+ end
27
+
28
+ after do
29
+ described_class.deregister_validator('validator_with_old_base')
30
+ end
31
+
32
+ def app
33
+ subject
34
+ end
35
+
36
+ it 'puts a deprecation warning' do
37
+ expect(Warning).to receive(:warn) do |message|
38
+ expect(message).to include('`Grape::Validations::Base` is deprecated')
39
+ end
40
+
41
+ get '/'
42
+ end
43
+ end
44
+
45
+ context 'using a custom length validator' do
18
46
  subject do
19
47
  Class.new(Grape::API) do
20
48
  params do
@@ -26,6 +54,25 @@ describe Grape::Validations do
26
54
  end
27
55
  end
28
56
 
57
+ let(:default_length_validator) do
58
+ Class.new(Grape::Validations::Validators::Base) do
59
+ def validate_param!(attr_name, params)
60
+ @option = params[:max].to_i if params.key?(:max)
61
+ return if params[attr_name].length <= @option
62
+
63
+ raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long")
64
+ end
65
+ end
66
+ end
67
+
68
+ before do
69
+ described_class.register_validator('default_length', default_length_validator)
70
+ end
71
+
72
+ after do
73
+ described_class.deregister_validator('default_length')
74
+ end
75
+
29
76
  def app
30
77
  subject
31
78
  end
@@ -35,11 +82,13 @@ describe Grape::Validations do
35
82
  expect(last_response.status).to eq 200
36
83
  expect(last_response.body).to eq 'bacon'
37
84
  end
85
+
38
86
  it 'over 140 characters' do
39
87
  get '/', text: 'a' * 141
40
88
  expect(last_response.status).to eq 400
41
89
  expect(last_response.body).to eq 'text must be at the most 140 characters long'
42
90
  end
91
+
43
92
  it 'specified in the query string' do
44
93
  get '/', text: 'a' * 141, max: 141
45
94
  expect(last_response.status).to eq 200
@@ -48,15 +97,6 @@ describe Grape::Validations do
48
97
  end
49
98
 
50
99
  context 'using a custom body-only validator' do
51
- before do
52
- module CustomValidationsSpec
53
- class InBody < Grape::Validations::PresenceValidator
54
- def validate(request)
55
- validate!(request.env['api.request.body'])
56
- end
57
- end
58
- end
59
- end
60
100
  subject do
61
101
  Class.new(Grape::API) do
62
102
  params do
@@ -68,6 +108,22 @@ describe Grape::Validations do
68
108
  end
69
109
  end
70
110
 
111
+ let(:in_body_validator) do
112
+ Class.new(Grape::Validations::Validators::PresenceValidator) do
113
+ def validate(request)
114
+ validate!(request.env['api.request.body'])
115
+ end
116
+ end
117
+ end
118
+
119
+ before do
120
+ described_class.register_validator('in_body', in_body_validator)
121
+ end
122
+
123
+ after do
124
+ described_class.deregister_validator('in_body')
125
+ end
126
+
71
127
  def app
72
128
  subject
73
129
  end
@@ -77,6 +133,7 @@ describe Grape::Validations do
77
133
  expect(last_response.status).to eq 200
78
134
  expect(last_response.body).to eq 'bacon'
79
135
  end
136
+
80
137
  it 'ignores field in query' do
81
138
  get '/', nil, text: 'abc'
82
139
  expect(last_response.status).to eq 400
@@ -85,15 +142,6 @@ describe Grape::Validations do
85
142
  end
86
143
 
87
144
  context 'using a custom validator with message_key' do
88
- before do
89
- module CustomValidationsSpec
90
- class WithMessageKey < Grape::Validations::PresenceValidator
91
- def validate_param!(attr_name, _params)
92
- raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: :presence)
93
- end
94
- end
95
- end
96
- end
97
145
  subject do
98
146
  Class.new(Grape::API) do
99
147
  params do
@@ -105,6 +153,22 @@ describe Grape::Validations do
105
153
  end
106
154
  end
107
155
 
156
+ let(:message_key_validator) do
157
+ Class.new(Grape::Validations::Validators::PresenceValidator) do
158
+ def validate_param!(attr_name, _params)
159
+ raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: :presence)
160
+ end
161
+ end
162
+ end
163
+
164
+ before do
165
+ described_class.register_validator('with_message_key', message_key_validator)
166
+ end
167
+
168
+ after do
169
+ described_class.deregister_validator('with_message_key')
170
+ end
171
+
108
172
  def app
109
173
  subject
110
174
  end
@@ -117,22 +181,6 @@ describe Grape::Validations do
117
181
  end
118
182
 
119
183
  context 'using a custom request/param validator' do
120
- before do
121
- module CustomValidationsSpec
122
- class Admin < Grape::Validations::Base
123
- def validate(request)
124
- # return if the param we are checking was not in request
125
- # @attrs is a list containing the attribute we are currently validating
126
- return unless request.params.key? @attrs.first
127
- # check if admin flag is set to true
128
- return unless @option
129
- # check if user is admin or not
130
- # as an example get a token from request and check if it's admin or not
131
- raise Grape::Exceptions::Validation.new(params: @attrs, message: 'Can not set Admin only field.') unless request.headers['X-Access-Token'] == 'admin'
132
- end
133
- end
134
- end
135
- end
136
184
  subject do
137
185
  Class.new(Grape::API) do
138
186
  params do
@@ -146,6 +194,29 @@ describe Grape::Validations do
146
194
  end
147
195
  end
148
196
 
197
+ let(:admin_validator) do
198
+ Class.new(Grape::Validations::Validators::Base) do
199
+ def validate(request)
200
+ # return if the param we are checking was not in request
201
+ # @attrs is a list containing the attribute we are currently validating
202
+ return unless request.params.key? @attrs.first
203
+ # check if admin flag is set to true
204
+ return unless @option
205
+ # check if user is admin or not
206
+ # as an example get a token from request and check if it's admin or not
207
+ raise Grape::Exceptions::Validation.new(params: @attrs, message: 'Can not set Admin only field.') unless request.headers['X-Access-Token'] == 'admin'
208
+ end
209
+ end
210
+ end
211
+
212
+ before do
213
+ described_class.register_validator('admin', admin_validator)
214
+ end
215
+
216
+ after do
217
+ described_class.deregister_validator('admin')
218
+ end
219
+
149
220
  def app
150
221
  subject
151
222
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  module DeeplyIncludedOptionsSpec
6
4
  module Defaults
7
5
  extend ActiveSupport::Concern
@@ -41,18 +39,18 @@ describe Grape::API do
41
39
 
42
40
  it 'works for unspecified format' do
43
41
  get '/users'
44
- expect(last_response.status).to eql 200
42
+ expect(last_response.status).to be 200
45
43
  expect(last_response.content_type).to eql 'application/json'
46
44
  end
47
45
 
48
46
  it 'works for specified format' do
49
47
  get '/users.json'
50
- expect(last_response.status).to eql 200
48
+ expect(last_response.status).to be 200
51
49
  expect(last_response.content_type).to eql 'application/json'
52
50
  end
53
51
 
54
52
  it "doesn't work for format different than specified" do
55
53
  get '/users.txt'
56
- expect(last_response.status).to eql 404
54
+ expect(last_response.status).to be 404
57
55
  end
58
56
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Instance do
6
4
  describe 'boolean constant' do
7
5
  module DefinesBooleanInstanceSpec
@@ -31,8 +29,9 @@ describe Grape::API::Instance do
31
29
 
32
30
  context 'Params endpoint type' do
33
31
  subject { DefinesBooleanInstanceSpec::API.new.router.map['POST'].first.options[:params]['message'][:type] }
32
+
34
33
  it 'params type is a boolean' do
35
- is_expected.to eq 'Grape::API::Boolean'
34
+ expect(subject).to eq 'Grape::API::Boolean'
36
35
  end
37
36
  end
38
37
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Grape::API do
6
+ subject { Class.new(described_class) }
7
+
8
+ let(:app) { subject }
9
+
10
+ context 'an endpoint with documentation' do
11
+ it 'documents parameters' do
12
+ subject.params do
13
+ requires 'price', type: Float, desc: 'Sales price'
14
+ end
15
+ subject.get '/'
16
+
17
+ expect(subject.routes.first.params['price']).to eq(required: true,
18
+ type: 'Float',
19
+ desc: 'Sales price')
20
+ end
21
+
22
+ it 'allows documentation with a hash' do
23
+ documentation = { example: 'Joe' }
24
+
25
+ subject.params do
26
+ requires 'first_name', documentation: documentation
27
+ end
28
+ subject.get '/'
29
+
30
+ expect(subject.routes.first.params['first_name'][:documentation]).to eq(documentation)
31
+ end
32
+ end
33
+
34
+ context 'an endpoint without documentation' do
35
+ before do
36
+ subject.do_not_document!
37
+
38
+ subject.params do
39
+ requires :city, type: String, desc: 'Should be ignored'
40
+ optional :postal_code, type: Integer
41
+ end
42
+ subject.post '/' do
43
+ declared(params).to_json
44
+ end
45
+ end
46
+
47
+ it 'does not document parameters for the endpoint' do
48
+ expect(subject.routes.first.params).to eq({})
49
+ end
50
+
51
+ it 'still declares params internally' do
52
+ data = { city: 'Berlin', postal_code: 10_115 }
53
+
54
+ post '/', data
55
+
56
+ expect(last_response.body).to eq(data.to_json)
57
+ end
58
+ end
59
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
4
  let(:user) { 'Miguel Caneo' }
7
5
  let(:id) { '42' }
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  require 'shared/versioning_examples'
5
4
 
6
5
  describe Grape::API::Instance do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -31,11 +29,13 @@ describe Grape::Endpoint do
31
29
  expect(last_response.status).to eq 200
32
30
  expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: nil))
33
31
  end
32
+
34
33
  it 'json format' do
35
34
  get '/foo.json'
36
35
  expect(last_response.status).to eq 200
37
36
  expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: 'json'))
38
37
  end
38
+
39
39
  it 'invalid format' do
40
40
  get '/foo.invalid'
41
41
  expect(last_response.status).to eq 200
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
4
  module NestedHelpersSpec
7
5
  module HelperMethods
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
4
  module PatchHelpersSpec
7
5
  class PatchPublic < Grape::API
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API do
6
4
  describe '.recognize_path' do
7
- subject { Class.new(Grape::API) }
5
+ subject { Class.new(described_class) }
8
6
 
9
7
  it 'fetches endpoint by given path' do
10
8
  subject.get('/foo/:id') {}
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -11,7 +9,7 @@ describe Grape::Endpoint do
11
9
 
12
10
  context 'get' do
13
11
  it 'routes to a namespace param with dots' do
14
- subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^\/]+} } do
12
+ subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
15
13
  get '/' do
16
14
  params[:ns_with_dots]
17
15
  end
@@ -23,8 +21,8 @@ describe Grape::Endpoint do
23
21
  end
24
22
 
25
23
  it 'routes to a path with multiple params with dots' do
26
- subject.get ':id_with_dots/:another_id_with_dots', requirements: { id_with_dots: %r{[^\/]+},
27
- another_id_with_dots: %r{[^\/]+} } do
24
+ subject.get ':id_with_dots/:another_id_with_dots', requirements: { id_with_dots: %r{[^/]+},
25
+ another_id_with_dots: %r{[^/]+} } do
28
26
  "#{params[:id_with_dots]}/#{params[:another_id_with_dots]}"
29
27
  end
30
28
 
@@ -34,9 +32,9 @@ describe Grape::Endpoint do
34
32
  end
35
33
 
36
34
  it 'routes to namespace and path params with dots, with overridden requirements' do
37
- subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^\/]+} } do
38
- get ':another_id_with_dots', requirements: { ns_with_dots: %r{[^\/]+},
39
- another_id_with_dots: %r{[^\/]+} } do
35
+ subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
36
+ get ':another_id_with_dots', requirements: { ns_with_dots: %r{[^/]+},
37
+ another_id_with_dots: %r{[^/]+} } do
40
38
  "#{params[:ns_with_dots]}/#{params[:another_id_with_dots]}"
41
39
  end
42
40
  end
@@ -47,8 +45,8 @@ describe Grape::Endpoint do
47
45
  end
48
46
 
49
47
  it 'routes to namespace and path params with dots, with merged requirements' do
50
- subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^\/]+} } do
51
- get ':another_id_with_dots', requirements: { another_id_with_dots: %r{[^\/]+} } do
48
+ subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
49
+ get ':another_id_with_dots', requirements: { another_id_with_dots: %r{[^/]+} } do
52
50
  "#{params[:ns_with_dots]}/#{params[:another_id_with_dots]}"
53
51
  end
54
52
  end
@@ -1,21 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
- subject do
7
- shared_params = Module.new do
8
- extend Grape::API::Helpers
4
+ let(:app) do
5
+ Class.new(Grape::API) do
6
+ helpers Module.new do
7
+ extend Grape::API::Helpers
9
8
 
10
- params :drink do
11
- optional :beer
12
- optional :wine
13
- exactly_one_of :beer, :wine
9
+ params :drink do
10
+ optional :beer
11
+ optional :wine
12
+ exactly_one_of :beer, :wine
13
+ end
14
14
  end
15
- end
16
-
17
- Class.new(Grape::API) do
18
- helpers shared_params
19
15
  format :json
20
16
 
21
17
  params do
@@ -35,10 +31,6 @@ describe Grape::API::Helpers do
35
31
  end
36
32
  end
37
33
 
38
- def app
39
- subject
40
- end
41
-
42
34
  it 'defines parameters' do
43
35
  get '/', orderType: 'food', pizza: 'mista'
44
36
  expect(last_response.status).to eq 200
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
4
  subject do
7
5
  shared_params = Module.new do