grape 1.7.1 → 1.8.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 +22 -1
- data/CONTRIBUTING.md +1 -1
- data/README.md +12 -4
- data/grape.gemspec +2 -2
- data/lib/grape/api.rb +2 -2
- data/lib/grape/content_types.rb +2 -8
- data/lib/grape/dsl/desc.rb +1 -1
- data/lib/grape/dsl/inside_route.rb +5 -5
- data/lib/grape/dsl/request_response.rb +2 -1
- data/lib/grape/dsl/settings.rb +2 -6
- data/lib/grape/endpoint.rb +19 -17
- data/lib/grape/error_formatter/base.rb +1 -1
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/missing_group_type.rb +1 -6
- data/lib/grape/exceptions/unsupported_group_type.rb +1 -6
- data/lib/grape/exceptions/validation_errors.rb +1 -6
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +3 -3
- data/lib/grape/extensions/hash.rb +4 -7
- data/lib/grape/extensions/hashie/mash.rb +3 -3
- data/lib/grape/formatter/serializable_hash.rb +7 -7
- data/lib/grape/middleware/auth/base.rb +1 -1
- data/lib/grape/middleware/error.rb +1 -1
- data/lib/grape/middleware/formatter.rb +1 -1
- data/lib/grape/middleware/versioner/header.rb +11 -19
- data/lib/grape/router/route.rb +1 -3
- data/lib/grape/util/lazy_value.rb +3 -11
- data/lib/grape/util/strict_hash_configuration.rb +3 -4
- data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
- data/lib/grape/validations/params_scope.rb +8 -2
- data/lib/grape/validations/single_attribute_iterator.rb +3 -1
- data/lib/grape/validations/types/custom_type_coercer.rb +2 -16
- data/lib/grape/validations/validators/base.rb +9 -20
- data/lib/grape/validations/validators/default_validator.rb +2 -20
- data/lib/grape/validations/validators/multiple_params_base.rb +4 -8
- data/lib/grape/validations/validators/values_validator.rb +14 -5
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +11 -3
- data/spec/grape/api/custom_validations_spec.rb +14 -57
- data/spec/grape/api_remount_spec.rb +36 -0
- data/spec/grape/api_spec.rb +10 -1
- data/spec/grape/dsl/desc_spec.rb +84 -87
- data/spec/grape/dsl/inside_route_spec.rb +6 -10
- data/spec/grape/dsl/request_response_spec.rb +21 -2
- data/spec/grape/endpoint_spec.rb +8 -8
- data/spec/grape/exceptions/body_parse_errors_spec.rb +40 -0
- data/spec/grape/exceptions/missing_group_type_spec.rb +5 -9
- data/spec/grape/exceptions/unsupported_group_type_spec.rb +5 -9
- data/spec/grape/grape_spec.rb +9 -0
- data/spec/grape/middleware/formatter_spec.rb +1 -1
- data/spec/grape/request_spec.rb +4 -14
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +6 -8
- data/spec/grape/validations/single_attribute_iterator_spec.rb +8 -9
- data/spec/grape/validations/validators/base_spec.rb +38 -0
- data/spec/grape/validations/validators/values_spec.rb +37 -0
- data/spec/grape/validations_spec.rb +7 -6
- data/spec/shared/deprecated_class_examples.rb +16 -0
- metadata +17 -22
- data/lib/grape/config.rb +0 -34
- data/lib/grape/extensions/deep_mergeable_hash.rb +0 -21
- data/lib/grape/extensions/deep_symbolize_hash.rb +0 -32
- data/spec/grape/config_spec.rb +0 -17
@@ -10,6 +10,11 @@ module Grape
|
|
10
10
|
|
11
11
|
include Grape::DSL::Parameters
|
12
12
|
|
13
|
+
# There are a number of documentation options on entities that don't have
|
14
|
+
# corresponding validators. Since there is nowhere that enumerates them all,
|
15
|
+
# we maintain a list of them here and skip looking up validators for them.
|
16
|
+
RESERVED_DOCUMENTATION_KEYWORDS = %i[as required param_type is_array format example].freeze
|
17
|
+
|
13
18
|
class Attr
|
14
19
|
attr_accessor :key, :scope
|
15
20
|
|
@@ -359,7 +364,8 @@ module Grape
|
|
359
364
|
coerce_type validations, attrs, doc, opts
|
360
365
|
|
361
366
|
validations.each do |type, options|
|
362
|
-
|
367
|
+
# Don't try to look up validators for documentation params that don't have one.
|
368
|
+
next if RESERVED_DOCUMENTATION_KEYWORDS.include?(type)
|
363
369
|
|
364
370
|
validate(type, options, attrs, doc, opts)
|
365
371
|
end
|
@@ -414,7 +420,7 @@ module Grape
|
|
414
420
|
|
415
421
|
# but not special JSON types, which
|
416
422
|
# already imply coercion method
|
417
|
-
return
|
423
|
+
return if [JSON, Array[JSON]].exclude? validations[:coerce]
|
418
424
|
|
419
425
|
raise ArgumentError, 'coerce_with disallowed for type: JSON'
|
420
426
|
end
|
@@ -141,7 +141,7 @@ module Grape
|
|
141
141
|
lambda do |val|
|
142
142
|
method.call(val).tap do |new_val|
|
143
143
|
new_val.map do |item|
|
144
|
-
item.is_a?(Hash) ?
|
144
|
+
item.is_a?(Hash) ? item.deep_symbolize_keys : item
|
145
145
|
end
|
146
146
|
end
|
147
147
|
end
|
@@ -149,7 +149,7 @@ module Grape
|
|
149
149
|
# Hash objects are processed directly
|
150
150
|
elsif type == Hash
|
151
151
|
lambda do |val|
|
152
|
-
|
152
|
+
method.call(val).deep_symbolize_keys
|
153
153
|
end
|
154
154
|
|
155
155
|
# Simple types are not processed.
|
@@ -158,20 +158,6 @@ module Grape
|
|
158
158
|
method
|
159
159
|
end
|
160
160
|
end
|
161
|
-
|
162
|
-
def symbolize_keys!(hash)
|
163
|
-
hash.each_key do |key|
|
164
|
-
hash[key.to_sym] = hash.delete(key) if key.respond_to?(:to_sym)
|
165
|
-
end
|
166
|
-
hash
|
167
|
-
end
|
168
|
-
|
169
|
-
def symbolize_keys(hash)
|
170
|
-
hash.inject({}) do |new_hash, (key, value)|
|
171
|
-
new_key = key.respond_to?(:to_sym) ? key.to_sym : key
|
172
|
-
new_hash.merge!(new_key => value)
|
173
|
-
end
|
174
|
-
end
|
175
161
|
end
|
176
162
|
end
|
177
163
|
end
|
@@ -46,34 +46,23 @@ module Grape
|
|
46
46
|
# there may be more than one error per field
|
47
47
|
array_errors = []
|
48
48
|
|
49
|
-
attributes.each do |val, attr_name, empty_val
|
50
|
-
next if skip_value
|
49
|
+
attributes.each do |val, attr_name, empty_val|
|
51
50
|
next if !@scope.required? && empty_val
|
52
51
|
next unless @scope.meets_dependency?(val, params)
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
array_errors << e
|
58
|
-
end
|
53
|
+
validate_param!(attr_name, val) if @required || (val.respond_to?(:key?) && val.key?(attr_name))
|
54
|
+
rescue Grape::Exceptions::Validation => e
|
55
|
+
array_errors << e
|
59
56
|
end
|
60
57
|
|
61
58
|
raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
|
62
59
|
end
|
63
60
|
|
64
|
-
def self.convert_to_short_name(klass)
|
65
|
-
ret = klass.name.gsub(/::/, '/')
|
66
|
-
ret.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
67
|
-
ret.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
68
|
-
ret.tr!('-', '_')
|
69
|
-
ret.downcase!
|
70
|
-
File.basename(ret, '_validator')
|
71
|
-
end
|
72
|
-
|
73
61
|
def self.inherited(klass)
|
74
|
-
return
|
62
|
+
return if klass.name.blank?
|
75
63
|
|
76
|
-
|
64
|
+
short_validator_name = klass.name.demodulize.underscore.delete_suffix('_validator')
|
65
|
+
Validations.register_validator(short_validator_name, klass)
|
77
66
|
end
|
78
67
|
|
79
68
|
def message(default_key = nil)
|
@@ -95,8 +84,8 @@ module Grape
|
|
95
84
|
end
|
96
85
|
|
97
86
|
Grape::Validations::Base = Class.new(Grape::Validations::Validators::Base) do
|
98
|
-
def
|
87
|
+
def self.inherited(*)
|
88
|
+
ActiveSupport::Deprecation.warn 'Grape::Validations::Base is deprecated! Use Grape::Validations::Validators::Base instead.'
|
99
89
|
super
|
100
|
-
warn '[DEPRECATION] `Grape::Validations::Base` is deprecated. Use `Grape::Validations::Validators::Base` instead.'
|
101
90
|
end
|
102
91
|
end
|
@@ -12,10 +12,10 @@ module Grape
|
|
12
12
|
def validate_param!(attr_name, params)
|
13
13
|
params[attr_name] = if @default.is_a? Proc
|
14
14
|
@default.call
|
15
|
-
elsif @default.frozen? ||
|
15
|
+
elsif @default.frozen? || !@default.duplicable?
|
16
16
|
@default
|
17
17
|
else
|
18
|
-
|
18
|
+
@default.dup
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -27,24 +27,6 @@ module Grape
|
|
27
27
|
validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil?
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
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
|
41
|
-
|
42
|
-
# make a best effort to dup the object
|
43
|
-
def duplicate(obj)
|
44
|
-
obj.dup
|
45
|
-
rescue TypeError
|
46
|
-
obj
|
47
|
-
end
|
48
30
|
end
|
49
31
|
end
|
50
32
|
end
|
@@ -8,14 +8,10 @@ module Grape
|
|
8
8
|
attributes = MultipleAttributesIterator.new(self, @scope, params)
|
9
9
|
array_errors = []
|
10
10
|
|
11
|
-
attributes.each do |resource_params
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
validate_params!(resource_params)
|
16
|
-
rescue Grape::Exceptions::Validation => e
|
17
|
-
array_errors << e
|
18
|
-
end
|
11
|
+
attributes.each do |resource_params|
|
12
|
+
validate_params!(resource_params)
|
13
|
+
rescue Grape::Exceptions::Validation => e
|
14
|
+
array_errors << e
|
19
15
|
end
|
20
16
|
|
21
17
|
raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
|
@@ -10,13 +10,11 @@ module Grape
|
|
10
10
|
@values = options[:value]
|
11
11
|
@proc = options[:proc]
|
12
12
|
|
13
|
-
warn
|
14
|
-
'Use the except validator instead.' if @excepts
|
13
|
+
ActiveSupport::Deprecation.warn('The values validator except option is deprecated. Use the except validator instead.') if @excepts
|
15
14
|
|
16
15
|
raise ArgumentError, 'proc must be a Proc' if @proc && !@proc.is_a?(Proc)
|
17
16
|
|
18
|
-
warn
|
19
|
-
'The lambda expression can now be assigned directly to values.' if @proc
|
17
|
+
ActiveSupport::Deprecation.warn('The values validator proc option is deprecated. The lambda expression can now be assigned directly to values.') if @proc
|
20
18
|
else
|
21
19
|
@excepts = nil
|
22
20
|
@values = nil
|
@@ -45,7 +43,7 @@ module Grape
|
|
45
43
|
unless check_values(param_array, attr_name)
|
46
44
|
|
47
45
|
raise validation_exception(attr_name, message(:values)) \
|
48
|
-
|
46
|
+
if @proc && !validate_proc(@proc, param_array)
|
49
47
|
end
|
50
48
|
|
51
49
|
private
|
@@ -70,6 +68,17 @@ module Grape
|
|
70
68
|
param_array.none? { |param| excepts.include?(param) }
|
71
69
|
end
|
72
70
|
|
71
|
+
def validate_proc(proc, param_array)
|
72
|
+
case proc.arity
|
73
|
+
when 0
|
74
|
+
param_array.all? { |_param| proc.call }
|
75
|
+
when 1
|
76
|
+
param_array.all? { |param| proc.call(param) }
|
77
|
+
else
|
78
|
+
raise ArgumentError, 'proc arity must be 0 or 1'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
73
82
|
def except_message
|
74
83
|
options = instance_variable_get(:@option)
|
75
84
|
options_key?(:except_message) ? options[:except_message] : message(:except_values)
|
data/lib/grape/version.rb
CHANGED
data/lib/grape.rb
CHANGED
@@ -11,6 +11,7 @@ require 'bigdecimal'
|
|
11
11
|
require 'date'
|
12
12
|
require 'active_support'
|
13
13
|
require 'active_support/concern'
|
14
|
+
require 'active_support/configurable'
|
14
15
|
require 'active_support/version'
|
15
16
|
require 'active_support/isolated_execution_state' if ActiveSupport::VERSION::MAJOR > 6
|
16
17
|
require 'active_support/core_ext/array/conversions'
|
@@ -20,16 +21,21 @@ require 'active_support/core_ext/hash/conversions'
|
|
20
21
|
require 'active_support/core_ext/hash/deep_merge'
|
21
22
|
require 'active_support/core_ext/hash/except'
|
22
23
|
require 'active_support/core_ext/hash/indifferent_access'
|
24
|
+
require 'active_support/core_ext/hash/keys'
|
23
25
|
require 'active_support/core_ext/hash/reverse_merge'
|
24
26
|
require 'active_support/core_ext/hash/slice'
|
25
27
|
require 'active_support/core_ext/object/blank'
|
28
|
+
require 'active_support/core_ext/object/duplicable'
|
26
29
|
require 'active_support/dependencies/autoload'
|
30
|
+
require 'active_support/deprecation'
|
31
|
+
require 'active_support/inflector'
|
27
32
|
require 'active_support/notifications'
|
28
33
|
require 'i18n'
|
29
34
|
|
30
35
|
I18n.load_path << File.expand_path('grape/locale/en.yml', __dir__)
|
31
36
|
|
32
37
|
module Grape
|
38
|
+
include ActiveSupport::Configurable
|
33
39
|
extend ::ActiveSupport::Autoload
|
34
40
|
|
35
41
|
eager_autoload do
|
@@ -92,8 +98,6 @@ module Grape
|
|
92
98
|
module Extensions
|
93
99
|
extend ::ActiveSupport::Autoload
|
94
100
|
eager_autoload do
|
95
|
-
autoload :DeepMergeableHash
|
96
|
-
autoload :DeepSymbolizeHash
|
97
101
|
autoload :Hash
|
98
102
|
end
|
99
103
|
module ActiveSupport
|
@@ -285,9 +289,13 @@ module Grape
|
|
285
289
|
autoload :InvalidValue
|
286
290
|
end
|
287
291
|
end
|
292
|
+
|
293
|
+
configure do |config|
|
294
|
+
config.param_builder = Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
|
295
|
+
config.compile_methods!
|
296
|
+
end
|
288
297
|
end
|
289
298
|
|
290
|
-
require 'grape/config'
|
291
299
|
require 'grape/content_types'
|
292
300
|
|
293
301
|
require 'grape/util/lazy_value'
|
@@ -1,48 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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
|
3
|
+
require 'shared/deprecated_class_examples'
|
27
4
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
def app
|
33
|
-
subject
|
5
|
+
describe Grape::Validations do
|
6
|
+
describe 'Grape::Validations::Base' do
|
7
|
+
let(:deprecated_class) do
|
8
|
+
Class.new(Grape::Validations::Base)
|
34
9
|
end
|
35
10
|
|
36
|
-
|
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
|
11
|
+
it_behaves_like 'deprecated class'
|
43
12
|
end
|
44
13
|
|
45
|
-
|
14
|
+
describe 'using a custom length validator' do
|
46
15
|
subject do
|
47
16
|
Class.new(Grape::API) do
|
48
17
|
params do
|
@@ -64,6 +33,7 @@ describe Grape::Validations do
|
|
64
33
|
end
|
65
34
|
end
|
66
35
|
end
|
36
|
+
let(:app) { Rack::Builder.new(subject) }
|
67
37
|
|
68
38
|
before do
|
69
39
|
described_class.register_validator('default_length', default_length_validator)
|
@@ -73,10 +43,6 @@ describe Grape::Validations do
|
|
73
43
|
described_class.deregister_validator('default_length')
|
74
44
|
end
|
75
45
|
|
76
|
-
def app
|
77
|
-
subject
|
78
|
-
end
|
79
|
-
|
80
46
|
it 'under 140 characters' do
|
81
47
|
get '/', text: 'abc'
|
82
48
|
expect(last_response.status).to eq 200
|
@@ -96,7 +62,7 @@ describe Grape::Validations do
|
|
96
62
|
end
|
97
63
|
end
|
98
64
|
|
99
|
-
|
65
|
+
describe 'using a custom body-only validator' do
|
100
66
|
subject do
|
101
67
|
Class.new(Grape::API) do
|
102
68
|
params do
|
@@ -115,6 +81,7 @@ describe Grape::Validations do
|
|
115
81
|
end
|
116
82
|
end
|
117
83
|
end
|
84
|
+
let(:app) { Rack::Builder.new(subject) }
|
118
85
|
|
119
86
|
before do
|
120
87
|
described_class.register_validator('in_body', in_body_validator)
|
@@ -124,10 +91,6 @@ describe Grape::Validations do
|
|
124
91
|
described_class.deregister_validator('in_body')
|
125
92
|
end
|
126
93
|
|
127
|
-
def app
|
128
|
-
subject
|
129
|
-
end
|
130
|
-
|
131
94
|
it 'allows field in body' do
|
132
95
|
get '/', text: 'abc'
|
133
96
|
expect(last_response.status).to eq 200
|
@@ -141,7 +104,7 @@ describe Grape::Validations do
|
|
141
104
|
end
|
142
105
|
end
|
143
106
|
|
144
|
-
|
107
|
+
describe 'using a custom validator with message_key' do
|
145
108
|
subject do
|
146
109
|
Class.new(Grape::API) do
|
147
110
|
params do
|
@@ -160,6 +123,7 @@ describe Grape::Validations do
|
|
160
123
|
end
|
161
124
|
end
|
162
125
|
end
|
126
|
+
let(:app) { Rack::Builder.new(subject) }
|
163
127
|
|
164
128
|
before do
|
165
129
|
described_class.register_validator('with_message_key', message_key_validator)
|
@@ -169,10 +133,6 @@ describe Grape::Validations do
|
|
169
133
|
described_class.deregister_validator('with_message_key')
|
170
134
|
end
|
171
135
|
|
172
|
-
def app
|
173
|
-
subject
|
174
|
-
end
|
175
|
-
|
176
136
|
it 'fails with message' do
|
177
137
|
get '/', text: 'foobar'
|
178
138
|
expect(last_response.status).to eq 400
|
@@ -180,7 +140,7 @@ describe Grape::Validations do
|
|
180
140
|
end
|
181
141
|
end
|
182
142
|
|
183
|
-
|
143
|
+
describe 'using a custom request/param validator' do
|
184
144
|
subject do
|
185
145
|
Class.new(Grape::API) do
|
186
146
|
params do
|
@@ -208,6 +168,7 @@ describe Grape::Validations do
|
|
208
168
|
end
|
209
169
|
end
|
210
170
|
end
|
171
|
+
let(:app) { Rack::Builder.new(subject) }
|
211
172
|
|
212
173
|
before do
|
213
174
|
described_class.register_validator('admin', admin_validator)
|
@@ -217,10 +178,6 @@ describe Grape::Validations do
|
|
217
178
|
described_class.deregister_validator('admin')
|
218
179
|
end
|
219
180
|
|
220
|
-
def app
|
221
|
-
subject
|
222
|
-
end
|
223
|
-
|
224
181
|
it 'fail when non-admin user sets an admin field' do
|
225
182
|
get '/', admin_field: 'tester', non_admin_field: 'toaster'
|
226
183
|
expect(last_response.status).to eq 400
|
@@ -147,6 +147,42 @@ describe Grape::API do
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
+
context 'when the params are configured via a configuration' do
|
151
|
+
subject(:a_remounted_api) do
|
152
|
+
Class.new(described_class) do
|
153
|
+
params do
|
154
|
+
requires configuration[:required_attr_name], type: String
|
155
|
+
end
|
156
|
+
|
157
|
+
get(mounted { configuration[:endpoint] }) do
|
158
|
+
status 200
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'when the configured param is my_attr' do
|
164
|
+
it 'requires the configured params' do
|
165
|
+
root_api.mount a_remounted_api, with: {
|
166
|
+
required_attr_name: 'my_attr',
|
167
|
+
endpoint: 'test'
|
168
|
+
}
|
169
|
+
get 'test?another_attr=1'
|
170
|
+
expect(last_response.status).to eq 400
|
171
|
+
get 'test?my_attr=1'
|
172
|
+
expect(last_response.status).to eq 200
|
173
|
+
|
174
|
+
root_api.mount a_remounted_api, with: {
|
175
|
+
required_attr_name: 'another_attr',
|
176
|
+
endpoint: 'test_b'
|
177
|
+
}
|
178
|
+
get 'test_b?another_attr=1'
|
179
|
+
expect(last_response.status).to eq 200
|
180
|
+
get 'test_b?my_attr=1'
|
181
|
+
expect(last_response.status).to eq 400
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
150
186
|
context 'when executing a standard block within a `mounted` block with all dynamic params' do
|
151
187
|
subject(:a_remounted_api) do
|
152
188
|
Class.new(described_class) do
|
data/spec/grape/api_spec.rb
CHANGED
@@ -3311,7 +3311,7 @@ describe Grape::API do
|
|
3311
3311
|
it 'is able to cascade' do
|
3312
3312
|
subject.mount lambda { |env|
|
3313
3313
|
headers = {}
|
3314
|
-
headers['X-Cascade'] == 'pass'
|
3314
|
+
headers['X-Cascade'] == 'pass' if env['PATH_INFO'].exclude?('boo')
|
3315
3315
|
[200, headers, ['Farfegnugen']]
|
3316
3316
|
} => '/'
|
3317
3317
|
|
@@ -4226,6 +4226,15 @@ describe Grape::API do
|
|
4226
4226
|
end
|
4227
4227
|
end
|
4228
4228
|
|
4229
|
+
it 'does not override methods inherited from Class' do
|
4230
|
+
Class.define_method(:test_method) {}
|
4231
|
+
subclass = Class.new(described_class)
|
4232
|
+
expect(subclass).not_to receive(:add_setup)
|
4233
|
+
subclass.test_method
|
4234
|
+
ensure
|
4235
|
+
Class.remove_method(:test_method)
|
4236
|
+
end
|
4237
|
+
|
4229
4238
|
context 'overriding via composition' do
|
4230
4239
|
module Inherited
|
4231
4240
|
def inherited(api)
|