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,8 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::Base do
4
+ describe '#to_s' do
5
+ subject { described_class.new(message: message).to_s }
6
+
7
+ let(:message) { 'a_message' }
8
+
9
+ it { is_expected.to eq(message) }
10
+ end
11
+
12
+ describe '#message' do
13
+ subject { described_class.new(message: message).message }
14
+
15
+ let(:message) { 'a_message' }
16
+
17
+ it { is_expected.to eq(message) }
18
+ end
19
+
6
20
  describe '#compose_message' do
7
21
  subject { described_class.new.send(:compose_message, key, **attributes) }
8
22
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::ValidationErrors do
6
4
  context 'api with rescue_from :all handler' do
7
5
  subject { Class.new(Grape::API) }
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::InvalidAcceptHeader do
6
4
  shared_examples_for 'a valid request' do
7
5
  it 'does return with status 200' do
@@ -12,11 +10,13 @@ describe Grape::Exceptions::InvalidAcceptHeader do
12
10
  expect(last_response.body).to eq('beer received')
13
11
  end
14
12
  end
13
+
15
14
  shared_examples_for 'a cascaded request' do
16
15
  it 'does not find a matching route' do
17
16
  expect(last_response.status).to eq 404
18
17
  end
19
18
  end
19
+
20
20
  shared_examples_for 'a not-cascaded request' do
21
21
  it 'does not include the X-Cascade=pass header' do
22
22
  expect(last_response.headers['X-Cascade']).to be_nil
@@ -26,6 +26,7 @@ describe Grape::Exceptions::InvalidAcceptHeader do
26
26
  expect(last_response.status).to eq 406
27
27
  end
28
28
  end
29
+
29
30
  shared_examples_for 'a rescued request' do
30
31
  it 'does not include the X-Cascade=pass header' do
31
32
  expect(last_response.headers['X-Cascade']).to be_nil
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::InvalidFormatter do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::InvalidResponse do
6
4
  describe '#message' do
7
5
  let(:error) { described_class.new }
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::InvalidVersionerOption do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -10,7 +8,7 @@ describe Grape::Exceptions::InvalidVersionerOption do
10
8
 
11
9
  it 'contains the problem in the message' do
12
10
  expect(error.message).to include(
13
- 'Unknown :using for versioner: headers'
11
+ 'unknown :using for versioner: headers'
14
12
  )
15
13
  end
16
14
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Grape::Exceptions::MissingGroupType do
4
+ describe '#message' do
5
+ subject { described_class.new.message }
6
+
7
+ it { is_expected.to include 'group type is required' }
8
+ end
9
+
10
+ describe 'deprecated Grape::Exceptions::MissingGroupTypeError' do
11
+ subject { Grape::Exceptions::MissingGroupTypeError.new }
12
+
13
+ it 'puts a deprecation warning' do
14
+ expect(Warning).to receive(:warn) do |message|
15
+ expect(message).to include('`Grape::Exceptions::MissingGroupTypeError` is deprecated')
16
+ end
17
+
18
+ subject
19
+ end
20
+ end
21
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::MissingMimeType do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::MissingOption do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -10,7 +8,7 @@ describe Grape::Exceptions::MissingOption do
10
8
 
11
9
  it 'contains the problem in the message' do
12
10
  expect(error.message).to include(
13
- 'You must specify :path options.'
11
+ 'you must specify :path options'
14
12
  )
15
13
  end
16
14
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::UnknownOptions do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::UnknownValidator do
6
4
  describe '#message' do
7
5
  let(:error) do
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Grape::Exceptions::UnsupportedGroupType do
4
+ subject { described_class.new }
5
+
6
+ describe '#message' do
7
+ subject { described_class.new.message }
8
+
9
+ it { is_expected.to include 'group type must be Array, Hash, JSON or Array[JSON]' }
10
+ end
11
+
12
+ describe 'deprecated Grape::Exceptions::UnsupportedGroupTypeError' do
13
+ subject { Grape::Exceptions::UnsupportedGroupTypeError.new }
14
+
15
+ it 'puts a deprecation warning' do
16
+ expect(Warning).to receive(:warn) do |message|
17
+ expect(message).to include('`Grape::Exceptions::UnsupportedGroupTypeError` is deprecated')
18
+ end
19
+
20
+ subject
21
+ end
22
+ end
23
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  require 'ostruct'
5
4
 
6
5
  describe Grape::Exceptions::ValidationErrors do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Exceptions::Validation do
6
4
  it 'fails when params are missing' do
7
5
  expect { described_class.new(message: 'presence') }.to raise_error(ArgumentError, /missing keyword:.+?params/)
@@ -15,7 +13,7 @@ describe Grape::Exceptions::Validation do
15
13
 
16
14
  context 'when message is a String' do
17
15
  it 'does not store the message_key' do
18
- expect(described_class.new(params: ['id'], message: 'presence').message_key).to eq(nil)
16
+ expect(described_class.new(params: ['id'], message: 'presence').message_key).to be_nil
19
17
  end
