grape 1.6.2 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -1
  3. data/CONTRIBUTING.md +30 -0
  4. data/README.md +146 -23
  5. data/UPGRADING.md +15 -0
  6. data/grape.gemspec +2 -2
  7. data/lib/grape/api/instance.rb +1 -1
  8. data/lib/grape/dry_types.rb +12 -0
  9. data/lib/grape/dsl/api.rb +0 -2
  10. data/lib/grape/dsl/callbacks.rb +0 -2
  11. data/lib/grape/dsl/configuration.rb +0 -2
  12. data/lib/grape/dsl/desc.rb +2 -16
  13. data/lib/grape/dsl/helpers.rb +0 -2
  14. data/lib/grape/dsl/inside_route.rb +34 -30
  15. data/lib/grape/dsl/middleware.rb +0 -2
  16. data/lib/grape/dsl/parameters.rb +10 -7
  17. data/lib/grape/dsl/request_response.rb +1 -3
  18. data/lib/grape/dsl/routing.rb +4 -2
  19. data/lib/grape/dsl/settings.rb +0 -2
  20. data/lib/grape/dsl/validations.rb +0 -15
  21. data/lib/grape/endpoint.rb +2 -2
  22. data/lib/grape/error_formatter/json.rb +7 -1
  23. data/lib/grape/exceptions/base.rb +3 -2
  24. data/lib/grape/exceptions/missing_group_type.rb +8 -1
  25. data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
  26. data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
  27. data/lib/grape/exceptions/validation.rb +0 -4
  28. data/lib/grape/locale/en.yml +9 -8
  29. data/lib/grape/middleware/auth/dsl.rb +0 -1
  30. data/lib/grape/middleware/error.rb +2 -2
  31. data/lib/grape/middleware/stack.rb +1 -1
  32. data/lib/grape/request.rb +3 -1
  33. data/lib/grape/router/attribute_translator.rb +1 -1
  34. data/lib/grape/types/invalid_value.rb +8 -0
  35. data/lib/grape/util/cache.rb +1 -1
  36. data/lib/grape/util/json.rb +2 -0
  37. data/lib/grape/validations/attributes_doc.rb +58 -0
  38. data/lib/grape/validations/params_scope.rb +67 -41
  39. data/lib/grape/validations/types/array_coercer.rb +0 -2
  40. data/lib/grape/validations/types/dry_type_coercer.rb +3 -7
  41. data/lib/grape/validations/types/invalid_value.rb +0 -7
  42. data/lib/grape/validations/types/primitive_coercer.rb +14 -6
  43. data/lib/grape/validations/types/set_coercer.rb +0 -2
  44. data/lib/grape/validations/types.rb +98 -30
  45. data/lib/grape/validations/validators/{all_or_none.rb → all_or_none_of_validator.rb} +0 -2
  46. data/lib/grape/validations/validators/{at_least_one_of.rb → at_least_one_of_validator.rb} +0 -2
  47. data/lib/grape/validations/validators/base.rb +7 -0
  48. data/lib/grape/validations/validators/{exactly_one_of.rb → exactly_one_of_validator.rb} +0 -2
  49. data/lib/grape/validations/validators/{mutual_exclusion.rb → mutual_exclusion_validator.rb} +0 -2
  50. data/lib/grape/validations.rb +16 -12
  51. data/lib/grape/version.rb +1 -1
  52. data/lib/grape.rb +74 -28
  53. data/spec/grape/api/custom_validations_spec.rb +41 -2
  54. data/spec/grape/api/deeply_included_options_spec.rb +0 -2
  55. data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -2
  56. data/spec/grape/api/documentation_spec.rb +59 -0
  57. data/spec/grape/api/inherited_helpers_spec.rb +0 -2
  58. data/spec/grape/api/instance_spec.rb +0 -1
  59. data/spec/grape/api/invalid_format_spec.rb +0 -2
  60. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
  61. data/spec/grape/api/nested_helpers_spec.rb +0 -2
  62. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
  63. data/spec/grape/api/parameters_modification_spec.rb +0 -2
  64. data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
  65. data/spec/grape/api/recognize_path_spec.rb +0 -2
  66. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
  67. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
  68. data/spec/grape/api/routes_with_requirements_spec.rb +0 -2
  69. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -2
  70. data/spec/grape/api/shared_helpers_spec.rb +0 -2
  71. data/spec/grape/api_remount_spec.rb +0 -1
  72. data/spec/grape/api_spec.rb +23 -25
  73. data/spec/grape/config_spec.rb +0 -2
  74. data/spec/grape/dsl/callbacks_spec.rb +0 -2
  75. data/spec/grape/dsl/desc_spec.rb +2 -2
  76. data/spec/grape/dsl/headers_spec.rb +2 -4
  77. data/spec/grape/dsl/helpers_spec.rb +0 -2
  78. data/spec/grape/dsl/inside_route_spec.rb +10 -12
  79. data/spec/grape/dsl/logger_spec.rb +0 -2
  80. data/spec/grape/dsl/middleware_spec.rb +0 -2
  81. data/spec/grape/dsl/parameters_spec.rb +0 -2
  82. data/spec/grape/dsl/request_response_spec.rb +6 -8
  83. data/spec/grape/dsl/routing_spec.rb +1 -3
  84. data/spec/grape/dsl/settings_spec.rb +0 -2
  85. data/spec/grape/dsl/validations_spec.rb +0 -17
  86. data/spec/grape/endpoint/declared_spec.rb +2 -4
  87. data/spec/grape/endpoint_spec.rb +29 -9
  88. data/spec/grape/entity_spec.rb +0 -1
  89. data/spec/grape/exceptions/base_spec.rb +16 -2
  90. data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -2
  91. data/spec/grape/exceptions/invalid_accept_header_spec.rb +3 -2
  92. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
  93. data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
  94. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
  95. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  96. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
  97. data/spec/grape/exceptions/missing_option_spec.rb +1 -3
  98. data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
  99. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
  100. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  101. data/spec/grape/exceptions/validation_errors_spec.rb +0 -1
  102. data/spec/grape/exceptions/validation_spec.rb +1 -3
  103. data/spec/grape/extensions/param_builders/hash_spec.rb +0 -2
  104. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -2
  105. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -2
  106. data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
  107. data/spec/grape/integration/rack_sendfile_spec.rb +0 -2
  108. data/spec/grape/integration/rack_spec.rb +6 -7
  109. data/spec/grape/loading_spec.rb +0 -2
  110. data/spec/grape/middleware/auth/base_spec.rb +0 -1
  111. data/spec/grape/middleware/auth/dsl_spec.rb +0 -2
  112. data/spec/grape/middleware/auth/strategies_spec.rb +0 -2
  113. data/spec/grape/middleware/base_spec.rb +7 -7
  114. data/spec/grape/middleware/error_spec.rb +6 -1
  115. data/spec/grape/middleware/exception_spec.rb +0 -2
  116. data/spec/grape/middleware/formatter_spec.rb +6 -8
  117. data/spec/grape/middleware/globals_spec.rb +0 -2
  118. data/spec/grape/middleware/stack_spec.rb +0 -2
  119. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -2
  120. data/spec/grape/middleware/versioner/header_spec.rb +18 -4
  121. data/spec/grape/middleware/versioner/param_spec.rb +0 -2
  122. data/spec/grape/middleware/versioner/path_spec.rb +0 -2
  123. data/spec/grape/middleware/versioner_spec.rb +0 -2
  124. data/spec/grape/named_api_spec.rb +0 -2
  125. data/spec/grape/parser_spec.rb +0 -2
  126. data/spec/grape/path_spec.rb +0 -2
  127. data/spec/grape/presenters/presenter_spec.rb +0 -2
  128. data/spec/grape/request_spec.rb +0 -2
  129. data/spec/grape/util/inheritable_setting_spec.rb +0 -1
  130. data/spec/grape/util/inheritable_values_spec.rb +0 -1
  131. data/spec/grape/util/reverse_stackable_values_spec.rb +0 -1
  132. data/spec/grape/util/stackable_values_spec.rb +0 -1
  133. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
  134. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  135. data/spec/grape/validations/instance_behaivour_spec.rb +0 -2
  136. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -2
  137. data/spec/grape/validations/params_scope_spec.rb +315 -86
  138. data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -2
  139. data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
  140. data/spec/grape/validations/types/primitive_coercer_spec.rb +20 -5
  141. data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
  142. data/spec/grape/validations/types_spec.rb +28 -2
  143. data/spec/grape/validations/validators/all_or_none_spec.rb +0 -2
  144. data/spec/grape/validations/validators/allow_blank_spec.rb +0 -2
  145. data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -2
  146. data/spec/grape/validations/validators/coerce_spec.rb +0 -2
  147. data/spec/grape/validations/validators/default_spec.rb +0 -2
  148. data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -2
  149. data/spec/grape/validations/validators/except_values_spec.rb +0 -2
  150. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -2
  151. data/spec/grape/validations/validators/presence_spec.rb +0 -2
  152. data/spec/grape/validations/validators/regexp_spec.rb +0 -2
  153. data/spec/grape/validations/validators/same_as_spec.rb +0 -2
  154. data/spec/grape/validations/validators/values_spec.rb +19 -2
  155. data/spec/grape/validations_spec.rb +78 -27
  156. data/spec/integration/multi_json/json_spec.rb +0 -2
  157. data/spec/integration/multi_xml/xml_spec.rb +0 -2
  158. data/spec/spec_helper.rb +9 -4
  159. metadata +134 -122
  160. data/spec/grape/dsl/configuration_spec.rb +0 -16
  161. data/spec/grape/validations/attributes_iterator_spec.rb +0 -6
  162. data/spec/support/eager_load.rb +0 -19
  163. /data/lib/grape/validations/validators/{allow_blank.rb → allow_blank_validator.rb} +0 -0
  164. /data/lib/grape/validations/validators/{as.rb → as_validator.rb} +0 -0
  165. /data/lib/grape/validations/validators/{coerce.rb → coerce_validator.rb} +0 -0
  166. /data/lib/grape/validations/validators/{default.rb → default_validator.rb} +0 -0
  167. /data/lib/grape/validations/validators/{except_values.rb → except_values_validator.rb} +0 -0
  168. /data/lib/grape/validations/validators/{presence.rb → presence_validator.rb} +0 -0
  169. /data/lib/grape/validations/validators/{regexp.rb → regexp_validator.rb} +0 -0
  170. /data/lib/grape/validations/validators/{same_as.rb → same_as_validator.rb} +0 -0
  171. /data/lib/grape/validations/validators/{values.rb → values_validator.rb} +0 -0
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  require 'shared/versioning_examples'
5
4
 
