grape 1.2.5 → 1.4.0

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 (262) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +97 -0
  3. data/LICENSE +1 -1
  4. data/README.md +53 -16
  5. data/UPGRADING.md +231 -23
  6. data/grape.gemspec +10 -1
  7. data/lib/grape.rb +6 -7
  8. data/lib/grape/api.rb +4 -2
  9. data/lib/grape/api/helpers.rb +2 -0
  10. data/lib/grape/api/instance.rb +36 -33
  11. data/lib/grape/config.rb +2 -0
  12. data/lib/grape/content_types.rb +34 -0
  13. data/lib/grape/cookies.rb +2 -0
  14. data/lib/grape/dsl/api.rb +2 -0
  15. data/lib/grape/dsl/callbacks.rb +2 -0
  16. data/lib/grape/dsl/configuration.rb +2 -0
  17. data/lib/grape/dsl/desc.rb +2 -0
  18. data/lib/grape/dsl/headers.rb +2 -0
  19. data/lib/grape/dsl/helpers.rb +4 -2
  20. data/lib/grape/dsl/inside_route.rb +83 -34
  21. data/lib/grape/dsl/logger.rb +2 -0
  22. data/lib/grape/dsl/middleware.rb +2 -0
  23. data/lib/grape/dsl/parameters.rb +8 -6
  24. data/lib/grape/dsl/request_response.rb +4 -2
  25. data/lib/grape/dsl/routing.rb +9 -5
  26. data/lib/grape/dsl/settings.rb +7 -1
  27. data/lib/grape/dsl/validations.rb +20 -1
  28. data/lib/grape/eager_load.rb +3 -1
  29. data/lib/grape/endpoint.rb +21 -13
  30. data/lib/grape/error_formatter.rb +3 -1
  31. data/lib/grape/error_formatter/base.rb +2 -0
  32. data/lib/grape/error_formatter/json.rb +2 -0
  33. data/lib/grape/error_formatter/txt.rb +2 -0
  34. data/lib/grape/error_formatter/xml.rb +2 -0
  35. data/lib/grape/exceptions/base.rb +11 -13
  36. data/lib/grape/exceptions/incompatible_option_values.rb +2 -0
  37. data/lib/grape/exceptions/invalid_accept_header.rb +2 -0
  38. data/lib/grape/exceptions/invalid_formatter.rb +2 -0
  39. data/lib/grape/exceptions/invalid_message_body.rb +2 -0
  40. data/lib/grape/exceptions/invalid_response.rb +2 -0
  41. data/lib/grape/exceptions/invalid_version_header.rb +2 -0
  42. data/lib/grape/exceptions/invalid_versioner_option.rb +2 -0
  43. data/lib/grape/exceptions/invalid_with_option_for_represent.rb +2 -0
  44. data/lib/grape/exceptions/method_not_allowed.rb +2 -0
  45. data/lib/grape/exceptions/missing_group_type.rb +2 -0
  46. data/lib/grape/exceptions/missing_mime_type.rb +2 -0
  47. data/lib/grape/exceptions/missing_option.rb +2 -0
  48. data/lib/grape/exceptions/missing_vendor_option.rb +2 -0
  49. data/lib/grape/exceptions/unknown_options.rb +2 -0
  50. data/lib/grape/exceptions/unknown_parameter.rb +2 -0
  51. data/lib/grape/exceptions/unknown_validator.rb +2 -0
  52. data/lib/grape/exceptions/unsupported_group_type.rb +2 -0
  53. data/lib/grape/exceptions/validation.rb +3 -1
  54. data/lib/grape/exceptions/validation_array_errors.rb +2 -0
  55. data/lib/grape/exceptions/validation_errors.rb +13 -12
  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.rb +5 -3
  62. data/lib/grape/formatter/json.rb +2 -0
  63. data/lib/grape/formatter/serializable_hash.rb +2 -0
  64. data/lib/grape/formatter/txt.rb +2 -0
  65. data/lib/grape/formatter/xml.rb +2 -0
  66. data/lib/grape/http/headers.rb +50 -18
  67. data/lib/grape/middleware/auth/base.rb +2 -0
  68. data/lib/grape/middleware/auth/dsl.rb +2 -0
  69. data/lib/grape/middleware/auth/strategies.rb +2 -0
  70. data/lib/grape/middleware/auth/strategy_info.rb +2 -0
  71. data/lib/grape/middleware/base.rb +7 -7
  72. data/lib/grape/middleware/error.rb +3 -1
  73. data/lib/grape/middleware/filter.rb +2 -0
  74. data/lib/grape/middleware/formatter.rb +8 -6
  75. data/lib/grape/middleware/globals.rb +2 -0
  76. data/lib/grape/middleware/helpers.rb +2 -0
  77. data/lib/grape/middleware/stack.rb +4 -1
  78. data/lib/grape/middleware/versioner.rb +2 -0
  79. data/lib/grape/middleware/versioner/accept_version_header.rb +2 -0
  80. data/lib/grape/middleware/versioner/header.rb +6 -4
  81. data/lib/grape/middleware/versioner/param.rb +3 -1
  82. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +4 -1
  83. data/lib/grape/middleware/versioner/path.rb +3 -1
  84. data/lib/grape/namespace.rb +14 -2
  85. data/lib/grape/parser.rb +3 -1
  86. data/lib/grape/parser/json.rb +2 -0
  87. data/lib/grape/parser/xml.rb +2 -0
  88. data/lib/grape/path.rb +15 -3
  89. data/lib/grape/presenters/presenter.rb +2 -0
  90. data/lib/grape/request.rb +15 -8
  91. data/lib/grape/router.rb +30 -29
  92. data/lib/grape/router/attribute_translator.rb +39 -8
  93. data/lib/grape/router/pattern.rb +20 -16
  94. data/lib/grape/router/route.rb +12 -26
  95. data/lib/grape/{serve_file → serve_stream}/file_body.rb +3 -1
  96. data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +3 -1
  97. data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +10 -8
  98. data/lib/grape/util/base_inheritable.rb +15 -6
  99. data/lib/grape/util/cache.rb +20 -0
  100. data/lib/grape/util/endpoint_configuration.rb +2 -0
  101. data/lib/grape/util/env.rb +19 -17
  102. data/lib/grape/util/inheritable_setting.rb +2 -0
  103. data/lib/grape/util/inheritable_values.rb +2 -0
  104. data/lib/grape/util/json.rb +2 -0
  105. data/lib/grape/util/lazy_block.rb +2 -0
  106. data/lib/grape/util/lazy_object.rb +43 -0
  107. data/lib/grape/util/lazy_value.rb +2 -0
  108. data/lib/grape/util/registrable.rb +2 -0
  109. data/lib/grape/util/reverse_stackable_values.rb +4 -0
  110. data/lib/grape/util/stackable_values.rb +10 -20
  111. data/lib/grape/util/strict_hash_configuration.rb +2 -0
  112. data/lib/grape/util/xml.rb +2 -0
  113. data/lib/grape/validations.rb +2 -0
  114. data/lib/grape/validations/attributes_iterator.rb +3 -3
  115. data/lib/grape/validations/multiple_attributes_iterator.rb +2 -0
  116. data/lib/grape/validations/params_scope.rb +27 -14
  117. data/lib/grape/validations/single_attribute_iterator.rb +13 -2
  118. data/lib/grape/validations/types.rb +12 -34
  119. data/lib/grape/validations/types/array_coercer.rb +65 -0
  120. data/lib/grape/validations/types/build_coercer.rb +47 -49
  121. data/lib/grape/validations/types/custom_type_coercer.rb +15 -49
  122. data/lib/grape/validations/types/custom_type_collection_coercer.rb +10 -25
  123. data/lib/grape/validations/types/dry_type_coercer.rb +76 -0
  124. data/lib/grape/validations/types/file.rb +22 -18
  125. data/lib/grape/validations/types/json.rb +46 -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/validator_factory.rb +2 -0
  131. data/lib/grape/validations/validators/all_or_none.rb +3 -1
  132. data/lib/grape/validations/validators/allow_blank.rb +3 -1
  133. data/lib/grape/validations/validators/as.rb +2 -0
  134. data/lib/grape/validations/validators/at_least_one_of.rb +3 -1
  135. data/lib/grape/validations/validators/base.rb +8 -5
  136. data/lib/grape/validations/validators/coerce.rb +39 -29
  137. data/lib/grape/validations/validators/default.rb +2 -1
  138. data/lib/grape/validations/validators/exactly_one_of.rb +6 -2
  139. data/lib/grape/validations/validators/except_values.rb +3 -1
  140. data/lib/grape/validations/validators/multiple_params_base.rb +2 -0
  141. data/lib/grape/validations/validators/mutual_exclusion.rb +3 -1
  142. data/lib/grape/validations/validators/presence.rb +3 -1
  143. data/lib/grape/validations/validators/regexp.rb +4 -2
  144. data/lib/grape/validations/validators/same_as.rb +6 -3
  145. data/lib/grape/validations/validators/values.rb +17 -5
  146. data/lib/grape/version.rb +3 -1
  147. data/spec/grape/api/custom_validations_spec.rb +5 -3
  148. data/spec/grape/api/deeply_included_options_spec.rb +2 -0
  149. data/spec/grape/api/defines_boolean_in_params_spec.rb +5 -3
  150. data/spec/grape/api/inherited_helpers_spec.rb +2 -0
  151. data/spec/grape/api/instance_spec.rb +104 -0
  152. data/spec/grape/api/invalid_format_spec.rb +2 -0
  153. data/spec/grape/api/namespace_parameters_in_route_spec.rb +2 -0
  154. data/spec/grape/api/nested_helpers_spec.rb +2 -0
  155. data/spec/grape/api/optional_parameters_in_route_spec.rb +2 -0
  156. data/spec/grape/api/parameters_modification_spec.rb +3 -1
  157. data/spec/grape/api/patch_method_helpers_spec.rb +2 -0
  158. data/spec/grape/api/recognize_path_spec.rb +2 -0
  159. data/spec/grape/api/required_parameters_in_route_spec.rb +2 -0
  160. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +2 -0
  161. data/spec/grape/api/routes_with_requirements_spec.rb +2 -0
  162. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +2 -0
  163. data/spec/grape/api/shared_helpers_spec.rb +2 -0
  164. data/spec/grape/api_remount_spec.rb +2 -0
  165. data/spec/grape/api_spec.rb +99 -11
  166. data/spec/grape/config_spec.rb +2 -0
  167. data/spec/grape/dsl/callbacks_spec.rb +2 -0
  168. data/spec/grape/dsl/configuration_spec.rb +2 -0
  169. data/spec/grape/dsl/desc_spec.rb +2 -0
  170. data/spec/grape/dsl/headers_spec.rb +2 -0
  171. data/spec/grape/dsl/helpers_spec.rb +4 -2
  172. data/spec/grape/dsl/inside_route_spec.rb +177 -33
  173. data/spec/grape/dsl/logger_spec.rb +2 -0
  174. data/spec/grape/dsl/middleware_spec.rb +2 -0
  175. data/spec/grape/dsl/parameters_spec.rb +2 -0
  176. data/spec/grape/dsl/request_response_spec.rb +2 -0
  177. data/spec/grape/dsl/routing_spec.rb +2 -0
  178. data/spec/grape/dsl/settings_spec.rb +2 -0
  179. data/spec/grape/dsl/validations_spec.rb +2 -0
  180. data/spec/grape/endpoint_spec.rb +21 -6
  181. data/spec/grape/entity_spec.rb +2 -0
  182. data/spec/grape/exceptions/base_spec.rb +3 -1
  183. data/spec/grape/exceptions/body_parse_errors_spec.rb +2 -0
  184. data/spec/grape/exceptions/invalid_accept_header_spec.rb +2 -0
  185. data/spec/grape/exceptions/invalid_formatter_spec.rb +2 -0
  186. data/spec/grape/exceptions/invalid_response_spec.rb +2 -0
  187. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +2 -0
  188. data/spec/grape/exceptions/missing_mime_type_spec.rb +2 -0
  189. data/spec/grape/exceptions/missing_option_spec.rb +2 -0
  190. data/spec/grape/exceptions/unknown_options_spec.rb +2 -0
  191. data/spec/grape/exceptions/unknown_validator_spec.rb +2 -0
  192. data/spec/grape/exceptions/validation_errors_spec.rb +4 -2
  193. data/spec/grape/exceptions/validation_spec.rb +3 -1
  194. data/spec/grape/extensions/param_builders/hash_spec.rb +2 -0
  195. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +2 -0
  196. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +2 -0
  197. data/spec/grape/integration/global_namespace_function_spec.rb +2 -0
  198. data/spec/grape/integration/rack_sendfile_spec.rb +14 -8
  199. data/spec/grape/integration/rack_spec.rb +3 -1
  200. data/spec/grape/loading_spec.rb +2 -0
  201. data/spec/grape/middleware/auth/base_spec.rb +2 -0
  202. data/spec/grape/middleware/auth/dsl_spec.rb +2 -0
  203. data/spec/grape/middleware/auth/strategies_spec.rb +3 -1
  204. data/spec/grape/middleware/base_spec.rb +2 -0
  205. data/spec/grape/middleware/error_spec.rb +2 -0
  206. data/spec/grape/middleware/exception_spec.rb +3 -1
  207. data/spec/grape/middleware/formatter_spec.rb +19 -12
  208. data/spec/grape/middleware/globals_spec.rb +2 -0
  209. data/spec/grape/middleware/stack_spec.rb +11 -0
  210. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -1
  211. data/spec/grape/middleware/versioner/header_spec.rb +3 -1
  212. data/spec/grape/middleware/versioner/param_spec.rb +3 -1
  213. data/spec/grape/middleware/versioner/path_spec.rb +3 -1
  214. data/spec/grape/middleware/versioner_spec.rb +2 -0
  215. data/spec/grape/named_api_spec.rb +2 -0
  216. data/spec/grape/parser_spec.rb +7 -5
  217. data/spec/grape/path_spec.rb +6 -4
  218. data/spec/grape/presenters/presenter_spec.rb +2 -0
  219. data/spec/grape/request_spec.rb +2 -0
  220. data/spec/grape/util/inheritable_setting_spec.rb +2 -0
  221. data/spec/grape/util/inheritable_values_spec.rb +2 -0
  222. data/spec/grape/util/reverse_stackable_values_spec.rb +2 -0
  223. data/spec/grape/util/stackable_values_spec.rb +3 -1
  224. data/spec/grape/util/strict_hash_configuration_spec.rb +2 -0
  225. data/spec/grape/validations/attributes_iterator_spec.rb +2 -0
  226. data/spec/grape/validations/instance_behaivour_spec.rb +5 -3
  227. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +2 -0
  228. data/spec/grape/validations/params_scope_spec.rb +3 -1
  229. data/spec/grape/validations/single_attribute_iterator_spec.rb +18 -4
  230. data/spec/grape/validations/types/array_coercer_spec.rb +35 -0
  231. data/spec/grape/validations/types/primitive_coercer_spec.rb +135 -0
  232. data/spec/grape/validations/types/set_coercer_spec.rb +34 -0
  233. data/spec/grape/validations/types_spec.rb +9 -36
  234. data/spec/grape/validations/validators/all_or_none_spec.rb +2 -0
  235. data/spec/grape/validations/validators/allow_blank_spec.rb +2 -0
  236. data/spec/grape/validations/validators/at_least_one_of_spec.rb +2 -0
  237. data/spec/grape/validations/validators/coerce_spec.rb +341 -136
  238. data/spec/grape/validations/validators/default_spec.rb +123 -0
  239. data/spec/grape/validations/validators/exactly_one_of_spec.rb +14 -12
  240. data/spec/grape/validations/validators/except_values_spec.rb +3 -1
  241. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +2 -0
  242. data/spec/grape/validations/validators/presence_spec.rb +30 -0
  243. data/spec/grape/validations/validators/regexp_spec.rb +2 -0
  244. data/spec/grape/validations/validators/same_as_spec.rb +2 -0
  245. data/spec/grape/validations/validators/values_spec.rb +30 -5
  246. data/spec/grape/validations_spec.rb +91 -33
  247. data/spec/integration/eager_load/eager_load_spec.rb +15 -0
  248. data/spec/integration/multi_json/json_spec.rb +2 -0
  249. data/spec/integration/multi_xml/xml_spec.rb +2 -0
  250. data/spec/shared/versioning_examples.rb +2 -0
  251. data/spec/spec_helper.rb +18 -0
  252. data/spec/support/basic_auth_encode_helpers.rb +2 -0
  253. data/spec/support/content_type_helpers.rb +2 -0
  254. data/spec/support/eager_load.rb +19 -0
  255. data/spec/support/endpoint_faker.rb +2 -0
  256. data/spec/support/file_streamer.rb +2 -0
  257. data/spec/support/integer_helpers.rb +2 -0
  258. data/spec/support/versioned_helpers.rb +4 -2
  259. metadata +48 -28
  260. data/lib/grape/extensions/deep_hash_with_indifferent_access.rb +0 -18
  261. data/lib/grape/util/content_types.rb +0 -26
  262. 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
 
