grape 1.5.3 → 1.6.2

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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/CONTRIBUTING.md +2 -1
  4. data/README.md +31 -3
  5. data/UPGRADING.md +46 -4
  6. data/grape.gemspec +5 -5
  7. data/lib/grape/api/instance.rb +13 -17
  8. data/lib/grape/api.rb +17 -12
  9. data/lib/grape/cookies.rb +2 -0
  10. data/lib/grape/dsl/desc.rb +3 -5
  11. data/lib/grape/dsl/headers.rb +5 -2
  12. data/lib/grape/dsl/helpers.rb +7 -5
  13. data/lib/grape/dsl/inside_route.rb +17 -8
  14. data/lib/grape/dsl/middleware.rb +4 -4
  15. data/lib/grape/dsl/parameters.rb +3 -3
  16. data/lib/grape/dsl/request_response.rb +9 -6
  17. data/lib/grape/dsl/routing.rb +2 -2
  18. data/lib/grape/dsl/settings.rb +5 -5
  19. data/lib/grape/endpoint.rb +20 -35
  20. data/lib/grape/error_formatter/json.rb +2 -6
  21. data/lib/grape/error_formatter/xml.rb +2 -6
  22. data/lib/grape/exceptions/validation.rb +1 -2
  23. data/lib/grape/formatter/json.rb +1 -0
  24. data/lib/grape/formatter/serializable_hash.rb +2 -1
  25. data/lib/grape/formatter/xml.rb +1 -0
  26. data/lib/grape/middleware/auth/dsl.rb +7 -1
  27. data/lib/grape/middleware/base.rb +3 -1
  28. data/lib/grape/middleware/formatter.rb +4 -4
  29. data/lib/grape/middleware/stack.rb +2 -2
  30. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  31. data/lib/grape/middleware/versioner/header.rb +6 -4
  32. data/lib/grape/middleware/versioner/param.rb +1 -0
  33. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  34. data/lib/grape/middleware/versioner/path.rb +2 -0
  35. data/lib/grape/path.rb +1 -0
  36. data/lib/grape/request.rb +1 -0
  37. data/lib/grape/router/pattern.rb +1 -1
  38. data/lib/grape/router/route.rb +2 -2
  39. data/lib/grape/router.rb +6 -0
  40. data/lib/grape/util/inheritable_setting.rb +1 -3
  41. data/lib/grape/util/lazy_value.rb +3 -2
  42. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  43. data/lib/grape/validations/params_scope.rb +88 -55
  44. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  45. data/lib/grape/validations/types/dry_type_coercer.rb +1 -1
  46. data/lib/grape/validations/types/json.rb +2 -1
  47. data/lib/grape/validations/types/primitive_coercer.rb +3 -3
  48. data/lib/grape/validations/validators/all_or_none.rb +8 -5
  49. data/lib/grape/validations/validators/allow_blank.rb +9 -7
  50. data/lib/grape/validations/validators/as.rb +6 -8
  51. data/lib/grape/validations/validators/at_least_one_of.rb +7 -4
  52. data/lib/grape/validations/validators/base.rb +75 -70
  53. data/lib/grape/validations/validators/coerce.rb +63 -79
  54. data/lib/grape/validations/validators/default.rb +37 -34
  55. data/lib/grape/validations/validators/exactly_one_of.rb +9 -6
  56. data/lib/grape/validations/validators/except_values.rb +13 -11
  57. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  58. data/lib/grape/validations/validators/mutual_exclusion.rb +8 -5
  59. data/lib/grape/validations/validators/presence.rb +7 -4
  60. data/lib/grape/validations/validators/regexp.rb +8 -5
  61. data/lib/grape/validations/validators/same_as.rb +18 -15
  62. data/lib/grape/validations/validators/values.rb +61 -56
  63. data/lib/grape/validations.rb +6 -0
  64. data/lib/grape/version.rb +1 -1
  65. data/lib/grape.rb +3 -1
  66. data/spec/grape/api/custom_validations_spec.rb +77 -45
  67. data/spec/grape/api/deeply_included_options_spec.rb +3 -3
  68. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -1
  69. data/spec/grape/api/invalid_format_spec.rb +2 -0
  70. data/spec/grape/api/recognize_path_spec.rb +1 -1
  71. data/spec/grape/api/routes_with_requirements_spec.rb +8 -8
  72. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -15
  73. data/spec/grape/api_remount_spec.rb +16 -15
  74. data/spec/grape/api_spec.rb +440 -227
  75. data/spec/grape/dsl/callbacks_spec.rb +2 -1
  76. data/spec/grape/dsl/headers_spec.rb +39 -9
  77. data/spec/grape/dsl/helpers_spec.rb +3 -2
  78. data/spec/grape/dsl/inside_route_spec.rb +6 -4
  79. data/spec/grape/dsl/logger_spec.rb +16 -18
  80. data/spec/grape/dsl/middleware_spec.rb +2 -1
  81. data/spec/grape/dsl/parameters_spec.rb +2 -0
  82. data/spec/grape/dsl/request_response_spec.rb +1 -0
  83. data/spec/grape/dsl/routing_spec.rb +10 -7
  84. data/spec/grape/endpoint/declared_spec.rb +259 -12
  85. data/spec/grape/endpoint_spec.rb +64 -55
  86. data/spec/grape/entity_spec.rb +22 -22
  87. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -0
  88. data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -22
  89. data/spec/grape/exceptions/validation_errors_spec.rb +13 -10
  90. data/spec/grape/exceptions/validation_spec.rb +5 -3
  91. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -7
  92. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -8
  93. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -8
  94. data/spec/grape/integration/rack_sendfile_spec.rb +1 -1
  95. data/spec/grape/loading_spec.rb +8 -8
  96. data/spec/grape/middleware/auth/dsl_spec.rb +15 -6
  97. data/spec/grape/middleware/auth/strategies_spec.rb +60 -20
  98. data/spec/grape/middleware/base_spec.rb +24 -15
  99. data/spec/grape/middleware/error_spec.rb +2 -2
  100. data/spec/grape/middleware/exception_spec.rb +111 -161
  101. data/spec/grape/middleware/formatter_spec.rb +27 -6
  102. data/spec/grape/middleware/globals_spec.rb +7 -4
  103. data/spec/grape/middleware/stack_spec.rb +14 -12
  104. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -1
  105. data/spec/grape/middleware/versioner/header_spec.rb +14 -13
  106. data/spec/grape/middleware/versioner/param_spec.rb +7 -1
  107. data/spec/grape/middleware/versioner/path_spec.rb +5 -1
  108. data/spec/grape/middleware/versioner_spec.rb +1 -1
  109. data/spec/grape/parser_spec.rb +4 -0
  110. data/spec/grape/path_spec.rb +52 -52
  111. data/spec/grape/presenters/presenter_spec.rb +7 -6
  112. data/spec/grape/request_spec.rb +6 -4
  113. data/spec/grape/util/inheritable_setting_spec.rb +7 -7
  114. data/spec/grape/util/inheritable_values_spec.rb +3 -2
  115. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -1
  116. data/spec/grape/util/stackable_values_spec.rb +7 -5
  117. data/spec/grape/validations/instance_behaivour_spec.rb +9 -10
  118. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -0
  119. data/spec/grape/validations/params_scope_spec.rb +46 -10
  120. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -1
  121. data/spec/grape/validations/types/primitive_coercer_spec.rb +4 -4
  122. data/spec/grape/validations/types_spec.rb +8 -8
  123. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -56
  124. data/spec/grape/validations/validators/allow_blank_spec.rb +136 -140
  125. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -56
  126. data/spec/grape/validations/validators/coerce_spec.rb +23 -22
  127. data/spec/grape/validations/validators/default_spec.rb +72 -78
  128. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -77
  129. data/spec/grape/validations/validators/except_values_spec.rb +3 -3
  130. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -77
  131. data/spec/grape/validations/validators/presence_spec.rb +16 -1
  132. data/spec/grape/validations/validators/regexp_spec.rb +25 -31
  133. data/spec/grape/validations/validators/same_as_spec.rb +14 -20
  134. data/spec/grape/validations/validators/values_spec.rb +183 -178
  135. data/spec/grape/validations_spec.rb +99 -58
  136. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  137. data/spec/integration/multi_json/json_spec.rb +1 -1
  138. data/spec/integration/multi_xml/xml_spec.rb +1 -1
  139. data/spec/shared/versioning_examples.rb +12 -9
  140. data/spec/spec_helper.rb +12 -2
  141. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  142. metadata +103 -103