6
5
  describe Grape::API::Instance do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
4
  module NestedHelpersSpec
7
5
  module HelperMethods
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
4
  module PatchHelpersSpec
7
5
  class PatchPublic < Grape::API
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API do
6
4
  describe '.recognize_path' do
7
5
  subject { Class.new(described_class) }
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
4
  let(:app) do
7
5
  Class.new(Grape::API) do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::API::Helpers do
6
4
  subject do
7
5
  shared_params = Module.new do
@@ -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
@@ -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
@@ -104,22 +103,6 @@ describe Grape::API do
104
103
  }
105
104
  end
106
105
  end
107
-
108
- # Behavior as defined by rfc2616 when no header is defined
109
- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
110
- describe 'no specified accept header' do
111
- # subject.version 'v1', using: :header
112
- # subject.get '/hello' do
113
- # 'hello'
114
- # end
115
-
116
- # it 'routes' do
117
- # get '/hello'
118
- # last_response.status.should eql 200
119
- # end
120
- end
121
-
122
- # pending 'routes if any media type is allowed'
123
106
  end
124
107
 
125
108
  describe '.version using accept_version_header' do
@@ -449,9 +432,10 @@ describe Grape::API do
449
432
  expect(last_response.body).to eql 'hiya'
450
433
  end
451
434
 
