diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml new file mode 100644 index 0000000000..681f52b46e --- /dev/null +++ b/.github/workflows/danger.yml @@ -0,0 +1,19 @@ +--- +name: Danger +on: + pull_request: + ypes: [opened, reopened, edited, synchronize] +jobs: + danger: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v1 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + bundler-cache: true + - name: Run Danger + run: bundle exec danger + env: + DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000..8782c8247d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,80 @@ +--- +name: test +on: + push: + branches: + - "*" + pull_request: + branches: + - "*" +jobs: + lint: + name: RuboCop + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7 + bundler-cache: true + - name: Run RuboCop + run: bundle exec rubocop + test: + strategy: + fail-fast: false + matrix: + ruby: + - 2.5 + - 2.6 + - 2.7 + gemfile: + - Gemfile + - gemfiles/rack1.gemfile + - gemfiles/rack2.gemfile + - gemfiles/rack_edge.gemfile + - gemfiles/rails_edge.gemfile + - gemfiles/rails_5.gemfile + - gemfiles/rails_6.gemfile + experimental: [false] + include: + - ruby: 2.7 + gemfile: 'gemfiles/multi_json.gemfile' + experimental: false + - ruby: 2.7 + gemfile: 'gemfiles/multi_xml.gemfile' + experimental: false + - ruby: "ruby-head" + experimental: true + - ruby: "truffleruby-head" + experimental: true + - ruby: "jruby-head" + experimental: true + runs-on: ubuntu-20.04 + continue-on-error: ${{ matrix.experimental }} + env: + BUNDLE_GEMFILE: ${{ matrix.gemfile }} + + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + + - name: Run tests + run: bundle exec rake spec + + - name: Run tests (spec/integration/eager_load) + if: ${{ matrix.gemfile == 'Gemfile' }} + run: bundle exec rspec spec/integration/eager_load + + - name: Run tests (spec/integration/multi_json) + if: ${{ matrix.gemfile == 'gemfiles/multi_json.gemfile' }} + run: bundle exec rspec spec/integration/multi_json + + - name: Run tests (spec/integration/multi_xml) + if: ${{ matrix.gemfile == 'gemfiles/multi_xml.gemfile' }} + run: bundle exec rspec spec/integration/multi_xml diff --git a/.rubocop.yml b/.rubocop.yml index e03c5ca662..ee4a91c64d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,7 @@ AllCops: NewCops: enable TargetRubyVersion: 2.4 + SuggestExtensions: false Exclude: - vendor/**/* - bin/**/* diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 84b9fc45bc..4320b39374 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,12 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2020-09-30 12:54:06 -0400 using RuboCop version 0.84.0. +# on 2020-12-26 22:10:33 UTC using RuboCop version 1.7.0. # 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 # versions of RuboCop, may require this file to be generated again. -# Offense count: 6 +# Offense count: 5 # Cop supports --auto-correct. Layout/ClosingHeredocIndentation: Exclude: @@ -18,6 +18,22 @@ Layout/ClosingHeredocIndentation: Layout/EmptyLineAfterGuardClause: Enabled: false +# Offense count: 6 +# Cop supports --auto-correct. +# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. +Layout/EmptyLineBetweenDefs: + Exclude: + - 'spec/grape/api_spec.rb' + - 'spec/grape/middleware/stack_spec.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_brackets +Layout/FirstArrayElementIndentation: + Exclude: + - 'spec/grape/validations_spec.rb' + # Offense count: 27 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. @@ -34,19 +50,90 @@ Layout/HashAlignment: # Offense count: 7 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: squiggly, active_support, powerpack, unindent Layout/HeredocIndentation: Exclude: - 'lib/grape/router/route.rb' - 'spec/grape/api_spec.rb' - 'spec/grape/entity_spec.rb' +# Offense count: 9 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: symmetrical, new_line, same_line +Layout/MultilineArrayBraceLayout: + Exclude: + - 'spec/grape/validations_spec.rb' + +# Offense count: 13 +# Cop supports --auto-correct. +Layout/SpaceBeforeBrackets: + Exclude: + - 'spec/grape/api_remount_spec.rb' + - 'spec/grape/dsl/desc_spec.rb' + - 'spec/grape/entity_spec.rb' + - 'spec/grape/exceptions/invalid_accept_header_spec.rb' + +# Offense count: 71 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'spec/grape/validations_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: AllowInHeredoc. +Layout/TrailingWhitespace: + Exclude: + - 'spec/grape/validations_spec.rb' + # Offense count: 1 Lint/AmbiguousBlockAssociation: Exclude: - 'spec/grape/dsl/routing_spec.rb' +# Offense count: 54 +# Configuration parameters: AllowedMethods. +# AllowedMethods: enums +Lint/ConstantDefinitionInBlock: + Enabled: false + +# Offense count: 5 +# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches. +Lint/DuplicateBranch: + Exclude: + - 'lib/grape/extensions/deep_symbolize_hash.rb' + - 'spec/support/versioned_helpers.rb' + +# Offense count: 85 +# Configuration parameters: AllowComments, AllowEmptyLambdas. +Lint/EmptyBlock: + Enabled: false + +# Offense count: 6 +# Configuration parameters: AllowComments. +Lint/EmptyClass: + Exclude: + - 'lib/grape/dsl/parameters.rb' + - 'lib/grape/validations/types.rb' + - 'spec/grape/api_spec.rb' + - 'spec/grape/entity_spec.rb' + - 'spec/grape/middleware/stack_spec.rb' + +# Offense count: 9 +Lint/MissingSuper: + Exclude: + - 'lib/grape/api.rb' + - 'lib/grape/api/instance.rb' + - 'lib/grape/exceptions/base.rb' + - 'lib/grape/exceptions/validation_array_errors.rb' + - 'lib/grape/namespace.rb' + - 'lib/grape/path.rb' + - 'lib/grape/router/pattern.rb' + - 'lib/grape/validations/validators/base.rb' + # Offense count: 1 # Cop supports --auto-correct. Lint/NonDeterministicRequireOrder: @@ -59,54 +146,68 @@ Lint/ToJSON: Exclude: - 'spec/grape/middleware/formatter_spec.rb' -# Offense count: 50 -# Configuration parameters: IgnoredMethods. +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AllowComments. +Lint/UselessMethodDefinition: + Exclude: + - 'lib/grape/validations/validators/coerce.rb' + +# Offense count: 42 +# Configuration parameters: IgnoredMethods, CountRepeatedAttributes. Metrics/AbcSize: - Max: 43 + Max: 47 # Offense count: 6 -# Configuration parameters: CountComments, ExcludedMethods. -# ExcludedMethods: refine +# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. +# IgnoredMethods: refine Metrics/BlockLength: Max: 182 # Offense count: 11 -# Configuration parameters: CountComments. +# Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: Max: 304 # Offense count: 30 # Configuration parameters: IgnoredMethods. Metrics/CyclomaticComplexity: - Max: 14 + Max: 17 -# Offense count: 69 -# Configuration parameters: CountComments, ExcludedMethods. +# Offense count: 71 +# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. Metrics/MethodLength: Max: 32 # Offense count: 12 -# Configuration parameters: CountComments. +# Configuration parameters: CountComments, CountAsOne. Metrics/ModuleLength: Max: 220 -# Offense count: 25 +# Offense count: 1 +# Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters. +Metrics/ParameterLists: + Exclude: + - 'lib/grape/middleware/error.rb' + +# Offense count: 27 # Configuration parameters: IgnoredMethods. Metrics/PerceivedComplexity: - Max: 14 + Max: 18 -# Offense count: 3 +# Offense count: 4 # Configuration parameters: EnforcedStyleForLeadingUnderscores. # SupportedStylesForLeadingUnderscores: disallowed, required, optional Naming/MemoizedInstanceVariableName: Exclude: - 'lib/grape/api/instance.rb' + - 'lib/grape/config.rb' - 'lib/grape/middleware/base.rb' - 'spec/grape/integration/rack_spec.rb' # Offense count: 5 # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: io, id, to, by, on, in, at, ip, db, os, pp +# AllowedNames: at, by, db, id, in, io, ip, of, on, os, pp, to Naming/MethodParameterName: Exclude: - 'lib/grape/endpoint.rb' @@ -114,12 +215,95 @@ Naming/MethodParameterName: - 'lib/grape/middleware/stack.rb' - 'spec/grape/api_spec.rb' +# Offense count: 18 +# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers. +# SupportedStyles: snake_case, normalcase, non_integer +# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339 +Naming/VariableNumber: + Exclude: + - 'spec/grape/dsl/settings_spec.rb' + - 'spec/grape/exceptions/validation_errors_spec.rb' + - 'spec/grape/validations_spec.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +Performance/BigDecimalWithNumericArgument: + Exclude: + - 'spec/grape/validations/types/primitive_coercer_spec.rb' + +# Offense count: 21 +# Cop supports --auto-correct. +Performance/BlockGivenWithExplicitBlock: + Exclude: + - 'lib/grape/api/instance.rb' + - 'lib/grape/dsl/desc.rb' + - 'lib/grape/dsl/helpers.rb' + - 'lib/grape/dsl/middleware.rb' + - 'lib/grape/dsl/parameters.rb' + - 'lib/grape/dsl/request_response.rb' + - 'lib/grape/dsl/routing.rb' + - 'lib/grape/dsl/settings.rb' + - 'lib/grape/endpoint.rb' + - 'lib/grape/validations/params_scope.rb' + +# Offense count: 2 +# Configuration parameters: MinSize. +Performance/CollectionLiteralInLoop: + Exclude: + - 'spec/grape/api_spec.rb' + - 'spec/grape/middleware/formatter_spec.rb' + # Offense count: 3 # Cop supports --auto-correct. Performance/InefficientHashSearch: Exclude: - 'spec/grape/validations/validators/values_spec.rb' +# Offense count: 1 +Performance/MethodObjectAsBlock: + Exclude: + - 'lib/grape/middleware/stack.rb' + +# Offense count: 9 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: separated, grouped +Style/AccessorGrouping: + Exclude: + - 'lib/grape/api/instance.rb' + - 'lib/grape/exceptions/validation.rb' + - 'lib/grape/util/inheritable_setting.rb' + - 'spec/grape/middleware/error_spec.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +Style/CaseLikeIf: + Exclude: + - 'lib/grape/util/lazy_value.rb' + - 'spec/grape/validations/validators/coerce_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: IgnoredMethods. +# IgnoredMethods: ==, equal?, eql? +Style/ClassEqualityComparison: + Exclude: + - 'lib/grape/validations/types/dry_type_coercer.rb' + - 'lib/grape/validations/validators/coerce.rb' + +# Offense count: 1 +Style/CombinableLoops: + Exclude: + - 'spec/grape/endpoint_spec.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: Keywords. +# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW, NOTE +Style/CommentAnnotation: + Exclude: + - 'spec/grape/api_spec.rb' + # Offense count: 5 # Cop supports --auto-correct. Style/EmptyLambdaParameter: @@ -138,12 +322,24 @@ Style/ExpandPathArguments: - 'lib/grape.rb' - 'spec/grape/validations/validators/coerce_spec.rb' +# Offense count: 1 +# Cop supports --auto-correct. +Style/ExplicitBlockArgument: + Exclude: + - 'lib/grape/middleware/stack.rb' + # Offense count: 2 -# Configuration parameters: . +# Configuration parameters: MaxUnannotatedPlaceholdersAllowed. # SupportedStyles: annotated, template, unannotated Style/FormatStringToken: EnforcedStyle: template +# Offense count: 1 +# Cop supports --auto-correct. +Style/GlobalStdStream: + Exclude: + - 'benchmark/remounting.rb' + # Offense count: 19 # Cop supports --auto-correct. Style/IfUnlessModifier: @@ -159,20 +355,41 @@ Style/IfUnlessModifier: - 'lib/grape/middleware/versioner/accept_version_header.rb' - 'lib/grape/validations/params_scope.rb' -# Offense count: 1 -Style/MethodMissingSuper: - Exclude: - - 'lib/grape/router/attribute_translator.rb' - # Offense count: 1 # Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. +# Configuration parameters: EnforcedStyle, IgnoredMethods. # SupportedStyles: predicate, comparison Style/NumericPredicate: Exclude: - 'spec/**/*' - 'lib/grape/middleware/formatter.rb' +# Offense count: 12 +# Configuration parameters: AllowedMethods. +# AllowedMethods: respond_to_missing? +Style/OptionalBooleanParameter: + Exclude: + - 'lib/grape/api.rb' + - 'lib/grape/dsl/inside_route.rb' + - 'lib/grape/dsl/parameters.rb' + - 'lib/grape/endpoint.rb' + - 'lib/grape/serve_stream/sendfile_response.rb' + - 'lib/grape/validations/params_scope.rb' + - 'lib/grape/validations/types/array_coercer.rb' + - 'lib/grape/validations/types/custom_type_collection_coercer.rb' + - 'lib/grape/validations/types/dry_type_coercer.rb' + - 'lib/grape/validations/types/primitive_coercer.rb' + - 'lib/grape/validations/types/set_coercer.rb' + +# Offense count: 18 +# Cop supports --auto-correct. +Style/RedundantRegexpEscape: + Exclude: + - 'lib/grape/middleware/versioner/header.rb' + - 'lib/grape/middleware/versioner/parse_media_type_patch.rb' + - 'spec/grape/api/routes_with_requirements_spec.rb' + - 'spec/grape/api_spec.rb' + # Offense count: 10 # Cop supports --auto-correct. # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods. @@ -187,6 +404,42 @@ Style/SafeNavigation: - 'lib/grape/middleware/versioner/accept_version_header.rb' - 'lib/grape/middleware/versioner/header.rb' +# Offense count: 4 +# Cop supports --auto-correct. +# Configuration parameters: AllowModifier. +Style/SoleNestedConditional: + Exclude: + - 'lib/grape/api/instance.rb' + - 'lib/grape/middleware/versioner/accept_version_header.rb' + - 'lib/grape/validations/params_scope.rb' + +# Offense count: 7 +# Cop supports --auto-correct. +Style/StringConcatenation: + Exclude: + - 'benchmark/large_model.rb' + - 'lib/grape/dsl/inside_route.rb' + - 'lib/grape/router/pattern.rb' + - 'spec/grape/validations/validators/values_spec.rb' + - 'spec/shared/versioning_examples.rb' + - 'spec/support/basic_auth_encode_helpers.rb' + +# Offense count: 32 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Exclude: + - 'spec/grape/validations_spec.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInArguments: + Exclude: + - 'spec/grape/validations/single_attribute_iterator_spec.rb' + # Offense count: 10 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinSize, WordRegex. @@ -196,7 +449,7 @@ Style/WordArray: - 'spec/grape/validations/validators/except_values_spec.rb' - 'spec/grape/validations/validators/values_spec.rb' -# Offense count: 131 +# Offense count: 132 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 48632523dc..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,64 +0,0 @@ -language: ruby - -sudo: false - -# "gemfile" is required for "allow_failures" option, -# see https://docs.travis-ci.com/user/customizing-the-build/#matching-jobs-with-allow_failures -gemfile: - -script: bundle exec rake spec - -matrix: - include: - - rvm: 2.7.1 - script: - - bundle exec danger - - rvm: 2.7.1 - gemfile: Gemfile - - rvm: 2.7.1 - gemfile: gemfiles/rack1.gemfile - - rvm: 2.7.1 - gemfile: gemfiles/rack2.gemfile - - rvm: 2.7.1 - gemfile: gemfiles/rack_edge.gemfile - - rvm: 2.7.1 - gemfile: gemfiles/rails_edge.gemfile - - rvm: 2.7.1 - gemfile: gemfiles/rails_5.gemfile - - rvm: 2.7.1 - gemfile: gemfiles/rails_6.gemfile - - rvm: 2.7.1 - gemfile: Gemfile - script: - - bundle exec rspec spec/integration/eager_load - - rvm: 2.7.1 - gemfile: gemfiles/multi_json.gemfile - script: - - bundle exec rspec spec/integration/multi_json - - rvm: 2.7.1 - gemfile: gemfiles/multi_xml.gemfile - script: - - bundle exec rspec spec/integration/multi_xml - - rvm: 2.6.6 - gemfile: Gemfile - - rvm: 2.6.6 - gemfile: gemfiles/rails_5.gemfile - - rvm: 2.6.6 - gemfile: gemfiles/rails_6.gemfile - - rvm: 2.5.8 - gemfile: Gemfile - - rvm: 2.5.8 - gemfile: gemfiles/rails_5.gemfile - - rvm: 2.5.8 - gemfile: gemfiles/rails_6.gemfile - - rvm: ruby-head - - rvm: jruby-head - - rvm: rbx-3 - - rvm: truffleruby-head - allow_failures: - - rvm: ruby-head - - rvm: jruby-head - - rvm: rbx-3 - - rvm: truffleruby-head - -bundler_args: --without development diff --git a/Appraisals b/Appraisals index 7e17deba50..1613cfa03d 100644 --- a/Appraisals +++ b/Appraisals @@ -8,6 +8,10 @@ appraise 'rails-6' do gem 'rails', '~> 6.0' end +appraise 'rails-6-1' do + gem 'rails', '~> 6.1' +end + appraise 'rails-edge' do gem 'rails', github: 'rails/rails' end diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cef5172ff..7d89d93528 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,13 @@ #### Features * Your contribution here. +* [#2143](https://github.com/ruby-grape/grape/pull/2143): Enable GitHub Actions with updated RuboCop and Danger - [@anakinj](https://github.com/anakinj). +* [#2145](https://github.com/ruby-grape/grape/pull/2145): Ruby 3.0 compatibility - [@ericproulx](https://github.com/ericproulx). #### Fixes * Your contribution here. +* [#2144](https://github.com/ruby-grape/grape/pull/2144): Fix compatibility issue with activesupport 6.1 and XML serialization of arrays - [@anakinj](https://github.com/anakinj). * [#2137](https://github.com/ruby-grape/grape/pull/2137): Fix typos - [@johnny-miyake](https://github.com/johnny-miyake). * [#2131](https://github.com/ruby-grape/grape/pull/2131): Fix Ruby 2.7 keyword deprecation warning in validators/coerce - [@K0H205](https://github.com/K0H205). * [#2132](https://github.com/ruby-grape/grape/pull/2132): Use #ruby2_keywords for correct delegation on Ruby <= 2.6, 2.7 and 3 - [@eregon](https://github.com/eregon). diff --git a/Dangerfile b/Dangerfile index 2f12006400..527dbb8b7a 100644 --- a/Dangerfile +++ b/Dangerfile @@ -1,4 +1,4 @@ # frozen_string_literal: true danger.import_dangerfile(gem: 'ruby-grape-danger') -toc.check +toc.check! diff --git a/Gemfile b/Gemfile index 99de12cfb7..6c4124a52d 100644 --- a/Gemfile +++ b/Gemfile @@ -10,9 +10,9 @@ group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' - gem 'rubocop', '0.84.0' - gem 'rubocop-ast', '< 0.7' - gem 'rubocop-performance', require: false + gem 'rubocop', '1.7.0' + gem 'rubocop-ast', '1.3.0' + gem 'rubocop-performance', '1.9.1', require: false end group :development do @@ -27,12 +27,11 @@ end group :test do gem 'cookiejar' gem 'coveralls_reborn' - gem 'danger-toc', '~> 0.1.2' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 1.1.0' gem 'rspec', '~> 3.0' - gem 'ruby-grape-danger', '~> 0.1.0', require: false + gem 'ruby-grape-danger', '~> 0.2.0', require: false end diff --git a/README.md b/README.md index 0261cbc531..9e3a1dd6c4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![grape logo](grape.png) [![Gem Version](https://badge.fury.io/rb/grape.svg)](http://badge.fury.io/rb/grape) -[![Build Status](https://travis-ci.org/ruby-grape/grape.svg?branch=master)](https://travis-ci.org/ruby-grape/grape) +[![Build Status](https://github.com/ruby-grape/grape/workflows/test/badge.svg?branch=master)](https://github.com/ruby-grape/grape/actions) [![Code Climate](https://codeclimate.com/github/ruby-grape/grape.svg)](https://codeclimate.com/github/ruby-grape/grape) [![Coverage Status](https://coveralls.io/repos/github/ruby-grape/grape/badge.svg?branch=master)](https://coveralls.io/github/ruby-grape/grape?branch=master) [![Inline docs](https://inch-ci.org/github/ruby-grape/grape.svg)](https://inch-ci.org/github/ruby-grape/grape) diff --git a/gemfiles/rails_6_1.gemfile b/gemfiles/rails_6_1.gemfile new file mode 100644 index 0000000000..53755018da --- /dev/null +++ b/gemfiles/rails_6_1.gemfile @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +# This file was generated by Appraisal + +source 'https://rubygems.org' + +gem 'rails', '~> 6.1' + +group :development, :test do + gem 'bundler' + gem 'hashie' + gem 'rake' + gem 'rubocop', '0.84.0' + gem 'rubocop-ast', '< 0.7' + gem 'rubocop-performance', require: false +end + +group :development do + gem 'appraisal' + gem 'benchmark-ips' + gem 'guard' + gem 'guard-rspec' + gem 'guard-rubocop' +end + +group :test do + gem 'cookiejar' + gem 'coveralls_reborn' + gem 'danger-toc', '~> 0.1.2' + gem 'grape-entity', '~> 0.6' + gem 'maruku' + gem 'mime-types' + gem 'rack-jsonp', require: 'rack/jsonp' + gem 'rack-test', '~> 1.1.0' + gem 'rspec', '~> 3.0' + gem 'ruby-grape-danger', '~> 0.1.0', require: false +end + +gemspec path: '../' diff --git a/lib/grape.rb b/lib/grape.rb index e2a0b98082..c1f313c2f9 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -12,6 +12,7 @@ require 'active_support/core_ext/object/blank' require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/array/conversions' require 'active_support/core_ext/hash/deep_merge' require 'active_support/core_ext/hash/reverse_merge' require 'active_support/core_ext/hash/except' diff --git a/lib/grape/dsl/routing.rb b/lib/grape/dsl/routing.rb index 76a22a79f0..61bf1f21a8 100644 --- a/lib/grape/dsl/routing.rb +++ b/lib/grape/dsl/routing.rb @@ -79,11 +79,12 @@ def do_not_route_options! namespace_inheritable(:do_not_route_options, true) end - def mount(mounts, **opts) + def mount(mounts, *opts) mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair) mounts.each_pair do |app, path| if app.respond_to?(:mount_instance) - mount(app.mount_instance(configuration: opts[:with] || {}) => path) + opts_with = opts.any? ? opts.shift[:with] : {} + mount({ app.mount_instance(configuration: opts_with) => path }) next end in_setting = inheritable_setting diff --git a/lib/grape/exceptions/validation_errors.rb b/lib/grape/exceptions/validation_errors.rb index f8bf32e31e..20f7dd2bfd 100644 --- a/lib/grape/exceptions/validation_errors.rb +++ b/lib/grape/exceptions/validation_errors.rb @@ -39,7 +39,7 @@ def as_json(**_opts) end end - def to_json(**_opts) + def to_json(*_opts) as_json.to_json end diff --git a/lib/grape/middleware/auth/base.rb b/lib/grape/middleware/auth/base.rb index 61a8cc5889..081613c920 100644 --- a/lib/grape/middleware/auth/base.rb +++ b/lib/grape/middleware/auth/base.rb @@ -10,9 +10,9 @@ class Base attr_accessor :options, :app, :env - def initialize(app, **options) + def initialize(app, *options) @app = app - @options = options + @options = options.shift end def call(env) @@ -23,7 +23,7 @@ def _call(env) self.env = env if options.key?(:type) - auth_proc = options[:proc] + auth_proc = options[:proc] auth_proc_context = context strategy_info = Grape::Middleware::Auth::Strategies[options[:type]] diff --git a/lib/grape/middleware/base.rb b/lib/grape/middleware/base.rb index 0e0f1729c4..730a6cb3cb 100644 --- a/lib/grape/middleware/base.rb +++ b/lib/grape/middleware/base.rb @@ -15,9 +15,9 @@ class Base # @param [Rack Application] app The standard argument for a Rack middleware. # @param [Hash] options A hash of options, simply stored for use by subclasses. - def initialize(app, **options) + def initialize(app, *options) @app = app - @options = default_options.merge(options) + @options = options.any? ? default_options.merge(options.shift) : default_options @app_response = nil end diff --git a/lib/grape/middleware/error.rb b/lib/grape/middleware/error.rb index 54bded3c87..20f6a89f35 100644 --- a/lib/grape/middleware/error.rb +++ b/lib/grape/middleware/error.rb @@ -27,7 +27,7 @@ def default_options } end - def initialize(app, **options) + def initialize(app, *options) super self.class.send(:include, @options[:helpers]) if @options[:helpers] end diff --git a/lib/grape/validations/validators/base.rb b/lib/grape/validations/validators/base.rb index af7030f140..f45a254ca5 100644 --- a/lib/grape/validations/validators/base.rb +++ b/lib/grape/validations/validators/base.rb @@ -12,14 +12,16 @@ class Base # @param options [Object] implementation-dependent Validator options # @param required [Boolean] attribute(s) are required or optional # @param scope [ParamsScope] parent scope for this Validator - # @param opts [Hash] additional validation options - def initialize(attrs, options, required, scope, **opts) + # @param opts [Array] additional validation options + def initialize(attrs, options, required, scope, *opts) @attrs = Array(attrs) @option = options @required = required @scope = scope - @fail_fast = opts[:fail_fast] || false - @allow_blank = opts[:allow_blank] || false + @opts = opts + opts = opts.any? ? opts.shift : {} + @fail_fast = opts.fetch(:fail_fast, false) + @allow_blank = opts.fetch(:allow_blank, false) end # Validates a given request. diff --git a/spec/grape/request_spec.rb b/spec/grape/request_spec.rb index ee5a436430..1bfce035e0 100644 --- a/spec/grape/request_spec.rb +++ b/spec/grape/request_spec.rb @@ -75,7 +75,7 @@ module Grape Grape.config.reset end - subject(:request_params) { Grape::Request.new(env, opts).params } + subject(:request_params) { Grape::Request.new(env, **opts).params } context 'when the API does not include a specific param builder' do let(:opts) { {} } diff --git a/spec/shared/versioning_examples.rb b/spec/shared/versioning_examples.rb index 8e8552070c..ebc0742d41 100644 --- a/spec/shared/versioning_examples.rb +++ b/spec/shared/versioning_examples.rb @@ -7,7 +7,7 @@ subject.get :hello do "Version: #{request.env['api.version']}" end - versioned_get '/hello', 'v1', macro_options + versioned_get '/hello', 'v1', **macro_options expect(last_response.body).to eql 'Version: v1' end @@ -18,7 +18,7 @@ subject.get :hello do "Version: #{request.env['api.version']}" end - versioned_get '/hello', 'v1', macro_options.merge(prefix: 'api') + versioned_get '/hello', 'v1', **macro_options.merge(prefix: 'api') expect(last_response.body).to eql 'Version: v1' end @@ -34,14 +34,14 @@ end end - versioned_get '/awesome', 'v1', macro_options + versioned_get '/awesome', 'v1', **macro_options expect(last_response.status).to eql 404 - versioned_get '/awesome', 'v2', macro_options + versioned_get '/awesome', 'v2', **macro_options expect(last_response.status).to eql 200 - versioned_get '/legacy', 'v1', macro_options + versioned_get '/legacy', 'v1', **macro_options expect(last_response.status).to eql 200 - versioned_get '/legacy', 'v2', macro_options + versioned_get '/legacy', 'v2', **macro_options expect(last_response.status).to eql 404 end @@ -51,11 +51,11 @@ 'I exist' end - versioned_get '/awesome', 'v1', macro_options + versioned_get '/awesome', 'v1', **macro_options expect(last_response.status).to eql 200 - versioned_get '/awesome', 'v2', macro_options + versioned_get '/awesome', 'v2', **macro_options expect(last_response.status).to eql 200 - versioned_get '/awesome', 'v3', macro_options + versioned_get '/awesome', 'v3', **macro_options expect(last_response.status).to eql 404 end @@ -74,10 +74,10 @@ end end - versioned_get '/version', 'v2', macro_options + versioned_get '/version', 'v2', **macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') - versioned_get '/version', 'v1', macro_options + versioned_get '/version', 'v1', **macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('version v1') end @@ -98,11 +98,11 @@ end end - versioned_get '/version', 'v1', macro_options.merge(prefix: subject.prefix) + versioned_get '/version', 'v1', **macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('version v1') - versioned_get '/version', 'v2', macro_options.merge(prefix: subject.prefix) + versioned_get '/version', 'v2', **macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') end @@ -131,11 +131,11 @@ end end - versioned_get '/version', 'v1', macro_options.merge(prefix: subject.prefix) + versioned_get '/version', 'v1', **macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v1-version') - versioned_get '/version', 'v2', macro_options.merge(prefix: subject.prefix) + versioned_get '/version', 'v2', **macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2-version') end @@ -148,7 +148,7 @@ subject.get :api_version_with_version_param do params[:version] end - versioned_get '/api_version_with_version_param?version=1', 'v1', macro_options + versioned_get '/api_version_with_version_param?version=1', 'v1', **macro_options expect(last_response.body).to eql '1' end @@ -183,13 +183,13 @@ context 'v1' do it 'finds endpoint' do - versioned_get '/version', 'v1', macro_options + versioned_get '/version', 'v1', **macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v1') end it 'finds catch all' do - versioned_get '/whatever', 'v1', macro_options + versioned_get '/whatever', 'v1', **macro_options expect(last_response.status).to eq(200) expect(last_response.body).to end_with 'whatever' end @@ -197,13 +197,13 @@ context 'v2' do it 'finds endpoint' do - versioned_get '/version', 'v2', macro_options + versioned_get '/version', 'v2', **macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') end it 'finds catch all' do - versioned_get '/whatever', 'v2', macro_options + versioned_get '/whatever', 'v2', **macro_options expect(last_response.status).to eq(200) expect(last_response.body).to end_with 'whatever' end diff --git a/spec/support/versioned_helpers.rb b/spec/support/versioned_helpers.rb index 8d7c07f184..ea78013d43 100644 --- a/spec/support/versioned_helpers.rb +++ b/spec/support/versioned_helpers.rb @@ -44,7 +44,7 @@ def versioned_headers(**options) end def versioned_get(path, version_name, **version_options) - path = versioned_path(version_options.merge(version: version_name, path: path)) + path = versioned_path(**version_options.merge(version: version_name, path: path)) headers = versioned_headers(**version_options.merge(version: version_name)) params = {} params = { version_options[:parameter] => version_name } if version_options[:using] == :param