@@ -1,90 +1,74 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Grape
4
- class API
5
- class Boolean
6
- def self.build(val)
7
- return nil if val != true && val != false
8
-
9
- new
10
- end
11
- end
12
-
13
- class Instance
14
- Boolean = Grape::API::Boolean
15
- end
16
- end
17
-
18
4
  module Validations
19
- class CoerceValidator < Base
20
- def initialize(attrs, options, required, scope, **opts)
21
- super
22
-
23
- @converter = if type.is_a?(Grape::Validations::Types::VariantCollectionCoercer)
24
- type
25
- else
26
- Types.build_coercer(type, method: @option[:method])
27
- end
28
- end
29
-
30
- def validate(request)
31
- super
32
- end
33
-
34
- def validate_param!(attr_name, params)
35
- raise validation_exception(attr_name) unless params.is_a? Hash
36
-
37
- new_value = coerce_value(params[attr_name])
38
-
39
- raise validation_exception(attr_name, new_value.message) unless valid_type?(new_value)
40
-
41
- # Don't assign a value if it is identical. It fixes a problem with Hashie::Mash
42
- # which looses wrappers for hashes and arrays after reassigning values
5
+ module Validators
6
+ class CoerceValidator < Base
7
+ def initialize(attrs, options, required, scope, **opts)
8
+ super
9
+
10
+ @converter = if type.is_a?(Grape::Validations::Types::VariantCollectionCoercer)
11
+ type
12
+ else
13
+ Types.build_coercer(type, method: @option[:method])
14
+ end
15
+ end
16
+
17
+ def validate_param!(attr_name, params)
18
+ raise validation_exception(attr_name) unless params.is_a? Hash
19
+
20
+ new_value = coerce_value(params[attr_name])
21
+
22
+ raise validation_exception(attr_name, new_value.message) unless valid_type?(new_value)
23
+
24
+ # Don't assign a value if it is identical. It fixes a problem with Hashie::Mash
25
+ # which looses wrappers for hashes and arrays after reassigning values
26
+ #
27
+ # h = Hashie::Mash.new(list: [1, 2, 3, 4])
28
+ # => #<Hashie::Mash list=#<Hashie::Array [1, 2, 3, 4]>>
29
+ # list = h.list
30
+ # h[:list] = list
31
+ # h
32
+ # => #<Hashie::Mash list=[1, 2, 3, 4]>
33
+ return if params[attr_name].instance_of?(new_value.class) && params[attr_name] == new_value
34
+
35
+ params[attr_name] = new_value
36
+ end
37
+
38
+ private
39
+
40
+ # @!attribute [r] converter
41
+ # Object that will be used for parameter coercion and type checking.
43
42
  #