435
+ objects = ['string', :symbol, 1, -1.1, {}, [], true, false, nil].freeze
452
436
  %i[put post].each do |verb|
453
437
  context verb.to_s do
454
- ['string', :symbol, 1, -1.1, {}, [], true, false, nil].each do |object|
438
+ objects.each do |object|
455
439
  it "allows a(n) #{object.class} json object in params" do
456
440
  subject.format :json
457
441
  subject.send(verb) do
@@ -1217,7 +1201,7 @@ describe Grape::API do
1217
1201
 
1218
1202
  it 'does not set Cache-Control' do
1219
1203
  get '/foo'
1220
- expect(last_response.headers['Cache-Control']).to eq(nil)
1204
+ expect(last_response.headers['Cache-Control']).to be_nil
1221
1205
  end
1222
1206
 
1223
1207
  it 'sets content type for xml' do
@@ -1242,7 +1226,7 @@ describe Grape::API do
1242
1226
 
1243
1227
  it 'returns raw data when content type binary' do
1244
1228
  image_filename = 'grape.png'
1245
- file = File.open(image_filename, 'rb', &:read)
1229
+ file = File.binread(image_filename)
1246
1230
  subject.format :binary
1247
1231
  subject.get('/binary_file') { File.binread(image_filename) }
1248
1232
  get '/binary_file'
