grape 1.6.0 → 1.6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/CONTRIBUTING.md +1 -0
- data/README.md +9 -1
- data/lib/grape/api.rb +12 -0
- data/lib/grape/dry_types.rb +12 -0
- data/lib/grape/dsl/headers.rb +5 -2
- data/lib/grape/dsl/helpers.rb +1 -1
- data/lib/grape/middleware/auth/dsl.rb +7 -1
- data/lib/grape/middleware/base.rb +1 -1
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/types/array_coercer.rb +0 -2
- data/lib/grape/validations/types/dry_type_coercer.rb +1 -10
- data/lib/grape/validations/types/json.rb +0 -2
- data/lib/grape/validations/types/primitive_coercer.rb +5 -7
- data/lib/grape/validations/types/set_coercer.rb +0 -3
- data/lib/grape/validations/types.rb +83 -9
- data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
- data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
- data/lib/grape/validations/validators/as_validator.rb +14 -0
- data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
- data/lib/grape/validations/validators/base.rb +73 -71
- data/lib/grape/validations/validators/coerce_validator.rb +75 -0
- data/lib/grape/validations/validators/default_validator.rb +51 -0
- data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
- data/lib/grape/validations/validators/except_values_validator.rb +24 -0
- data/lib/grape/validations/validators/multiple_params_base.rb +24 -22
- data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
- data/lib/grape/validations/validators/presence_validator.rb +15 -0
- data/lib/grape/validations/validators/regexp_validator.rb +16 -0
- data/lib/grape/validations/validators/same_as_validator.rb +29 -0
- data/lib/grape/validations/validators/values_validator.rb +88 -0
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +59 -24
- data/spec/grape/api/custom_validations_spec.rb +77 -46
- data/spec/grape/api/deeply_included_options_spec.rb +3 -3
- data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -1
- data/spec/grape/api/invalid_format_spec.rb +2 -0
- data/spec/grape/api/recognize_path_spec.rb +1 -1
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -15
- data/spec/grape/api_remount_spec.rb +16 -15
- data/spec/grape/api_spec.rb +317 -193
- data/spec/grape/dsl/callbacks_spec.rb +1 -0
- data/spec/grape/dsl/headers_spec.rb +39 -9
- data/spec/grape/dsl/helpers_spec.rb +3 -2
- data/spec/grape/dsl/inside_route_spec.rb +6 -4
- data/spec/grape/dsl/logger_spec.rb +16 -18
- data/spec/grape/dsl/middleware_spec.rb +1 -0
- data/spec/grape/dsl/parameters_spec.rb +1 -0
- data/spec/grape/dsl/request_response_spec.rb +1 -0
- data/spec/grape/dsl/routing_spec.rb +9 -6
- data/spec/grape/endpoint/declared_spec.rb +12 -12
- data/spec/grape/endpoint_spec.rb +59 -50
- data/spec/grape/entity_spec.rb +13 -13
- data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -0
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -22
- data/spec/grape/exceptions/validation_errors_spec.rb +13 -10
- data/spec/grape/exceptions/validation_spec.rb +5 -3
- data/spec/grape/extensions/param_builders/hash_spec.rb +7 -7
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -8
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -8
- data/spec/grape/integration/rack_sendfile_spec.rb +1 -1
- data/spec/grape/loading_spec.rb +8 -8
- data/spec/grape/middleware/auth/dsl_spec.rb +14 -5
- data/spec/grape/middleware/auth/strategies_spec.rb +60 -20
- data/spec/grape/middleware/base_spec.rb +24 -15
- data/spec/grape/middleware/error_spec.rb +1 -0
- data/spec/grape/middleware/exception_spec.rb +111 -161
- data/spec/grape/middleware/formatter_spec.rb +25 -4
- data/spec/grape/middleware/globals_spec.rb +7 -4
- data/spec/grape/middleware/stack_spec.rb +11 -11
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -1
- data/spec/grape/middleware/versioner/header_spec.rb +14 -13
- data/spec/grape/middleware/versioner/param_spec.rb +7 -1
- data/spec/grape/middleware/versioner/path_spec.rb +5 -1
- data/spec/grape/middleware/versioner_spec.rb +1 -1
- data/spec/grape/parser_spec.rb +4 -0
- data/spec/grape/path_spec.rb +52 -52
- data/spec/grape/presenters/presenter_spec.rb +7 -6
- data/spec/grape/request_spec.rb +6 -4
- data/spec/grape/util/inheritable_setting_spec.rb +7 -7
- data/spec/grape/util/inheritable_values_spec.rb +3 -2
- data/spec/grape/util/reverse_stackable_values_spec.rb +3 -1
- data/spec/grape/util/stackable_values_spec.rb +7 -5
- data/spec/grape/validations/instance_behaivour_spec.rb +9 -10
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -0
- data/spec/grape/validations/params_scope_spec.rb +9 -7
- data/spec/grape/validations/single_attribute_iterator_spec.rb +1 -0
- data/spec/grape/validations/types/primitive_coercer_spec.rb +2 -2
- data/spec/grape/validations/types_spec.rb +8 -8
- data/spec/grape/validations/validators/all_or_none_spec.rb +50 -56
- data/spec/grape/validations/validators/allow_blank_spec.rb +136 -140
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -56
- data/spec/grape/validations/validators/coerce_spec.rb +10 -12
- data/spec/grape/validations/validators/default_spec.rb +72 -78
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -77
- data/spec/grape/validations/validators/except_values_spec.rb +1 -1
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -77
- data/spec/grape/validations/validators/presence_spec.rb +16 -1
- data/spec/grape/validations/validators/regexp_spec.rb +25 -31
- data/spec/grape/validations/validators/same_as_spec.rb +14 -20
- data/spec/grape/validations/validators/values_spec.rb +172 -171
- data/spec/grape/validations_spec.rb +45 -16
- data/spec/integration/eager_load/eager_load_spec.rb +2 -2
- data/spec/integration/multi_json/json_spec.rb +1 -1
- data/spec/integration/multi_xml/xml_spec.rb +1 -1
- data/spec/shared/versioning_examples.rb +10 -7
- data/spec/spec_helper.rb +11 -1
- metadata +116 -116
- data/lib/grape/validations/types/build_coercer.rb +0 -94
- data/lib/grape/validations/validators/all_or_none.rb +0 -16
- data/lib/grape/validations/validators/allow_blank.rb +0 -18
- data/lib/grape/validations/validators/as.rb +0 -12
- data/lib/grape/validations/validators/at_least_one_of.rb +0 -15
- data/lib/grape/validations/validators/coerce.rb +0 -87
- data/lib/grape/validations/validators/default.rb +0 -49
- data/lib/grape/validations/validators/exactly_one_of.rb +0 -17
- data/lib/grape/validations/validators/except_values.rb +0 -22
- data/lib/grape/validations/validators/mutual_exclusion.rb +0 -16
- data/lib/grape/validations/validators/presence.rb +0 -13
- data/lib/grape/validations/validators/regexp.rb +0 -14
- data/lib/grape/validations/validators/same_as.rb +0 -27
- data/lib/grape/validations/validators/values.rb +0 -86
@@ -12,21 +12,51 @@ module Grape
|
|
12
12
|
describe Headers do
|
13
13
|
subject { HeadersSpec::Dummy.new }
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
let(:header_data) do
|
16
|
+
{ 'First Key' => 'First Value',
|
17
|
+
'Second Key' => 'Second Value' }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when headers are set' do
|
21
|
+
describe '#header' do
|
17
22
|
before do
|
18
|
-
subject.header
|
23
|
+
header_data.each { |k, v| subject.header(k, v) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'get' do
|
27
|
+
it 'returns a specifc value' do
|
28
|
+
expect(subject.header['First Key']).to eq 'First Value'
|
29
|
+
expect(subject.header['Second Key']).to eq 'Second Value'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns all set headers' do
|
33
|
+
expect(subject.header).to eq header_data
|
34
|
+
expect(subject.headers).to eq header_data
|
35
|
+
end
|
19
36
|
end
|
20
37
|
|
21
|
-
|
22
|
-
|
23
|
-
|
38
|
+
describe 'set' do
|
39
|
+
it 'returns value' do
|
40
|
+
expect(subject.header('Third Key', 'Third Value'))
|
41
|
+
expect(subject.header['Third Key']).to eq 'Third Value'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'delete' do
|
46
|
+
it 'deletes a header key-value pair' do
|
47
|
+
expect(subject.header('First Key')).to eq header_data['First Key']
|
48
|
+
expect(subject.header).not_to have_key('First Key')
|
49
|
+
end
|
24
50
|
end
|
25
51
|
end
|
52
|
+
end
|
26
53
|
|
27
|
-
|
28
|
-
|
29
|
-
|
54
|
+
context 'when no headers are set' do
|
55
|
+
describe '#header' do
|
56
|
+
it 'returns nil' do
|
57
|
+
expect(subject.header['First Key']).to be nil
|
58
|
+
expect(subject.header('First Key')).to be nil
|
59
|
+
end
|
30
60
|
end
|
31
61
|
end
|
32
62
|
end
|
@@ -34,6 +34,7 @@ module Grape
|
|
34
34
|
|
35
35
|
describe Helpers do
|
36
36
|
subject { Class.new(HelpersSpec::Dummy) }
|
37
|
+
|
37
38
|
let(:proc) do
|
38
39
|
lambda do |*|
|
39
40
|
def test
|
@@ -54,7 +55,7 @@ module Grape
|
|
54
55
|
it 'uses provided modules' do
|
55
56
|
mod = Module.new
|
56
57
|
|
57
|
-
expect(subject).to receive(:namespace_stackable).with(:helpers, kind_of(Grape::DSL::Helpers::BaseHelper)).and_call_original.
|
58
|
+
expect(subject).to receive(:namespace_stackable).with(:helpers, kind_of(Grape::DSL::Helpers::BaseHelper)).and_call_original.twice
|
58
59
|
expect(subject).to receive(:namespace_stackable).with(:helpers).and_call_original
|
59
60
|
subject.helpers(mod, &proc)
|
60
61
|
|
@@ -92,7 +93,7 @@ module Grape
|
|
92
93
|
use :requires_toggle_prm
|
93
94
|
end
|
94
95
|
end
|
95
|
-
end.
|
96
|
+
end.not_to raise_exception
|
96
97
|
end
|
97
98
|
end
|
98
99
|
end
|
@@ -43,6 +43,7 @@ describe Grape::Endpoint do
|
|
43
43
|
before do
|
44
44
|
catch(:error) { subject.error! 'Not Found', 404 }
|
45
45
|
end
|
46
|
+
|
46
47
|
it 'sets status' do
|
47
48
|
expect(subject.status).to eq 404
|
48
49
|
end
|
@@ -53,6 +54,7 @@ describe Grape::Endpoint do
|
|
53
54
|
subject.namespace_inheritable(:default_error_status, 500)
|
54
55
|
catch(:error) { subject.error! 'Unknown' }
|
55
56
|
end
|
57
|
+
|
56
58
|
it 'sets status to default_error_status' do
|
57
59
|
expect(subject.status).to eq 500
|
58
60
|
end
|
@@ -136,7 +138,7 @@ describe Grape::Endpoint do
|
|
136
138
|
end
|
137
139
|
|
138
140
|
it 'accepts unknown Integer status codes' do
|
139
|
-
expect { subject.status 210 }.
|
141
|
+
expect { subject.status 210 }.not_to raise_error
|
140
142
|
end
|
141
143
|
|
142
144
|
it 'raises error if status is not a integer or symbol' do
|
@@ -273,7 +275,7 @@ describe Grape::Endpoint do
|
|
273
275
|
end
|
274
276
|
|
275
277
|
it 'sends no deprecation warnings' do
|
276
|
-
expect(subject).
|
278
|
+
expect(subject).not_to receive(:warn)
|
277
279
|
|
278
280
|
subject.sendfile file_path
|
279
281
|
end
|
@@ -334,7 +336,7 @@ describe Grape::Endpoint do
|
|
334
336
|
end
|
335
337
|
|
336
338
|
it 'emits no deprecation warnings' do
|
337
|
-
expect(subject).
|
339
|
+
expect(subject).not_to receive(:warn)
|
338
340
|
|
339
341
|
subject.stream file_path
|
340
342
|
end
|
@@ -384,7 +386,7 @@ describe Grape::Endpoint do
|
|
384
386
|
end
|
385
387
|
|
386
388
|
it 'emits no deprecation warnings' do
|
387
|
-
expect(subject).
|
389
|
+
expect(subject).not_to receive(:warn)
|
388
390
|
|
389
391
|
subject.stream stream_object
|
390
392
|
end
|
@@ -2,27 +2,25 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
describe Grape::DSL::Logger do
|
6
|
+
subject { Class.new(dummy_logger) }
|
7
|
+
|
8
|
+
let(:dummy_logger) do
|
9
|
+
Class.new do
|
10
|
+
extend Grape::DSL::Logger
|
11
11
|
end
|
12
|
-
|
13
|
-
subject { Class.new(LoggerSpec::Dummy) }
|
14
|
-
let(:logger) { double(:logger) }
|
12
|
+
end
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
let(:logger) { instance_double(::Logger) }
|
15
|
+
|
16
|
+
describe '.logger' do
|
17
|
+
it 'sets a logger' do
|
18
|
+
subject.logger logger
|
19
|
+
expect(subject.logger).to eq logger
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
22
|
+
it 'returns a logger' do
|
23
|
+
expect(subject.logger(logger)).to eq logger
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
@@ -12,6 +12,7 @@ module Grape
|
|
12
12
|
|
13
13
|
describe Routing do
|
14
14
|
subject { Class.new(RoutingSpec::Dummy) }
|
15
|
+
|
15
16
|
let(:proc) { -> {} }
|
16
17
|
let(:options) { { a: :b } }
|
17
18
|
let(:path) { '/dummy' }
|
@@ -109,7 +110,7 @@ module Grape
|
|
109
110
|
it 'does not duplicate identical endpoints' do
|
110
111
|
subject.route(:any)
|
111
112
|
expect { subject.route(:any) }
|
112
|
-
.
|
113
|
+
.not_to change(subject.endpoints, :count)
|
113
114
|
end
|
114
115
|
|
115
116
|
it 'generates correct endpoint options' do
|
@@ -233,21 +234,23 @@ module Grape
|
|
233
234
|
allow(subject).to receive(:prepare_routes).and_return(routes)
|
234
235
|
subject.routes
|
235
236
|
end
|
236
|
-
|
237
|
-
|
237
|
+
|
238
|
+
it 'does not call prepare_routes again' do
|
239
|
+
expect(subject).not_to receive(:prepare_routes)
|
238
240
|
expect(subject.routes).to eq routes
|
239
241
|
end
|
240
242
|
end
|
241
243
|
end
|
242
244
|
|
243
245
|
describe '.route_param' do
|
246
|
+
let!(:options) { { requirements: regex } }
|
247
|
+
let(:regex) { /(.*)/ }
|
248
|
+
|
244
249
|
it 'calls #namespace with given params' do
|
245
250
|
expect(subject).to receive(:namespace).with(':foo', {}).and_yield
|
246
251
|
subject.route_param('foo', {}, &proc {})
|
247
252
|
end
|
248
253
|
|
249
|
-
let(:regex) { /(.*)/ }
|
250
|
-
let!(:options) { { requirements: regex } }
|
251
254
|
it 'nests requirements option under param name' do
|
252
255
|
expect(subject).to receive(:namespace) do |_param, options|
|
253
256
|
expect(options[:requirements][:foo]).to eq regex
|
@@ -258,7 +261,7 @@ module Grape
|
|
258
261
|
it 'does not modify options parameter' do
|
259
262
|
allow(subject).to receive(:namespace)
|
260
263
|
expect { subject.route_param('foo', options, &proc {}) }
|
261
|
-
.
|
264
|
+
.not_to change { options }
|
262
265
|
end
|
263
266
|
end
|
264
267
|
|
@@ -87,7 +87,7 @@ describe Grape::Endpoint do
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
it '
|
90
|
+
it 'shows nil for nested params if include_missing is true' do
|
91
91
|
subject.get '/declared' do
|
92
92
|
declared(params, include_missing: true)
|
93
93
|
end
|
@@ -97,7 +97,7 @@ describe Grape::Endpoint do
|
|
97
97
|
expect(JSON.parse(last_response.body)['nested']['fourth']).to be_nil
|
98
98
|
end
|
99
99
|
|
100
|
-
it '
|
100
|
+
it 'shows nil for multiple allowed types if include_missing is true' do
|
101
101
|
subject.get '/declared' do
|
102
102
|
declared(params, include_missing: true)
|
103
103
|
end
|
@@ -568,34 +568,34 @@ describe Grape::Endpoint do
|
|
568
568
|
get '/artists/1'
|
569
569
|
json = JSON.parse(last_response.body, symbolize_names: true)
|
570
570
|
|
571
|
-
expect(json.
|
572
|
-
expect(json.
|
571
|
+
expect(json).to be_key(:id)
|
572
|
+
expect(json).not_to be_key(:artist_id)
|
573
573
|
end
|
574
574
|
|
575
575
|
it 'return only :artist_id without :id' do
|
576
576
|
get '/artists/1/compositions'
|
577
577
|
json = JSON.parse(last_response.body, symbolize_names: true)
|
578
578
|
|
579
|
-
expect(json.
|
580
|
-
expect(json.
|
579
|
+
expect(json).to be_key(:artist_id)
|
580
|
+
expect(json).not_to be_key(:id)
|
581
581
|
end
|
582
582
|
|
583
583
|
it 'return :filter and :id parameters in declared for second enpoint inside route_param' do
|
584
584
|
get '/artists/1/some_route', filter: 'some_filter'
|
585
585
|
json = JSON.parse(last_response.body, symbolize_names: true)
|
586
586
|
|
587
|
-
expect(json.
|
588
|
-
expect(json.
|
589
|
-
expect(json.
|
587
|
+
expect(json).to be_key(:filter)
|
588
|
+
expect(json).to be_key(:id)
|
589
|
+
expect(json).not_to be_key(:artist_id)
|
590
590
|
end
|
591
591
|
|
592
592
|
it 'return :compositor_id for mounter in route_param' do
|
593
593
|
get '/artists/1/albums'
|
594
594
|
json = JSON.parse(last_response.body, symbolize_names: true)
|
595
595
|
|
596
|
-
expect(json.
|
597
|
-
expect(json.
|
598
|
-
expect(json.
|
596
|
+
expect(json).to be_key(:compositor_id)
|
597
|
+
expect(json).not_to be_key(:id)
|
598
|
+
expect(json).not_to be_key(:artist_id)
|
599
599
|
end
|
600
600
|
end
|
601
601
|
|