44
- # h = Hashie::Mash.new(list: [1, 2, 3, 4])
45
- # => #<Hashie::Mash list=#<Hashie::Array [1, 2, 3, 4]>>
46
- # list = h.list
47
- # h[:list] = list
48
- # h
49
- # => #<Hashie::Mash list=[1, 2, 3, 4]>
50
- return if params[attr_name].class == new_value.class && params[attr_name] == new_value
51
-
52
- params[attr_name] = new_value
53
- end
54
-
55
- private
56
-
57
- # @!attribute [r] converter
58
- # Object that will be used for parameter coercion and type checking.
59
- #
60
- # See {Types.build_coercer}
61
- #
62
- # @return [Object]
63
- attr_reader :converter
64
-
65
- def valid_type?(val)
66
- !val.is_a?(Types::InvalidValue)
67
- end
43
+ # See {Types.build_coercer}
44
+ #
45
+ # @return [Object]
46
+ attr_reader :converter
68
47
 
69
- def coerce_value(val)
70
- converter.call(val)
71
- # Some custom types might fail, so it should be treated as an invalid value
72
- rescue StandardError
73
- Types::InvalidValue.new
74
- end
48
+ def valid_type?(val)
49
+ !val.is_a?(Types::InvalidValue)
50
+ end
75
51
 
76
- # Type to which the parameter will be coerced.
77
- #
78
- # @return [Class]
79
- def type
80
- @option[:type].is_a?(Hash) ? @option[:type][:value] : @option[:type]
81
- end
52
+ def coerce_value(val)
53
+ converter.call(val)
54
+ # Some custom types might fail, so it should be treated as an invalid value
55
+ rescue StandardError
56
+ Types::InvalidValue.new
57
+ end
82
58
 