20
18
  end
21
19
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Extensions::Hash::ParamBuilder 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::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder 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::Extensions::Hashie::Mash::ParamBuilder do
6
4
  subject { Class.new(Grape::API) }
7
5
 
@@ -2,8 +2,6 @@
2
2
 
3
3
  # see https://github.com/ruby-grape/grape/issues/1348
4
4
 
5
- require 'spec_helper'
6
-
7
5
  def namespace
8
6
  raise
9
7
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Rack::Sendfile do
6
4
  subject do
7
5
  content_object = file_object
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Rack do
6
4
  it 'correctly populates params from a Tempfile' do
7
5
  input = Tempfile.new 'rubbish'
@@ -29,19 +27,20 @@ describe Rack do
29
27
  end
30
28
 
31
29
  context 'when the app is mounted' do
32
- def app
33
- @main_app ||= Class.new(Grape::API) do
30
+ let(:ping_mount) do
31
+ Class.new(Grape::API) do
34
32
  get 'ping'
35
33
  end
36
34
  end
37
35
 
38
- let!(:base) do
39
- app_to_mount = app
40
- Class.new(Grape::API) do
36
+ let(:app) do
37
+ app_to_mount = ping_mount
38
+ app = Class.new(Grape::API) do
41
39
  namespace 'namespace' do
42
40
  mount app_to_mount
43
41
  end
44
42
  end
43
+ Rack::Builder.new(app)
45
44
  end
46
45
 
47
46
  it 'finds the app on the namespace' do
@@ -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
  subject do
7
5
  CombinedApi = combined_api
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  require 'base64'
5
4
 
6
5
  describe Grape::Middleware::Auth::Base do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Auth::DSL 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
  require 'base64'
6
4
 
7
5
  describe Grape::Middleware::Auth::Strategies do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Base do
6
4
  subject { described_class.new(blank_app) }
7
5
 
@@ -72,18 +70,18 @@ describe Grape::Middleware::Base do
72
70
 
73
71
  it 'is able to access the response' do
74
72
  subject.call({})
75
- expect(subject.response).to be_kind_of(Rack::Response)
73
+ expect(subject.response).to be_a(Rack::Response)
76
74
  end
77
75
 
78
76
  describe '#response' do
79
77
  subject do
80
- puts described_class
81
78
  described_class.new(response)
82
79
  end
83
80
 
84
81
  before { subject.call({}) }
85
82
 
86
83
  context 'when Array' do
84
+ let(:rack_response) { Rack::Response.new('test', 204, abc: 1) }
87
85
  let(:response) { ->(_) { [204, { abc: 1 }, 'test'] } }
88
86
 
89
87
  it 'status' do
@@ -99,12 +97,14 @@ describe Grape::Middleware::Base do
99
97
  end
100
98
 
101
99
  it 'returns the memoized Rack::Response instance' do
102
- expect(subject.response).to be(subject.response)
100
+ allow(Rack::Response).to receive(:new).and_return(rack_response)
101
+ expect(subject.response).to eq(rack_response)
103
102
  end
104
103
  end
105
104
 
106
105
  context 'when Rack::Response' do
107
- let(:response) { ->(_) { Rack::Response.new('test', 204, abc: 1) } }
106
+ let(:rack_response) { Rack::Response.new('test', 204, abc: 1) }
107
+ let(:response) { ->(_) { rack_response } }
108
108
 
109
109
  it 'status' do
110
110
  expect(subject.response.status).to eq(204)
@@ -119,7 +119,7 @@ describe Grape::Middleware::Base do
119
119
  end
120
120
 
121
121
  it 'returns the memoized Rack::Response instance' do
122
- expect(subject.response).to be(subject.response)
122
+ expect(subject.response).to eq(rack_response)
123
123
  end
124
124
  end
125
125
  end
@@ -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::Middleware::Error do
@@ -42,6 +41,12 @@ describe Grape::Middleware::Error do
42
41
  expect(last_response.status).to eq(410)
43
42
  end
44
43
 
44
+ it 'sets the status code based on the rack util status code symbol' do
45
+ ErrorSpec::ErrApp.error = { status: :gone }
46
+ get '/'
47
+ expect(last_response.status).to eq(410)
48
+ end
49
+
45
50
  it 'sets the error message appropriately' do
46
51
  ErrorSpec::ErrApp.error = { message: 'Awesome stuff.' }
47
52
  get '/'
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Error do
6
4
  let(:exception_app) do
7
5
  Class.new do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Formatter do
6
4
  subject { described_class.new(app) }
7
5
 
@@ -15,7 +13,7 @@ describe Grape::Middleware::Formatter do
15
13
 
16
14
  it 'looks at the bodies for possibly serializable data' do
17
15
  _, _, bodies = *subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json')
