grape 1.1.0 → 1.5.3
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 +278 -44
- data/LICENSE +1 -1
- data/README.md +514 -69
- data/UPGRADING.md +424 -17
- data/grape.gemspec +13 -2
- data/lib/grape.rb +104 -71
- data/lib/grape/api.rb +138 -175
- data/lib/grape/api/helpers.rb +2 -0
- data/lib/grape/api/instance.rb +283 -0
- data/lib/grape/config.rb +34 -0
- data/lib/grape/content_types.rb +34 -0
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dsl/api.rb +2 -0
- data/lib/grape/dsl/callbacks.rb +22 -0
- data/lib/grape/dsl/configuration.rb +2 -0
- data/lib/grape/dsl/desc.rb +41 -7
- data/lib/grape/dsl/headers.rb +2 -0
- data/lib/grape/dsl/helpers.rb +5 -2
- data/lib/grape/dsl/inside_route.rb +92 -49
- data/lib/grape/dsl/logger.rb +2 -0
- data/lib/grape/dsl/middleware.rb +9 -0
- data/lib/grape/dsl/parameters.rb +25 -14
- data/lib/grape/dsl/request_response.rb +4 -2
- data/lib/grape/dsl/routing.rb +17 -10
- data/lib/grape/dsl/settings.rb +7 -1
- data/lib/grape/dsl/validations.rb +24 -4
- data/lib/grape/eager_load.rb +20 -0
- data/lib/grape/endpoint.rb +59 -35
- data/lib/grape/error_formatter.rb +4 -2
- data/lib/grape/error_formatter/base.rb +2 -0
- data/lib/grape/error_formatter/json.rb +2 -0
- data/lib/grape/error_formatter/txt.rb +2 -0
- data/lib/grape/error_formatter/xml.rb +2 -0
- data/lib/grape/exceptions/base.rb +20 -14
- data/lib/grape/exceptions/empty_message_body.rb +11 -0
- data/lib/grape/exceptions/incompatible_option_values.rb +2 -0
- data/lib/grape/exceptions/invalid_accept_header.rb +2 -0
- data/lib/grape/exceptions/invalid_formatter.rb +2 -0
- data/lib/grape/exceptions/invalid_message_body.rb +2 -0
- data/lib/grape/exceptions/invalid_response.rb +11 -0
- data/lib/grape/exceptions/invalid_version_header.rb +2 -0
- data/lib/grape/exceptions/invalid_versioner_option.rb +2 -0
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +2 -0
- data/lib/grape/exceptions/method_not_allowed.rb +2 -0
- data/lib/grape/exceptions/missing_group_type.rb +2 -0
- data/lib/grape/exceptions/missing_mime_type.rb +2 -0
- data/lib/grape/exceptions/missing_option.rb +2 -0
- data/lib/grape/exceptions/missing_vendor_option.rb +2 -0
- data/lib/grape/exceptions/unknown_options.rb +2 -0
- data/lib/grape/exceptions/unknown_parameter.rb +2 -0
- data/lib/grape/exceptions/unknown_validator.rb +2 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +2 -0
- data/lib/grape/exceptions/validation.rb +4 -2
- data/lib/grape/exceptions/validation_array_errors.rb +2 -0
- data/lib/grape/exceptions/validation_errors.rb +16 -13
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +4 -3
- data/lib/grape/extensions/deep_mergeable_hash.rb +2 -0
- data/lib/grape/extensions/deep_symbolize_hash.rb +2 -0
- data/lib/grape/extensions/hash.rb +2 -0
- data/lib/grape/extensions/hashie/mash.rb +2 -0
- data/lib/grape/formatter.rb +5 -3
- data/lib/grape/formatter/json.rb +2 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -0
- data/lib/grape/formatter/txt.rb +2 -0
- data/lib/grape/formatter/xml.rb +2 -0
- data/lib/grape/http/headers.rb +50 -18
- data/lib/grape/locale/en.yml +3 -1
- data/lib/grape/middleware/auth/base.rb +7 -7
- data/lib/grape/middleware/auth/dsl.rb +2 -0
- data/lib/grape/middleware/auth/strategies.rb +2 -0
- data/lib/grape/middleware/auth/strategy_info.rb +2 -0
- data/lib/grape/middleware/base.rb +10 -7
- data/lib/grape/middleware/error.rb +21 -16
- data/lib/grape/middleware/filter.rb +2 -0
- data/lib/grape/middleware/formatter.rb +8 -6
- data/lib/grape/middleware/globals.rb +2 -0
- data/lib/grape/middleware/helpers.rb +12 -0
- data/lib/grape/middleware/stack.rb +13 -3
- data/lib/grape/middleware/versioner.rb +2 -0
- data/lib/grape/middleware/versioner/accept_version_header.rb +2 -0
- data/lib/grape/middleware/versioner/header.rb +10 -8
- data/lib/grape/middleware/versioner/param.rb +3 -1
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +4 -1
- data/lib/grape/middleware/versioner/path.rb +3 -1
- data/lib/grape/namespace.rb +14 -2
- data/lib/grape/parser.rb +4 -2
- data/lib/grape/parser/json.rb +3 -1
- data/lib/grape/parser/xml.rb +3 -1
- data/lib/grape/path.rb +15 -3
- data/lib/grape/presenters/presenter.rb +2 -0
- data/lib/grape/request.rb +19 -10
- data/lib/grape/router.rb +30 -29
- data/lib/grape/router/attribute_translator.rb +41 -8
- data/lib/grape/router/pattern.rb +20 -16
- data/lib/grape/router/route.rb +14 -28
- data/lib/grape/{serve_file → serve_stream}/file_body.rb +3 -1
- data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +3 -1
- data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +10 -8
- data/lib/grape/util/base_inheritable.rb +43 -0
- data/lib/grape/util/cache.rb +20 -0
- data/lib/grape/util/endpoint_configuration.rb +8 -0
- data/lib/grape/util/env.rb +19 -17
- data/lib/grape/util/inheritable_setting.rb +2 -0
- data/lib/grape/util/inheritable_values.rb +7 -25
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/lazy_block.rb +27 -0
- data/lib/grape/util/lazy_object.rb +43 -0
- data/lib/grape/util/lazy_value.rb +98 -0
- data/lib/grape/util/registrable.rb +2 -0
- data/lib/grape/util/reverse_stackable_values.rb +10 -35
- data/lib/grape/util/stackable_values.rb +21 -34
- data/lib/grape/util/strict_hash_configuration.rb +2 -0
- data/lib/grape/util/xml.rb +2 -0
- data/lib/grape/validations.rb +2 -0
- data/lib/grape/validations/attributes_iterator.rb +16 -6
- data/lib/grape/validations/multiple_attributes_iterator.rb +13 -0
- data/lib/grape/validations/params_scope.rb +51 -30
- data/lib/grape/validations/single_attribute_iterator.rb +24 -0
- data/lib/grape/validations/types.rb +13 -38
- data/lib/grape/validations/types/array_coercer.rb +65 -0
- data/lib/grape/validations/types/build_coercer.rb +47 -49
- data/lib/grape/validations/types/custom_type_coercer.rb +29 -51
- data/lib/grape/validations/types/custom_type_collection_coercer.rb +10 -25
- data/lib/grape/validations/types/dry_type_coercer.rb +76 -0
- data/lib/grape/validations/types/file.rb +22 -18
- data/lib/grape/validations/types/invalid_value.rb +24 -0
- data/lib/grape/validations/types/json.rb +46 -39
- data/lib/grape/validations/types/multiple_type_coercer.rb +14 -33
- data/lib/grape/validations/types/primitive_coercer.rb +67 -0
- data/lib/grape/validations/types/set_coercer.rb +40 -0
- data/lib/grape/validations/types/variant_collection_coercer.rb +5 -13
- data/lib/grape/validations/validator_factory.rb +8 -11
- data/lib/grape/validations/validators/all_or_none.rb +8 -13
- data/lib/grape/validations/validators/allow_blank.rb +3 -1
- data/lib/grape/validations/validators/as.rb +5 -4
- data/lib/grape/validations/validators/at_least_one_of.rb +7 -13
- data/lib/grape/validations/validators/base.rb +20 -16
- data/lib/grape/validations/validators/coerce.rb +46 -29
- data/lib/grape/validations/validators/default.rb +6 -6
- data/lib/grape/validations/validators/exactly_one_of.rb +10 -23
- data/lib/grape/validations/validators/except_values.rb +4 -2
- data/lib/grape/validations/validators/multiple_params_base.rb +17 -10
- data/lib/grape/validations/validators/mutual_exclusion.rb +8 -18
- data/lib/grape/validations/validators/presence.rb +3 -1
- data/lib/grape/validations/validators/regexp.rb +4 -2
- data/lib/grape/validations/validators/same_as.rb +26 -0
- data/lib/grape/validations/validators/values.rb +18 -6
- data/lib/grape/version.rb +3 -1
- data/spec/grape/api/custom_validations_spec.rb +5 -3
- data/spec/grape/api/deeply_included_options_spec.rb +2 -0
- data/spec/grape/api/defines_boolean_in_params_spec.rb +39 -0
- data/spec/grape/api/inherited_helpers_spec.rb +2 -0
- data/spec/grape/api/instance_spec.rb +104 -0
- data/spec/grape/api/invalid_format_spec.rb +2 -0
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/nested_helpers_spec.rb +2 -0
- data/spec/grape/api/optional_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/parameters_modification_spec.rb +3 -1
- data/spec/grape/api/patch_method_helpers_spec.rb +2 -0
- data/spec/grape/api/recognize_path_spec.rb +2 -0
- data/spec/grape/api/required_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +2 -0
- data/spec/grape/api/routes_with_requirements_spec.rb +61 -0
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +2 -0
- data/spec/grape/api/shared_helpers_spec.rb +2 -0
- data/spec/grape/api_remount_spec.rb +473 -0
- data/spec/grape/api_spec.rb +565 -12
- data/spec/grape/config_spec.rb +19 -0
- data/spec/grape/dsl/callbacks_spec.rb +2 -0
- data/spec/grape/dsl/configuration_spec.rb +2 -0
- data/spec/grape/dsl/desc_spec.rb +42 -16
- data/spec/grape/dsl/headers_spec.rb +2 -0
- data/spec/grape/dsl/helpers_spec.rb +4 -2
- data/spec/grape/dsl/inside_route_spec.rb +184 -33
- data/spec/grape/dsl/logger_spec.rb +2 -0
- data/spec/grape/dsl/middleware_spec.rb +10 -0
- data/spec/grape/dsl/parameters_spec.rb +2 -0
- data/spec/grape/dsl/request_response_spec.rb +2 -0
- data/spec/grape/dsl/routing_spec.rb +12 -0
- data/spec/grape/dsl/settings_spec.rb +2 -0
- data/spec/grape/dsl/validations_spec.rb +2 -0
- data/spec/grape/endpoint/declared_spec.rb +601 -0
- data/spec/grape/endpoint_spec.rb +53 -523
- data/spec/grape/entity_spec.rb +9 -1
- data/spec/grape/exceptions/base_spec.rb +67 -0
- data/spec/grape/exceptions/body_parse_errors_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_formatter_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_response_spec.rb +13 -0
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +2 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +2 -0
- data/spec/grape/exceptions/missing_option_spec.rb +2 -0
- data/spec/grape/exceptions/unknown_options_spec.rb +2 -0
- data/spec/grape/exceptions/unknown_validator_spec.rb +2 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +8 -4
- data/spec/grape/exceptions/validation_spec.rb +3 -1
- data/spec/grape/extensions/param_builders/hash_spec.rb +2 -0
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +2 -0
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +2 -0
- data/spec/grape/integration/global_namespace_function_spec.rb +2 -0
- data/spec/grape/integration/rack_sendfile_spec.rb +14 -8
- data/spec/grape/integration/rack_spec.rb +25 -7
- data/spec/grape/loading_spec.rb +2 -0
- data/spec/grape/middleware/auth/base_spec.rb +2 -0
- data/spec/grape/middleware/auth/dsl_spec.rb +5 -3
- data/spec/grape/middleware/auth/strategies_spec.rb +3 -1
- data/spec/grape/middleware/base_spec.rb +10 -0
- data/spec/grape/middleware/error_spec.rb +3 -1
- data/spec/grape/middleware/exception_spec.rb +4 -2
- data/spec/grape/middleware/formatter_spec.rb +33 -16
- data/spec/grape/middleware/globals_spec.rb +2 -0
- data/spec/grape/middleware/stack_spec.rb +12 -0
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -1
- data/spec/grape/middleware/versioner/header_spec.rb +9 -1
- data/spec/grape/middleware/versioner/param_spec.rb +3 -1
- data/spec/grape/middleware/versioner/path_spec.rb +3 -1
- data/spec/grape/middleware/versioner_spec.rb +2 -0
- data/spec/grape/named_api_spec.rb +21 -0
- data/spec/grape/parser_spec.rb +7 -5
- data/spec/grape/path_spec.rb +6 -4
- data/spec/grape/presenters/presenter_spec.rb +2 -0
- data/spec/grape/request_spec.rb +26 -0
- data/spec/grape/util/inheritable_setting_spec.rb +2 -0
- data/spec/grape/util/inheritable_values_spec.rb +2 -0
- data/spec/grape/util/reverse_stackable_values_spec.rb +2 -0
- data/spec/grape/util/stackable_values_spec.rb +3 -1
- data/spec/grape/util/strict_hash_configuration_spec.rb +2 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +2 -0
- data/spec/grape/validations/instance_behaivour_spec.rb +5 -3
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +41 -0
- data/spec/grape/validations/params_scope_spec.rb +213 -9
- data/spec/grape/validations/single_attribute_iterator_spec.rb +58 -0
- data/spec/grape/validations/types/array_coercer_spec.rb +35 -0
- data/spec/grape/validations/types/primitive_coercer_spec.rb +135 -0
- data/spec/grape/validations/types/set_coercer_spec.rb +34 -0
- data/spec/grape/validations/types_spec.rb +9 -36
- data/spec/grape/validations/validators/all_or_none_spec.rb +140 -30
- data/spec/grape/validations/validators/allow_blank_spec.rb +2 -0
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +175 -29
- data/spec/grape/validations/validators/coerce_spec.rb +476 -135
- data/spec/grape/validations/validators/default_spec.rb +172 -0
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +204 -38
- data/spec/grape/validations/validators/except_values_spec.rb +4 -1
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +186 -27
- data/spec/grape/validations/validators/presence_spec.rb +30 -0
- data/spec/grape/validations/validators/regexp_spec.rb +2 -0
- data/spec/grape/validations/validators/same_as_spec.rb +65 -0
- data/spec/grape/validations/validators/values_spec.rb +30 -5
- data/spec/grape/validations_spec.rb +388 -50
- data/spec/integration/eager_load/eager_load_spec.rb +15 -0
- data/spec/integration/multi_json/json_spec.rb +2 -0
- data/spec/integration/multi_xml/xml_spec.rb +2 -0
- data/spec/shared/versioning_examples.rb +22 -20
- data/spec/spec_helper.rb +12 -1
- data/spec/support/basic_auth_encode_helpers.rb +2 -0
- data/spec/support/chunks.rb +14 -0
- data/spec/support/content_type_helpers.rb +2 -0
- data/spec/support/eager_load.rb +19 -0
- data/spec/support/endpoint_faker.rb +2 -0
- data/spec/support/file_streamer.rb +2 -0
- data/spec/support/integer_helpers.rb +2 -0
- data/spec/support/versioned_helpers.rb +8 -8
- metadata +86 -48
- data/Appraisals +0 -32
- data/Dangerfile +0 -2
- data/Gemfile +0 -33
- data/Gemfile.lock +0 -231
- data/Guardfile +0 -10
- data/RELEASING.md +0 -111
- data/Rakefile +0 -25
- data/benchmark/simple.rb +0 -27
- data/benchmark/simple_with_type_coercer.rb +0 -22
- data/gemfiles/multi_json.gemfile +0 -35
- data/gemfiles/multi_xml.gemfile +0 -35
- data/gemfiles/rack_1.5.2.gemfile +0 -35
- data/gemfiles/rack_edge.gemfile +0 -35
- data/gemfiles/rails_3.gemfile +0 -36
- data/gemfiles/rails_4.gemfile +0 -35
- data/gemfiles/rails_5.gemfile +0 -35
- data/gemfiles/rails_edge.gemfile +0 -35
- data/lib/grape/extensions/deep_hash_with_indifferent_access.rb +0 -18
- data/lib/grape/util/content_types.rb +0 -26
- data/lib/grape/validations/types/virtus_collection_patch.rb +0 -16
- data/pkg/grape-0.17.0.gem +0 -0
- data/pkg/grape-0.19.0.gem +0 -0
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Middleware::Error do
|
@@ -53,7 +55,7 @@ describe Grape::Middleware::Error do
|
|
53
55
|
class CustomErrorApp
|
54
56
|
class << self
|
55
57
|
def call(_env)
|
56
|
-
raise CustomError
|
58
|
+
raise CustomError.new(status: 400, message: 'failed validation')
|
57
59
|
end
|
58
60
|
end
|
59
61
|
end
|
@@ -128,7 +130,7 @@ describe Grape::Middleware::Error do
|
|
128
130
|
subject do
|
129
131
|
Rack::Builder.app do
|
130
132
|
use Spec::Support::EndpointFaker
|
131
|
-
use Grape::Middleware::Error, rescue_handlers: { NotImplementedError => -> {
|
133
|
+
use Grape::Middleware::Error, rescue_handlers: { NotImplementedError => -> { Rack::Response.new('rescued', 200, {}) } }
|
132
134
|
run ExceptionSpec::OtherExceptionApp
|
133
135
|
end
|
134
136
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Middleware::Formatter do
|
@@ -41,7 +43,7 @@ describe Grape::Middleware::Formatter do
|
|
41
43
|
end
|
42
44
|
|
43
45
|
context 'xml' do
|
44
|
-
let(:body) { 'string' }
|
46
|
+
let(:body) { +'string' }
|
45
47
|
it 'calls #to_xml if the content type is xml' do
|
46
48
|
body.instance_eval do
|
47
49
|
def to_xml
|
@@ -194,26 +196,32 @@ describe Grape::Middleware::Formatter do
|
|
194
196
|
subject.options[:content_types][:custom] = "don't care"
|
195
197
|
subject.options[:formatters][:custom] = ->(_obj, _env) { 'CUSTOM FORMAT' }
|
196
198
|
_, _, body = subject.call('PATH_INFO' => '/info.custom')
|
197
|
-
expect(body
|
199
|
+
expect(read_chunks(body)).to eq(['CUSTOM FORMAT'])
|
198
200
|
end
|
199
201
|
context 'default' do
|
200
202
|
let(:body) { ['blah'] }
|
201
203
|
it 'uses default json formatter' do
|
202
204
|
_, _, body = subject.call('PATH_INFO' => '/info.json')
|
203
|
-
expect(body
|
205
|
+
expect(read_chunks(body)).to eq(['["blah"]'])
|
204
206
|
end
|
205
207
|
end
|
206
208
|
it 'uses custom json formatter' do
|
207
209
|
subject.options[:formatters][:json] = ->(_obj, _env) { 'CUSTOM JSON FORMAT' }
|
208
210
|
_, _, body = subject.call('PATH_INFO' => '/info.json')
|
209
|
-
expect(body
|
211
|
+
expect(read_chunks(body)).to eq(['CUSTOM JSON FORMAT'])
|
210
212
|
end
|
211
213
|
end
|
212
214
|
|
213
215
|
context 'no content responses' do
|
214
216
|
let(:no_content_response) { ->(status) { [status, {}, ['']] } }
|
215
217
|
|
216
|
-
|
218
|
+
STATUSES_WITHOUT_BODY = if Gem::Version.new(Rack.release) >= Gem::Version.new('2.1.0')
|
219
|
+
Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.keys
|
220
|
+
else
|
221
|
+
Rack::Utils::STATUS_WITH_NO_ENTITY_BODY
|
222
|
+
end
|
223
|
+
|
224
|
+
STATUSES_WITHOUT_BODY.each do |status|
|
217
225
|
it "does not modify a #{status} response" do
|
218
226
|
expected_response = no_content_response[status]
|
219
227
|
allow(app).to receive(:call).and_return(expected_response)
|
@@ -247,7 +255,7 @@ describe Grape::Middleware::Formatter do
|
|
247
255
|
let(:content_type) { 'application/atom+xml' }
|
248
256
|
|
249
257
|
it 'returns a 415 HTTP error status' do
|
250
|
-
error = catch(:error)
|
258
|
+
error = catch(:error) do
|
251
259
|
subject.call(
|
252
260
|
'PATH_INFO' => '/info',
|
253
261
|
'REQUEST_METHOD' => method,
|
@@ -255,7 +263,7 @@ describe Grape::Middleware::Formatter do
|
|
255
263
|
'rack.input' => io,
|
256
264
|
'CONTENT_LENGTH' => io.length
|
257
265
|
)
|
258
|
-
|
266
|
+
end
|
259
267
|
expect(error[:status]).to eq(415)
|
260
268
|
expect(error[:message]).to eq("The provided content-type 'application/atom+xml' is not supported.")
|
261
269
|
end
|
@@ -371,12 +379,17 @@ describe Grape::Middleware::Formatter do
|
|
371
379
|
end
|
372
380
|
|
373
381
|
context 'send file' do
|
374
|
-
let(:
|
375
|
-
let(:
|
382
|
+
let(:file) { double(File) }
|
383
|
+
let(:file_body) { Grape::ServeStream::StreamResponse.new(file) }
|
384
|
+
let(:app) { ->(_env) { [200, {}, file_body] } }
|
376
385
|
|
377
|
-
it 'returns
|
386
|
+
it 'returns a file response' do
|
387
|
+
expect(file).to receive(:each).and_yield('data')
|
378
388
|
env = { 'PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json' }
|
379
|
-
|
389
|
+
status, headers, body = subject.call(env)
|
390
|
+
expect(status).to be == 200
|
391
|
+
expect(headers).to be == { 'Content-Type' => 'application/json' }
|
392
|
+
expect(read_chunks(body)).to be == ['data']
|
380
393
|
end
|
381
394
|
end
|
382
395
|
|
@@ -389,13 +402,17 @@ describe Grape::Middleware::Formatter do
|
|
389
402
|
let(:app) { ->(_env) { [200, {}, ['']] } }
|
390
403
|
before do
|
391
404
|
Grape::Formatter.register :invalid, InvalidFormatter
|
392
|
-
Grape::ContentTypes
|
405
|
+
Grape::ContentTypes.register :invalid, 'application/x-invalid'
|
406
|
+
end
|
407
|
+
after do
|
408
|
+
Grape::ContentTypes.default_elements.delete(:invalid)
|
409
|
+
Grape::Formatter.default_elements.delete(:invalid)
|
393
410
|
end
|
394
411
|
|
395
412
|
it 'returns response by invalid formatter' do
|
396
413
|
env = { 'PATH_INFO' => '/hello.invalid', 'HTTP_ACCEPT' => 'application/x-invalid' }
|
397
|
-
_, _,
|
398
|
-
expect(
|
414
|
+
_, _, body = *subject.call(env)
|
415
|
+
expect(read_chunks(body).join).to eq({ message: 'invalid' }.to_json)
|
399
416
|
end
|
400
417
|
end
|
401
418
|
|
@@ -407,7 +424,7 @@ describe Grape::Middleware::Formatter do
|
|
407
424
|
parsers: { json: ->(_object, _env) { raise StandardError, 'fail' } }
|
408
425
|
)
|
409
426
|
io = StringIO.new('{invalid}')
|
410
|
-
error = catch(:error)
|
427
|
+
error = catch(:error) do
|
411
428
|
subject.call(
|
412
429
|
'PATH_INFO' => '/info',
|
413
430
|
'REQUEST_METHOD' => 'POST',
|
@@ -415,7 +432,7 @@ describe Grape::Middleware::Formatter do
|
|
415
432
|
'rack.input' => io,
|
416
433
|
'CONTENT_LENGTH' => io.length
|
417
434
|
)
|
418
|
-
|
435
|
+
end
|
419
436
|
|
420
437
|
expect(error[:message]).to eq 'fail'
|
421
438
|
expect(error[:backtrace].size).to be >= 1
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Middleware::Stack do
|
@@ -6,6 +8,7 @@ describe Grape::Middleware::Stack do
|
|
6
8
|
class BarMiddleware; end
|
7
9
|
class BlockMiddleware
|
8
10
|
attr_reader :block
|
11
|
+
|
9
12
|
def initialize(&block)
|
10
13
|
@block = block
|
11
14
|
end
|
@@ -109,6 +112,15 @@ describe Grape::Middleware::Stack do
|
|
109
112
|
expect(subject[1]).to eq(StackSpec::BlockMiddleware)
|
110
113
|
expect(subject[2]).to eq(StackSpec::BarMiddleware)
|
111
114
|
end
|
115
|
+
|
116
|
+
context 'middleware spec with proc declaration exists' do
|
117
|
+
let(:middleware_spec_with_proc) { [:use, StackSpec::FooMiddleware, proc] }
|
118
|
+
|
119
|
+
it 'properly forwards spec arguments' do
|
120
|
+
expect(subject).to receive(:use).with(StackSpec::FooMiddleware)
|
121
|
+
subject.merge_with([middleware_spec_with_proc])
|
122
|
+
end
|
123
|
+
end
|
112
124
|
end
|
113
125
|
|
114
126
|
describe '#build' do
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Middleware::Versioner::AcceptVersionHeader do
|
4
6
|
let(:app) { ->(env) { [200, env, env] } }
|
5
|
-
subject { Grape::Middleware::Versioner::AcceptVersionHeader.new(app, @options || {}) }
|
7
|
+
subject { Grape::Middleware::Versioner::AcceptVersionHeader.new(app, **(@options || {})) }
|
6
8
|
|
7
9
|
before do
|
8
10
|
@options = {
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Middleware::Versioner::Header do
|
4
6
|
let(:app) { ->(env) { [200, env, env] } }
|
5
|
-
subject { Grape::Middleware::Versioner::Header.new(app, @options || {}) }
|
7
|
+
subject { Grape::Middleware::Versioner::Header.new(app, **(@options || {})) }
|
6
8
|
|
7
9
|
before do
|
8
10
|
@options = {
|
@@ -160,6 +162,12 @@ describe Grape::Middleware::Versioner::Header do
|
|
160
162
|
expect(subject.call({}).first).to eq(200)
|
161
163
|
end
|
162
164
|
|
165
|
+
it 'succeeds if :strict is set to false and given an invalid header' do
|
166
|
+
@options[:version_options][:strict] = false
|
167
|
+
expect(subject.call('HTTP_ACCEPT' => 'yaml').first).to eq(200)
|
168
|
+
expect(subject.call({}).first).to eq(200)
|
169
|
+
end
|
170
|
+
|
163
171
|
context 'when :strict is set' do
|
164
172
|
before do
|
165
173
|
@options[:versions] = ['v1']
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Middleware::Versioner::Param do
|
4
6
|
let(:app) { ->(env) { [200, env, env['api.version']] } }
|
5
7
|
let(:options) { {} }
|
6
|
-
subject { Grape::Middleware::Versioner::Param.new(app, options) }
|
8
|
+
subject { Grape::Middleware::Versioner::Param.new(app, **options) }
|
7
9
|
|
8
10
|
it 'sets the API version based on the default param (apiver)' do
|
9
11
|
env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' })
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Middleware::Versioner::Path do
|
4
6
|
let(:app) { ->(env) { [200, env, env['api.version']] } }
|
5
7
|
let(:options) { {} }
|
6
|
-
subject { Grape::Middleware::Versioner::Path.new(app, options) }
|
8
|
+
subject { Grape::Middleware::Versioner::Path.new(app, **options) }
|
7
9
|
|
8
10
|
it 'sets the API version based on the first path' do
|
9
11
|
expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1')
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'A named API' do
|
6
|
+
subject(:api_name) { NamedAPI.endpoints.last.options[:for].to_s }
|
7
|
+
|
8
|
+
let(:api) do
|
9
|
+
Class.new(Grape::API) do
|
10
|
+
get 'test' do
|
11
|
+
'response'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before { stub_const('NamedAPI', api) }
|
17
|
+
|
18
|
+
it 'can access the name of the API' do
|
19
|
+
expect(api_name).to eq 'NamedAPI'
|
20
|
+
end
|
21
|
+
end
|
data/spec/grape/parser_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Parser do
|
@@ -15,11 +17,11 @@ describe Grape::Parser do
|
|
15
17
|
|
16
18
|
describe '.parsers' do
|
17
19
|
it 'returns an instance of Hash' do
|
18
|
-
expect(subject.parsers({})).to be_an_instance_of(Hash)
|
20
|
+
expect(subject.parsers(**{})).to be_an_instance_of(Hash)
|
19
21
|
end
|
20
22
|
|
21
23
|
it 'includes built-in parsers' do
|
22
|
-
expect(subject.parsers({})).to include(subject.builtin_parsers)
|
24
|
+
expect(subject.parsers(**{})).to include(subject.builtin_parsers)
|
23
25
|
end
|
24
26
|
|
25
27
|
context 'with :parsers option' do
|
@@ -33,7 +35,7 @@ describe Grape::Parser do
|
|
33
35
|
let(:added_parser) { Class.new }
|
34
36
|
before { subject.register :added, added_parser }
|
35
37
|
it 'includes added parser' do
|
36
|
-
expect(subject.parsers({})).to include(added: added_parser)
|
38
|
+
expect(subject.parsers(**{})).to include(added: added_parser)
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
@@ -42,8 +44,8 @@ describe Grape::Parser do
|
|
42
44
|
let(:options) { {} }
|
43
45
|
|
44
46
|
it 'calls .parsers' do
|
45
|
-
expect(subject).to receive(:parsers).with(
|
46
|
-
subject.parser_for(:json, options)
|
47
|
+
expect(subject).to receive(:parsers).with(any_args).and_return(subject.builtin_parsers)
|
48
|
+
subject.parser_for(:json, **options)
|
47
49
|
end
|
48
50
|
|
49
51
|
it 'returns parser correctly' do
|
data/spec/grape/path_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
module Grape
|
@@ -85,12 +87,12 @@ module Grape
|
|
85
87
|
describe '#namespace?' do
|
86
88
|
it 'is false when the namespace is nil' do
|
87
89
|
path = Path.new(anything, nil, anything)
|
88
|
-
expect(path.namespace?).to
|
90
|
+
expect(path.namespace?).to be_falsey
|
89
91
|
end
|
90
92
|
|
91
93
|
it 'is false when the namespace starts with whitespace' do
|
92
94
|
path = Path.new(anything, ' /foo', anything)
|
93
|
-
expect(path.namespace?).to
|
95
|
+
expect(path.namespace?).to be_falsey
|
94
96
|
end
|
95
97
|
|
96
98
|
it 'is false when the namespace is the root path' do
|
@@ -107,12 +109,12 @@ module Grape
|
|
107
109
|
describe '#path?' do
|
108
110
|
it 'is false when the path is nil' do
|
109
111
|
path = Path.new(nil, anything, anything)
|
110
|
-
expect(path.path?).to
|
112
|
+
expect(path.path?).to be_falsey
|
111
113
|
end
|
112
114
|
|
113
115
|
it 'is false when the path starts with whitespace' do
|
114
116
|
path = Path.new(' /foo', anything, anything)
|
115
|
-
expect(path.path?).to
|
117
|
+
expect(path.path?).to be_falsey
|
116
118
|
end
|
117
119
|
|
118
120
|
it 'is false when the path is the root path' do
|
data/spec/grape/request_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
module Grape
|
@@ -62,6 +64,30 @@ module Grape
|
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
67
|
+
describe 'when the param_builder is set to Hashie' do
|
68
|
+
before do
|
69
|
+
Grape.configure do |config|
|
70
|
+
config.param_builder = Grape::Extensions::Hashie::Mash::ParamBuilder
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
after do
|
75
|
+
Grape.config.reset
|
76
|
+
end
|
77
|
+
|
78
|
+
subject(:request_params) { Grape::Request.new(env, **opts).params }
|
79
|
+
|
80
|
+
context 'when the API does not include a specific param builder' do
|
81
|
+
let(:opts) { {} }
|
82
|
+
it { is_expected.to be_a(Hashie::Mash) }
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when the API includes a specific param builder' do
|
86
|
+
let(:opts) { { build_params_with: Grape::Extensions::Hash::ParamBuilder } }
|
87
|
+
it { is_expected.to be_a(Hash) }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
65
91
|
describe '#headers' do
|
66
92
|
let(:options) do
|
67
93
|
default_options.merge(request_headers)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
module Grape
|
3
5
|
module Util
|
@@ -6,7 +8,7 @@ module Grape
|
|
6
8
|
subject { StackableValues.new(parent) }
|
7
9
|
|
8
10
|
describe '#keys' do
|
9
|
-
it 'returns all
|
11
|
+
it 'returns all keys' do
|
10
12
|
subject[:some_thing] = :foo_bar
|
11
13
|
subject[:some_thing_else] = :foo_bar
|
12
14
|
expect(subject.keys).to eq %i[some_thing some_thing_else].sort
|