grape 1.5.3 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/CONTRIBUTING.md +2 -1
  4. data/README.md +31 -3
  5. data/UPGRADING.md +46 -4
  6. data/grape.gemspec +5 -5
  7. data/lib/grape/api/instance.rb +13 -17
  8. data/lib/grape/api.rb +17 -12
  9. data/lib/grape/cookies.rb +2 -0
  10. data/lib/grape/dsl/desc.rb +3 -5
  11. data/lib/grape/dsl/headers.rb +5 -2
  12. data/lib/grape/dsl/helpers.rb +7 -5
  13. data/lib/grape/dsl/inside_route.rb +17 -8
  14. data/lib/grape/dsl/middleware.rb +4 -4
  15. data/lib/grape/dsl/parameters.rb +3 -3
  16. data/lib/grape/dsl/request_response.rb +9 -6
  17. data/lib/grape/dsl/routing.rb +2 -2
  18. data/lib/grape/dsl/settings.rb +5 -5
  19. data/lib/grape/endpoint.rb +20 -35
  20. data/lib/grape/error_formatter/json.rb +2 -6
  21. data/lib/grape/error_formatter/xml.rb +2 -6
  22. data/lib/grape/exceptions/validation.rb +1 -2
  23. data/lib/grape/formatter/json.rb +1 -0
  24. data/lib/grape/formatter/serializable_hash.rb +2 -1
  25. data/lib/grape/formatter/xml.rb +1 -0
  26. data/lib/grape/middleware/auth/dsl.rb +7 -1
  27. data/lib/grape/middleware/base.rb +3 -1
  28. data/lib/grape/middleware/formatter.rb +4 -4
  29. data/lib/grape/middleware/stack.rb +2 -2
  30. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  31. data/lib/grape/middleware/versioner/header.rb +6 -4
  32. data/lib/grape/middleware/versioner/param.rb +1 -0
  33. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  34. data/lib/grape/middleware/versioner/path.rb +2 -0
  35. data/lib/grape/path.rb +1 -0
  36. data/lib/grape/request.rb +1 -0
  37. data/lib/grape/router/pattern.rb +1 -1
  38. data/lib/grape/router/route.rb +2 -2
  39. data/lib/grape/router.rb +6 -0
  40. data/lib/grape/util/inheritable_setting.rb +1 -3
  41. data/lib/grape/util/lazy_value.rb +3 -2
  42. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  43. data/lib/grape/validations/params_scope.rb +88 -55
  44. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  45. data/lib/grape/validations/types/dry_type_coercer.rb +1 -1
  46. data/lib/grape/validations/types/json.rb +2 -1
  47. data/lib/grape/validations/types/primitive_coercer.rb +3 -3
  48. data/lib/grape/validations/validators/all_or_none.rb +8 -5
  49. data/lib/grape/validations/validators/allow_blank.rb +9 -7
  50. data/lib/grape/validations/validators/as.rb +6 -8
  51. data/lib/grape/validations/validators/at_least_one_of.rb +7 -4
  52. data/lib/grape/validations/validators/base.rb +75 -70
  53. data/lib/grape/validations/validators/coerce.rb +63 -79
  54. data/lib/grape/validations/validators/default.rb +37 -34
  55. data/lib/grape/validations/validators/exactly_one_of.rb +9 -6
  56. data/lib/grape/validations/validators/except_values.rb +13 -11
  57. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  58. data/lib/grape/validations/validators/mutual_exclusion.rb +8 -5
  59. data/lib/grape/validations/validators/presence.rb +7 -4
  60. data/lib/grape/validations/validators/regexp.rb +8 -5
  61. data/lib/grape/validations/validators/same_as.rb +18 -15
  62. data/lib/grape/validations/validators/values.rb +61 -56
  63. data/lib/grape/validations.rb +6 -0
  64. data/lib/grape/version.rb +1 -1
  65. data/lib/grape.rb +3 -1
  66. data/spec/grape/api/custom_validations_spec.rb +77 -45
  67. data/spec/grape/api/deeply_included_options_spec.rb +3 -3
  68. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -1
  69. data/spec/grape/api/invalid_format_spec.rb +2 -0
  70. data/spec/grape/api/recognize_path_spec.rb +1 -1
  71. data/spec/grape/api/routes_with_requirements_spec.rb +8 -8
  72. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -15
  73. data/spec/grape/api_remount_spec.rb +16 -15
  74. data/spec/grape/api_spec.rb +440 -227
  75. data/spec/grape/dsl/callbacks_spec.rb +2 -1
  76. data/spec/grape/dsl/headers_spec.rb +39 -9
  77. data/spec/grape/dsl/helpers_spec.rb +3 -2
  78. data/spec/grape/dsl/inside_route_spec.rb +6 -4
  79. data/spec/grape/dsl/logger_spec.rb +16 -18
  80. data/spec/grape/dsl/middleware_spec.rb +2 -1
  81. data/spec/grape/dsl/parameters_spec.rb +2 -0
  82. data/spec/grape/dsl/request_response_spec.rb +1 -0
  83. data/spec/grape/dsl/routing_spec.rb +10 -7
  84. data/spec/grape/endpoint/declared_spec.rb +259 -12
  85. data/spec/grape/endpoint_spec.rb +64 -55
  86. data/spec/grape/entity_spec.rb +22 -22
  87. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -0
  88. data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -22
  89. data/spec/grape/exceptions/validation_errors_spec.rb +13 -10
  90. data/spec/grape/exceptions/validation_spec.rb +5 -3
  91. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -7
  92. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -8
  93. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -8
  94. data/spec/grape/integration/rack_sendfile_spec.rb +1 -1
  95. data/spec/grape/loading_spec.rb +8 -8
  96. data/spec/grape/middleware/auth/dsl_spec.rb +15 -6
  97. data/spec/grape/middleware/auth/strategies_spec.rb +60 -20
  98. data/spec/grape/middleware/base_spec.rb +24 -15
  99. data/spec/grape/middleware/error_spec.rb +2 -2
  100. data/spec/grape/middleware/exception_spec.rb +111 -161
  101. data/spec/grape/middleware/formatter_spec.rb +27 -6
  102. data/spec/grape/middleware/globals_spec.rb +7 -4
  103. data/spec/grape/middleware/stack_spec.rb +14 -12
  104. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -1
  105. data/spec/grape/middleware/versioner/header_spec.rb +14 -13
  106. data/spec/grape/middleware/versioner/param_spec.rb +7 -1
  107. data/spec/grape/middleware/versioner/path_spec.rb +5 -1
  108. data/spec/grape/middleware/versioner_spec.rb +1 -1
  109. data/spec/grape/parser_spec.rb +4 -0
  110. data/spec/grape/path_spec.rb +52 -52
  111. data/spec/grape/presenters/presenter_spec.rb +7 -6
  112. data/spec/grape/request_spec.rb +6 -4
  113. data/spec/grape/util/inheritable_setting_spec.rb +7 -7
  114. data/spec/grape/util/inheritable_values_spec.rb +3 -2
  115. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -1
  116. data/spec/grape/util/stackable_values_spec.rb +7 -5
  117. data/spec/grape/validations/instance_behaivour_spec.rb +9 -10
  118. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -0
  119. data/spec/grape/validations/params_scope_spec.rb +46 -10
  120. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -1
  121. data/spec/grape/validations/types/primitive_coercer_spec.rb +4 -4
  122. data/spec/grape/validations/types_spec.rb +8 -8
  123. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -56
  124. data/spec/grape/validations/validators/allow_blank_spec.rb +136 -140
  125. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -56
  126. data/spec/grape/validations/validators/coerce_spec.rb +23 -22
  127. data/spec/grape/validations/validators/default_spec.rb +72 -78
  128. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -77
  129. data/spec/grape/validations/validators/except_values_spec.rb +3 -3
  130. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -77
  131. data/spec/grape/validations/validators/presence_spec.rb +16 -1
  132. data/spec/grape/validations/validators/regexp_spec.rb +25 -31
  133. data/spec/grape/validations/validators/same_as_spec.rb +14 -20
  134. data/spec/grape/validations/validators/values_spec.rb +183 -178
  135. data/spec/grape/validations_spec.rb +99 -58
  136. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  137. data/spec/integration/multi_json/json_spec.rb +1 -1
  138. data/spec/integration/multi_xml/xml_spec.rb +1 -1
  139. data/spec/shared/versioning_examples.rb +12 -9
  140. data/spec/spec_helper.rb +12 -2
  141. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  142. metadata +103 -103