@@ -1274,7 +1258,7 @@ describe Grape::API do
1274
1258
  get '/stream', {}, 'HTTP_VERSION' => 'HTTP/1.1', 'SERVER_PROTOCOL' => 'HTTP/1.1'
1275
1259
 
1276
1260
  expect(last_response.headers['Content-Type']).to eq('text/plain')
1277
- expect(last_response.headers['Content-Length']).to eq(nil)
1261
+ expect(last_response.headers['Content-Length']).to be_nil
1278
1262
  expect(last_response.headers['Cache-Control']).to eq('no-cache')
1279
1263
  expect(last_response.headers['Transfer-Encoding']).to eq('chunked')
1280
1264
 
@@ -1602,7 +1586,7 @@ describe Grape::API do
1602
1586
 
1603
1587
  subject.get(:hello) { 'Hello, world.' }
1604
1588
  get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('allow', 'whatever')
1605
- expect(basic_auth_context).to be_a_kind_of(Grape::Endpoint)
1589
+ expect(basic_auth_context).to be_a(Grape::Endpoint)
1606
1590
  end
1607
1591
 
1608
1592
  it 'has access to helper methods' do
@@ -2292,7 +2276,7 @@ describe Grape::API do
2292
2276
  subject.rescue_from :all, with: :not_exist_method
2293
2277
  subject.get('/rescue_method') { raise StandardError }
2294
2278
 