3
5
  module Grape
@@ -85,12 +87,12 @@ module Grape
85
87
  describe '#namespace?' do
86
88
  it 'is false when the namespace is nil' do
87
89
  path = Path.new(anything, nil, anything)
88
- expect(path.namespace?).to be nil
90
+ expect(path.namespace?).to be_falsey
89
91
  end
90
92
 
91
93
  it 'is false when the namespace starts with whitespace' do
92
94
  path = Path.new(anything, ' /foo', anything)
93
- expect(path.namespace?).to be nil
95
+ expect(path.namespace?).to be_falsey
94
96
  end
95
97
 
96
98
  it 'is false when the namespace is the root path' do
@@ -107,12 +109,12 @@ module Grape
107
109
  describe '#path?' do
108
110
  it 'is false when the path is nil' do
109
111
  path = Path.new(nil, anything, anything)
110
- expect(path.path?).to be nil
112
+ expect(path.path?).to be_falsey
111
113
  end
112
114
 
113
115
  it 'is false when the path starts with whitespace' do
114
116
  path = Path.new(' /foo', anything, anything)
115
- expect(path.path?).to be nil
117
+ expect(path.path?).to be_falsey
116
118
  end
117
119
 
118
120
  it 'is false when the path is the root path' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Grape
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Grape
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  module Grape
3
5
  module Util
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  module Grape
3
5
  module Util
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  module Grape
3
5
  module Util
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  module Grape
3
5
  module Util