@@ -6,63 +6,63 @@ module Grape
6
6
  describe Path do
7
7
  describe '#initialize' do
8
8
  it 'remembers the path' do
9
- path = Path.new('/:id', anything, anything)
9
+ path = described_class.new('/:id', anything, anything)
10
10
  expect(path.raw_path).to eql('/:id')
11
11
  end
12
12
 
13
13
  it 'remembers the namespace' do
14
- path = Path.new(anything, '/users', anything)
14
+ path = described_class.new(anything, '/users', anything)
15
15
  expect(path.namespace).to eql('/users')
16
16
  end
17
17
 
18
18
  it 'remebers the settings' do
19
- path = Path.new(anything, anything, foo: 'bar')
19
+ path = described_class.new(anything, anything, foo: 'bar')
20
20
  expect(path.settings).to eql(foo: 'bar')
21
21
  end
22
22
  end
23
23
 
24
24
  describe '#mount_path' do
25
25
  it 'is nil when no mount path setting exists' do
26
- path = Path.new(anything, anything, {})
26
+ path = described_class.new(anything, anything, {})
27
27
  expect(path.mount_path).to be_nil
28
28
  end
29
29
 
30
30
  it 'is nil when the mount path is nil' do
31
- path = Path.new(anything, anything, mount_path: nil)
31
+ path = described_class.new(anything, anything, mount_path: nil)
32
32
  expect(path.mount_path).to be_nil