2295
- expect { get '/rescue_method' }.to raise_error(NoMethodError, /^undefined method `not_exist_method'/)
2279
+ expect { get '/rescue_method' }.to raise_error(NoMethodError, /^undefined method 'not_exist_method'/)
2296
2280
  end
2297
2281
 
2298
2282
  it 'correctly chooses exception handler if :all handler is specified' do
@@ -3068,7 +3052,7 @@ describe Grape::API do
3068
3052
  expect(route.description).to eq('first method')
3069
3053
  expect(route.route_foo).to be_nil
3070
3054
  expect(route.params).to eq({})
3071
- expect(route.options).to be_a_kind_of(Hash)
3055
+ expect(route.options).to be_a(Hash)
3072
3056
  end
3073
3057
 
3074
3058
  it 'has params which does not include format and version as named captures' do
@@ -3726,7 +3710,7 @@ describe Grape::API do
3726
3710
  it 'sets the instance' do
3727
3711
  expect(subject.instance).to be_nil
3728
3712
  subject.compile
3729
- expect(subject.instance).to be_kind_of(subject.base_instance)
3713
+ expect(subject.instance).to be_a(subject.base_instance)
3730
3714
  end
3731
3715
  end
3732
3716
 
@@ -4158,6 +4142,20 @@ describe Grape::API do
4158
4142
  end
4159
4143
  end
4160
4144
 
4145
+ context 'with non-UTF-8 characters in specified format' do
4146
+ it 'converts the characters' do
4147
+ subject.format :json
4148
+ subject.content_type :json, 'application/json'
4149
+ subject.get '/something' do
4150
+ 'foo'
4151
+ end
4152
+ get '/something?format=%0A%0B%BF'
4153
+ expect(last_response.status).to eq(406)
4154
+ message = "The requested format '\n\u000b\357\277\275' is not supported."
4155
+ expect(last_response.body).to eq({ error: message }.to_json)
4156
+ end
4157
+ end
4158
+
4161
4159
  context 'body' do
4162
4160
  context 'false' do
4163
4161
  before do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe '.configure' do
6
4
  before do
7
5
  Grape.configure do |config|
@@ -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 CallbacksSpec
@@ -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 DescSpec
@@ -28,6 +26,7 @@ module Grape
28
26
  detail: 'more details',
29
27
  params: { first: :param },
30
28
  entity: Object,
29
+ default: { code: 400, message: 'Invalid' },
31
30
  http_codes: [[401, 'Unauthorized', 'Entities::Error']],
32
31
  named: 'My named route',
33
32
  body_name: 'My body name',
@@ -56,6 +55,7 @@ module Grape
56
55
  detail 'more details'
57
56
  params(first: :param)
58
57
  success Object
58
+ default code: 400, message: 'Invalid'
59
59
  failure [[401, 'Unauthorized', 'Entities::Error']]
60
60
  named 'My named route'
61
61
  body_name 'My body name'
@@ -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 be nil
58
- expect(subject.header('First Key')).to be nil
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
@@ -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 HelpersSpec
@@ -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 InsideRouteSpec
@@ -25,7 +23,7 @@ describe Grape::Endpoint do
25
23
 
26
24
  describe '#version' do
27
25
  it 'defaults to nil' do
28
- expect(subject.version).to be nil
26
+ expect(subject.version).to be_nil
29
27
  end
30
28
 
31
29
  it 'returns env[api.version]' do
@@ -167,7 +165,7 @@ describe Grape::Endpoint do
167
165
  end
168
166
 
169
167
  it 'returns default' do
170
- expect(subject.content_type).to be nil
168
+ expect(subject.content_type).to be_nil
171
169
  end
172
170
  end
173
171
 
@@ -200,7 +198,7 @@ describe Grape::Endpoint do
200
198
  end
201
199
 
202
200
  it 'returns default' do
203
- expect(subject.body).to be nil
201
+ expect(subject.body).to be_nil
204
202
  end
205
203
  end
206
204
 
@@ -315,7 +313,7 @@ describe Grape::Endpoint do
315
313
  end
316
314
 
317
315
  it 'returns default' do
318
- expect(subject.sendfile).to be nil
316
+ expect(subject.sendfile).to be_nil
319
317
  end
320
318
  end
321
319
 
@@ -362,13 +360,13 @@ describe Grape::Endpoint do
362
360
  it 'sets Content-Length header to nil' do
363
361
  subject.stream file_path
364
362
 
365
- expect(subject.header['Content-Length']).to eq nil
363
+ expect(subject.header['Content-Length']).to be_nil
366
364
  end
367
365
 
368
366
  it 'sets Transfer-Encoding header to nil' do
369
367
  subject.stream file_path
370
368
 
371
- expect(subject.header['Transfer-Encoding']).to eq nil
369
+ expect(subject.header['Transfer-Encoding']).to be_nil
372
370
  end
373
371
  end
374
372
 
@@ -406,13 +404,13 @@ describe Grape::Endpoint do
406
404
  it 'sets Content-Length header to nil' do
407
405
  subject.stream stream_object
408
406
 
409
- expect(subject.header['Content-Length']).to eq nil
407
+ expect(subject.header['Content-Length']).to be_nil
410
408
  end
411
409
 
412
410
  it 'sets Transfer-Encoding header to nil' do
413
411
  subject.stream stream_object
414
412
 
415
- expect(subject.header['Transfer-Encoding']).to eq nil
413
+ expect(subject.header['Transfer-Encoding']).to be_nil
416
414
  end
417
415
  end
418
416
 
@@ -426,8 +424,8 @@ describe Grape::Endpoint do
426
424
  end
427
425
 
428
426
  it 'returns default' do
429
- expect(subject.stream).to be nil
430
- expect(subject.header['Cache-Control']).to eq nil
427
+ expect(subject.stream).to be_nil
428
+ expect(subject.header['Cache-Control']).to be_nil
431
429
  end
432
430
  end
433
431
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::DSL::Logger do
6
4
  subject { Class.new(dummy_logger) }
7
5
 
@@ -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 MiddlewareSpec
@@ -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 ParametersSpec
@@ -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 RequestResponseSpec
@@ -162,34 +160,34 @@ module Grape
162
160
 
163
161
  describe 'list of exceptions is passed' do
164
162
  it 'sets hash of exceptions as rescue handlers' do
165
- expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, StandardError => nil)
163
+ expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, { StandardError => nil })
166
164
  expect(subject).to receive(:namespace_stackable).with(:rescue_options, {})
167
165
  subject.rescue_from StandardError
168
166
  end
169
167
 
170
168
  it 'rescues only base handlers if rescue_subclasses: false option is passed' do
171
- expect(subject).to receive(:namespace_reverse_stackable).with(:base_only_rescue_handlers, StandardError => nil)
172
- expect(subject).to receive(:namespace_stackable).with(:rescue_options, rescue_subclasses: false)
169
+ expect(subject).to receive(:namespace_reverse_stackable).with(:base_only_rescue_handlers, { StandardError => nil })
170
+ expect(subject).to receive(:namespace_stackable).with(:rescue_options, { rescue_subclasses: false })
173
171
  subject.rescue_from StandardError, rescue_subclasses: false
174
172
  end
175
173
 
176
174
  it 'sets given proc as rescue handler for each key in hash' do
177
175
  rescue_handler_proc = proc {}
178
- expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, StandardError => rescue_handler_proc)
176
+ expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, { StandardError => rescue_handler_proc })
179
177
  expect(subject).to receive(:namespace_stackable).with(:rescue_options, {})
180
178
  subject.rescue_from StandardError, rescue_handler_proc
181
179
  end
182
180
 
183
181
  it 'sets given block as rescue handler for each key in hash' do
184
182
  rescue_handler_proc = proc {}
185
- expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, StandardError => rescue_handler_proc)
183
+ expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, { StandardError => rescue_handler_proc })
186
184
  expect(subject).to receive(:namespace_stackable).with(:rescue_options, {})
187
185
  subject.rescue_from StandardError, &rescue_handler_proc
188
186
  end
189
187
 
190
188
  it 'sets a rescue handler declared through :with option for each key in hash' do
191
189
  with_block = -> { 'hello' }
192
- expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, StandardError => an_instance_of(Proc))
190
+ expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, { StandardError => an_instance_of(Proc) })
193
191
  expect(subject).to receive(:namespace_stackable).with(:rescue_options, {})
194
192
  subject.rescue_from StandardError, with: with_block
195
193
  end
@@ -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 RoutingSpec
@@ -21,7 +19,7 @@ module Grape
21
19
  it 'sets a version for route' do
22
20
  version = 'v1'
23
21
  expect(subject).to receive(:namespace_inheritable).with(:version, [version])
24
- expect(subject).to receive(:namespace_inheritable).with(:version_options, using: :path)
22
+ expect(subject).to receive(:namespace_inheritable).with(:version_options, { using: :path })
25
23
  expect(subject.version(version)).to eq(version)
26
24
  end
27
25
  end
@@ -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 SettingsSpec
@@ -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 ValidationsSpec
@@ -38,10 +36,6 @@ module Grape
38
36
  expect(subject.namespace_stackable(:params)).to eq []
39
37
  end
40
38
 
41
- it 'resets documentation params' do
42
- expect(subject.route_setting(:description)[:params]).to be_nil
43
- end
44
-
45
39
  it 'does not reset documentation description' do
46
40
  expect(subject.route_setting(:description)[:description]).to eq 'lol'
47
41
  end
@@ -56,17 +50,6 @@ module Grape
56
50
  expect { subject.params { raise 'foo' } }.to raise_error RuntimeError, 'foo'
57
51
  end
58
52
  end
59
-
60
- describe '.document_attribute' do
61
- before do
62
- subject.document_attribute([full_name: 'xxx'], foo: 'bar')
63
- end
64
-
65
- it 'creates a param documentation' do
66
- expect(subject.namespace_stackable(:params)).to eq(['xxx' => { foo: 'bar' }])
67
- expect(subject.route_setting(:description)).to eq(params: { 'xxx' => { foo: 'bar' } })
68
- end
69
- end
70
53
  end
71
54
  end
72
55
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -249,7 +247,7 @@ describe Grape::Endpoint do
249
247
  end
250
248
  get '/declared?first=one&other=two'
251
249
  expect(last_response.status).to eq(200)
252
- expect(JSON.parse(last_response.body).key?(:other)).to eq false
250
+ expect(JSON.parse(last_response.body).key?(:other)).to be false
253
251
  end
254
252
 
255
253
  it 'stringifies if that option is passed' do
@@ -522,7 +520,7 @@ describe Grape::Endpoint do
522
520
  json = JSON.parse(last_response.body, symbolize_names: true)
523
521
 
524
522
  expect(json[:declared_params][:id]).to eq 123
525
- expect(json[:declared_params_no_parent][:id]).to eq nil
523
+ expect(json[:declared_params_no_parent][:id]).to be_nil
526
524
  end
527
525
  end
528
526
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Endpoint do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -77,7 +75,7 @@ describe Grape::Endpoint do
77
75
  it 'sets itself in the env upon call' do
78
76
  subject.get('/') { 'Hello world.' }
79
77
  get '/'
80
- expect(last_request.env['api.endpoint']).to be_kind_of(described_class)
78
+ expect(last_request.env['api.endpoint']).to be_a(described_class)
81
79
  end
82
80
 
83
81
  describe '#status' do
@@ -142,7 +140,8 @@ describe Grape::Endpoint do
142
140
  get '/headers'
143
141
  expect(JSON.parse(last_response.body)).to eq(
144
142
  'Host' => 'example.org',
145
- 'Cookie' => ''
143
+ 'Cookie' => '',
144
+ 'Version' => 'HTTP/1.0'
146
145
  )
147
146
  end
148
147
 
@@ -215,10 +214,10 @@ describe Grape::Endpoint do
215
214
  end
216
215
  get '/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2'
217
216
  expect(last_response.body).to eq('3')
218
- cookies = last_response.headers['Set-Cookie'].split("\n").map do |set_cookie|
217
+ cookies = last_response.headers['Set-Cookie'].split("\n").to_h do |set_cookie|
219
218
  cookie = CookieJar::Cookie.from_set_cookie 'http://localhost/test', set_cookie
220
219
  [cookie.name, cookie]
221
- end.to_h
220
+ end
222
221
  expect(cookies.size).to eq(2)
223
222
  %w[and_this delete_this_cookie].each do |cookie_name|
224
223
  cookie = cookies[cookie_name]
@@ -239,10 +238,10 @@ describe Grape::Endpoint do
239
238
  end
240
239
  get('/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2')
241
240
  expect(last_response.body).to eq('3')
242
- cookies = last_response.headers['Set-Cookie'].split("\n").map do |set_cookie|
241
+ cookies = last_response.headers['Set-Cookie'].split("\n").to_h do |set_cookie|
243
242
  cookie = CookieJar::Cookie.from_set_cookie 'http://localhost/test', set_cookie
244
243
  [cookie.name, cookie]
245
- end.to_h
244
+ end
246
245
  expect(cookies.size).to eq(2)
247
246
  %w[and_this delete_this_cookie].each do |cookie_name|
248
247
  cookie = cookies[cookie_name]
@@ -434,7 +433,28 @@ describe Grape::Endpoint do
434
433
  end
435
434
  post '/upload', { file: '' }, 'CONTENT_TYPE' => 'multipart/form-data; boundary=foobar'
436
435
  expect(last_response.status).to eq(400)
437
- expect(last_response.body).to eq('Empty message body supplied with multipart/form-data; boundary=foobar content-type')
436
+ expect(last_response.body).to eq('file is invalid')
437
+ end
438
+ end
439
+
440
+ context 'when the limit on multipart files is exceeded' do
441
+ around do |example|
442
+ limit = Rack::Utils.multipart_part_limit
443
+ Rack::Utils.multipart_part_limit = 1
444
+ example.run
445
+ Rack::Utils.multipart_part_limit = limit
446
+ end
447
+
448
+ it 'returns a 413 if given too many multipart files' do
449
+ subject.params do
450
+ requires :file, type: Rack::Multipart::UploadedFile
451
+ end
452
+ subject.post '/upload' do
453
+ params[:file][:filename]
454
+ end
455
+ post '/upload', { file: Rack::Test::UploadedFile.new(__FILE__, 'text/plain'), extra: Rack::Test::UploadedFile.new(__FILE__, 'text/plain') }
456
+ expect(last_response.status).to eq(413)
457
+ expect(last_response.body).to eq("the number of uploaded files exceeded the system's configured limit (1)")
438
458
  end
439
459
  end
440
460
 
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  require 'grape_entity'
5
4
 
6
5
  describe Grape::Entity do