@@ -6,7 +8,7 @@ module Grape
6
8
  subject { StackableValues.new(parent) }
7
9
 
8
10
  describe '#keys' do
9
- it 'returns all key' do
11
+ it 'returns all keys' do
10
12
  subject[:some_thing] = :foo_bar
11
13
  subject[:some_thing_else] = :foo_bar
12
14
  expect(subject.keys).to eq %i[some_thing some_thing_else].sort
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  module Grape
3
5
  module Util
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Validations::AttributesIterator do
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'Validator with instance variables' do
4
6
  let(:validator_type) do
5
7
  Class.new(Grape::Validations::Base) do
6
8
  def validate_param!(_attr_name, _params)
7
- if @instance_variable
8
- raise Grape::Exceptions::Validation, params: ['params'],
9
- message: 'This should never happen'
9
+ if instance_variable_defined?(:@instance_variable) && @instance_variable
10
+ raise Grape::Exceptions::Validation.new(params: ['params'],
11
+ message: 'This should never happen')
10
12
  end
11
13
  @instance_variable = true
12
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Validations::MultipleAttributesIterator do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Validations::ParamsScope do
@@ -30,7 +32,7 @@ describe Grape::Validations::ParamsScope do
30
32
  context 'when the default value is false' do
31
33
  before do
