diff --git a/.rubocop.yml b/.rubocop.yml index 9e4cc8bd49..44b9d7e874 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -80,3 +80,6 @@ RSpec/MultipleMemoizedHelpers: RSpec/ContextWording: Enabled: false + +RSpec/MessageSpies: + EnforcedStyle: receive diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a3956b5bce..f4482aff41 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-06-15 15:12:21 UTC using RuboCop version 1.64.1. +# on 2024-06-22 17:26:10 UTC using RuboCop version 1.64.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -14,13 +14,6 @@ Gemspec/RequireMFA: Exclude: - 'grape.gemspec' -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowedMethods, AllowedPatterns. -Lint/AmbiguousBlockAssociation: - Exclude: - - 'spec/grape/dsl/routing_spec.rb' - # Offense count: 1 # Configuration parameters: AllowedMethods. # AllowedMethods: enums @@ -28,43 +21,12 @@ Lint/ConstantDefinitionInBlock: Exclude: - 'spec/grape/validations/validators/except_values_spec.rb' -# Offense count: 3 -# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches. -Lint/DuplicateBranch: - Exclude: - - 'spec/support/versioned_helpers.rb' - -# Offense count: 1 -# Configuration parameters: AllowComments. -Lint/EmptyClass: - Exclude: - - 'lib/grape/dsl/parameters.rb' - # Offense count: 1 # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Exclude: - 'lib/grape/endpoint.rb' -# Offense count: 2 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyleForLeadingUnderscores. -# SupportedStylesForLeadingUnderscores: disallowed, required, optional -Naming/MemoizedInstanceVariableName: - Exclude: - - 'lib/grape/api/instance.rb' - - 'lib/grape/middleware/base.rb' - -# Offense count: 5 -# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to -Naming/MethodParameterName: - Exclude: - - 'lib/grape/endpoint.rb' - - 'lib/grape/middleware/error.rb' - - 'lib/grape/middleware/stack.rb' - - 'spec/grape/api_spec.rb' - # Offense count: 18 # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. # SupportedStyles: snake_case, normalcase, non_integer @@ -117,10 +79,9 @@ RSpec/ExpectActual: - 'spec/grape/endpoint/declared_spec.rb' - 'spec/grape/middleware/exception_spec.rb' -# Offense count: 3 +# Offense count: 1 RSpec/ExpectInHook: Exclude: - - 'spec/grape/api_spec.rb' - 'spec/grape/validations/validators/values_spec.rb' # Offense count: 6 @@ -147,31 +108,16 @@ RSpec/LeakyConstantDeclaration: Exclude: - 'spec/grape/validations/validators/except_values_spec.rb' -# Offense count: 2 +# Offense count: 1 RSpec/MessageChain: Exclude: - 'spec/grape/middleware/formatter_spec.rb' -# Offense count: 144 -# Configuration parameters: . -# SupportedStyles: have_received, receive -RSpec/MessageSpies: - EnforcedStyle: receive - # Offense count: 12 RSpec/MissingExampleGroupArgument: Exclude: - 'spec/grape/middleware/exception_spec.rb' -# Offense count: 17 -# Configuration parameters: AllowedPatterns. -# AllowedPatterns: ^expect_, ^assert_ -RSpec/NoExpectationExample: - Exclude: - - 'spec/grape/api_remount_spec.rb' - - 'spec/grape/api_spec.rb' - - 'spec/grape/validations_spec.rb' - # Offense count: 12 RSpec/RepeatedDescription: Exclude: @@ -180,10 +126,9 @@ RSpec/RepeatedDescription: - 'spec/grape/validations/validators/allow_blank_spec.rb' - 'spec/grape/validations/validators/values_spec.rb' -# Offense count: 8 +# Offense count: 6 RSpec/RepeatedExample: Exclude: - - 'spec/grape/api_spec.rb' - 'spec/grape/middleware/versioner/accept_version_header_spec.rb' - 'spec/grape/validations/validators/allow_blank_spec.rb' @@ -195,13 +140,6 @@ RSpec/RepeatedExampleGroupDescription: - 'spec/grape/util/inheritable_setting_spec.rb' - 'spec/grape/validations/validators/values_spec.rb' -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect. -RSpec/ScatteredSetup: - Exclude: - - 'spec/grape/util/inheritable_setting_spec.rb' - # Offense count: 5 RSpec/StubbedMock: Exclude: @@ -228,7 +166,7 @@ RSpec/SubjectStub: - 'spec/grape/middleware/stack_spec.rb' - 'spec/grape/parser_spec.rb' -# Offense count: 24 +# Offense count: 23 # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: Exclude: @@ -251,13 +189,6 @@ Style/CombinableLoops: Exclude: - 'spec/grape/endpoint_spec.rb' -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns. -# SupportedStyles: annotated, template, unannotated -Style/FormatStringToken: - EnforcedStyle: template - # Offense count: 12 # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? @@ -274,55 +205,3 @@ Style/OptionalBooleanParameter: - 'lib/grape/validations/types/dry_type_coercer.rb' - 'lib/grape/validations/types/primitive_coercer.rb' - 'lib/grape/validations/types/set_coercer.rb' - -# Offense count: 29 -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantConstantBase: - Exclude: - - 'spec/grape/api/invalid_format_spec.rb' - - 'spec/grape/api_spec.rb' - - 'spec/grape/dsl/logger_spec.rb' - - 'spec/grape/endpoint/declared_spec.rb' - - 'spec/grape/endpoint_spec.rb' - - 'spec/grape/middleware/formatter_spec.rb' - - 'spec/grape/validations/validators/coerce_spec.rb' - - 'spec/grape/validations/validators/default_spec.rb' - - 'spec/integration/multi_json/json_spec.rb' - - 'spec/integration/multi_xml/xml_spec.rb' - -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowAsExpressionSeparator. -Style/Semicolon: - Exclude: - - 'spec/grape/api_spec.rb' - -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -Style/SuperArguments: - Exclude: - - 'lib/grape/api.rb' - - 'spec/support/deprecated_warning_handlers.rb' - -# Offense count: 2 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments. -# AllowedMethods: define_method -Style/SymbolProc: - Exclude: - - 'benchmark/large_model.rb' - - 'spec/grape/validations/params_scope_spec.rb' - -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: forbid_for_all_comparison_operators, forbid_for_equality_operators_only, require_for_all_comparison_operators, require_for_equality_operators_only -Style/YodaCondition: - Exclude: - - 'lib/grape/api.rb' - -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -Style/ZeroLengthPredicate: - Exclude: - - 'lib/grape/validations/validators/exactly_one_of_validator.rb' diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dec503c80..f384013f84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ #### Fixes +* [#2459](https://github.com/ruby-grape/grape/pull/2459): Autocorrect cops - [@ericproulx](https://github.com/ericproulx). * [#3458](https://github.com/ruby-grape/grape/pull/2458): Remove unused Grape::Util::Accept::Header - [@ericproulx](https://github.com/ericproulx). * Your contribution here. diff --git a/benchmark/large_model.rb b/benchmark/large_model.rb index 27dc9a3574..9eaa1a5288 100644 --- a/benchmark/large_model.rb +++ b/benchmark/large_model.rb @@ -140,7 +140,7 @@ def self.vrp_request_configuration(this) def self.vrp_request_partition(this) this.requires(:method, type: String, values: %w[hierarchical_tree balanced_kmeans]) this.optional(:metric, type: Symbol) - this.optional(:entity, type: Symbol, values: %i[vehicle work_day], coerce_with: ->(value) { value.to_sym }) + this.optional(:entity, type: Symbol, values: %i[vehicle work_day], coerce_with: lambda(&:to_sym)) this.optional(:threshold, type: Integer) end diff --git a/lib/grape/api.rb b/lib/grape/api.rb index 38f17dcc56..eaa351c9bf 100644 --- a/lib/grape/api.rb +++ b/lib/grape/api.rb @@ -32,7 +32,7 @@ def new(...) def inherited(api) super - api.initial_setup(Grape::API == self ? Grape::API::Instance : @base_instance) + api.initial_setup(self == Grape::API ? Grape::API::Instance : @base_instance) api.override_all_methods! end @@ -108,7 +108,7 @@ def replay_setup_on(instance) end def respond_to?(method, include_private = false) - super(method, include_private) || base_instance.respond_to?(method, include_private) + super || base_instance.respond_to?(method, include_private) end def respond_to_missing?(method, include_private = false) diff --git a/lib/grape/api/instance.rb b/lib/grape/api/instance.rb index a17c8e63f0..ce290df7cc 100644 --- a/lib/grape/api/instance.rb +++ b/lib/grape/api/instance.rb @@ -46,7 +46,7 @@ def reset! # Parses the API's definition and compiles it into an instance of # Grape::API. def compile - @instance ||= new + @instance ||= new # rubocop:disable Naming/MemoizedInstanceVariableName end # Wipe the compiled API so we can recompile after changes were made. diff --git a/lib/grape/dsl/parameters.rb b/lib/grape/dsl/parameters.rb index bfc9b408e3..821da5d793 100644 --- a/lib/grape/dsl/parameters.rb +++ b/lib/grape/dsl/parameters.rb @@ -231,7 +231,7 @@ def declared_param?(param) alias group requires - class EmptyOptionalValue; end + class EmptyOptionalValue; end # rubocop:disable Lint/EmptyClass def map_params(params, element, is_array = false) if params.is_a?(Array) diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index 7fc83fc437..cc1fdba833 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -231,8 +231,8 @@ def endpoints options[:app].endpoints if options[:app].respond_to?(:endpoints) end - def equals?(e) - (options == e.options) && (inheritable_setting.to_hash == e.inheritable_setting.to_hash) + def equals?(endpoint) + (options == endpoint.options) && (inheritable_setting.to_hash == endpoint.inheritable_setting.to_hash) end protected diff --git a/lib/grape/exceptions/validation_errors.rb b/lib/grape/exceptions/validation_errors.rb index 09e4a37b0a..b8a843b1a5 100644 --- a/lib/grape/exceptions/validation_errors.rb +++ b/lib/grape/exceptions/validation_errors.rb @@ -4,7 +4,7 @@ module Grape module Exceptions class ValidationErrors < Grape::Exceptions::Base ERRORS_FORMAT_KEY = 'grape.errors.format' - DEFAULT_ERRORS_FORMAT = '%{attributes} %{message}' + DEFAULT_ERRORS_FORMAT = '%s %s' include Enumerable diff --git a/lib/grape/middleware/base.rb b/lib/grape/middleware/base.rb index 87f2429fff..2ee9cbeaea 100644 --- a/lib/grape/middleware/base.rb +++ b/lib/grape/middleware/base.rb @@ -74,7 +74,7 @@ def content_type end def mime_types - @mime_type ||= content_types.each_pair.with_object({}) do |(k, v), types_without_params| + @mime_types ||= content_types.each_pair.with_object({}) do |(k, v), types_without_params| types_without_params[v.split(';').first] = k end end diff --git a/lib/grape/middleware/error.rb b/lib/grape/middleware/error.rb index b1fc02767f..2dc71c1daf 100644 --- a/lib/grape/middleware/error.rb +++ b/lib/grape/middleware/error.rb @@ -74,8 +74,8 @@ def error_response(error = {}) rack_response(status, headers, format_message(message, backtrace, original_exception)) end - def default_rescue_handler(e) - error_response(message: e.message, backtrace: e.backtrace, original_exception: e) + def default_rescue_handler(exception) + error_response(message: exception.message, backtrace: exception.backtrace, original_exception: exception) end def rescue_handler_for_base_only_class(klass) diff --git a/lib/grape/middleware/stack.rb b/lib/grape/middleware/stack.rb index 9ba339a78e..8e25af385f 100644 --- a/lib/grape/middleware/stack.rb +++ b/lib/grape/middleware/stack.rb @@ -57,8 +57,8 @@ def last middlewares.last end - def [](i) - middlewares[i] + def [](index) + middlewares[index] end def insert(index, *args, &block) diff --git a/lib/grape/validations/validators/exactly_one_of_validator.rb b/lib/grape/validations/validators/exactly_one_of_validator.rb index 735c457019..aa1c54711c 100644 --- a/lib/grape/validations/validators/exactly_one_of_validator.rb +++ b/lib/grape/validations/validators/exactly_one_of_validator.rb @@ -7,7 +7,7 @@ class ExactlyOneOfValidator < MultipleParamsBase def validate_params!(params) keys = keys_in_common(params) return if keys.length == 1 - raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:exactly_one)) if keys.length.zero? + raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:exactly_one)) if keys.empty? raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion)) end diff --git a/spec/grape/api/invalid_format_spec.rb b/spec/grape/api/invalid_format_spec.rb index 79da1ac1db..0e6399d32c 100644 --- a/spec/grape/api/invalid_format_spec.rb +++ b/spec/grape/api/invalid_format_spec.rb @@ -27,19 +27,19 @@ def app it 'no format' do get '/foo' expect(last_response.status).to eq 200 - expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: nil)) + expect(last_response.body).to eq(Grape::Json.dump(id: 'foo', format: nil)) end it 'json format' do get '/foo.json' expect(last_response.status).to eq 200 - expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: 'json')) + expect(last_response.body).to eq(Grape::Json.dump(id: 'foo', format: 'json')) end it 'invalid format' do get '/foo.invalid' expect(last_response.status).to eq 200 - expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: 'invalid')) + expect(last_response.body).to eq(Grape::Json.dump(id: 'foo', format: 'invalid')) end end end diff --git a/spec/grape/api_remount_spec.rb b/spec/grape/api_remount_spec.rb index 2c6c6ae4bb..793d49d9fd 100644 --- a/spec/grape/api_remount_spec.rb +++ b/spec/grape/api_remount_spec.rb @@ -306,13 +306,15 @@ tags ['not_configurable_tag', configuration[:a_configurable_tag]] end get 'location' do - 'success' + route.tags end end end it 'mounts the endpoint with the appropiate tags' do root_api.mount({ a_remounted_api => 'integer' }, with: { a_configurable_tag: 'a configured tag' }) + get '/integer/location', param_key: 'a' + expect(JSON.parse(last_response.body)).to eq ['not_configurable_tag', 'a configured tag'] end end diff --git a/spec/grape/api_spec.rb b/spec/grape/api_spec.rb index fbd0ee38c7..dd280c9a56 100644 --- a/spec/grape/api_spec.rb +++ b/spec/grape/api_spec.rb @@ -287,8 +287,10 @@ def subject.enable_root_route! end end - after do - expect(last_response.body).to eql 'root' + shared_examples_for 'a root route' do + it 'returns root' do + expect(last_response.body).to eql 'root' + end end describe 'path versioned APIs' do @@ -300,56 +302,104 @@ def subject.enable_root_route! context 'when a single version provided' do let(:version) { 'v1' } - it 'without a format' do - versioned_get '/', 'v1', using: :path + context 'without a format' do + before do + versioned_get '/', 'v1', using: :path + end + + it_behaves_like 'a root route' end - it 'with a format' do - get '/v1/.json' + context 'with a format' do + before do + get '/v1/.json' + end + + it_behaves_like 'a root route' end end context 'when array of versions provided' do let(:version) { %w[v1 v2] } - it { versioned_get '/', 'v1', using: :path } - it { versioned_get '/', 'v2', using: :path } + context 'when v1' do + before do + versioned_get '/', 'v1', using: :path + end + + it_behaves_like 'a root route' + end + + context 'when v2' do + before do + versioned_get '/', 'v2', using: :path + end + + it_behaves_like 'a root route' + end end end - it 'header versioned APIs' do - subject.version 'v1', using: :header, vendor: 'test' - subject.enable_root_route! + context 'when header versioned APIs' do + before do + subject.version 'v1', using: :header, vendor: 'test' + subject.enable_root_route! + versioned_get '/', 'v1', using: :header, vendor: 'test' + end - versioned_get '/', 'v1', using: :header, vendor: 'test' + it_behaves_like 'a root route' end - it 'header versioned APIs with multiple headers' do - subject.version %w[v1 v2], using: :header, vendor: 'test' - subject.enable_root_route! + context 'when header versioned APIs with multiple headers' do + before do + subject.version %w[v1 v2], using: :header, vendor: 'test' + subject.enable_root_route! + end + + context 'when v1' do + before do + versioned_get '/', 'v1', using: :header, vendor: 'test' + end - versioned_get '/', 'v1', using: :header, vendor: 'test' - versioned_get '/', 'v2', using: :header, vendor: 'test' + it_behaves_like 'a root route' + end + + context 'when v2' do + before do + versioned_get '/', 'v2', using: :header, vendor: 'test' + end + + it_behaves_like 'a root route' + end end - it 'param versioned APIs' do - subject.version 'v1', using: :param - subject.enable_root_route! + context 'param versioned APIs' do + before do + subject.version 'v1', using: :param + subject.enable_root_route! + versioned_get '/', 'v1', using: :param + end - versioned_get '/', 'v1', using: :param + it_behaves_like 'a root route' end - it 'Accept-Version header versioned APIs' do - subject.version 'v1', using: :accept_version_header - subject.enable_root_route! + context 'when Accept-Version header versioned APIs' do + before do + subject.version 'v1', using: :accept_version_header + subject.enable_root_route! + versioned_get '/', 'v1', using: :accept_version_header + end - versioned_get '/', 'v1', using: :accept_version_header + it_behaves_like 'a root route' end - it 'unversioned APIs' do - subject.enable_root_route! + context 'unversioned APIss' do + before do + subject.enable_root_route! + get '/' + end - get '/' + it_behaves_like 'a root route' end end @@ -438,9 +488,9 @@ def to_txt subject.send(verb) do env[Grape::Env::API_REQUEST_BODY] end - send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' + send verb, '/', Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(verb == :post ? 201 : 200) - expect(last_response.body).to eql ::Grape::Json.dump(object) + expect(last_response.body).to eql Grape::Json.dump(object) expect(last_request.params).to eql({}) end @@ -449,9 +499,9 @@ def to_txt subject.send(verb) do env[Grape::Env::API_REQUEST_INPUT] end - send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' + send verb, '/', Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(verb == :post ? 201 : 200) - expect(last_response.body).to eql ::Grape::Json.dump(object).to_json + expect(last_response.body).to eql Grape::Json.dump(object).to_json end context 'chunked transfer encoding' do @@ -460,9 +510,9 @@ def to_txt subject.send(verb) do env[Grape::Env::API_REQUEST_INPUT] end - send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json', Grape::Http::Headers::HTTP_TRANSFER_ENCODING => 'chunked' + send verb, '/', Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json', Grape::Http::Headers::HTTP_TRANSFER_ENCODING => 'chunked' expect(last_response.status).to eq(verb == :post ? 201 : 200) - expect(last_response.body).to eql ::Grape::Json.dump(object).to_json + expect(last_response.body).to eql Grape::Json.dump(object).to_json end end end @@ -993,9 +1043,14 @@ def to_txt end describe '.compile!' do - it 'compiles the instance for rack!' do - stubbed_object = double(:instance_for_rack) - allow(app).to receive(:instance_for_rack) { stubbed_object } + let(:base_instance) { app.base_instance } + + before do + allow(base_instance).to receive(:compile!).and_return(:compiled!) + end + + it 'returns compiled!' do + expect(app.send(:compile!)).to eq(:compiled!) end end @@ -1593,8 +1648,8 @@ def call(env) it 'has access to helper methods' do subject.helpers do - def authorize(u, p) - u == 'allow' && p == 'whatever' + def authorize(user, password) + user == 'allow' && password == 'whatever' end end @@ -1634,7 +1689,7 @@ def authorize(u, p) def self.io @io ||= StringIO.new end - logger ::Logger.new(io) + logger Logger.new(io) end end @@ -2496,7 +2551,7 @@ def self.call(message, _backtrace, _options, _env, _original_exception) raise 'rain!' end get '/exception' - json = ::Grape::Json.load(last_response.body) + json = Grape::Json.load(last_response.body) expect(json['error']).to eql 'rain!' expect(json['backtrace'].length).to be > 0 end @@ -2511,24 +2566,26 @@ def self.call(message, _backtrace, _options, _env, _original_exception) end context 'with json format' do - before { subject.format :json } + shared_examples_for 'a json format api' do |error_message| + subject { JSON.parse(last_response.body) } - after do - get '/error' - expect(last_response.body).to eql('{"error":"failure"}') - end + before { get '/error' } - it 'rescues error! called with a string and returns json' do - subject.get('/error') { error!(:failure, 401) } - end + let(:app) do + Class.new(Grape::API) do + format :json + get('/error') { error!(error_message, 401) } + end + end - it 'rescues error! called with a symbol and returns json' do - subject.get('/error') { error!(:failure, 401) } + context "when error! called with #{error_message.class.name}" do + it { is_expected.to eq('error' => 'failure') } + end end - it 'rescues error! called with a hash and returns json' do - subject.get('/error') { error!({ error: :failure }, 401) } - end + it_behaves_like 'a json format api', 'failure' + it_behaves_like 'a json format api', :failure + it_behaves_like 'a json format api', { error: :failure } end end @@ -3083,13 +3140,13 @@ def self.call(object, _env) optional :param2 end subject.namespace 'ns1' do - get { ; } + get {} end subject.params do optional :param2 end subject.namespace 'ns2' do - get { ; } + get {} end routes_doc = subject.routes.map do |route| { description: route.description, params: route.params } @@ -3216,6 +3273,12 @@ def self.call(object, _env) optional :bar end end + subject.get 'method' + expect(subject.routes.map do |route| + { description: route.description, params: route.params } + end).to eq [ + { description: nil, params: { 'foo' => { required: true, type: 'Array' }, 'foo[bar]' => { required: false } } } + ] end it 'parses parameters when no description is given' do @@ -3693,7 +3756,7 @@ def my_method it 'path' do get '/endpoint/options' - options = ::Grape::Json.load(last_response.body) + options = Grape::Json.load(last_response.body) expect(options['path']).to eq(['/endpoint/options']) expect(options['source_location'][0]).to include 'api_spec.rb' expect(options['source_location'][1].to_i).to be > 0 diff --git a/spec/grape/dsl/logger_spec.rb b/spec/grape/dsl/logger_spec.rb index 2c9739f75e..ae1bab5671 100644 --- a/spec/grape/dsl/logger_spec.rb +++ b/spec/grape/dsl/logger_spec.rb @@ -9,7 +9,7 @@ end end - let(:logger) { instance_double(::Logger) } + let(:logger) { instance_double(Logger) } describe '.logger' do it 'sets a logger' do diff --git a/spec/grape/dsl/routing_spec.rb b/spec/grape/dsl/routing_spec.rb index 6d64586198..e763428f61 100644 --- a/spec/grape/dsl/routing_spec.rb +++ b/spec/grape/dsl/routing_spec.rb @@ -259,7 +259,7 @@ class Dummy it 'does not modify options parameter' do allow(subject).to receive(:namespace) expect { subject.route_param('foo', options, &proc {}) } - .not_to change { options } + .not_to(change { options }) end end diff --git a/spec/grape/endpoint/declared_spec.rb b/spec/grape/endpoint/declared_spec.rb index dcf2fe9d62..6bf5d206ca 100644 --- a/spec/grape/endpoint/declared_spec.rb +++ b/spec/grape/endpoint/declared_spec.rb @@ -281,7 +281,7 @@ '' end - post '/declared', ::Grape::Json.dump(first: 'one', boolean: false), 'CONTENT_TYPE' => 'application/json' + post '/declared', Grape::Json.dump(first: 'one', boolean: false), 'CONTENT_TYPE' => 'application/json' expect(last_response).to be_created end @@ -296,7 +296,7 @@ '' end - post '/declared', ::Grape::Json.dump(first: 'one', second: nil), 'CONTENT_TYPE' => 'application/json' + post '/declared', Grape::Json.dump(first: 'one', second: nil), 'CONTENT_TYPE' => 'application/json' expect(last_response).to be_created end diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index ee4c8986d5..ee44efc39a 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -371,7 +371,7 @@ def app end it 'converts JSON bodies to params' do - post '/request_body', ::Grape::Json.dump(user: 'Bobby T.'), 'CONTENT_TYPE' => 'application/json' + post '/request_body', Grape::Json.dump(user: 'Bobby T.'), 'CONTENT_TYPE' => 'application/json' expect(last_response.body).to eq('Bobby T.') end @@ -407,7 +407,7 @@ def app error! 400, 'expected nil' if params[:version] params[:user] end - post '/omitted_params', ::Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'application/json' + post '/omitted_params', Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(201) expect(last_response.body).to eq('Bob') end @@ -464,7 +464,7 @@ def app subject.put '/request_body' do params[:user] end - put '/request_body', ::Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'text/plain' + put '/request_body', Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'text/plain' expect(last_response.status).to eq(415) expect(last_response.body).to eq('{"error":"The provided content-type \'text/plain\' is not supported."}') @@ -478,7 +478,7 @@ def app subject.post do params[:data] end - post '/', ::Grape::Json.dump(data: { some: 'payload' }), 'CONTENT_TYPE' => 'application/json' + post '/', Grape::Json.dump(data: { some: 'payload' }), 'CONTENT_TYPE' => 'application/json' end it 'does not response with 406 for same type without params' do diff --git a/spec/grape/middleware/formatter_spec.rb b/spec/grape/middleware/formatter_spec.rb index 61a2a67bf9..9b7dc9b56e 100644 --- a/spec/grape/middleware/formatter_spec.rb +++ b/spec/grape/middleware/formatter_spec.rb @@ -16,7 +16,7 @@ it 'looks at the bodies for possibly serializable data' do r = Rack::MockResponse[*subject.call(env)] - expect(r.body).to eq(::Grape::Json.dump(body)) + expect(r.body).to eq(Grape::Json.dump(body)) end context 'default format' do @@ -336,7 +336,7 @@ def to_xml let(:io) { double } before do - allow(io).to receive_message_chain(:rewind, :read).and_return(nil) + allow(io).to receive_message_chain(rewind: nil, read: nil) end it 'does not read and parse the body' do @@ -355,7 +355,7 @@ def to_xml let(:io) { double } before do - allow(io).to receive_message_chain(:rewind, :read).and_return('') + allow(io).to receive_messages(rewind: nil, read: '') end it 'does not read and parse the body' do diff --git a/spec/grape/util/inheritable_setting_spec.rb b/spec/grape/util/inheritable_setting_spec.rb index 2941b31810..c9ad93bd9e 100644 --- a/spec/grape/util/inheritable_setting_spec.rb +++ b/spec/grape/util/inheritable_setting_spec.rb @@ -5,6 +5,7 @@ module Util describe InheritableSetting do before do described_class.reset_global! + subject.inherit_from parent end let(:parent) do @@ -28,10 +29,6 @@ module Util end end - before do - subject.inherit_from parent - end - describe '#global' do it 'sets a global value' do subject.global[:some_thing] = :foo_bar diff --git a/spec/grape/validations/params_scope_spec.rb b/spec/grape/validations/params_scope_spec.rb index af6a4a2c93..454fdf6c03 100644 --- a/spec/grape/validations/params_scope_spec.rb +++ b/spec/grape/validations/params_scope_spec.rb @@ -58,7 +58,7 @@ def initialize(value) it do subject.params do - requires :foo, as: :bar, type: String, coerce_with: ->(c) { c.strip } + requires :foo, as: :bar, type: String, coerce_with: lambda(&:strip) end subject.get('/renaming-coerced') { "#{params['bar']}-#{params['foo']}" } get '/renaming-coerced', foo: ' there we go ' diff --git a/spec/grape/validations/validators/coerce_spec.rb b/spec/grape/validations/validators/coerce_spec.rb index 6b8f500686..81cd4b5119 100644 --- a/spec/grape/validations/validators/coerce_spec.rb +++ b/spec/grape/validations/validators/coerce_spec.rb @@ -655,19 +655,19 @@ def self.parse(_val) params[:values] end - post '/coerce_nested_strings', ::Grape::Json.dump(values: 'a,b,c,d'), 'CONTENT_TYPE' => 'application/json' + post '/coerce_nested_strings', Grape::Json.dump(values: 'a,b,c,d'), 'CONTENT_TYPE' => 'application/json' expect(last_response).to be_created expect(JSON.parse(last_response.body)).to eq([%w[a b c d]]) - post '/coerce_nested_strings', ::Grape::Json.dump(values: [%w[a c], %w[b]]), 'CONTENT_TYPE' => 'application/json' + post '/coerce_nested_strings', Grape::Json.dump(values: [%w[a c], %w[b]]), 'CONTENT_TYPE' => 'application/json' expect(last_response).to be_created expect(JSON.parse(last_response.body)).to eq([%w[a c], %w[b]]) - post '/coerce_nested_strings', ::Grape::Json.dump(values: [[]]), 'CONTENT_TYPE' => 'application/json' + post '/coerce_nested_strings', Grape::Json.dump(values: [[]]), 'CONTENT_TYPE' => 'application/json' expect(last_response).to be_created expect(JSON.parse(last_response.body)).to eq([[]]) - post '/coerce_nested_strings', ::Grape::Json.dump(values: [['a', { bar: 0 }], ['b']]), 'CONTENT_TYPE' => 'application/json' + post '/coerce_nested_strings', Grape::Json.dump(values: [['a', { bar: 0 }], ['b']]), 'CONTENT_TYPE' => 'application/json' expect(last_response).to be_bad_request end diff --git a/spec/grape/validations/validators/default_spec.rb b/spec/grape/validations/validators/default_spec.rb index 2bb59792d8..df84f06ee3 100644 --- a/spec/grape/validations/validators/default_spec.rb +++ b/spec/grape/validations/validators/default_spec.rb @@ -382,8 +382,8 @@ def app [JSON, { test: 'non-empty-string' }.to_json], [Array[JSON], []], [Array[JSON], [{ test: 'non-empty-string' }.to_json]], - [::File, ''], - [::File, { test: 'non-empty-string' }.to_json], + [File, ''], + [File, { test: 'non-empty-string' }.to_json], [Rack::Multipart::UploadedFile, ''], [Rack::Multipart::UploadedFile, { test: 'non-empty-string' }.to_json] ].each do |type, default| diff --git a/spec/grape/validations_spec.rb b/spec/grape/validations_spec.rb index 12acb33d3c..8f7db50c4b 100644 --- a/spec/grape/validations_spec.rb +++ b/spec/grape/validations_spec.rb @@ -4,11 +4,7 @@ subject { Class.new(Grape::API) } let(:app) { subject } - let(:declard_params) {} - - def declared_params - subject.namespace_stackable(:declared_params).flatten - end + let(:declared_params) { subject.namespace_stackable(:declared_params).flatten } describe 'params' do context 'optional' do @@ -1365,24 +1361,6 @@ def validate_param!(attr_name, params) end context 'named' do - context 'can be defined' do - it 'in helpers' do - subject.helpers do - params :pagination do - end - end - end - - it 'in helper module which kind of Grape::DSL::Helpers::BaseHelper' do - shared_params = Module.new do - extend Grape::DSL::Helpers::BaseHelper - params :pagination do - end - end - subject.helpers shared_params - end - end - context 'can be included in usual params' do before do shared_params = Module.new do diff --git a/spec/integration/multi_json/json_spec.rb b/spec/integration/multi_json/json_spec.rb index 994a0aeb2b..56ded26b02 100644 --- a/spec/integration/multi_json/json_spec.rb +++ b/spec/integration/multi_json/json_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true # grape_entity depends on multi-json and it breaks the test. -describe Grape::Json, if: defined?(::MultiJson) && !defined?(Grape::Entity) do +describe Grape::Json, if: defined?(MultiJson) && !defined?(Grape::Entity) do subject { described_class } - it { is_expected.to eq(::MultiJson) } + it { is_expected.to eq(MultiJson) } end diff --git a/spec/integration/multi_xml/xml_spec.rb b/spec/integration/multi_xml/xml_spec.rb index cda102b1d2..a5d998847e 100644 --- a/spec/integration/multi_xml/xml_spec.rb +++ b/spec/integration/multi_xml/xml_spec.rb @@ -3,5 +3,5 @@ describe Grape::Xml, if: defined?(MultiXml) do subject { described_class } - it { is_expected.to eq(::MultiXml) } + it { is_expected.to eq(MultiXml) } end diff --git a/spec/support/deprecated_warning_handlers.rb b/spec/support/deprecated_warning_handlers.rb index 85c4bb78d5..040410fb1d 100644 --- a/spec/support/deprecated_warning_handlers.rb +++ b/spec/support/deprecated_warning_handlers.rb @@ -8,7 +8,7 @@ class DeprecationWarning < StandardError; end DEPRECATION_REGEX = /is deprecated/.freeze def warn(message) - return super(message) unless message.match?(DEPRECATION_REGEX) + return super unless message.match?(DEPRECATION_REGEX) exception = DeprecationWarning.new(message) exception.set_backtrace(caller) diff --git a/spec/support/versioned_helpers.rb b/spec/support/versioned_helpers.rb index e216f7c8f6..75e56e7d18 100644 --- a/spec/support/versioned_helpers.rb +++ b/spec/support/versioned_helpers.rb @@ -10,11 +10,7 @@ def versioned_path(**options) case options[:using] when :path File.join('/', options[:prefix] || '', options[:version], options[:path]) - when :param - File.join('/', options[:prefix] || '', options[:path]) - when :header - File.join('/', options[:prefix] || '', options[:path]) - when :accept_version_header + when :param, :header, :accept_version_header File.join('/', options[:prefix] || '', options[:path]) else raise ArgumentError.new("unknown versioning strategy: #{options[:using]}") @@ -23,10 +19,8 @@ def versioned_path(**options) def versioned_headers(**options) case options[:using] - when :path - {} # no-op - when :param - {} # no-op + when :path, :param + {} when :header { Grape::Http::Headers::HTTP_ACCEPT => [