grape 1.5.3 → 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 (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +92 -0
  3. data/CONTRIBUTING.md +32 -1
  4. data/README.md +176 -25
  5. data/UPGRADING.md +61 -4
  6. data/grape.gemspec +6 -6
  7. data/lib/grape/api/instance.rb +14 -18
  8. data/lib/grape/api.rb +17 -12
  9. data/lib/grape/cookies.rb +2 -0
  10. data/lib/grape/dry_types.rb +12 -0
  11. data/lib/grape/dsl/api.rb +0 -2
  12. data/lib/grape/dsl/callbacks.rb +0 -2
  13. data/lib/grape/dsl/configuration.rb +0 -2
  14. data/lib/grape/dsl/desc.rb +4 -20
  15. data/lib/grape/dsl/headers.rb +5 -2
  16. data/lib/grape/dsl/helpers.rb +7 -7
  17. data/lib/grape/dsl/inside_route.rb +43 -30
  18. data/lib/grape/dsl/middleware.rb +4 -6
  19. data/lib/grape/dsl/parameters.rb +13 -10
  20. data/lib/grape/dsl/request_response.rb +9 -8
  21. data/lib/grape/dsl/routing.rb +6 -4
  22. data/lib/grape/dsl/settings.rb +5 -7
  23. data/lib/grape/dsl/validations.rb +0 -15
  24. data/lib/grape/endpoint.rb +22 -37
  25. data/lib/grape/error_formatter/json.rb +9 -7
  26. data/lib/grape/error_formatter/xml.rb +2 -6
  27. data/lib/grape/exceptions/base.rb +3 -2
  28. data/lib/grape/exceptions/missing_group_type.rb +8 -1
  29. data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
  30. data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
  31. data/lib/grape/exceptions/validation.rb +1 -6
  32. data/lib/grape/formatter/json.rb +1 -0
  33. data/lib/grape/formatter/serializable_hash.rb +2 -1
  34. data/lib/grape/formatter/xml.rb +1 -0
  35. data/lib/grape/locale/en.yml +9 -8
  36. data/lib/grape/middleware/auth/dsl.rb +7 -2
  37. data/lib/grape/middleware/base.rb +3 -1
  38. data/lib/grape/middleware/error.rb +2 -2
  39. data/lib/grape/middleware/formatter.rb +4 -4
  40. data/lib/grape/middleware/stack.rb +3 -3
  41. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  42. data/lib/grape/middleware/versioner/header.rb +6 -4
  43. data/lib/grape/middleware/versioner/param.rb +1 -0
  44. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  45. data/lib/grape/middleware/versioner/path.rb +2 -0
  46. data/lib/grape/path.rb +1 -0
  47. data/lib/grape/request.rb +4 -1
  48. data/lib/grape/router/attribute_translator.rb +1 -1
  49. data/lib/grape/router/pattern.rb +1 -1
  50. data/lib/grape/router/route.rb +2 -2
  51. data/lib/grape/router.rb +6 -0
  52. data/lib/grape/types/invalid_value.rb +8 -0
  53. data/lib/grape/util/cache.rb +1 -1
  54. data/lib/grape/util/inheritable_setting.rb +1 -3
  55. data/lib/grape/util/json.rb +2 -0
  56. data/lib/grape/util/lazy_value.rb +3 -2
  57. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  58. data/lib/grape/validations/attributes_doc.rb +58 -0
  59. data/lib/grape/validations/params_scope.rb +138 -79
  60. data/lib/grape/validations/types/array_coercer.rb +0 -2
  61. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  62. data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
  63. data/lib/grape/validations/types/invalid_value.rb +0 -7
  64. data/lib/grape/validations/types/json.rb +2 -1
  65. data/lib/grape/validations/types/primitive_coercer.rb +16 -8
  66. data/lib/grape/validations/types/set_coercer.rb +0 -2
  67. data/lib/grape/validations/types.rb +98 -30
  68. data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
  69. data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
  70. data/lib/grape/validations/validators/as_validator.rb +14 -0
  71. data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
  72. data/lib/grape/validations/validators/base.rb +82 -70
  73. data/lib/grape/validations/validators/coerce_validator.rb +75 -0
  74. data/lib/grape/validations/validators/default_validator.rb +51 -0
  75. data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
  76. data/lib/grape/validations/validators/except_values_validator.rb +24 -0
  77. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  78. data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
  79. data/lib/grape/validations/validators/presence_validator.rb +15 -0
  80. data/lib/grape/validations/validators/regexp_validator.rb +16 -0
  81. data/lib/grape/validations/validators/same_as_validator.rb +29 -0
  82. data/lib/grape/validations/validators/values_validator.rb +88 -0
  83. data/lib/grape/validations.rb +16 -6
  84. data/lib/grape/version.rb +1 -1
  85. data/lib/grape.rb +77 -29
  86. data/spec/grape/api/custom_validations_spec.rb +116 -45
  87. data/spec/grape/api/deeply_included_options_spec.rb +3 -5
  88. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
  89. data/spec/grape/api/documentation_spec.rb +59 -0
  90. data/spec/grape/api/inherited_helpers_spec.rb +0 -2
  91. data/spec/grape/api/instance_spec.rb +0 -1
  92. data/spec/grape/api/invalid_format_spec.rb +2 -2
  93. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
  94. data/spec/grape/api/nested_helpers_spec.rb +0 -2
  95. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
  96. data/spec/grape/api/parameters_modification_spec.rb +0 -2
  97. data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
  98. data/spec/grape/api/recognize_path_spec.rb +1 -3
  99. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
  100. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
  101. data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
  102. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
  103. data/spec/grape/api/shared_helpers_spec.rb +0 -2
  104. data/spec/grape/api_remount_spec.rb +16 -16
  105. data/spec/grape/api_spec.rb +462 -251
  106. data/spec/grape/config_spec.rb +0 -2
  107. data/spec/grape/dsl/callbacks_spec.rb +2 -3
  108. data/spec/grape/dsl/desc_spec.rb +2 -2
  109. data/spec/grape/dsl/headers_spec.rb +39 -11
  110. data/spec/grape/dsl/helpers_spec.rb +3 -4
  111. data/spec/grape/dsl/inside_route_spec.rb +16 -16
  112. data/spec/grape/dsl/logger_spec.rb +15 -19
  113. data/spec/grape/dsl/middleware_spec.rb +2 -3
  114. data/spec/grape/dsl/parameters_spec.rb +2 -2
  115. data/spec/grape/dsl/request_response_spec.rb +7 -8
  116. data/spec/grape/dsl/routing_spec.rb +11 -10
  117. data/spec/grape/dsl/settings_spec.rb +0 -2
  118. data/spec/grape/dsl/validations_spec.rb +0 -17
  119. data/spec/grape/endpoint/declared_spec.rb +261 -16
  120. data/spec/grape/endpoint_spec.rb +88 -59
  121. data/spec/grape/entity_spec.rb +22 -23
  122. data/spec/grape/exceptions/base_spec.rb +16 -2
  123. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
  124. data/spec/grape/exceptions/invalid_accept_header_spec.rb +64 -24
  125. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
  126. data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
  127. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
  128. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  129. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
  130. data/spec/grape/exceptions/missing_option_spec.rb +1 -3
  131. data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
  132. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
  133. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  134. data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
  135. data/spec/grape/exceptions/validation_spec.rb +5 -5
  136. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
  137. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
  138. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
  139. data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
  140. data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
  141. data/spec/grape/integration/rack_spec.rb +6 -7
  142. data/spec/grape/loading_spec.rb +8 -10
  143. data/spec/grape/middleware/auth/base_spec.rb +0 -1
  144. data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
  145. data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
  146. data/spec/grape/middleware/base_spec.rb +28 -19
  147. data/spec/grape/middleware/error_spec.rb +8 -3
  148. data/spec/grape/middleware/exception_spec.rb +111 -163
  149. data/spec/grape/middleware/formatter_spec.rb +33 -14
  150. data/spec/grape/middleware/globals_spec.rb +7 -6
  151. data/spec/grape/middleware/stack_spec.rb +14 -14
  152. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
  153. data/spec/grape/middleware/versioner/header_spec.rb +30 -15
  154. data/spec/grape/middleware/versioner/param_spec.rb +7 -3
  155. data/spec/grape/middleware/versioner/path_spec.rb +5 -3
  156. data/spec/grape/middleware/versioner_spec.rb +1 -3
  157. data/spec/grape/named_api_spec.rb +0 -2
  158. data/spec/grape/parser_spec.rb +4 -2
  159. data/spec/grape/path_spec.rb +52 -54
  160. data/spec/grape/presenters/presenter_spec.rb +7 -8
  161. data/spec/grape/request_spec.rb +6 -6
  162. data/spec/grape/util/inheritable_setting_spec.rb +7 -8
  163. data/spec/grape/util/inheritable_values_spec.rb +3 -3
  164. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
  165. data/spec/grape/util/stackable_values_spec.rb +7 -6
  166. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
  167. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  168. data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
  169. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
  170. data/spec/grape/validations/params_scope_spec.rb +361 -96
  171. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
  172. data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
  173. data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
  174. data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
  175. data/spec/grape/validations/types_spec.rb +36 -10
  176. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
  177. data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
  178. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
  179. data/spec/grape/validations/validators/coerce_spec.rb +23 -24
  180. data/spec/grape/validations/validators/default_spec.rb +72 -80
  181. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
  182. data/spec/grape/validations/validators/except_values_spec.rb +3 -5
  183. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
  184. data/spec/grape/validations/validators/presence_spec.rb +16 -3
  185. data/spec/grape/validations/validators/regexp_spec.rb +25 -33
  186. data/spec/grape/validations/validators/same_as_spec.rb +14 -22
  187. data/spec/grape/validations/validators/values_spec.rb +201 -179
  188. data/spec/grape/validations_spec.rb +171 -79
  189. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  190. data/spec/integration/multi_json/json_spec.rb +1 -3
  191. data/spec/integration/multi_xml/xml_spec.rb +1 -3
  192. data/spec/shared/versioning_examples.rb +12 -9
  193. data/spec/spec_helper.rb +21 -6
  194. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  195. metadata +41 -29
  196. data/lib/grape/validations/validators/all_or_none.rb +0 -15
  197. data/lib/grape/validations/validators/allow_blank.rb +0 -18
  198. data/lib/grape/validations/validators/as.rb +0 -16
  199. data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
  200. data/lib/grape/validations/validators/coerce.rb +0 -91
  201. data/lib/grape/validations/validators/default.rb +0 -48
  202. data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
  203. data/lib/grape/validations/validators/except_values.rb +0 -22
  204. data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
  205. data/lib/grape/validations/validators/presence.rb +0 -12
  206. data/lib/grape/validations/validators/regexp.rb +0 -13
  207. data/lib/grape/validations/validators/same_as.rb +0 -26
  208. data/lib/grape/validations/validators/values.rb +0 -83
  209. data/spec/grape/dsl/configuration_spec.rb +0 -16
  210. data/spec/grape/validations/attributes_iterator_spec.rb +0 -6
  211. data/spec/support/eager_load.rb +0 -19
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Globals do
6
- subject { Grape::Middleware::Globals.new(blank_app) }
4
+ subject { described_class.new(blank_app) }
5
+
7
6
  before { allow(subject).to receive(:dup).and_return(subject) }
8
7
 
9
8
  let(:blank_app) { ->(_env) { [200, {}, 'Hi there.'] } }
@@ -13,15 +12,17 @@ describe Grape::Middleware::Globals do
13
12
  end
14
13
 
15
14
  context 'environment' do
16
- it 'should set the grape.request environment' do
15
+ it 'sets the grape.request environment' do
17
16
  subject.call({})
18
17
  expect(subject.env['grape.request']).to be_a(Grape::Request)
19
18
  end
20
- it 'should set the grape.request.headers environment' do
19
+
20
+ it 'sets the grape.request.headers environment' do
21
21
  subject.call({})
22
22
  expect(subject.env['grape.request.headers']).to be_a(Hash)
23
23
  end
24
- it 'should set the grape.request.params environment' do
24
+
25
+ it 'sets the grape.request.params environment' do
25
26
  subject.call('QUERY_STRING' => 'test=1', 'rack.input' => StringIO.new)
26
27
  expect(subject.env['grape.request.params']).to be_a(Hash)
27
28
  end
@@ -1,11 +1,11 @@
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
6
+
8
7
  class BarMiddleware; end
8
+
9
9
  class BlockMiddleware
10
10
  attr_reader :block
11
11
 
@@ -15,10 +15,10 @@ describe Grape::Middleware::Stack do
15
15
  end
16
16
  end
17
17
 
18
- let(:proc) { ->() {} }
19
- let(:others) { [[:use, StackSpec::BarMiddleware], [:insert_before, StackSpec::BarMiddleware, StackSpec::BlockMiddleware, proc]] }
18
+ subject { described_class.new }
20
19
 
21
- subject { Grape::Middleware::Stack.new }
20
+ let(:proc) { -> {} }
21
+ let(:others) { [[:use, StackSpec::BarMiddleware], [:insert_before, StackSpec::BarMiddleware, StackSpec::BlockMiddleware, proc]] }
22
22
 
23
23
  before do
24
24
  subject.use StackSpec::FooMiddleware
@@ -27,20 +27,20 @@ describe Grape::Middleware::Stack do
27
27
  describe '#use' do
28
28
  it 'pushes a middleware class onto the stack' do
29
29
  expect { subject.use StackSpec::BarMiddleware }
30
- .to change { subject.size }.by(1)
30
+ .to change(subject, :size).by(1)
31
31
  expect(subject.last).to eq(StackSpec::BarMiddleware)
32
32
  end
33
33
 
34
34
  it 'pushes a middleware class with arguments onto the stack' do
35
35
  expect { subject.use StackSpec::BarMiddleware, false, my_arg: 42 }
36
- .to change { subject.size }.by(1)
36
+ .to change(subject, :size).by(1)
37
37
  expect(subject.last).to eq(StackSpec::BarMiddleware)
38
38
  expect(subject.last.args).to eq([false, { my_arg: 42 }])
39
39
  end
40
40
 
41
41
  it 'pushes a middleware class with block arguments onto the stack' do
42
42
  expect { subject.use StackSpec::BlockMiddleware, &proc }
43
- .to change { subject.size }.by(1)
43
+ .to change(subject, :size).by(1)
44
44
  expect(subject.last).to eq(StackSpec::BlockMiddleware)
45
45
  expect(subject.last.args).to eq([])
46
46
  expect(subject.last.block).to eq(proc)
@@ -50,7 +50,7 @@ describe Grape::Middleware::Stack do
50
50
  describe '#insert' do
51
51
  it 'inserts a middleware class at the integer index' do
52
52
  expect { subject.insert 0, StackSpec::BarMiddleware }
53
- .to change { subject.size }.by(1)
53
+ .to change(subject, :size).by(1)
54
54
  expect(subject[0]).to eq(StackSpec::BarMiddleware)
55
55
  expect(subject[1]).to eq(StackSpec::FooMiddleware)
56
56
  end
@@ -59,7 +59,7 @@ describe Grape::Middleware::Stack do
59
59
  describe '#insert_before' do
60
60
  it 'inserts a middleware before another middleware class' do
61
61
  expect { subject.insert_before StackSpec::FooMiddleware, StackSpec::BarMiddleware }
62
- .to change { subject.size }.by(1)
62
+ .to change(subject, :size).by(1)
63
63
  expect(subject[0]).to eq(StackSpec::BarMiddleware)
64
64
  expect(subject[1]).to eq(StackSpec::FooMiddleware)
65
65
  end
@@ -68,7 +68,7 @@ describe Grape::Middleware::Stack do
68
68
  subject.use Class.new(StackSpec::BlockMiddleware)
69
69
 
70
70
  expect { subject.insert_before StackSpec::BlockMiddleware, StackSpec::BarMiddleware }
71
- .to change { subject.size }.by(1)
71
+ .to change(subject, :size).by(1)
72
72
 
73
73
  expect(subject[1]).to eq(StackSpec::BarMiddleware)
74
74
  expect(subject[2]).to eq(StackSpec::BlockMiddleware)
@@ -83,7 +83,7 @@ describe Grape::Middleware::Stack do
83
83
  describe '#insert_after' do
84
84
  it 'inserts a middleware after another middleware class' do
85
85
  expect { subject.insert_after StackSpec::FooMiddleware, StackSpec::BarMiddleware }
86
- .to change { subject.size }.by(1)
86
+ .to change(subject, :size).by(1)
87
87
  expect(subject[1]).to eq(StackSpec::BarMiddleware)
88
88
  expect(subject[0]).to eq(StackSpec::FooMiddleware)
89
89
  end
@@ -92,7 +92,7 @@ describe Grape::Middleware::Stack do
92
92
  subject.use Class.new(StackSpec::BlockMiddleware)
93
93
 
94
94
  expect { subject.insert_after StackSpec::BlockMiddleware, StackSpec::BarMiddleware }
95
- .to change { subject.size }.by(1)
95
+ .to change(subject, :size).by(1)
96
96
 
97
97
  expect(subject[1]).to eq(StackSpec::BlockMiddleware)
98
98
  expect(subject[2]).to eq(StackSpec::BarMiddleware)
@@ -107,7 +107,7 @@ describe Grape::Middleware::Stack do
107
107
  describe '#merge_with' do
108
108
  it 'applies a collection of operations and middlewares' do
109
109
  expect { subject.merge_with(others) }
110
- .to change { subject.size }.by(2)
110
+ .to change(subject, :size).by(2)
111
111
  expect(subject[0]).to eq(StackSpec::FooMiddleware)
112
112
  expect(subject[1]).to eq(StackSpec::BlockMiddleware)
113
113
  expect(subject[2]).to eq(StackSpec::BarMiddleware)
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner::AcceptVersionHeader do
4
+ subject { described_class.new(app, **(@options || {})) }
5
+
6
6
  let(:app) { ->(env) { [200, env, env] } }
7
- subject { Grape::Middleware::Versioner::AcceptVersionHeader.new(app, **(@options || {})) }
8
7
 
9
8
  before do
10
9
  @options = {
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner::Header do
4
+ subject { described_class.new(app, **(@options || {})) }
5
+
6
6
  let(:app) { ->(env) { [200, env, env] } }
7
- subject { Grape::Middleware::Versioner::Header.new(app, **(@options || {})) }
8
7
 
9
8
  before do
10
9
  @options = {
@@ -47,7 +46,7 @@ describe Grape::Middleware::Versioner::Header do
47
46
 
48
47
  it 'is nil if not provided' do
49
48
  status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor')
50
- expect(env['api.format']).to eql nil
49
+ expect(env['api.format']).to be_nil
51
50
  expect(status).to eq(200)
52
51
  end
53
52
 
@@ -65,7 +64,7 @@ describe Grape::Middleware::Versioner::Header do
65
64
 
66
65
  it 'is nil if not provided' do
67
66
  status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1')
68
- expect(env['api.format']).to eql nil
67
+ expect(env['api.format']).to be_nil
69
68
  expect(status).to eq(200)
70
69
  end
71
70
  end
@@ -90,7 +89,7 @@ describe Grape::Middleware::Versioner::Header do
90
89
  .to raise_exception do |exception|
91
90
  expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
92
91
  expect(exception.headers).to eql('X-Cascade' => 'pass')
93
- expect(exception.status).to eql 406
92
+ expect(exception.status).to be 406
94
93
  expect(exception.message).to include 'API vendor not found'
95
94
  end
96
95
  end
@@ -117,7 +116,7 @@ describe Grape::Middleware::Versioner::Header do
117
116
  .to raise_exception do |exception|
118
117
  expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
119
118
  expect(exception.headers).to eql('X-Cascade' => 'pass')
120
- expect(exception.status).to eql 406
119
+ expect(exception.status).to be 406
121
120
  expect(exception.message).to include('API vendor not found')
122
121
  end
123
122
  end
@@ -145,7 +144,7 @@ describe Grape::Middleware::Versioner::Header do
145
144
  expect { subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v2+json').last }.to raise_exception do |exception|
146
145
  expect(exception).to be_a(Grape::Exceptions::InvalidVersionHeader)
147
146
  expect(exception.headers).to eql('X-Cascade' => 'pass')
148
- expect(exception.status).to eql 406
147
+ expect(exception.status).to be 406
149
148
  expect(exception.message).to include('API version not found')
150
149
  end
151
150
  end
@@ -178,7 +177,7 @@ describe Grape::Middleware::Versioner::Header do
178
177
  expect { subject.call({}).last }.to raise_exception do |exception|
179
178
  expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
180
179
  expect(exception.headers).to eql('X-Cascade' => 'pass')
181
- expect(exception.status).to eql 406
180
+ expect(exception.status).to be 406
182
181
  expect(exception.message).to include('Accept header must be set.')
183
182
  end
184
183
  end
@@ -187,7 +186,7 @@ describe Grape::Middleware::Versioner::Header do
187
186
  expect { subject.call('HTTP_ACCEPT' => '').last }.to raise_exception do |exception|
188
187
  expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
189
188
  expect(exception.headers).to eql('X-Cascade' => 'pass')
190
- expect(exception.status).to eql 406
189
+ expect(exception.status).to be 406
191
190
  expect(exception.message).to include('Accept header must be set.')
192
191
  end
193
192
  end
@@ -208,7 +207,7 @@ describe Grape::Middleware::Versioner::Header do
208
207
  expect { subject.call({}).last }.to raise_exception do |exception|
209
208
  expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
210
209
  expect(exception.headers).to eql({})
211
- expect(exception.status).to eql 406
210
+ expect(exception.status).to be 406
212
211
  expect(exception.message).to include('Accept header must be set.')
213
212
  end
214
213
  end
@@ -218,7 +217,7 @@ describe Grape::Middleware::Versioner::Header do
218
217
  .to raise_exception do |exception|
219
218
  expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
220
219
  expect(exception.headers).to eql({})
221
- expect(exception.status).to eql 406
220
+ expect(exception.status).to be 406
222
221
  expect(exception.message).to include('API vendor or version not found.')
223
222
  end
224
223
  end
@@ -227,7 +226,7 @@ describe Grape::Middleware::Versioner::Header do
227
226
  expect { subject.call('HTTP_ACCEPT' => '').last }.to raise_exception do |exception|
228
227
  expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
229
228
  expect(exception.headers).to eql({})
230
- expect(exception.status).to eql 406
229
+ expect(exception.status).to be 406
231
230
  expect(exception.message).to include('Accept header must be set.')
232
231
  end
233
232
  end
@@ -237,7 +236,7 @@ describe Grape::Middleware::Versioner::Header do
237
236
  .to raise_exception do |exception|
238
237
  expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
239
238
  expect(exception.headers).to eql({})
240
- expect(exception.status).to eql 406
239
+ expect(exception.status).to be 406
241
240
  expect(exception.message).to include('API vendor or version not found.')
242
241
  end
243
242
  end
@@ -264,7 +263,7 @@ describe Grape::Middleware::Versioner::Header do
264
263
  expect { subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v3+json') }.to raise_exception do |exception|
265
264
  expect(exception).to be_a(Grape::Exceptions::InvalidVersionHeader)
266
265
  expect(exception.headers).to eql('X-Cascade' => 'pass')
267
- expect(exception.status).to eql 406
266
+ expect(exception.status).to be 406
268
267
  expect(exception.message).to include('API version not found')
269
268
  end
270
269
  end
@@ -327,4 +326,20 @@ describe Grape::Middleware::Versioner::Header do
327
326
  end
328
327
  end
329
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
330
345
  end
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner::Param do
4
+ subject { described_class.new(app, **options) }
5
+
6
6
  let(:app) { ->(env) { [200, env, env['api.version']] } }
7
7
  let(:options) { {} }
8
- subject { Grape::Middleware::Versioner::Param.new(app, **options) }
9
8
 
10
9
  it 'sets the API version based on the default param (apiver)' do
11
10
  env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' })
@@ -26,10 +25,12 @@ describe Grape::Middleware::Versioner::Param do
26
25
 
27
26
  context 'with specified parameter name' do
28
27
  let(:options) { { version_options: { parameter: 'v' } } }
28
+
29
29
  it 'sets the API version based on the custom parameter name' do
30
30
  env = Rack::MockRequest.env_for('/awesome', params: { 'v' => 'v1' })
31
31
  expect(subject.call(env)[1]['api.version']).to eq('v1')
32
32
  end
33
+
33
34
  it 'does not set the API version based on the default param' do
34
35
  env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' })
35
36
  expect(subject.call(env)[1]['api.version']).to be_nil
@@ -38,10 +39,12 @@ describe Grape::Middleware::Versioner::Param do
38
39
 
39
40
  context 'with specified versions' do
40
41
  let(:options) { { versions: %w[v1 v2] } }
42
+
41
43
  it 'throws an error if a non-allowed version is specified' do
42
44
  env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v3' })
43
45
  expect(catch(:error) { subject.call(env) }[:status]).to eq(404)
44
46
  end
47
+
45
48
  it 'allows versions that have been specified' do
46
49
  env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' })
47
50
  expect(subject.call(env)[1]['api.version']).to eq('v1')
@@ -55,6 +58,7 @@ describe Grape::Middleware::Versioner::Param do
55
58
  version_options: { using: :header }
56
59
  }
57
60
  end
61
+
58
62
  it 'returns a 200 (matches the first version found)' do
59
63
  env = Rack::MockRequest.env_for('/awesome', params: {})
60
64
  expect(subject.call(env).first).to eq(200)
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner::Path do
4
+ subject { described_class.new(app, **options) }
5
+
6
6
  let(:app) { ->(env) { [200, env, env['api.version']] } }
7
7
  let(:options) { {} }
8
- subject { Grape::Middleware::Versioner::Path.new(app, **options) }
9
8
 
10
9
  it 'sets the API version based on the first path' do
11
10
  expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1')
@@ -21,6 +20,7 @@ describe Grape::Middleware::Versioner::Path do
21
20
 
22
21
  context 'with a pattern' do
23
22
  let(:options) { { pattern: /v./i } }
23
+
24
24
  it 'sets the version if it matches' do
25
25
  expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1')
26
26
  end
@@ -46,6 +46,7 @@ describe Grape::Middleware::Versioner::Path do
46
46
 
47
47
  context 'with prefix, but requested version is not matched' do
48
48
  let(:options) { { prefix: '/v1', pattern: /v./i } }
49
+
49
50
  it 'recognizes potential version' do
50
51
  expect(subject.call('PATH_INFO' => '/v3/foo').last).to eq('v3')
51
52
  end
@@ -53,6 +54,7 @@ describe Grape::Middleware::Versioner::Path do
53
54
 
54
55
  context 'with mount path' do
55
56
  let(:options) { { mount_path: '/mounted', versions: [:v1] } }
57
+
56
58
  it 'recognizes potential version' do
57
59
  expect(subject.call('PATH_INFO' => '/mounted/v1/foo').last).to eq('v1')
58
60
  end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Middleware::Versioner do
6
- let(:klass) { Grape::Middleware::Versioner }
4
+ let(:klass) { described_class }
7
5
 
8
6
  it 'recognizes :path' do
9
7
  expect(klass.using(:path)).to eq(Grape::Middleware::Versioner::Path)
@@ -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
 
@@ -26,6 +24,7 @@ describe Grape::Parser do
26
24
 
27
25
  context 'with :parsers option' do
28
26
  let(:parsers) { { customized: Class.new } }
27
+
29
28
  it 'includes passed :parsers values' do
30
29
  expect(subject.parsers(parsers: parsers)).to include(parsers)
31
30
  end
@@ -33,7 +32,9 @@ describe Grape::Parser do
33
32
 
34
33
  context 'with added parser by using `register` keyword' do
35
34
  let(:added_parser) { Class.new }
35
+
36
36
  before { subject.register :added, added_parser }
37
+
37
38
  it 'includes added parser' do
38
39
  expect(subject.parsers(**{})).to include(added: added_parser)
39
40
  end
@@ -54,6 +55,7 @@ describe Grape::Parser do
54
55
 
55
56
  context 'when parser is available' do
56
57
  before { subject.register :customized_json, Grape::Parser::Json }
58
+
57
59
  it 'returns registered parser if available' do
58
60
  expect(subject.parser_for(:customized_json)).to eq(Grape::Parser::Json)
59
61
  end