32
34
  subject.params do
33
- optional :bool, type: Virtus::Attribute::Boolean, default: false
35
+ optional :bool, type: Grape::API::Boolean, default: false
34
36
  end
35
37
  subject.get
36
38
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Validations::SingleAttributeIterator do
4
6
  describe '#each' do
5
7
  subject(:iterator) { described_class.new(validator, scope, params) }
6
8
  let(:scope) { Grape::Validations::ParamsScope.new(api: Class.new(Grape::API)) }
7
- let(:validator) { double(attrs: %i[first second third]) }
9
+ let(:validator) { double(attrs: %i[first second]) }
8
10
 
9
11
  context 'when params is a hash' do
10
12
  let(:params) do
@@ -13,7 +15,7 @@ describe Grape::Validations::SingleAttributeIterator do
13
15
 
14
16
  it 'yields params and every single attribute from the list' do
15
17
  expect { |b| iterator.each(&b) }
16
- .to yield_successive_args([params, :first], [params, :second], [params, :third])
18
+ .to yield_successive_args([params, :first, false], [params, :second, false])
17
19
  end
18
20
  end
19
21
 
@@ -24,10 +26,22 @@ describe Grape::Validations::SingleAttributeIterator do
24
26
 
25
27
  it 'yields every single attribute from the list for each of the array elements' do