33
33
  end
34
34
 
35
35
  it 'splits the mount path' do
36
- path = Path.new(anything, anything, mount_path: %w[foo bar])
36
+ path = described_class.new(anything, anything, mount_path: %w[foo bar])
37
37
  expect(path.mount_path).to eql(%w[foo bar])
38
38
  end
39
39
  end
40
40
 
41
41
  describe '#root_prefix' do
42
42
  it 'is nil when no root prefix setting exists' do
43
- path = Path.new(anything, anything, {})
43
+ path = described_class.new(anything, anything, {})
44
44
  expect(path.root_prefix).to be_nil
45
45
  end
46
46
 
47
47
  it 'is nil when the mount path is nil' do
48
- path = Path.new(anything, anything, root_prefix: nil)
48
+ path = described_class.new(anything, anything, root_prefix: nil)
49
49
  expect(path.root_prefix).to be_nil
50
50
  end
51
51
 
52
52
  it 'splits the mount path' do
53
- path = Path.new(anything, anything, root_prefix: 'hello/world')
53
+ path = described_class.new(anything, anything, root_prefix: 'hello/world')
54
54
  expect(path.root_prefix).to eql(%w[hello world])
55
55
  end
56
56
  end
57
57
 
58
58
  describe '#uses_path_versioning?' do
59
59
  it 'is false when the version setting is nil' do
60
- path = Path.new(anything, anything, version: nil)
60
+ path = described_class.new(anything, anything, version: nil)
61
61
  expect(path.uses_path_versioning?).to be false
62
62
  end
63
63
 
64
64
  it 'is false when the version option is header' do
