grape 1.6.1 → 1.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/CONTRIBUTING.md +1 -1
- data/README.md +120 -19
- data/UPGRADING.md +19 -4
- data/lib/grape/api/instance.rb +1 -1
- data/lib/grape/dsl/api.rb +0 -2
- data/lib/grape/dsl/callbacks.rb +0 -2
- data/lib/grape/dsl/configuration.rb +0 -2
- data/lib/grape/dsl/desc.rb +0 -15
- data/lib/grape/dsl/helpers.rb +0 -2
- data/lib/grape/dsl/inside_route.rb +33 -29
- data/lib/grape/dsl/middleware.rb +0 -2
- data/lib/grape/dsl/parameters.rb +5 -7
- data/lib/grape/dsl/request_response.rb +0 -2
- data/lib/grape/dsl/routing.rb +4 -2
- data/lib/grape/dsl/settings.rb +0 -2
- data/lib/grape/dsl/validations.rb +0 -15
- data/lib/grape/error_formatter/json.rb +7 -1
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/missing_group_type.rb +8 -1
- data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
- data/lib/grape/exceptions/validation.rb +0 -4
- data/lib/grape/locale/en.yml +9 -8
- data/lib/grape/middleware/auth/dsl.rb +0 -1
- data/lib/grape/middleware/error.rb +2 -2
- data/lib/grape/request.rb +2 -0
- data/lib/grape/validations/attributes_doc.rb +58 -0
- data/lib/grape/validations/params_scope.rb +66 -40
- data/lib/grape/validations/types/array_coercer.rb +2 -2
- data/lib/grape/validations/types/build_coercer.rb +94 -0
- data/lib/grape/validations/types/dry_type_coercer.rb +13 -8
- data/lib/grape/validations/types/json.rb +2 -0
- data/lib/grape/validations/types/primitive_coercer.rb +20 -10
- data/lib/grape/validations/types/set_coercer.rb +3 -2
- data/lib/grape/validations/types.rb +20 -26
- data/lib/grape/validations/validators/base.rb +7 -0
- data/lib/grape/validations.rb +16 -6
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +20 -15
- data/spec/grape/api/custom_validations_spec.rb +41 -2
- data/spec/grape/api/deeply_included_options_spec.rb +0 -2
- data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -2
- data/spec/grape/api/documentation_spec.rb +59 -0
- data/spec/grape/api/inherited_helpers_spec.rb +0 -2
- data/spec/grape/api/instance_spec.rb +0 -1
- data/spec/grape/api/invalid_format_spec.rb +0 -2
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/nested_helpers_spec.rb +0 -2
- data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/parameters_modification_spec.rb +0 -2
- data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
- data/spec/grape/api/recognize_path_spec.rb +0 -2
- data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
- data/spec/grape/api/routes_with_requirements_spec.rb +0 -2
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -2
- data/spec/grape/api/shared_helpers_spec.rb +0 -2
- data/spec/grape/api_remount_spec.rb +0 -1
- data/spec/grape/api_spec.rb +18 -5
- data/spec/grape/config_spec.rb +0 -2
- data/spec/grape/dsl/callbacks_spec.rb +0 -2
- data/spec/grape/dsl/configuration_spec.rb +0 -2
- data/spec/grape/dsl/desc_spec.rb +0 -2
- data/spec/grape/dsl/headers_spec.rb +2 -4
- data/spec/grape/dsl/helpers_spec.rb +0 -2
- data/spec/grape/dsl/inside_route_spec.rb +10 -12
- data/spec/grape/dsl/logger_spec.rb +0 -2
- data/spec/grape/dsl/middleware_spec.rb +0 -2
- data/spec/grape/dsl/parameters_spec.rb +0 -2
- data/spec/grape/dsl/request_response_spec.rb +6 -8
- data/spec/grape/dsl/routing_spec.rb +1 -3
- data/spec/grape/dsl/settings_spec.rb +0 -2
- data/spec/grape/dsl/validations_spec.rb +0 -17
- data/spec/grape/endpoint/declared_spec.rb +2 -4
- data/spec/grape/endpoint_spec.rb +22 -3
- data/spec/grape/entity_spec.rb +0 -1
- data/spec/grape/exceptions/base_spec.rb +16 -2
- data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
- data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
- data/spec/grape/exceptions/missing_option_spec.rb +1 -3
- data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
- data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
- data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +0 -1
- data/spec/grape/exceptions/validation_spec.rb +1 -3
- data/spec/grape/extensions/param_builders/hash_spec.rb +0 -2
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -2
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -2
- data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
- data/spec/grape/integration/rack_sendfile_spec.rb +0 -2
- data/spec/grape/integration/rack_spec.rb +0 -2
- data/spec/grape/loading_spec.rb +0 -2
- data/spec/grape/middleware/auth/base_spec.rb +0 -1
- data/spec/grape/middleware/auth/dsl_spec.rb +0 -2
- data/spec/grape/middleware/auth/strategies_spec.rb +0 -2
- data/spec/grape/middleware/base_spec.rb +0 -2
- data/spec/grape/middleware/error_spec.rb +6 -1
- data/spec/grape/middleware/exception_spec.rb +0 -2
- data/spec/grape/middleware/formatter_spec.rb +0 -2
- data/spec/grape/middleware/globals_spec.rb +0 -2
- data/spec/grape/middleware/stack_spec.rb +0 -2
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -2
- data/spec/grape/middleware/versioner/header_spec.rb +18 -4
- data/spec/grape/middleware/versioner/param_spec.rb +0 -2
- data/spec/grape/middleware/versioner/path_spec.rb +0 -2
- data/spec/grape/middleware/versioner_spec.rb +0 -2
- data/spec/grape/named_api_spec.rb +0 -2
- data/spec/grape/parser_spec.rb +0 -2
- data/spec/grape/path_spec.rb +0 -2
- data/spec/grape/presenters/presenter_spec.rb +0 -2
- data/spec/grape/request_spec.rb +0 -2
- data/spec/grape/util/inheritable_setting_spec.rb +0 -1
- data/spec/grape/util/inheritable_values_spec.rb +0 -1
- data/spec/grape/util/reverse_stackable_values_spec.rb +0 -1
- data/spec/grape/util/stackable_values_spec.rb +0 -1
- data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
- data/spec/grape/validations/attributes_doc_spec.rb +153 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +0 -2
- data/spec/grape/validations/instance_behaivour_spec.rb +0 -2
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -2
- data/spec/grape/validations/params_scope_spec.rb +315 -86
- data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -2
- data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
- data/spec/grape/validations/types/primitive_coercer_spec.rb +20 -5
- data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
- data/spec/grape/validations/types_spec.rb +28 -2
- data/spec/grape/validations/validators/all_or_none_spec.rb +0 -2
- data/spec/grape/validations/validators/allow_blank_spec.rb +0 -2
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -2
- data/spec/grape/validations/validators/coerce_spec.rb +0 -2
- data/spec/grape/validations/validators/default_spec.rb +0 -2
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -2
- data/spec/grape/validations/validators/except_values_spec.rb +0 -2
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -2
- data/spec/grape/validations/validators/presence_spec.rb +0 -2
- data/spec/grape/validations/validators/regexp_spec.rb +0 -2
- data/spec/grape/validations/validators/same_as_spec.rb +0 -2
- data/spec/grape/validations/validators/values_spec.rb +0 -2
- data/spec/grape/validations_spec.rb +50 -22
- data/spec/integration/multi_json/json_spec.rb +0 -2
- data/spec/integration/multi_xml/xml_spec.rb +0 -2
- data/spec/spec_helper.rb +9 -4
- metadata +17 -8
- data/spec/support/eager_load.rb +0 -19
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'grape/validations/types/json'
|
4
|
+
require 'grape/validations/types/file'
|
5
|
+
|
3
6
|
module Grape
|
4
7
|
module Validations
|
5
8
|
# Module for code related to grape's system for
|
@@ -13,7 +16,8 @@ module Grape
|
|
13
16
|
# and {Grape::Dsl::Parameters#optional}. The main
|
14
17
|
# entry point for this process is {Types.build_coercer}.
|
15
18
|
module Types
|
16
|
-
|
19
|
+
module_function
|
20
|
+
|
17
21
|
PRIMITIVES = [
|
18
22
|
# Numerical
|
19
23
|
Integer,
|
@@ -35,33 +39,23 @@ module Grape
|
|
35
39
|
].freeze
|
36
40
|
|
37
41
|
# Types representing data structures.
|
38
|
-
STRUCTURES = [
|
39
|
-
Hash,
|
40
|
-
Array,
|
41
|
-
Set
|
42
|
-
].freeze
|
42
|
+
STRUCTURES = [Hash, Array, Set].freeze
|
43
43
|
|
44
|
-
# Special custom types provided by Grape.
|
45
44
|
SPECIAL = {
|
46
|
-
JSON => Json,
|
45
|
+
::JSON => Json,
|
47
46
|
Array[JSON] => JsonArray,
|
48
47
|
::File => File,
|
49
48
|
Rack::Multipart::UploadedFile => File
|
50
49
|
}.freeze
|
51
50
|
|
52
|
-
GROUPS = [
|
53
|
-
Array,
|
54
|
-
Hash,
|
55
|
-
JSON,
|
56
|
-
Array[JSON]
|
57
|
-
].freeze
|
51
|
+
GROUPS = [Array, Hash, JSON, Array[JSON]].freeze
|
58
52
|
|
59
53
|
# Is the given class a primitive type as recognized by Grape?
|
60
54
|
#
|
61
55
|
# @param type [Class] type to check
|
62
56
|
# @return [Boolean] whether or not the type is known by Grape as a valid
|
63
57
|
# type for a single value
|
64
|
-
def
|
58
|
+
def primitive?(type)
|
65
59
|
PRIMITIVES.include?(type)
|
66
60
|
end
|
67
61
|
|
@@ -71,7 +65,7 @@ module Grape
|
|
71
65
|
# @param type [Class] type to check
|
72
66
|
# @return [Boolean] whether or not the type is known by Grape as a valid
|
73
67
|
# data structure type
|
74
|
-
def
|
68
|
+
def structure?(type)
|
75
69
|
STRUCTURES.include?(type)
|
76
70
|
end
|
77
71
|
|
@@ -83,7 +77,7 @@ module Grape
|
|
83
77
|
# @param type [Array<Class>,Set<Class>] type (or type list!) to check
|
84
78
|
# @return [Boolean] +true+ if the given value will be treated as
|
85
79
|
# a list of types.
|
86
|
-
def
|
80
|
+
def multiple?(type)
|
87
81
|
(type.is_a?(Array) || type.is_a?(Set)) && type.size > 1
|
88
82
|
end
|
89
83
|
|
@@ -94,7 +88,7 @@ module Grape
|
|
94
88
|
#
|
95
89
|
# @param type [Class] type to check
|
96
90
|
# @return [Boolean] +true+ if special routines are available
|
97
|
-
def
|
91
|
+
def special?(type)
|
98
92
|
SPECIAL.key? type
|
99
93
|
end
|
100
94
|
|
@@ -103,7 +97,7 @@ module Grape
|
|
103
97
|
#
|
104
98
|
# @param type [Array<Class>,Class] type to check
|
105
99
|
# @return [Boolean] +true+ if the type is a supported group type
|
106
|
-
def
|
100
|
+
def group?(type)
|
107
101
|
GROUPS.include? type
|
108
102
|
end
|
109
103
|
|
@@ -112,7 +106,7 @@ module Grape
|
|
112
106
|
#
|
113
107
|
# @param type [Class] type to check
|
114
108
|
# @return [Boolean] whether or not the type can be used as a custom type
|
115
|
-
def
|
109
|
+
def custom?(type)
|
116
110
|
!primitive?(type) &&
|
117
111
|
!structure?(type) &&
|
118
112
|
!multiple?(type) &&
|
@@ -125,13 +119,13 @@ module Grape
|
|
125
119
|
# @param type [Array<Class>,Class] type to check
|
126
120
|
# @return [Boolean] true if +type+ is a collection of a type that implements
|
127
121
|
# its own +#parse+ method.
|
128
|
-
def
|
122
|
+
def collection_of_custom?(type)
|
129
123
|
(type.is_a?(Array) || type.is_a?(Set)) &&
|
130
124
|
type.length == 1 &&
|
131
125
|
(custom?(type.first) || special?(type.first))
|
132
126
|
end
|
133
127
|
|
134
|
-
def
|
128
|
+
def map_special(type)
|
135
129
|
SPECIAL.fetch(type, type)
|
136
130
|
end
|
137
131
|
|
@@ -163,13 +157,13 @@ module Grape
|
|
163
157
|
# @param method [Class,#call] the coercion method to use
|
164
158
|
# @return [Object] object to be used
|
165
159
|
# for coercion and type validation
|
166
|
-
def
|
160
|
+
def build_coercer(type, method: nil, strict: false)
|
167
161
|
cache_instance(type, method, strict) do
|
168
162
|
create_coercer_instance(type, method, strict)
|
169
163
|
end
|
170
164
|
end
|
171
165
|
|
172
|
-
def
|
166
|
+
def create_coercer_instance(type, method, strict)
|
173
167
|
# Maps a custom type provided by Grape, it doesn't map types wrapped by collections!!!
|
174
168
|
type = Types.map_special(type)
|
175
169
|
|
@@ -193,7 +187,7 @@ module Grape
|
|
193
187
|
end
|
194
188
|
end
|
195
189
|
|
196
|
-
def
|
190
|
+
def cache_instance(type, method, strict, &_block)
|
197
191
|
key = cache_key(type, method, strict)
|
198
192
|
|
199
193
|
return @__cache[key] if @__cache.key?(key)
|
@@ -207,7 +201,7 @@ module Grape
|
|
207
201
|
instance
|
208
202
|
end
|
209
203
|
|
210
|
-
def
|
204
|
+
def cache_key(type, method, strict)
|
211
205
|
[type, method, strict].each_with_object(+'_') do |val, memo|
|
212
206
|
next if val.nil?
|
213
207
|
|
@@ -93,3 +93,10 @@ module Grape
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
96
|
+
|
97
|
+
Grape::Validations::Base = Class.new(Grape::Validations::Validators::Base) do
|
98
|
+
def initialize(*)
|
99
|
+
super
|
100
|
+
warn '[DEPRECATION] `Grape::Validations::Base` is deprecated. Use `Grape::Validations::Validators::Base` instead.'
|
101
|
+
end
|
102
|
+
end
|
data/lib/grape/validations.rb
CHANGED
@@ -3,22 +3,32 @@
|
|
3
3
|
module Grape
|
4
4
|
# Registry to store and locate known Validators.
|
5
5
|
module Validations
|
6
|
-
|
7
|
-
attr_accessor :validators
|
8
|
-
end
|
6
|
+
module_function
|
9
7
|
|
10
|
-
|
8
|
+
def validators
|
9
|
+
@validators ||= {}
|
10
|
+
end
|
11
11
|
|
12
12
|
# Register a new validator, so it can be used to validate parameters.
|
13
13
|
# @param short_name [String] all lower-case, no spaces
|
14
14
|
# @param klass [Class] the validator class. Should inherit from
|
15
15
|
# Validations::Base.
|
16
|
-
def
|
16
|
+
def register_validator(short_name, klass)
|
17
17
|
validators[short_name] = klass
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
20
|
+
def deregister_validator(short_name)
|
21
21
|
validators.delete(short_name)
|
22
22
|
end
|
23
|
+
|
24
|
+
# Find a validator and if not found will try to load it
|
25
|
+
def require_validator(short_name)
|
26
|
+
str_name = short_name.to_s
|
27
|
+
validators.fetch(str_name) do
|
28
|
+
Grape::Validations::Validators.const_get("#{str_name.camelize}Validator")
|
29
|
+
end
|
30
|
+
rescue NameError
|
31
|
+
raise Grape::Exceptions::UnknownValidator.new(short_name)
|
32
|
+
end
|
23
33
|
end
|
24
34
|
end
|
data/lib/grape/version.rb
CHANGED
data/lib/grape.rb
CHANGED
@@ -7,19 +7,22 @@ require 'rack/accept'
|
|
7
7
|
require 'rack/auth/basic'
|
8
8
|
require 'rack/auth/digest/md5'
|
9
9
|
require 'set'
|
10
|
+
require 'bigdecimal'
|
11
|
+
require 'date'
|
10
12
|
require 'active_support'
|
13
|
+
require 'active_support/concern'
|
11
14
|
require 'active_support/version'
|
12
15
|
require 'active_support/isolated_execution_state' if ActiveSupport::VERSION::MAJOR > 6
|
13
|
-
require 'active_support/core_ext/hash/indifferent_access'
|
14
|
-
require 'active_support/core_ext/object/blank'
|
15
16
|
require 'active_support/core_ext/array/conversions'
|
16
17
|
require 'active_support/core_ext/array/extract_options'
|
17
18
|
require 'active_support/core_ext/array/wrap'
|
18
19
|
require 'active_support/core_ext/hash/conversions'
|
19
20
|
require 'active_support/core_ext/hash/deep_merge'
|
20
21
|
require 'active_support/core_ext/hash/except'
|
22
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
21
23
|
require 'active_support/core_ext/hash/reverse_merge'
|
22
24
|
require 'active_support/core_ext/hash/slice'
|
25
|
+
require 'active_support/core_ext/object/blank'
|
23
26
|
require 'active_support/dependencies/autoload'
|
24
27
|
require 'active_support/notifications'
|
25
28
|
require 'i18n'
|
@@ -72,14 +75,17 @@ module Grape
|
|
72
75
|
autoload :UnknownParameter
|
73
76
|
autoload :InvalidWithOptionForRepresent
|
74
77
|
autoload :IncompatibleOptionValues
|
75
|
-
autoload :
|
76
|
-
autoload :
|
78
|
+
autoload :MissingGroupType
|
79
|
+
autoload :UnsupportedGroupType
|
77
80
|
autoload :InvalidMessageBody
|
78
81
|
autoload :InvalidAcceptHeader
|
79
82
|
autoload :InvalidVersionHeader
|
80
83
|
autoload :MethodNotAllowed
|
81
84
|
autoload :InvalidResponse
|
82
85
|
autoload :EmptyMessageBody
|
86
|
+
autoload :TooManyMultipartFiles
|
87
|
+
autoload :MissingGroupTypeError, 'grape/exceptions/missing_group_type'
|
88
|
+
autoload :UnsupportedGroupTypeError, 'grape/exceptions/unsupported_group_type'
|
83
89
|
end
|
84
90
|
end
|
85
91
|
|
@@ -223,13 +229,21 @@ module Grape
|
|
223
229
|
module Validations
|
224
230
|
extend ::ActiveSupport::Autoload
|
225
231
|
|
232
|
+
eager_autoload do
|
233
|
+
autoload :AttributesIterator
|
234
|
+
autoload :MultipleAttributesIterator
|
235
|
+
autoload :SingleAttributeIterator
|
236
|
+
autoload :Types
|
237
|
+
autoload :ParamsScope
|
238
|
+
autoload :ValidatorFactory
|
239
|
+
autoload :Base, 'grape/validations/validators/base'
|
240
|
+
end
|
241
|
+
|
226
242
|
module Types
|
227
243
|
extend ::ActiveSupport::Autoload
|
228
244
|
|
229
245
|
eager_autoload do
|
230
246
|
autoload :InvalidValue
|
231
|
-
autoload :File
|
232
|
-
autoload :Json
|
233
247
|
autoload :DryTypeCoercer
|
234
248
|
autoload :ArrayCoercer
|
235
249
|
autoload :SetCoercer
|
@@ -241,15 +255,6 @@ module Grape
|
|
241
255
|
end
|
242
256
|
end
|
243
257
|
|
244
|
-
eager_autoload do
|
245
|
-
autoload :AttributesIterator
|
246
|
-
autoload :MultipleAttributesIterator
|
247
|
-
autoload :SingleAttributeIterator
|
248
|
-
autoload :ParamsScope
|
249
|
-
autoload :Types
|
250
|
-
autoload :ValidatorFactory
|
251
|
-
end
|
252
|
-
|
253
258
|
module Validators
|
254
259
|
extend ::ActiveSupport::Autoload
|
255
260
|
|
@@ -1,8 +1,47 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
describe Grape::Validations do
|
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
|
19
|
+
end
|
20
|
+
end
|
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
|
+
|
6
45
|
context 'using a custom length validator' do
|
7
46
|
subject do
|
8
47
|
Class.new(Grape::API) do
|
@@ -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
|
data/spec/grape/api_spec.rb
CHANGED
@@ -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 do
|
@@ -1217,7 +1216,7 @@ describe Grape::API do
|
|
1217
1216
|
|
1218
1217
|
it 'does not set Cache-Control' do
|
1219
1218
|
get '/foo'
|
1220
|
-
expect(last_response.headers['Cache-Control']).to
|
1219
|
+
expect(last_response.headers['Cache-Control']).to be_nil
|
1221
1220
|
end
|
1222
1221
|
|
1223
1222
|
it 'sets content type for xml' do
|
@@ -1242,7 +1241,7 @@ describe Grape::API do
|
|
1242
1241
|
|
1243
1242
|
it 'returns raw data when content type binary' do
|
1244
1243
|
image_filename = 'grape.png'
|
1245
|
-
file = File.
|
1244
|
+
file = File.binread(image_filename)
|
1246
1245
|
subject.format :binary
|
1247
1246
|
subject.get('/binary_file') { File.binread(image_filename) }
|
1248
1247
|
get '/binary_file'
|
@@ -1274,7 +1273,7 @@ describe Grape::API do
|
|
1274
1273
|
get '/stream', {}, 'HTTP_VERSION' => 'HTTP/1.1', 'SERVER_PROTOCOL' => 'HTTP/1.1'
|
1275
1274
|
|
1276
1275
|
expect(last_response.headers['Content-Type']).to eq('text/plain')
|
1277
|
-
expect(last_response.headers['Content-Length']).to
|
1276
|
+
expect(last_response.headers['Content-Length']).to be_nil
|
1278
1277
|
expect(last_response.headers['Cache-Control']).to eq('no-cache')
|
1279
1278
|
expect(last_response.headers['Transfer-Encoding']).to eq('chunked')
|
1280
1279
|
|
@@ -2292,7 +2291,7 @@ describe Grape::API do
|
|
2292
2291
|
subject.rescue_from :all, with: :not_exist_method
|
2293
2292
|
subject.get('/rescue_method') { raise StandardError }
|
2294
2293
|
|
2295
|
-
expect { get '/rescue_method' }.to raise_error(NoMethodError, /^undefined method
|
2294
|
+
expect { get '/rescue_method' }.to raise_error(NoMethodError, /^undefined method 'not_exist_method'/)
|
2296
2295
|
end
|
2297
2296
|
|
2298
2297
|
it 'correctly chooses exception handler if :all handler is specified' do
|
@@ -4158,6 +4157,20 @@ describe Grape::API do
|
|
4158
4157
|
end
|
4159
4158
|
end
|
4160
4159
|
|
4160
|
+
context 'with non-UTF-8 characters in specified format' do
|
4161
|
+
it 'converts the characters' do
|
4162
|
+
subject.format :json
|
4163
|
+
subject.content_type :json, 'application/json'
|
4164
|
+
subject.get '/something' do
|
4165
|
+
'foo'
|
4166
|
+
end
|
4167
|
+
get '/something?format=%0A%0B%BF'
|
4168
|
+
expect(last_response.status).to eq(406)
|
4169
|
+
message = "The requested format '\n\u000b\357\277\275' is not supported."
|
4170
|
+
expect(last_response.body).to eq({ error: message }.to_json)
|
4171
|
+
end
|
4172
|
+
end
|
4173
|
+
|
4161
4174
|
context 'body' do
|
4162
4175
|
context 'false' do
|
4163
4176
|
before do
|
data/spec/grape/config_spec.rb
CHANGED
data/spec/grape/dsl/desc_spec.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
module Grape
|
6
4
|
module DSL
|
7
5
|
module HeadersSpec
|
@@ -54,8 +52,8 @@ module Grape
|
|
54
52
|
context 'when no headers are set' do
|
55
53
|
describe '#header' do
|
56
54
|
it 'returns nil' do
|
57
|
-
expect(subject.header['First Key']).to
|
58
|
-
expect(subject.header('First Key')).to
|
55
|
+
expect(subject.header['First Key']).to be_nil
|
56
|
+
expect(subject.header('First Key')).to be_nil
|
59
57
|
end
|
60
58
|
end
|
61
59
|
end
|