grape 1.3.3 → 1.6.2
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 +111 -2
- data/CONTRIBUTING.md +2 -1
- data/README.md +135 -23
- data/UPGRADING.md +237 -46
- data/grape.gemspec +5 -5
- data/lib/grape/api/instance.rb +34 -42
- data/lib/grape/api.rb +21 -16
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dsl/callbacks.rb +1 -1
- data/lib/grape/dsl/desc.rb +3 -5
- data/lib/grape/dsl/headers.rb +5 -2
- data/lib/grape/dsl/helpers.rb +8 -5
- data/lib/grape/dsl/inside_route.rb +72 -53
- data/lib/grape/dsl/middleware.rb +4 -4
- data/lib/grape/dsl/parameters.rb +11 -7
- data/lib/grape/dsl/request_response.rb +9 -6
- data/lib/grape/dsl/routing.rb +8 -9
- data/lib/grape/dsl/settings.rb +5 -5
- data/lib/grape/dsl/validations.rb +18 -1
- data/lib/grape/eager_load.rb +1 -1
- data/lib/grape/endpoint.rb +29 -42
- data/lib/grape/error_formatter/json.rb +2 -6
- data/lib/grape/error_formatter/xml.rb +2 -6
- data/lib/grape/exceptions/empty_message_body.rb +11 -0
- data/lib/grape/exceptions/validation.rb +2 -3
- data/lib/grape/exceptions/validation_errors.rb +1 -1
- data/lib/grape/formatter/json.rb +1 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -1
- data/lib/grape/formatter/xml.rb +1 -0
- data/lib/grape/locale/en.yml +1 -1
- data/lib/grape/middleware/auth/base.rb +3 -3
- data/lib/grape/middleware/auth/dsl.rb +7 -1
- data/lib/grape/middleware/base.rb +6 -3
- data/lib/grape/middleware/error.rb +11 -13
- data/lib/grape/middleware/formatter.rb +7 -7
- data/lib/grape/middleware/stack.rb +10 -3
- data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
- data/lib/grape/middleware/versioner/header.rb +6 -4
- data/lib/grape/middleware/versioner/param.rb +1 -0
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
- data/lib/grape/middleware/versioner/path.rb +2 -0
- data/lib/grape/parser/json.rb +1 -1
- data/lib/grape/parser/xml.rb +1 -1
- data/lib/grape/path.rb +1 -0
- data/lib/grape/request.rb +4 -1
- data/lib/grape/router/attribute_translator.rb +3 -3
- data/lib/grape/router/pattern.rb +1 -1
- data/lib/grape/router/route.rb +2 -2
- data/lib/grape/router.rb +31 -30
- data/lib/grape/{serve_file → serve_stream}/file_body.rb +1 -1
- data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +1 -1
- data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +8 -8
- data/lib/grape/util/base_inheritable.rb +2 -2
- data/lib/grape/util/inheritable_setting.rb +1 -3
- data/lib/grape/util/lazy_value.rb +4 -2
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/attributes_iterator.rb +8 -0
- data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
- data/lib/grape/validations/params_scope.rb +97 -62
- data/lib/grape/validations/single_attribute_iterator.rb +1 -1
- data/lib/grape/validations/types/custom_type_coercer.rb +16 -3
- data/lib/grape/validations/types/dry_type_coercer.rb +1 -1
- data/lib/grape/validations/types/invalid_value.rb +24 -0
- data/lib/grape/validations/types/json.rb +2 -1
- data/lib/grape/validations/types/primitive_coercer.rb +4 -5
- data/lib/grape/validations/types.rb +1 -4
- data/lib/grape/validations/validator_factory.rb +1 -1
- data/lib/grape/validations/validators/all_or_none.rb +8 -5
- data/lib/grape/validations/validators/allow_blank.rb +9 -7
- data/lib/grape/validations/validators/as.rb +6 -8
- data/lib/grape/validations/validators/at_least_one_of.rb +7 -4
- data/lib/grape/validations/validators/base.rb +74 -69
- data/lib/grape/validations/validators/coerce.rb +63 -76
- data/lib/grape/validations/validators/default.rb +36 -34
- data/lib/grape/validations/validators/exactly_one_of.rb +9 -6
- data/lib/grape/validations/validators/except_values.rb +13 -11
- data/lib/grape/validations/validators/multiple_params_base.rb +24 -19
- data/lib/grape/validations/validators/mutual_exclusion.rb +8 -5
- data/lib/grape/validations/validators/presence.rb +7 -4
- data/lib/grape/validations/validators/regexp.rb +8 -5
- data/lib/grape/validations/validators/same_as.rb +18 -15
- data/lib/grape/validations/validators/values.rb +61 -56
- data/lib/grape/validations.rb +6 -0
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +7 -3
- data/spec/grape/api/custom_validations_spec.rb +77 -45
- 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/routes_with_requirements_spec.rb +8 -8
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -15
- data/spec/grape/api_remount_spec.rb +25 -19
- data/spec/grape/api_spec.rb +576 -211
- data/spec/grape/dsl/callbacks_spec.rb +2 -1
- 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 +185 -34
- data/spec/grape/dsl/logger_spec.rb +16 -18
- data/spec/grape/dsl/middleware_spec.rb +2 -1
- data/spec/grape/dsl/parameters_spec.rb +2 -0
- data/spec/grape/dsl/request_response_spec.rb +1 -0
- data/spec/grape/dsl/routing_spec.rb +10 -7
- data/spec/grape/endpoint/declared_spec.rb +848 -0
- data/spec/grape/endpoint_spec.rb +77 -589
- data/spec/grape/entity_spec.rb +29 -23
- 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 +13 -9
- data/spec/grape/loading_spec.rb +8 -8
- data/spec/grape/middleware/auth/dsl_spec.rb +15 -6
- data/spec/grape/middleware/auth/strategies_spec.rb +61 -21
- data/spec/grape/middleware/base_spec.rb +24 -15
- data/spec/grape/middleware/error_spec.rb +3 -3
- data/spec/grape/middleware/exception_spec.rb +111 -161
- data/spec/grape/middleware/formatter_spec.rb +28 -7
- data/spec/grape/middleware/globals_spec.rb +7 -4
- data/spec/grape/middleware/stack_spec.rb +15 -12
- 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 +14 -3
- data/spec/grape/validations/params_scope_spec.rb +72 -10
- data/spec/grape/validations/single_attribute_iterator_spec.rb +18 -6
- data/spec/grape/validations/types/primitive_coercer_spec.rb +63 -7
- 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 +248 -33
- data/spec/grape/validations/validators/default_spec.rb +121 -78
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -77
- data/spec/grape/validations/validators/except_values_spec.rb +4 -3
- 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 +183 -178
- data/spec/grape/validations_spec.rb +342 -29
- data/spec/integration/eager_load/eager_load_spec.rb +15 -0
- 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 +32 -29
- data/spec/spec_helper.rb +12 -12
- data/spec/support/basic_auth_encode_helpers.rb +1 -1
- data/spec/support/chunks.rb +14 -0
- data/spec/support/versioned_helpers.rb +4 -6
- metadata +110 -102
@@ -31,11 +31,13 @@ describe Grape::Endpoint do
|
|
31
31
|
expect(last_response.status).to eq 200
|
32
32
|
expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: nil))
|
33
33
|
end
|
34
|
+
|
34
35
|
it 'json format' do
|
35
36
|
get '/foo.json'
|
36
37
|
expect(last_response.status).to eq 200
|
37
38
|
expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: 'json'))
|
38
39
|
end
|
40
|
+
|
39
41
|
it 'invalid format' do
|
40
42
|
get '/foo.invalid'
|
41
43
|
expect(last_response.status).to eq 200
|
@@ -11,7 +11,7 @@ describe Grape::Endpoint do
|
|
11
11
|
|
12
12
|
context 'get' do
|
13
13
|
it 'routes to a namespace param with dots' do
|
14
|
-
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[
|
14
|
+
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
|
15
15
|
get '/' do
|
16
16
|
params[:ns_with_dots]
|
17
17
|
end
|
@@ -23,8 +23,8 @@ describe Grape::Endpoint do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'routes to a path with multiple params with dots' do
|
26
|
-
subject.get ':id_with_dots/:another_id_with_dots', requirements: { id_with_dots: %r{[
|
27
|
-
another_id_with_dots: %r{[
|
26
|
+
subject.get ':id_with_dots/:another_id_with_dots', requirements: { id_with_dots: %r{[^/]+},
|
27
|
+
another_id_with_dots: %r{[^/]+} } do
|
28
28
|
"#{params[:id_with_dots]}/#{params[:another_id_with_dots]}"
|
29
29
|
end
|
30
30
|
|
@@ -34,9 +34,9 @@ describe Grape::Endpoint do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'routes to namespace and path params with dots, with overridden requirements' do
|
37
|
-
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[
|
38
|
-
get ':another_id_with_dots', requirements: { ns_with_dots: %r{[
|
39
|
-
another_id_with_dots: %r{[
|
37
|
+
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
|
38
|
+
get ':another_id_with_dots', requirements: { ns_with_dots: %r{[^/]+},
|
39
|
+
another_id_with_dots: %r{[^/]+} } do
|
40
40
|
"#{params[:ns_with_dots]}/#{params[:another_id_with_dots]}"
|
41
41
|
end
|
42
42
|
end
|
@@ -47,8 +47,8 @@ describe Grape::Endpoint do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'routes to namespace and path params with dots, with merged requirements' do
|
50
|
-
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[
|
51
|
-
get ':another_id_with_dots', requirements: { another_id_with_dots: %r{[
|
50
|
+
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
|
51
|
+
get ':another_id_with_dots', requirements: { another_id_with_dots: %r{[^/]+} } do
|
52
52
|
"#{params[:ns_with_dots]}/#{params[:another_id_with_dots]}"
|
53
53
|
end
|
54
54
|
end
|
@@ -3,19 +3,17 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Grape::API::Helpers do
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
let(:app) do
|
7
|
+
Class.new(Grape::API) do
|
8
|
+
helpers Module.new do
|
9
|
+
extend Grape::API::Helpers
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
params :drink do
|
12
|
+
optional :beer
|
13
|
+
optional :wine
|
14
|
+
exactly_one_of :beer, :wine
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
16
|
-
|
17
|
-
Class.new(Grape::API) do
|
18
|
-
helpers shared_params
|
19
17
|
format :json
|
20
18
|
|
21
19
|
params do
|
@@ -35,10 +33,6 @@ describe Grape::API::Helpers do
|
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
38
|
-
def app
|
39
|
-
subject
|
40
|
-
end
|
41
|
-
|
42
36
|
it 'defines parameters' do
|
43
37
|
get '/', orderType: 'food', pizza: 'mista'
|
44
38
|
expect(last_response.status).to eq 200
|
@@ -4,8 +4,9 @@ require 'spec_helper'
|
|
4
4
|
require 'shared/versioning_examples'
|
5
5
|
|
6
6
|
describe Grape::API do
|
7
|
-
subject(:a_remounted_api) { Class.new(
|
8
|
-
|
7
|
+
subject(:a_remounted_api) { Class.new(described_class) }
|
8
|
+
|
9
|
+
let(:root_api) { Class.new(described_class) }
|
9
10
|
|
10
11
|
def app
|
11
12
|
root_api
|
@@ -68,7 +69,7 @@ describe Grape::API do
|
|
68
69
|
describe 'with dynamic configuration' do
|
69
70
|
context 'when mounting an endpoint conditional on a configuration' do
|
70
71
|
subject(:a_remounted_api) do
|
71
|
-
Class.new(
|
72
|
+
Class.new(described_class) do
|
72
73
|
get 'always' do
|
73
74
|
'success'
|
74
75
|
end
|
@@ -101,7 +102,7 @@ describe Grape::API do
|
|
101
102
|
|
102
103
|
context 'when using an expression derived from a configuration' do
|
103
104
|
subject(:a_remounted_api) do
|
104
|
-
Class.new(
|
105
|
+
Class.new(described_class) do
|
105
106
|
get(mounted { "api_name_#{configuration[:api_name]}" }) do
|
106
107
|
'success'
|
107
108
|
end
|
@@ -126,7 +127,7 @@ describe Grape::API do
|
|
126
127
|
|
127
128
|
context 'when the expression lives in a namespace' do
|
128
129
|
subject(:a_remounted_api) do
|
129
|
-
Class.new(
|
130
|
+
Class.new(described_class) do
|
130
131
|
namespace :base do
|
131
132
|
get(mounted { "api_name_#{configuration[:api_name]}" }) do
|
132
133
|
'success'
|
@@ -149,7 +150,7 @@ describe Grape::API do
|
|
149
150
|
|
150
151
|
context 'when executing a standard block within a `mounted` block with all dynamic params' do
|
151
152
|
subject(:a_remounted_api) do
|
152
|
-
Class.new(
|
153
|
+
Class.new(described_class) do
|
153
154
|
mounted do
|
154
155
|
desc configuration[:description] do
|
155
156
|
headers configuration[:headers]
|
@@ -191,7 +192,7 @@ describe Grape::API do
|
|
191
192
|
|
192
193
|
context 'when executing a custom block on mount' do
|
193
194
|
subject(:a_remounted_api) do
|
194
|
-
Class.new(
|
195
|
+
Class.new(described_class) do
|
195
196
|
get 'always' do
|
196
197
|
'success'
|
197
198
|
end
|
@@ -215,7 +216,7 @@ describe Grape::API do
|
|
215
216
|
|
216
217
|
context 'when the configuration is part of the arguments of a method' do
|
217
218
|
subject(:a_remounted_api) do
|
218
|
-
Class.new(
|
219
|
+
Class.new(described_class) do
|
219
220
|
get configuration[:endpoint_name] do
|
220
221
|
'success'
|
221
222
|
end
|
@@ -237,7 +238,7 @@ describe Grape::API do
|
|
237
238
|
|
238
239
|
context 'when the configuration is the value in a key-arg pair' do
|
239
240
|
subject(:a_remounted_api) do
|
240
|
-
Class.new(
|
241
|
+
Class.new(described_class) do
|
241
242
|
version 'v1', using: :param, parameter: configuration[:version_param]
|
242
243
|
get 'endpoint' do
|
243
244
|
'version 1'
|
@@ -267,7 +268,7 @@ describe Grape::API do
|
|
267
268
|
|
268
269
|
context 'on the DescSCope' do
|
269
270
|
subject(:a_remounted_api) do
|
270
|
-
Class.new(
|
271
|
+
Class.new(described_class) do
|
271
272
|
desc 'The description of this' do
|
272
273
|
tags ['not_configurable_tag', configuration[:a_configurable_tag]]
|
273
274
|
end
|
@@ -284,7 +285,7 @@ describe Grape::API do
|
|
284
285
|
|
285
286
|
context 'on the ParamScope' do
|
286
287
|
subject(:a_remounted_api) do
|
287
|
-
Class.new(
|
288
|
+
Class.new(described_class) do
|
288
289
|
params do
|
289
290
|
requires configuration[:required_param], type: configuration[:required_type]
|
290
291
|
end
|
@@ -314,7 +315,7 @@ describe Grape::API do
|
|
314
315
|
|
315
316
|
context 'on dynamic checks' do
|
316
317
|
subject(:a_remounted_api) do
|
317
|
-
Class.new(
|
318
|
+
Class.new(described_class) do
|
318
319
|
params do
|
319
320
|
optional :restricted_values, values: -> { [configuration[:allowed_value], 'always'] }
|
320
321
|
end
|
@@ -340,25 +341,30 @@ describe Grape::API do
|
|
340
341
|
context 'when the configuration is read within a namespace' do
|
341
342
|
before do
|
342
343
|
a_remounted_api.namespace 'api' do
|
344
|
+
params do
|
345
|
+
requires configuration[:required_param]
|
346
|
+
end
|
343
347
|
get "/#{configuration[:path]}" do
|
344
348
|
'10 votes'
|
345
349
|
end
|
346
350
|
end
|
347
|
-
root_api.mount a_remounted_api, with: { path: 'votes' }
|
348
|
-
root_api.mount a_remounted_api, with: { path: 'scores' }
|
351
|
+
root_api.mount a_remounted_api, with: { path: 'votes', required_param: 'param_key' }
|
352
|
+
root_api.mount a_remounted_api, with: { path: 'scores', required_param: 'param_key' }
|
349
353
|
end
|
350
354
|
|
351
355
|
it 'will use the dynamic configuration on all routes' do
|
352
|
-
get 'api/votes'
|
356
|
+
get 'api/votes', param_key: 'a'
|
353
357
|
expect(last_response.body).to eql '10 votes'
|
354
|
-
get 'api/scores'
|
358
|
+
get 'api/scores', param_key: 'a'
|
355
359
|
expect(last_response.body).to eql '10 votes'
|
360
|
+
get 'api/votes'
|
361
|
+
expect(last_response.status).to eq 400
|
356
362
|
end
|
357
363
|
end
|
358
364
|
|
359
365
|
context 'a very complex configuration example' do
|
360
366
|
before do
|
361
|
-
top_level_api = Class.new(
|
367
|
+
top_level_api = Class.new(described_class) do
|
362
368
|
remounted_api = Class.new(Grape::API) do
|
363
369
|
get configuration[:endpoint_name] do
|
364
370
|
configuration[:response]
|
@@ -426,7 +432,7 @@ describe Grape::API do
|
|
426
432
|
|
427
433
|
context 'when the configuration is read in a helper' do
|
428
434
|
subject(:a_remounted_api) do
|
429
|
-
Class.new(
|
435
|
+
Class.new(described_class) do
|
430
436
|
helpers do
|
431
437
|
def printed_response
|
432
438
|
configuration[:some_value]
|
@@ -449,7 +455,7 @@ describe Grape::API do
|
|
449
455
|
|
450
456
|
context 'when the configuration is read within the response block' do
|
451
457
|
subject(:a_remounted_api) do
|
452
|
-
Class.new(
|
458
|
+
Class.new(described_class) do
|
453
459
|
get 'location' do
|
454
460
|
configuration[:some_value]
|
455
461
|
end
|