65
- path = Path.new(
65
+ path = described_class.new(
66
66
  anything,
67
67
  anything,
68
68
  version: 'v1',
@@ -73,7 +73,7 @@ module Grape
73
73
  end
74
74
 
75
75
  it 'is true when the version option is path' do
76
- path = Path.new(
76
+ path = described_class.new(
77
77
  anything,
78
78
  anything,
79
79
  version: 'v1',
@@ -86,44 +86,44 @@ module Grape
86
86
 
87
87
  describe '#namespace?' do
88
88
  it 'is false when the namespace is nil' do
89
- path = Path.new(anything, nil, anything)
90
- expect(path.namespace?).to be_falsey
89
+ path = described_class.new(anything, nil, anything)
90
+ expect(path).not_to be_namespace
91
91
  end
92
92
 
93
93
  it 'is false when the namespace starts with whitespace' do
94
- path = Path.new(anything, ' /foo', anything)
95
- expect(path.namespace?).to be_falsey
94
+ path = described_class.new(anything, ' /foo', anything)
95
+ expect(path).not_to be_namespace
96
96
  end
97
97
 
98
98
  it 'is false when the namespace is the root path' do
99
- path = Path.new(anything, '/', anything)
99
+ path = described_class.new(anything, '/', anything)
100
100
  expect(path.namespace?).to be false
101
101
  end
102
102
 
103
103
  it 'is true otherwise' do
104
- path = Path.new(anything, '/world', anything)
104
+ path = described_class.new(anything, '/world', anything)
105
105
  expect(path.namespace?).to be true
106
106
  end
107
107
  end
108
108
 
109
109
  describe '#path?' do
110
110
  it 'is false when the path is nil' do
111
- path = Path.new(nil, anything, anything)
112
- expect(path.path?).to be_falsey
111
+ path = described_class.new(nil, anything, anything)
112
+ expect(path).not_to be_path
113
113
  end
114
114
 
115
115
  it 'is false when the path starts with whitespace' do
116
- path = Path.new(' /foo', anything, anything)
117
- expect(path.path?).to be_falsey
116
+ path = described_class.new(' /foo', anything, anything)
117
+ expect(path).not_to be_path
118
118
  end
119
119
 
120
120
  it 'is false when the path is the root path' do
121
- path = Path.new('/', anything, anything)
121
+ path = described_class.new('/', anything, anything)
122
122
  expect(path.path?).to be false
123
123
  end
124
124
 
125
125
  it 'is true otherwise' do
126
- path = Path.new('/hello', anything, anything)
126
+ path = described_class.new('/hello', anything, anything)
127
127
  expect(path.path?).to be true
128
128
  end
129
129
  end
@@ -131,24 +131,24 @@ module Grape
131
131
  describe '#path' do
132
132
  context 'mount_path' do
133
133
  it 'is not included when it is nil' do
134
- path = Path.new(nil, nil, mount_path: '/foo/bar')
134
+ path = described_class.new(nil, nil, mount_path: '/foo/bar')
135
135
  expect(path.path).to eql '/foo/bar'
136
136
  end
137
137
 
138
138
  it 'is included when it is not nil' do
139
- path = Path.new(nil, nil, {})
139
+ path = described_class.new(nil, nil, {})
140
140
  expect(path.path).to eql('/')
141
141
  end
142
142
  end
143
143
 
144
144
  context 'root_prefix' do
145
145
  it 'is not included when it is nil' do
146
- path = Path.new(nil, nil, {})
146
+ path = described_class.new(nil, nil, {})
147
147
  expect(path.path).to eql('/')
148
148
  end
149
149
 
150
150
  it 'is included after the mount path' do
151
- path = Path.new(
151
+ path = described_class.new(
152
152
  nil,
153
153
  nil,
154
154
  mount_path: '/foo',
@@ -160,7 +160,7 @@ module Grape
160
160
  end
161
161
 
162
162
  it 'uses the namespace after the mount path and root prefix' do
163
- path = Path.new(
163
+ path = described_class.new(
164
164
  nil,
165
165
  'namespace',
166
166
  mount_path: '/foo',
@@ -171,7 +171,7 @@ module Grape
171
171
  end
172
172
 
173
173
  it 'uses the raw path after the namespace' do
174
- path = Path.new(
174
+ path = described_class.new(
175
175
  'raw_path',
176
176
  'namespace',
177
177
  mount_path: '/foo',
@@ -185,9 +185,9 @@ module Grape
185
185
  describe '#suffix' do
186
186
  context 'when using a specific format' do
187
187
  it 'accepts specified format' do
188
- path = Path.new(nil, nil, {})
189
- allow(path).to receive(:uses_specific_format?) { true }
190
- allow(path).to receive(:settings) { { format: :json } }
188
+ path = described_class.new(nil, nil, {})
189
+ allow(path).to receive(:uses_specific_format?).and_return(true)
190
+ allow(path).to receive(:settings).and_return({ format: :json })
191
191
 
192
192
  expect(path.suffix).to eql('(.json)')
193
193
  end
@@ -195,9 +195,9 @@ module Grape
195
195
 
196
196
  context 'when path versioning is used' do
197
197
  it "includes a '/'" do
198
- path = Path.new(nil, nil, {})
199
- allow(path).to receive(:uses_specific_format?) { false }
200
- allow(path).to receive(:uses_path_versioning?) { true }
198
+ path = described_class.new(nil, nil, {})
199
+ allow(path).to receive(:uses_specific_format?).and_return(false)
200
+ allow(path).to receive(:uses_path_versioning?).and_return(true)
201
201
 
202
202
  expect(path.suffix).to eql('(/.:format)')
203
203
  end
@@ -205,25 +205,25 @@ module Grape
205
205
 
206
206
  context 'when path versioning is not used' do
207
207
  it "does not include a '/' when the path has a namespace" do
208
- path = Path.new(nil, 'namespace', {})
209
- allow(path).to receive(:uses_specific_format?) { false }
210
- allow(path).to receive(:uses_path_versioning?) { true }
208
+ path = described_class.new(nil, 'namespace', {})
209
+ allow(path).to receive(:uses_specific_format?).and_return(false)
210
+ allow(path).to receive(:uses_path_versioning?).and_return(true)
211
211
 
212
212
  expect(path.suffix).to eql('(.:format)')
213
213
  end
214
214
 
215
215
  it "does not include a '/' when the path has a path" do
216
- path = Path.new('/path', nil, {})
217
- allow(path).to receive(:uses_specific_format?) { false }
218
- allow(path).to receive(:uses_path_versioning?) { true }
216
+ path = described_class.new('/path', nil, {})
217
+ allow(path).to receive(:uses_specific_format?).and_return(false)
218
+ allow(path).to receive(:uses_path_versioning?).and_return(true)
219
219
 
220
220
  expect(path.suffix).to eql('(.:format)')
221
221
  end
222
222
 
223
223
  it "includes a '/' otherwise" do
224
- path = Path.new(nil, nil, {})
225
- allow(path).to receive(:uses_specific_format?) { false }
226
- allow(path).to receive(:uses_path_versioning?) { true }
224
+ path = described_class.new(nil, nil, {})
225
+ allow(path).to receive(:uses_specific_format?).and_return(false)
226
+ allow(path).to receive(:uses_path_versioning?).and_return(true)
227
227
 
228
228
  expect(path.suffix).to eql('(/.:format)')
229
229
  end
@@ -232,19 +232,19 @@ module Grape
232
232
 
233
233
  describe '#path_with_suffix' do
234
234
  it 'combines the path and suffix' do
235
- path = Path.new(nil, nil, {})
236
- allow(path).to receive(:path) { '/the/path' }
237
- allow(path).to receive(:suffix) { 'suffix' }
235
+ path = described_class.new(nil, nil, {})
236
+ allow(path).to receive(:path).and_return('/the/path')
237
+ allow(path).to receive(:suffix).and_return('suffix')
238
238
 
239
239
  expect(path.path_with_suffix).to eql('/the/pathsuffix')
240
240
  end
241
241
 
242
242
  context 'when using a specific format' do
243
243
  it 'might have a suffix with specified format' do
244
- path = Path.new(nil, nil, {})
245
- allow(path).to receive(:path) { '/the/path' }
246
- allow(path).to receive(:uses_specific_format?) { true }
247
- allow(path).to receive(:settings) { { format: :json } }
244
+ path = described_class.new(nil, nil, {})
245
+ allow(path).to receive(:path).and_return('/the/path')
246
+ allow(path).to receive(:uses_specific_format?).and_return(true)
247
+ allow(path).to receive(:settings).and_return({ format: :json })
248
248
 
249
249
  expect(path.path_with_suffix).to eql('/the/path(.json)')
250
250
  end
@@ -19,18 +19,18 @@ module Grape
19
19
  end
20
20
 
21
21
  describe Presenter do
22
+ subject { PresenterSpec::Dummy.new }
23
+
22
24
  describe 'represent' do
23
25
  let(:object_mock) do
24
26
  Object.new
25
27
  end
26
28
 
27
29
  it 'represent object' do
28
- expect(Presenter.represent(object_mock)).to eq object_mock
30
+ expect(described_class.represent(object_mock)).to eq object_mock
29
31
  end
30
32
  end
31
33
 
32
- subject { PresenterSpec::Dummy.new }
33
-
34
34
  describe 'present' do
35
35
  let(:hash_mock) do
36
36
  { key: :value }
@@ -38,8 +38,9 @@ module Grape
38
38
 
39
39
  describe 'instance' do
40
40
  before do
41
- subject.present hash_mock, with: Grape::Presenters::Presenter
41
+ subject.present hash_mock, with: described_class
42
42
  end
43
+
43
44
  it 'presents dummy hash' do
44
45
  expect(subject.body).to eq hash_mock
45
46
  end
@@ -56,8 +57,8 @@ module Grape
56
57
 
57
58
  describe 'instance' do
58
59
  before do
59
- subject.present hash_mock1, with: Grape::Presenters::Presenter
60
- subject.present hash_mock2, with: Grape::Presenters::Presenter
60
+ subject.present hash_mock1, with: described_class
61
+ subject.present hash_mock2, with: described_class
61
62
  end
62
63
 
63
64
  it 'presents both dummy presenter' do
@@ -21,7 +21,7 @@ module Grape
21
21
  let(:env) { default_env }
22
22
 
23
23
  let(:request) do
24
- Grape::Request.new(env)
24
+ described_class.new(env)
25
25
  end
26
26
 
27
27
  describe '#params' do
@@ -38,7 +38,7 @@ module Grape
38
38
 
39
39
  context 'when build_params_with: Grape::Extensions::Hash::ParamBuilder is specified' do
40
40
  let(:request) do
41
- Grape::Request.new(env, build_params_with: Grape::Extensions::Hash::ParamBuilder)
41
+ described_class.new(env, build_params_with: Grape::Extensions::Hash::ParamBuilder)
42
42
  end
43
43
 
44
44
  it 'returns symbolized params' do
@@ -65,6 +65,8 @@ module Grape
65
65
  end
66
66
 
67
67
  describe 'when the param_builder is set to Hashie' do
68
+ subject(:request_params) { described_class.new(env, **opts).params }
69
+
68
70
  before do
69
71
  Grape.configure do |config|
70
72
  config.param_builder = Grape::Extensions::Hashie::Mash::ParamBuilder
@@ -75,15 +77,15 @@ module Grape
75
77
  Grape.config.reset
76
78
  end
77
79
 
78
- subject(:request_params) { Grape::Request.new(env, **opts).params }
79
-
80
80
  context 'when the API does not include a specific param builder' do
81
81
  let(:opts) { {} }
82
+
82
83
  it { is_expected.to be_a(Hashie::Mash) }
83
84
  end
84
85
 
85
86
  context 'when the API includes a specific param builder' do
86
87
  let(:opts) { { build_params_with: Grape::Extensions::Hash::ParamBuilder } }
88
+
87
89
  it { is_expected.to be_a(Hash) }
88
90
  end
89
91
  end
@@ -4,12 +4,12 @@ require 'spec_helper'
4
4
  module Grape
5
5
  module Util
6
6
  describe InheritableSetting do
7
- before :each do
8
- InheritableSetting.reset_global!
7
+ before do
8
+ described_class.reset_global!
9
9
  end
10
10
 
11
11
  let(:parent) do
12
- Grape::Util::InheritableSetting.new.tap do |settings|
12
+ described_class.new.tap do |settings|
13
13
  settings.global[:global_thing] = :global_foo_bar
14
14
  settings.namespace[:namespace_thing] = :namespace_foo_bar
15
15
  settings.namespace_inheritable[:namespace_inheritable_thing] = :namespace_inheritable_foo_bar
@@ -20,7 +20,7 @@ module Grape
20
20
  end
21
21
 
22
22
  let(:other_parent) do
23
- Grape::Util::InheritableSetting.new.tap do |settings|
23
+ described_class.new.tap do |settings|
24
24
  settings.namespace[:namespace_thing] = :namespace_foo_bar_other
25
25
  settings.namespace_inheritable[:namespace_inheritable_thing] = :namespace_inheritable_foo_bar_other
26
26
  settings.namespace_stackable[:namespace_stackable_thing] = :namespace_stackable_foo_bar_other
@@ -29,7 +29,7 @@ module Grape
29
29
  end
30
30
  end
31
31
 
32
- before :each do
32
+ before do
33
33
  subject.inherit_from parent
34
34
  end
35
35
 
@@ -50,7 +50,7 @@ module Grape
50
50
  expect(parent.global[:global_thing]).to eq :global_new_foo_bar
51
51
  end
52
52
 
53
- it 'should handle different parents' do
53
+ it 'handles different parents' do
54
54
  subject.global[:global_thing] = :global_new_foo_bar
55
55
 
56
56
  subject.inherit_from other_parent
@@ -89,7 +89,7 @@ module Grape
89
89
  expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar
90
90
  end
91
91
 
92
- it 'should handle different parents' do
92
+ it 'handles different parents' do
93
93
  expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar
94
94
 
95
95
  subject.inherit_from other_parent
@@ -4,8 +4,9 @@ require 'spec_helper'
4
4
  module Grape
5
5
  module Util
6
6
  describe InheritableValues do
7
- let(:parent) { InheritableValues.new }
8
- subject { InheritableValues.new(parent) }
7
+ subject { described_class.new(parent) }
8
+
9
+ let(:parent) { described_class.new }
9
10
 
10
11
  describe '#delete' do
11
12
  it 'deletes a key' do
@@ -4,9 +4,10 @@ require 'spec_helper'
4
4
  module Grape
5
5
  module Util
6
6
  describe ReverseStackableValues do
7
- let(:parent) { described_class.new }
8
7
  subject { described_class.new(parent) }
9
8
 
9
+ let(:parent) { described_class.new }
10
+
10
11
  describe '#keys' do
11
12
  it 'returns all keys' do
12
13
  subject[:some_thing] = :foo_bar
@@ -102,6 +103,7 @@ module Grape
102
103
 
103
104
  describe '#clone' do
104
105
  let(:obj_cloned) { subject.clone }
106
+
105
107
  it 'copies all values' do
106
108
  parent = described_class.new
107
109
  child = described_class.new parent
@@ -4,8 +4,9 @@ require 'spec_helper'
4
4
  module Grape
5
5
  module Util
6
6
  describe StackableValues do
7
- let(:parent) { StackableValues.new }
8
- subject { StackableValues.new(parent) }
7
+ subject { described_class.new(parent) }
8
+
9
+ let(:parent) { described_class.new }
9
10
 
10
11
  describe '#keys' do
11
12
  it 'returns all keys' do
@@ -99,10 +100,11 @@ module Grape
99
100
 
100
101
  describe '#clone' do
101
102
  let(:obj_cloned) { subject.clone }
103
+
102
104
  it 'copies all values' do
103
- parent = StackableValues.new
104
- child = StackableValues.new parent
105
- grandchild = StackableValues.new child
105
+ parent = described_class.new
106
+ child = described_class.new parent
107
+ grandchild = described_class.new child
106
108
 
107
109
  parent[:some_thing] = :foo
108
110
  child[:some_thing] = %i[bar more]
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
 
5
5
  describe 'Validator with instance variables' do
6
6
  let(:validator_type) do
7
- Class.new(Grape::Validations::Base) do
7
+ Class.new(Grape::Validations::Validators::Base) do
8
8
  def validate_param!(_attr_name, _params)
9
9
  if instance_variable_defined?(:@instance_variable) && @instance_variable
10
10
  raise Grape::Exceptions::Validation.new(params: ['params'],
@@ -14,15 +14,6 @@ describe 'Validator with instance variables' do
14
14
  end
15
15
  end
16
16
  end
17
-
18
- before do
19
- Grape::Validations.register_validator('instance_validator', validator_type)
20
- end
21
-
22
- after do
23
- Grape::Validations.deregister_validator('instance_validator')
24
- end
25
-
26
17
  let(:app) do
27
18
  Class.new(Grape::API) do
28
19
  params do
@@ -35,6 +26,14 @@ describe 'Validator with instance variables' do
35
26
  end
36
27
  end
37
28
 
29
+ before do
30
+ Grape::Validations.register_validator('instance_validator', validator_type)
31
+ end
32
+
33
+ after do
34
+ Grape::Validations.deregister_validator('instance_validator')
35
+ end
36
+
38
37
  it 'passes validation every time' do
39
38
  expect(validator_type).to receive(:new).exactly(4).times.and_call_original
40
39
 
@@ -5,6 +5,7 @@ require 'spec_helper'
5
5
  describe Grape::Validations::MultipleAttributesIterator do
6
6
  describe '#each' do
7
7
  subject(:iterator) { described_class.new(validator, scope, params) }
8
+
8
9
  let(:scope) { Grape::Validations::ParamsScope.new(api: Class.new(Grape::API)) }
9
10
  let(:validator) { double(attrs: %i[first second third]) }
10
11
 
@@ -98,6 +98,7 @@ describe Grape::Validations::ParamsScope do
98
98
 
99
99
  def self.parse(value)
100
100
  raise if value == 'invalid'
101
+
101
102
  new(value)
102
103
  end
103
104
 
@@ -144,7 +145,7 @@ describe Grape::Validations::ParamsScope do
144
145
  get '/renaming-coerced', foo: ' there we go '
145
146
 
146
147
  expect(last_response.status).to eq(200)
147
- expect(last_response.body).to eq('there we go-')
148
+ expect(last_response.body).to eq('-there we go')
148
149
  end
149
150
 
150
151
  it do
@@ -180,6 +181,28 @@ describe Grape::Validations::ParamsScope do
180
181
  expect(last_response.status).to eq(200)
181
182
  expect(last_response.body).to eq('{"baz":{"qux":"any"}}')
182
183
  end
184
+
185
+ it 'renaming can be defined before default' do
186
+ subject.params do
187
+ optional :foo, as: :bar, default: 'before'
188
+ end
189
+ subject.get('/rename-before-default') { declared(params)[:bar] }
190
+ get '/rename-before-default'
191
+
192
+ expect(last_response.status).to eq(200)
193
+ expect(last_response.body).to eq('before')
194
+ end
195
+
196
+ it 'renaming can be defined after default' do
197
+ subject.params do
198
+ optional :foo, default: 'after', as: :bar
199
+ end
200
+ subject.get('/rename-after-default') { declared(params)[:bar] }
201
+ get '/rename-after-default'
202
+
203
+ expect(last_response.status).to eq(200)
204
+ expect(last_response.body).to eq('after')
205
+ end
183
206
  end
184
207
 
185
208
  context 'array without coerce type explicitly given' do
@@ -269,7 +292,7 @@ describe Grape::Validations::ParamsScope do
269
292
  it 'does not raise an exception' do
270
293
  expect do
271
294
  subject.params { optional :numbers, type: Array[Integer], values: 0..2, default: 0..2 }
272
- end.to_not raise_error
295
+ end.not_to raise_error
273
296
  end
274
297
  end
275
298
 
@@ -277,7 +300,7 @@ describe Grape::Validations::ParamsScope do
277
300
  it 'does not raise an exception' do
278
301
  expect do
279
302
  subject.params { optional :numbers, type: Array[Integer], values: [0, 1, 2], default: [1, 0] }
280
- end.to_not raise_error
303
+ end.not_to raise_error
281
304
  end
282
305
  end
283
306
  end
@@ -501,7 +524,7 @@ describe Grape::Validations::ParamsScope do
501
524
  requires :c
502
525
  end
503
526
  end
504
- end.to_not raise_error
527
+ end.not_to raise_error
505
528
  end
506
529
 
507
530
  it 'does not raise an error if when using nested given' do
@@ -517,7 +540,7 @@ describe Grape::Validations::ParamsScope do
517
540
  end
518
541
  end
519
542
  end
520
- end.to_not raise_error
543
+ end.not_to raise_error
521
544
  end
522
545
 
523
546
  it 'allows nested dependent parameters' do
@@ -562,13 +585,13 @@ describe Grape::Validations::ParamsScope do
562
585
  body = JSON.parse(last_response.body)
563
586
 
564
587
  expect(body.keys).to include('c')
565
- expect(body.keys).to_not include('b')
588
+ expect(body.keys).not_to include('b')
566
589
  end
567
590
 
568
591
  it 'allows renaming of dependent on parameter' do
569
592
  subject.params do
570
593
  optional :a, as: :b
571
- given b: ->(val) { val == 'x' } do
594
+ given a: ->(val) { val == 'x' } do
572
595
  requires :c
573
596
  end
574
597
  end
@@ -582,7 +605,7 @@ describe Grape::Validations::ParamsScope do
582
605
  expect(last_response.status).to eq 200
583
606
  end
584
607
 
585
- it 'raises an error if the dependent parameter is not the renamed one' do
608
+ it 'does not raise if the dependent parameter is not the renamed one' do
586
609
  expect do
587
610
  subject.params do
588
611
  optional :a, as: :b
@@ -590,6 +613,17 @@ describe Grape::Validations::ParamsScope do
590
613
  requires :c
591
614
  end
592
615
  end
616
+ end.not_to raise_error
617
+ end
618
+
619
+ it 'raises an error if the dependent parameter is the renamed one' do
620
+ expect do
621
+ subject.params do
622
+ optional :a, as: :b
623
+ given :b do
624
+ requires :c
625
+ end
626
+ end
593
627
  end.to raise_error(Grape::Exceptions::UnknownParameter)
594
628
  end
595
629
 
@@ -753,7 +787,7 @@ describe Grape::Validations::ParamsScope do
753
787
  subject.get('/test') { 'ok' }
754
788
  end
755
789
 
756
- it 'should pass none Hash params' do
790
+ it 'passes none Hash params' do
757
791
  get '/test', foos: ['']
758
792
  expect(last_response.status).to eq(200)
759
793
  expect(last_response.body).to eq('ok')
@@ -929,6 +963,7 @@ describe Grape::Validations::ParamsScope do
929
963
  expect(last_response.body).to eq('one is missing, two is missing, three is missing')
930
964
  end
931
965
  end
966
+
932
967
  context 'when fail_fast is defined it stops the validation' do
933
968
  it 'of other params' do
934
969
  subject.params do
@@ -941,6 +976,7 @@ describe Grape::Validations::ParamsScope do
941
976
  expect(last_response.status).to eq(400)
942
977
  expect(last_response.body).to eq('one is missing')
943
978
  end
979
+
944
980
  it 'for a single param' do
945
981
  subject.params do
946
982
  requires :one, allow_blank: false, regexp: /[0-9]+/, fail_fast: true
@@ -991,7 +1027,7 @@ describe Grape::Validations::ParamsScope do
991
1027
  end
992
1028
 
993
1029
  it 'prioritizes parameter validation over group validation' do
994
- expect(last_response.body).to_not include('address is empty')
1030
+ expect(last_response.body).not_to include('address is empty')
995
1031
  end
996
1032
  end
997
1033
  end