18
- bodies.each { |b| expect(b).to eq(::Grape::Json.dump(body)) }
16
+ bodies.each { |b| expect(b).to eq(::Grape::Json.dump(body)) } # rubocop:disable RSpec/IteratedExpectation
19
17
  end
20
18
 
21
19
  context 'default format' do
@@ -28,7 +26,7 @@ describe Grape::Middleware::Formatter do
28
26
  end
29
27
  end
30
28
 
31
- subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('"bar"') }
29
+ subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('"bar"') } # rubocop:disable RSpec/IteratedExpectation
32
30
  end
33
31
  end
34
32
 
@@ -42,7 +40,7 @@ describe Grape::Middleware::Formatter do
42
40
  end
43
41
  end
44
42
 
45
- subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/vnd.api+json').to_a.last.each { |b| expect(b).to eq('{"foos":[{"bar":"baz"}] }') }
43
+ subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/vnd.api+json').to_a.last.each { |b| expect(b).to eq('{"foos":[{"bar":"baz"}] }') } # rubocop:disable RSpec/IteratedExpectation
46
44
  end
47
45
  end
48
46
 
@@ -55,8 +53,7 @@ describe Grape::Middleware::Formatter do
55
53
  '<bar/>'
56
54
  end
57
55
  end
58
-
59
- subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('<bar/>') }
56
+ subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('<bar/>') } # rubocop:disable RSpec/IteratedExpectation
60
57
  end
61
58
  end
62
59
  end
@@ -245,6 +242,7 @@ describe Grape::Middleware::Formatter do
245
242
  end
246
243
 
247
244
  context 'input' do
245
+ content_types = ['application/json', 'application/json; charset=utf-8'].freeze
248
246
  %w[POST PATCH PUT DELETE].each do |method|
249
247
  context 'when body is not nil or empty' do
250
248
  context 'when Content-Type is supported' do
@@ -322,7 +320,7 @@ describe Grape::Middleware::Formatter do
322
320
  end
323
321
  end
324
322
 
325
- ['application/json', 'application/json; charset=utf-8'].each do |content_type|
323
+ content_types.each do |content_type|
326
324
  context content_type do
327
325
  it "parses the body from #{method} and copies values into rack.request.form_hash" do
328
326
  io = StringIO.new('{"is_boolean":true,"string":"thing"}')
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Globals do
6
4
  subject { described_class.new(blank_app) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Stack do
6
4
  module StackSpec
7
5
  class FooMiddleware; end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner::AcceptVersionHeader do
6
4
  subject { described_class.new(app, **(@options || {})) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner::Header do
6
4
  subject { described_class.new(app, **(@options || {})) }
7
5
 
@@ -48,7 +46,7 @@ describe Grape::Middleware::Versioner::Header do
48
46
 
49
47
  it 'is nil if not provided' do
50
48
  status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor')
51
- expect(env['api.format']).to be nil
49
+ expect(env['api.format']).to be_nil
52
50
  expect(status).to eq(200)
53
51
  end
54
52
 
@@ -66,7 +64,7 @@ describe Grape::Middleware::Versioner::Header do
66
64
 
67
65
  it 'is nil if not provided' do
68
66
  status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1')
69
- expect(env['api.format']).to be nil
67
+ expect(env['api.format']).to be_nil
70
68
  expect(status).to eq(200)
71
69
  end
72
70
  end
@@ -328,4 +326,20 @@ describe Grape::Middleware::Versioner::Header do
328
326
  end
329
327
  end
330
328
  end
329
+
330
+ context 'with missing vendor option' do
331
+ subject do
332
+ Class.new(Grape::API) do
333
+ version 'v1', using: :header
334
+ end
335
+ end
336
+
337
+ def app
338
+ subject
339
+ end
340
+
341
+ it 'fails' do
342
+ expect { versioned_get '/', 'v1', using: :header }.to raise_error Grape::Exceptions::MissingVendorOption
343
+ end
344
+ end
331
345
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner::Param do
6
4
  subject { described_class.new(app, **options) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner::Path do
6
4
  subject { described_class.new(app, **options) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner do
6
4
  let(:klass) { described_class }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe 'A named API' do
6
4
  subject(:api_name) { NamedAPI.endpoints.last.options[:for].to_s }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Parser do
6
4
  subject { described_class }
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
  describe Path do
7
5
  describe '#initialize' do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  module Grape
6
4
  module Presenters
7
5
  module PresenterSpec
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  module Grape
6
4
  describe Request do
7
5
  let(:default_method) { 'GET' }
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  module Grape
5
4
  module Util
6
5
  describe InheritableSetting do
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  module Grape
5
4
  module Util
6
5
  describe InheritableValues do
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  module Grape
5
4
  module Util
6
5
  describe ReverseStackableValues do
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  module Grape
5
4
  module Util
6
5
  describe StackableValues do
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
3
  module Grape
5
4
  module Util
6
5
  describe 'StrictHashConfiguration' do