83
- def validation_exception(attr_name, custom_msg = nil)
84
- Grape::Exceptions::Validation.new(
85
- params: [@scope.full_name(attr_name)],
86
- message: custom_msg || message(:coerce)
87
- )
59
+ # Type to which the parameter will be coerced.
60
+ #
61
+ # @return [Class]
62
+ def type
63
+ @option[:type].is_a?(Hash) ? @option[:type][:value] : @option[:type]
64
+ end
65
+
66
+ def validation_exception(attr_name, custom_msg = nil)
67
+ Grape::Exceptions::Validation.new(
68
+ params: [@scope.full_name(attr_name)],
69
+ message: custom_msg || message(:coerce)
70
+ )
71
+ end
88
72
  end
89
73
  end
90
74
  end
@@ -2,46 +2,49 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
- class DefaultValidator < Base
6
- def initialize(attrs, options, required, scope, **opts)
7
- @default = options
8
- super
9
- end
5
+ module Validators
6
+ class DefaultValidator < Base
7
+ def initialize(attrs, options, required, scope, **opts)
8
+ @default = options
9
+ super
10
+ end
10
11
 
11
- def validate_param!(attr_name, params)
12
- params[attr_name] = if @default.is_a? Proc
13
- @default.call
14
- elsif @default.frozen? || !duplicatable?(@default)
15
- @default
16
- else
17
- duplicate(@default)
18
- end
19
- end
12
+ def validate_param!(attr_name, params)
13
+ params[attr_name] = if @default.is_a? Proc
14
+ @default.call
15
+ elsif @default.frozen? || !duplicatable?(@default)
16
+ @default
17
+ else
18
+ duplicate(@default)
19
+ end
20
+ end
21
+
22
+ def validate!(params)
23
+ attrs = SingleAttributeIterator.new(self, @scope, params)
24
+ attrs.each do |resource_params, attr_name|
25
+ next unless @scope.meets_dependency?(resource_params, params)
20
26
 
21
- def validate!(params)
22
- attrs = SingleAttributeIterator.new(self, @scope, params)
23
- attrs.each do |resource_params, attr_name|
24
- next unless @scope.meets_dependency?(resource_params, params)
25
- validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil?
27
+ validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil?
28
+ end
26
29
  end
27
- end
28
30
 
29
- private
31
+ private
30
32
 
31
- # return true if we might be able to dup this object
32
- def duplicatable?(obj)
33
- !obj.nil? &&
34
- obj != true &&
35
- obj != false &&
36
- !obj.is_a?(Symbol) &&
37
- !obj.is_a?(Numeric)
38
- end
33
+ # return true if we might be able to dup this object
34
+ def duplicatable?(obj)
35
+ !obj.nil? &&
36
+ obj != true &&
37
+ obj != false &&
38
+ !obj.is_a?(Symbol) &&
39
+ !obj.is_a?(Numeric)
40
+ end
39
41
 
40
- # make a best effort to dup the object
41
- def duplicate(obj)
42
- obj.dup
43
- rescue TypeError
44
- obj
42
+ # make a best effort to dup the object
43
+ def duplicate(obj)
44
+ obj.dup
45
+ rescue TypeError
46
+ obj
47
+ end
45
48
  end
46
49
  end
47
50
  end
@@ -4,12 +4,15 @@ require 'grape/validations/validators/multiple_params_base'
4
4
 
5
5
  module Grape
6
6
  module Validations
7
- class ExactlyOneOfValidator < MultipleParamsBase
8
- def validate_params!(params)
9
- keys = keys_in_common(params)
10
- return if keys.length == 1
11
- raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:exactly_one)) if keys.length.zero?
12
- raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
7
+ module Validators
8
+ class ExactlyOneOfValidator < MultipleParamsBase
9
+ def validate_params!(params)
10
+ keys = keys_in_common(params)
11
+ return if keys.length == 1
12
+ raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:exactly_one)) if keys.length.zero?
13
+
14
+ raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
15
+ end
13
16
  end
14
17
  end
15
18
  end
@@ -2,20 +2,22 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
- class ExceptValuesValidator < Base
6
- def initialize(attrs, options, required, scope, **opts)
7
- @except = options.is_a?(Hash) ? options[:value] : options
8
- super
9
- end
5
+ module Validators
6
+ class ExceptValuesValidator < Base
7
+ def initialize(attrs, options, required, scope, **opts)
8
+ @except = options.is_a?(Hash) ? options[:value] : options
9
+ super
10
+ end
10
11
 