26
28
  expect { |b| iterator.each(&b) }.to yield_successive_args(
27
- [params[0], :first], [params[0], :second], [params[0], :third],
28
- [params[1], :first], [params[1], :second], [params[1], :third]
29
+ [params[0], :first, false], [params[0], :second, false],
30
+ [params[1], :first, false], [params[1], :second, false]
29
31
  )
30
32
  end
33
+
34
+ context 'empty values' do
35
+ let(:params) { [{}, '', 10] }
36
+
37
+ it 'marks params with empty values' do
38
+ expect { |b| iterator.each(&b) }.to yield_successive_args(
39
+ [params[0], :first, true], [params[0], :second, true],
40
+ [params[1], :first, true], [params[1], :second, true],
41
+ [params[2], :first, false], [params[2], :second, false]
42
+ )
43
+ end
44
+ end
31
45
  end
32
46
  end
33
47
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Grape::Validations::Types::ArrayCoercer do
6
+ subject { described_class.new(type) }
7
+
8
+ describe '#call' do
9
+ context 'an array of primitives' do
10
+ let(:type) { Array[String] }
11
+
12
+ it 'coerces elements in the array' do
13
+ expect(subject.call([10, 20])).to eq(%w[10 20])
14
+ end
15
+ end
16
+
17
+ context 'an array of arrays' do
18
+ let(:type) { Array[Array[Integer]] }
19
+
20
+ it 'coerces elements in the nested array' do
21
+ expect(subject.call([%w[10 20]])).to eq([[10, 20]])
22
+ expect(subject.call([['10'], ['20']])).to eq([[10], [20]])
23
+ end
24
+ end
25
+
26
+ context 'an array of sets' do
27
+ let(:type) { Array[Set[Integer]] }
28
+
29
+ it 'coerces elements in the nested set' do
30
+ expect(subject.call([%w[10 20]])).to eq([Set[10, 20]])
31
+ expect(subject.call([['10'], ['20']])).to eq([Set[10], Set[20]])
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Grape::Validations::Types::PrimitiveCoercer do
6
+ let(:strict) { false }
7
+
8
+ subject { described_class.new(type, strict) }
9
+
10
+ describe '#call' do
11
+ context 'BigDecimal' do
12
+ let(:type) { BigDecimal }
13
+
14
+ it 'coerces to BigDecimal' do
15
+ expect(subject.call(5)).to eq(BigDecimal(5))
16
+ end
17
+
18
+ it 'coerces an empty string to nil' do
19
+ expect(subject.call('')).to be_nil
20
+ end
21
+ end
22
+
23
+ context 'Boolean' do
24
+ let(:type) { Grape::API::Boolean }
25
+
26
+ [true, 'true', 1].each do |val|
27
+ it "coerces '#{val}' to true" do
28
+ expect(subject.call(val)).to eq(true)
29
+ end
30
+ end
31
+
32
+ [false, 'false', 0].each do |val|
33
+ it "coerces '#{val}' to false" do
34
+ expect(subject.call(val)).to eq(false)
35
+ end
36
+ end
37
+
38
+ it 'returns an error when the given value cannot be coerced' do
39
+ expect(subject.call(123)).to be_instance_of(Grape::Validations::Types::InvalidValue)
40
+ end
41
+
42
+ it 'coerces an empty string to nil' do
43
+ expect(subject.call('')).to be_nil
44
+ end
45
+ end
46
+
47
+ context 'DateTime' do
48
+ let(:type) { DateTime }
49
+
50
+ it 'coerces an empty string to nil' do
51
+ expect(subject.call('')).to be_nil
52
+ end
53
+ end
54
+
55
+ context 'Float' do
56
+ let(:type) { Float }
57
+
58
+ it 'coerces an empty string to nil' do
59
+ expect(subject.call('')).to be_nil
60
+ end
61
+ end
62
+
63
+ context 'Integer' do
64
+ let(:type) { Integer }
65
+
66
+ it 'coerces an empty string to nil' do
67
+ expect(subject.call('')).to be_nil
68
+ end
69
+ end
70
+
71
+ context 'Numeric' do
72
+ let(:type) { Numeric }
73
+
74
+ it 'coerces an empty string to nil' do
75
+ expect(subject.call('')).to be_nil
76
+ end
77
+ end
78
+
79
+ context 'Time' do
80
+ let(:type) { Time }
81
+
82
+ it 'coerces an empty string to nil' do
83
+ expect(subject.call('')).to be_nil
84
+ end
85
+ end
86
+
87
+ context 'String' do
88
+ let(:type) { String }
89
+
90
+ it 'coerces to String' do
91
+ expect(subject.call(10)).to eq('10')
92
+ end
93
+
94
+ it 'does not coerce an empty string to nil' do
95
+ expect(subject.call('')).to eq('')
96
+ end
97
+ end
98
+
99
+ context 'Symbol' do
100
+ let(:type) { Symbol }
101
+
102
+ it 'coerces an empty string to nil' do
103
+ expect(subject.call('')).to be_nil
104
+ end
105
+ end
106
+
107
+ context 'the strict mode' do
108
+ let(:strict) { true }
109
+
110
+ context 'Boolean' do
111
+ let(:type) { Grape::API::Boolean }
112
+
113
+ it 'returns an error when the given value is not Boolean' do
114
+ expect(subject.call(1)).to be_instance_of(Grape::Validations::Types::InvalidValue)
115
+ end
116
+
117
+ it 'returns a value as it is when the given value is Boolean' do
118
+ expect(subject.call(true)).to eq(true)
119
+ end
120
+ end
121
+
122
+ context 'BigDecimal' do
123
+ let(:type) { BigDecimal }
124
+
125
+ it 'returns an error when the given value is not BigDecimal' do
126
+ expect(subject.call(1)).to be_instance_of(Grape::Validations::Types::InvalidValue)
127
+ end
128
+
129
+ it 'returns a value as it is when the given value is BigDecimal' do
130
+ expect(subject.call(BigDecimal(0))).to eq(BigDecimal(0))
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Grape::Validations::Types::SetCoercer do
6
+ subject { described_class.new(type) }
7
+
8
+ describe '#call' do
9
+ context 'a set of primitives' do
10
+ let(:type) { Set[String] }
11
+
12
+ it 'coerces elements to the set' do
13
+ expect(subject.call([10, 20])).to eq(Set['10', '20'])
14
+ end
15
+ end
16
+
17
+ context 'a set of sets' do
18
+ let(:type) { Set[Set[Integer]] }
19
+
20
+ it 'coerces elements in the nested set' do
21
+ expect(subject.call([%w[10 20]])).to eq(Set[Set[10, 20]])
22
+ expect(subject.call([['10'], ['20']])).to eq(Set[Set[10], Set[20]])
23
+ end
24
+ end
25
+
26
+ context 'a set of sets of arrays' do
27
+ let(:type) { Set[Set[Array[Integer]]] }
28
+
29
+ it 'coerces elements in the nested set' do
30
+ expect(subject.call([[['10'], ['20']]])).to eq(Set[Set[Array[10], Array[20]]])
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Validations::Types do
@@ -11,30 +13,11 @@ describe Grape::Validations::Types do
11
13
  end
