grape 1.6.2 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
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