11
- def validate_param!(attr_name, params)
12
- return unless params.respond_to?(:key?) && params.key?(attr_name)
12
+ def validate_param!(attr_name, params)
13
+ return unless params.respond_to?(:key?) && params.key?(attr_name)
13
14
 
14
- excepts = @except.is_a?(Proc) ? @except.call : @except
15
- return if excepts.nil?
15
+ excepts = @except.is_a?(Proc) ? @except.call : @except
16
+ return if excepts.nil?
16
17
 
17
- param_array = params[attr_name].nil? ? [nil] : Array.wrap(params[attr_name])
18
- raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:except_values)) if param_array.any? { |param| excepts.include?(param) }
18
+ param_array = params[attr_name].nil? ? [nil] : Array.wrap(params[attr_name])
19
+ raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:except_values)) if param_array.any? { |param| excepts.include?(param) }
20
+ end
19
21
  end
20
22
  end
21
23
  end
@@ -2,32 +2,36 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
- class MultipleParamsBase < Base
6
- def validate!(params)
7
- attributes = MultipleAttributesIterator.new(self, @scope, params)
8
- array_errors = []
9
-
10
- attributes.each do |resource_params, skip_value|
11
- next if skip_value
12
- begin
13
- validate_params!(resource_params)
14
- rescue Grape::Exceptions::Validation => e
15
- array_errors << e
5
+ module Validators
6
+ class MultipleParamsBase < Base
7
+ def validate!(params)
8
+ attributes = MultipleAttributesIterator.new(self, @scope, params)
9
+ array_errors = []
10
+
11
+ attributes.each do |resource_params, skip_value|
12
+ next if skip_value
13
+
14
+ begin
15
+ validate_params!(resource_params)
16
+ rescue Grape::Exceptions::Validation => e
17
+ array_errors << e
18
+ end
16
19
  end
20
+
21
+ raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
17
22
  end
18
23
 
19
- raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
20
- end
24
+ private
21
25
 
22
- private
26
+ def keys_in_common(resource_params)
27
+ return [] unless resource_params.is_a?(Hash)
23
28
 
24
- def keys_in_common(resource_params)
25
- return [] unless resource_params.is_a?(Hash)
26
- all_keys & resource_params.keys.map! { |attr| @scope.full_name(attr) }
27
- end
29
+ all_keys & resource_params.keys.map! { |attr| @scope.full_name(attr) }
30
+ end
28
31
 
29
- def all_keys
30
- attrs.map { |attr| @scope.full_name(attr) }
32
+ def all_keys
33
+ attrs.map { |attr| @scope.full_name(attr) }
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -4,11 +4,14 @@ require 'grape/validations/validators/multiple_params_base'
4
4
 
5
5
  module Grape
6
6
  module Validations
7
- class MutualExclusionValidator < MultipleParamsBase
8
- def validate_params!(params)
9
- keys = keys_in_common(params)
10
- return if keys.length <= 1
11
- raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
7
+ module Validators
8
+ class MutualExclusionValidator < MultipleParamsBase
9
+ def validate_params!(params)
10
+ keys = keys_in_common(params)
11
+ return if keys.length <= 1
12
+
13
+ raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
14
+ end
12
15
  end
13
16
  end
14
17
  end
@@ -2,10 +2,13 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
- class PresenceValidator < Base
6
- def validate_param!(attr_name, params)
7
- return if params.respond_to?(:key?) && params.key?(attr_name)
8
- raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:presence))
5
+ module Validators
6
+ class PresenceValidator < Base
7
+ def validate_param!(attr_name, params)
8
+ return if params.respond_to?(:key?) && params.key?(attr_name)
9
+
10
+ raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:presence))
11
+ end
9
12
  end
10
13
  end
11
14
  end
@@ -2,11 +2,14 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
- class RegexpValidator < Base
6
- def validate_param!(attr_name, params)
7
- return unless params.respond_to?(:key?) && params.key?(attr_name)
8
- return if Array.wrap(params[attr_name]).all? { |param| param.nil? || param.to_s.match?((options_key?(:value) ? @option[:value] : @option)) }
9
- raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:regexp))
5
+ module Validators
6
+ class RegexpValidator < Base
7
+ def validate_param!(attr_name, params)
8
+ return unless params.respond_to?(:key?) && params.key?(attr_name)
9
+ return if Array.wrap(params[attr_name]).all? { |param| param.nil? || param.to_s.match?((options_key?(:value) ? @option[:value] : @option)) }
10
+
11
+ raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:regexp))
12
+ end
10
13
  end