12
14
  end
13
15
 
14
- VirtusA = Virtus::Attribute.build(String)
15
-
16
- module VirtusModule
17
- include Virtus.module
18
- end
19
-
20
- class VirtusB
21
- include VirtusModule
22
- end
23
-
24
- class VirtusC
25
- include Virtus.model
26
- end
27
-
28
- MyAxiom = Axiom::Types::String.new do
29
- minimum_length 1
30
- maximum_length 30
31
- end
32
-
33
16
  describe '::primitive?' do
34
17
  [
35
18
  Integer, Float, Numeric, BigDecimal,
36
- Virtus::Attribute::Boolean, String, Symbol,
37
- Date, DateTime, Time, Rack::Multipart::UploadedFile
19
+ Grape::API::Boolean, String, Symbol,
20
+ Date, DateTime, Time
38
21
  ].each do |type|
39
22
  it "recognizes #{type} as a primitive" do
40
23
  expect(described_class.primitive?(type)).to be_truthy
@@ -57,16 +40,6 @@ describe Grape::Validations::Types do
57
40
  end
58
41
  end
59
42
 
60
- describe '::recognized?' do
61
- [
62
- VirtusA, VirtusB, VirtusC, MyAxiom
63
- ].each do |type|
64
- it "recognizes #{type}" do
65
- expect(described_class.recognized?(type)).to be_truthy
66
- end
67
- end
68
- end
69
-
70
43
  describe '::special?' do
71
44
  [
72
45
  JSON, Array[JSON], File, Rack::Multipart::UploadedFile
@@ -97,14 +70,14 @@ describe Grape::Validations::Types do
97
70
  expect(described_class.instance_variable_get(:@__cache_write_lock)).to be_a(Mutex)
98
71
  end
99
72
 
100
- it 'caches the result of the Virtus::Attribute.build method' do
73
+ it 'caches the result of the build_coercer method' do
101
74
  original_cache = described_class.instance_variable_get(:@__cache)
102
75
  described_class.instance_variable_set(:@__cache, {})
103
76
 
104
- coercer = 'TestCoercer'
105
- expect(Virtus::Attribute).to receive(:build).once.and_return(coercer)
106
- expect(described_class.build_coercer(Array[String])).to eq(coercer)
107
- expect(described_class.build_coercer(Array[String])).to eq(coercer)
77
+ a_coercer = described_class.build_coercer(Array[String])
78
+ b_coercer = described_class.build_coercer(Array[String])
79
+
80
+ expect(a_coercer.object_id).to eq(b_coercer.object_id)
108
81
 
109
82
  described_class.instance_variable_set(:@__cache, original_cache)
110
83
  end