11
14
  end
12
15
  end
@@ -2,23 +2,26 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
- class SameAsValidator < Base
6
- def validate_param!(attr_name, params)
7
- confirmation = options_key?(:value) ? @option[:value] : @option
8
- return if params[attr_name] == params[confirmation]
9
- raise Grape::Exceptions::Validation.new(
10
- params: [@scope.full_name(attr_name)],
11
- message: build_message
12
- )
13
- end
5
+ module Validators
6
+ class SameAsValidator < Base
7
+ def validate_param!(attr_name, params)
8
+ confirmation = options_key?(:value) ? @option[:value] : @option
9
+ return if params[attr_name] == params[confirmation]
10
+
11
+ raise Grape::Exceptions::Validation.new(
12
+ params: [@scope.full_name(attr_name)],
13
+ message: build_message
14
+ )
15
+ end
14
16
 
15
- private
17
+ private
16
18
 
17
- def build_message
18
- if options_key?(:message)
19
- @option[:message]
20
- else
21
- format I18n.t(:same_as, scope: 'grape.errors.messages'), parameter: @option
19
+ def build_message
20
+ if options_key?(:message)
21
+ @option[:message]
22
+ else
23
+ format I18n.t(:same_as, scope: 'grape.errors.messages'), parameter: @option
24
+ end
22
25
  end
23
26
  end
24
27
  end
@@ -2,81 +2,86 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
- class ValuesValidator < Base
6
- def initialize(attrs, options, required, scope, **opts)
7
- if options.is_a?(Hash)
8
- @excepts = options[:except]
9
- @values = options[:value]
10
- @proc = options[:proc]
11
-
12
- warn '[DEPRECATION] The values validator except option is deprecated. ' \
13
- 'Use the except validator instead.' if @excepts
14
-
15
- raise ArgumentError, 'proc must be a Proc' if @proc && !@proc.is_a?(Proc)
16
- warn '[DEPRECATION] The values validator proc option is deprecated. ' \
17
- 'The lambda expression can now be assigned directly to values.' if @proc
18
- else
19
- @excepts = nil
20
- @values = nil
21
- @proc = nil
22
- @values = options
5
+ module Validators
6
+ class ValuesValidator < Base
7
+ def initialize(attrs, options, required, scope, **opts)
8
+ if options.is_a?(Hash)
9
+ @excepts = options[:except]
10
+ @values = options[:value]
11
+ @proc = options[:proc]
12
+
13
+ warn '[DEPRECATION] The values validator except option is deprecated. ' \
14
+ 'Use the except validator instead.' if @excepts
15
+
16
+ raise ArgumentError, 'proc must be a Proc' if @proc && !@proc.is_a?(Proc)
17
+
18
+ warn '[DEPRECATION] The values validator proc option is deprecated. ' \
19
+ 'The lambda expression can now be assigned directly to values.' if @proc
20
+ else
21
+ @excepts = nil
22
+ @values = nil
23
+ @proc = nil
24
+ @values = options
25
+ end
26
+ super
23
27
  end
24
- super
25
- end
26
28
 
27
- def validate_param!(attr_name, params)
28
- return unless params.is_a?(Hash)
29
+ def validate_param!(attr_name, params)
30
+ return unless params.is_a?(Hash)
29
31
 
30
- val = params[attr_name]
32
+ val = params[attr_name]
31
33
 
32
- return if val.nil? && !required_for_root_scope?
34
+ return if val.nil? && !required_for_root_scope?
33
35
 
34
- # don't forget that +false.blank?+ is true
35
- return if val != false && val.blank? && @allow_blank
36
+ # don't forget that +false.blank?+ is true
37
+ return if val != false && val.blank? && @allow_blank
36
38
 
37
- param_array = val.nil? ? [nil] : Array.wrap(val)
39
+ param_array = val.nil? ? [nil] : Array.wrap(val)
38
40
 
39
- raise validation_exception(attr_name, except_message) \
41
+ raise validation_exception(attr_name, except_message) \
40
42
  unless check_excepts(param_array)
41
43
 
42
- raise validation_exception(attr_name, message(:values)) \
44
+ raise validation_exception(attr_name, message(:values)) \
43
45
  unless check_values(param_array, attr_name)
44
46
 
45
- raise validation_exception(attr_name, message(:values)) \
47
+ raise validation_exception(attr_name, message(:values)) \
46
48
  if @proc && !param_array.all? { |param| @proc.call(param) }
47
- end
49
+ end
50
+
51
+ private
48
52
 
49
- private
53
+ def check_values(param_array, attr_name)
54
+ values = @values.is_a?(Proc) && @values.arity.zero? ? @values.call : @values
55
+ return true if values.nil?
50
56
 
51
- def check_values(param_array, attr_name)
52
- values = @values.is_a?(Proc) && @values.arity.zero? ? @values.call : @values
53
- return true if values.nil?
54
- begin
55
- return param_array.all? { |param| values.call(param) } if values.is_a? Proc
56
- rescue StandardError => e
57
- warn "Error '#{e}' raised while validating attribute '#{attr_name}'"
58
- return false
57
+ begin
58
+ return param_array.all? { |param| values.call(param) } if values.is_a? Proc
59
+ rescue StandardError => e
60
+ warn "Error '#{e}' raised while validating attribute '#{attr_name}'"
61
+ return false
62
+ end
63
+ param_array.all? { |param| values.include?(param) }
59
64
  end
60
- param_array.all? { |param| values.include?(param) }
61
- end
62
65
 
63
- def check_excepts(param_array)
64
- excepts = @excepts.is_a?(Proc) ? @excepts.call : @excepts
65
- return true if excepts.nil?
66
- param_array.none? { |param| excepts.include?(param) }
67
- end
66
+ def check_excepts(param_array)
67
+ excepts = @excepts.is_a?(Proc) ? @excepts.call : @excepts
68
+ return true if excepts.nil?
68
69
 
69
- def except_message
70
- options = instance_variable_get(:@option)
71
- options_key?(:except_message) ? options[:except_message] : message(:except_values)
72
- end
70
+ param_array.none? { |param| excepts.include?(param) }
71
+ end
73
72
 
74
- def required_for_root_scope?
75
- @required && @scope.root?
76
- end
73
+ def except_message
74
+ options = instance_variable_get(:@option)
75
+ options_key?(:except_message) ? options[:except_message] : message(:except_values)
76
+ end
77
77
 
78
- def validation_exception(attr_name, message)
79
- Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message)
78
+ def required_for_root_scope?
79
+ @required && @scope.root?
80
+ end
81
+
82
+ def validation_exception(attr_name, message)
83
+ Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message)
84
+ end
80
85
  end
81
86
  end
82
87
  end
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'grape/validations/attributes_iterator'
4
+ require 'grape/validations/single_attribute_iterator'
5
+ require 'grape/validations/multiple_attributes_iterator'
6
+ require 'grape/validations/params_scope'
7
+ require 'grape/validations/types'
8
+
3
9
  module Grape
4
10
  # Registry to store and locate known Validators.
5
11
  module Validations
data/lib/grape/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Grape
4
4
  # The current version of Grape.
5
- VERSION = '1.5.3'
5
+ VERSION = '1.6.2'
6
6
  end
data/lib/grape.rb CHANGED
@@ -7,7 +7,9 @@ require 'rack/accept'
7
7
  require 'rack/auth/basic'
8
8
  require 'rack/auth/digest/md5'
9
9
  require 'set'
10
+ require 'active_support'
10
11
  require 'active_support/version'
12
+ require 'active_support/isolated_execution_state' if ActiveSupport::VERSION::MAJOR > 6
11
13
  require 'active_support/core_ext/hash/indifferent_access'
12
14
  require 'active_support/core_ext/object/blank'
13
15
  require 'active_support/core_ext/array/extract_options'
@@ -22,7 +24,7 @@ require 'active_support/dependencies/autoload'
22
24
  require 'active_support/notifications'
23
25
  require 'i18n'
24
26
 
25
- I18n.load_path << File.expand_path('../grape/locale/en.yml', __FILE__)
27
+ I18n.load_path << File.expand_path('grape/locale/en.yml', __dir__)
26
28
 
27
29
  module Grape
28
30
  extend ::ActiveSupport::Autoload