diff --git a/.github/workflows/release-rubygem.yml b/.github/workflows/release-rubygem.yml index 0314b2b2d..4399b4e84 100644 --- a/.github/workflows/release-rubygem.yml +++ b/.github/workflows/release-rubygem.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: - ruby-version: '3.2' + ruby-version: '3.3' bundler-cache: true - uses: cucumber/action-publish-rubygem@v1.0.0 with: diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index c07d8cc2c..c032002b0 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -26,10 +26,10 @@ jobs: matrix: os: - ubuntu-latest - ruby: ['2.6', '2.7', '3.0', '3.1', '3.2'] + ruby: ['3.0', '3.1', '3.2', '3.3'] include: - os: macos-latest - ruby: '3.2' + ruby: '3.3' steps: - uses: actions/checkout@v4 @@ -38,9 +38,7 @@ jobs: ruby-version: ${{ matrix.ruby }} bundler-cache: true working-directory: ruby - - run: bundle exec rake working-directory: ruby - - run: make acceptance working-directory: ruby diff --git a/CHANGELOG.md b/CHANGELOG.md index a7c4fb96a..5b5f947c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt ## [Unreleased] ### Added - (i18n) Added Gujarati translation for "Rule" ([#249](https://github.com/cucumber/gherkin/pull/249)) +- [Ruby] Skeleton to begin technical refactor of internals ([#259](https://github.com/cucumber/gherkin/pull/259)) ### Fixed - [.NET] Provide informative exception for trailing escapes in tables ([#245](https://github.com/cucumber/gherkin/pull/245)) @@ -20,6 +21,10 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt - (i18n) Tamil "And" and "But" translations should have single trailing space ([#243](https://github.com/cucumber/gherkin/pull/243)) - Intermittent failure of cpp test jobs in CI ([#217](https://github.com/cucumber/gherkin/issues/217)) +### Changed +- [Java, JavaScript, PHP, Go, Ruby] Upgraded messages to v25 +- [Ruby] Update minimum ruby requirement from 2.5 to 3.0 ([#259](https://github.com/cucumber/gherkin/pull/259)) + ## [28.0.0] - 2024-02-15 ### Added - [Python] Added release workflow for releasing to Pypi ([#213](https://github.com/cucumber/gherkin/pull/213)) @@ -30,7 +35,6 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt - [Python] Reuse the action cucumber/action-publish-pypi in release ([#220](https://github.com/cucumber/gherkin/pull/220)) - [Python] Removed duplicate code in markdown token matcher ([#205](https://github.com/cucumber/gherkin/pull/205)) - [Java, JavaScript, PHP, Go, Ruby] Upgraded messages to v24 -- Upgraded messages to v22 ## [27.0.0] - 2023-09-15 ### Added diff --git a/ruby/.rspec b/ruby/.rspec index 4e1e0d2f7..3687797e5 100644 --- a/ruby/.rspec +++ b/ruby/.rspec @@ -1 +1,2 @@ +--require spec_helper --color diff --git a/ruby/.rubocop.yml b/ruby/.rubocop.yml new file mode 100644 index 000000000..6a64fcbb2 --- /dev/null +++ b/ruby/.rubocop.yml @@ -0,0 +1,13 @@ +inherit_from: .rubocop_todo.yml + +inherit_mode: + merge: + - Exclude + +AllCops: + NewCops: disable + # Keep this inline with the lowest ruby version in the gemspec + TargetRubyVersion: 3.0 + # Display cop name / style guide references + DisplayCopNames: true + DisplayStyleGuide: true diff --git a/ruby/.rubocop_todo.yml b/ruby/.rubocop_todo.yml new file mode 100644 index 000000000..7da3223d8 --- /dev/null +++ b/ruby/.rubocop_todo.yml @@ -0,0 +1,714 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2024-07-18 10:25:13 UTC using RuboCop version 1.26.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 +# versions of RuboCop, may require this file to be generated again. + +# TODO: We need to scan this file VERY carefully as the majority of items here WON'T be fixable as we want to keep +# a similar style with each language implementation to ensure fixing bugs is easy +# Pass 0 - July 2024 - 26 files inspected, 3031 offenses detected, 2667 offenses auto-correctable + +# Offense count: 6 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: with_first_argument, with_fixed_indentation +Layout/ArgumentAlignment: + Exclude: + - 'lib/gherkin/token_formatter_builder.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +Layout/ClosingParenthesisIndentation: + Exclude: + - 'lib/gherkin.rb' + +# Offense count: 80 +# This cop supports safe auto-correction (--auto-correct). +Layout/EmptyLineAfterGuardClause: + Exclude: + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/dialect.rb' + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/pickles/compiler.rb' + - 'lib/gherkin/query.rb' + - 'lib/gherkin/stream/parser_message_stream.rb' + - 'lib/gherkin/token_matcher.rb' + - 'spec/gherkin/query_spec.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +Layout/EmptyLineAfterMagicComment: + Exclude: + - 'Gemfile' + - 'spec/gherkin/dialect_spec.rb' + +# Offense count: 51 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. +Layout/EmptyLineBetweenDefs: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 3 +# This cop supports safe auto-correction (--auto-correct). +Layout/EmptyLines: + Exclude: + - 'lib/gherkin/parser.rb' + - 'spec/gherkin/stream/parser_message_stream_spec.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: around, only_before +Layout/EmptyLinesAroundAccessModifier: + Exclude: + - 'lib/gherkin/token_formatter_builder.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowAliasSyntax, AllowedMethods. +# AllowedMethods: alias_method, public, protected, private +Layout/EmptyLinesAroundAttributeAccessor: + Exclude: + - 'lib/gherkin/gherkin_line.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, no_empty_lines +Layout/EmptyLinesAroundBlockBody: + Exclude: + - 'lib/gherkin/pickles/compiler.rb' + +# Offense count: 3 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only +Layout/EmptyLinesAroundClassBody: + Exclude: + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/token_formatter_builder.rb' + - 'lib/gherkin/token_scanner.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines +Layout/EmptyLinesAroundModuleBody: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. +Layout/ExtraSpacing: + Exclude: + - 'lib/gherkin/errors.rb' + +# Offense count: 4 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses +Layout/FirstArgumentIndentation: + Exclude: + - 'lib/gherkin.rb' + - 'lib/gherkin/ast_builder.rb' + +# Offense count: 6 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_brackets +Layout/FirstArrayElementIndentation: + EnforcedStyle: consistent + +# Offense count: 58 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: Width, IgnoredPatterns. +Layout/IndentationWidth: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment. +Layout/LeadingCommentSpace: + Exclude: + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 6 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: aligned, indented +Layout/MultilineOperationIndentation: + Exclude: + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 3 +# This cop supports safe auto-correction (--auto-correct). +Layout/SpaceAfterComma: + Exclude: + - 'bin/gherkin' + - 'bin/gherkin-generate-tokens' + - 'lib/gherkin/gherkin_line.rb' + +# Offense count: 4 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: space, no_space +Layout/SpaceAroundEqualsInParameterDefault: + Exclude: + - 'lib/gherkin.rb' + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +Layout/SpaceAroundKeyword: + Exclude: + - 'lib/gherkin/token_scanner.rb' + +# Offense count: 8 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator. +# SupportedStylesForExponentOperator: space, no_space +Layout/SpaceAroundOperators: + Exclude: + - 'bin/gherkin' + - 'bin/gherkin-generate-tokens' + - 'lib/gherkin/errors.rb' + - 'lib/gherkin/gherkin_line.rb' + - 'lib/gherkin/parser.rb' + +# Offense count: 3 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. +# SupportedStyles: space, no_space +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideBlockBraces: + Exclude: + - 'lib/gherkin/pickles/compiler.rb' + - 'lib/gherkin/token_formatter_builder.rb' + +# Offense count: 10 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'lib/gherkin/errors.rb' + - 'lib/gherkin/token_scanner.rb' + - 'spec/gherkin/gherkin_spec.rb' + +# Offense count: 14 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: space, compact, no_space +Layout/SpaceInsideParens: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: final_newline, final_blank_line +Layout/TrailingEmptyLines: + Exclude: + - 'spec/gherkin/gherkin_line_spec.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowInHeredoc. +Layout/TrailingWhitespace: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# Configuration parameters: AllowSafeAssignment. +Lint/AssignmentInCondition: + Exclude: + - 'lib/gherkin/token_scanner.rb' + +# Offense count: 2 +Lint/ImplicitStringConcatenation: + Exclude: + - 'spec/gherkin/query_spec.rb' + +# Offense count: 1 +Lint/IneffectiveAccessModifier: + Exclude: + - 'lib/gherkin.rb' + +# Offense count: 4 +Lint/LiteralAsCondition: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports unsafe auto-correction (--auto-correct-all). +Lint/Loop: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +Lint/NonLocalExitFromIterator: + Exclude: + - 'spec/gherkin/query_spec.rb' + +# Offense count: 4 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods. +Lint/UnusedMethodArgument: + Exclude: + - 'bin/gherkin' + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/errors.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. +Lint/UselessAccessModifier: + Exclude: + - 'lib/gherkin.rb' + +# Offense count: 2 +Lint/UselessAssignment: + Exclude: + - 'lib/gherkin/ast_builder.rb' + - 'spec/gherkin/gherkin_spec.rb' + +# Offense count: 59 +# Configuration parameters: IgnoredMethods, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 121 + +# Offense count: 8 +# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. +# IgnoredMethods: refine +Metrics/BlockLength: + Max: 162 + +# Offense count: 1 +# Configuration parameters: CountBlocks. +Metrics/BlockNesting: + Max: 4 + +# Offense count: 4 +# Configuration parameters: CountComments, CountAsOne. +Metrics/ClassLength: + Max: 3693 + +# Offense count: 44 +# Configuration parameters: IgnoredMethods. +Metrics/CyclomaticComplexity: + Max: 51 + +# Offense count: 71 +# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. +Metrics/MethodLength: + Max: 142 + +# Offense count: 5 +# Configuration parameters: CountKeywordArgs. +Metrics/ParameterLists: + Max: 7 + MaxOptionalParameters: 5 + +# Offense count: 44 +# Configuration parameters: IgnoredMethods. +Metrics/PerceivedComplexity: + Max: 18 + +# Offense count: 3 +Naming/AccessorMethodName: + Exclude: + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/token_formatter_builder.rb' + +# Offense count: 29 +# Configuration parameters: IgnoredPatterns. +# SupportedStyles: snake_case, camelCase +Naming/MethodName: + EnforcedStyle: snake_case + +# Offense count: 3 +# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. +# AllowedNames: at, by, db, id, in, io, ip, of, on, os, pp, to +Naming/MethodParameterName: + Exclude: + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/stream/parser_message_stream.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: PreferredName. +Naming/RescuedExceptionsVariableName: + Exclude: + - 'lib/gherkin/stream/parser_message_stream.rb' + +# Offense count: 4 +# Configuration parameters: EnforcedStyle, AllowedIdentifiers. +# SupportedStyles: snake_case, camelCase +Naming/VariableName: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 52 +# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers. +# SupportedStyles: snake_case, normalcase, non_integer +# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339 +Naming/VariableNumber: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 6 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods, AllowBracesOnProceduralOneLiners, BracesRequiredMethods. +# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces +# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object +# FunctionalMethods: let, let!, subject, watch +# IgnoredMethods: lambda, proc, it +Style/BlockDelimiters: + Exclude: + - 'lib/gherkin/gherkin_line.rb' + - 'spec/gherkin/stream/parser_message_stream_spec.rb' + +# Offense count: 2 +# This cop supports unsafe auto-correction (--auto-correct-all). +Style/CaseLikeIf: + Exclude: + - 'lib/gherkin/gherkin_line.rb' + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. +# SupportedStyles: assign_to_condition, assign_inside_condition +Style/ConditionalAssignment: + Exclude: + - 'bin/gherkin' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +Style/DefWithParentheses: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 18 +# Configuration parameters: AllowedConstants. +Style/Documentation: + Exclude: + - 'lib/gherkin.rb' + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/ast_node.rb' + - 'lib/gherkin/dialect.rb' + - 'lib/gherkin/errors.rb' + - 'lib/gherkin/gherkin_line.rb' + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/pickles/compiler.rb' + - 'lib/gherkin/query.rb' + - 'lib/gherkin/stream/parser_message_stream.rb' + - 'lib/gherkin/token.rb' + - 'lib/gherkin/token_formatter_builder.rb' + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: compact, expanded +Style/EmptyMethod: + Exclude: + - 'lib/gherkin/token_formatter_builder.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +Style/Encoding: + Exclude: + - 'spec/gherkin/dialect_spec.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +Style/ExpandPathArguments: + Exclude: + - 'Rakefile' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: format, sprintf, percent +Style/FormatString: + Exclude: + - 'lib/gherkin/token_formatter_builder.rb' + +# Offense count: 8 +# Configuration parameters: MaxUnannotatedPlaceholdersAllowed, IgnoredMethods. +# SupportedStyles: annotated, template, unannotated +Style/FormatStringToken: + EnforcedStyle: unannotated + +# Offense count: 25 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, always_true, never +Style/FrozenStringLiteralComment: + Enabled: false + +# Offense count: 3 +# This cop supports safe auto-correction (--auto-correct). +Style/GlobalStdStream: + Exclude: + - 'bin/gherkin' + +# Offense count: 6 +# This cop supports safe auto-correction (--auto-correct). +Style/IfUnlessModifier: + Exclude: + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/gherkin_line.rb' + - 'lib/gherkin/pickles/compiler.rb' + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: IgnoredMethods. +Style/MethodCallWithoutArgsParentheses: + Exclude: + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 3 +# This cop supports safe auto-correction (--auto-correct). +Style/MultilineTernaryOperator: + Exclude: + - 'lib/gherkin/pickles/compiler.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: literals, strict +Style/MutableConstant: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: both, prefix, postfix +Style/NegatedIf: + Exclude: + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +Style/Not: + Exclude: + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 3 +# This cop supports unsafe auto-correction (--auto-correct-all). +# Configuration parameters: EnforcedStyle, IgnoredMethods. +# SupportedStyles: predicate, comparison +Style/NumericPredicate: + Exclude: + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/gherkin_line.rb' + +# Offense count: 54 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowSafeAssignment, AllowInMultilineConditions. +Style/ParenthesesAroundCondition: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +Style/PerlBackrefs: + Exclude: + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 3 +# This cop supports unsafe auto-correction (--auto-correct-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: short, verbose +Style/PreferredHashMethods: + Exclude: + - 'lib/gherkin/query.rb' + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, AllowedCompactTypes. +# SupportedStyles: compact, exploded +Style/RaiseArgs: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 50 +# This cop supports safe auto-correction (--auto-correct). +Style/RedundantParentheses: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 4 +# This cop supports safe auto-correction (--auto-correct). +Style/RedundantRegexpEscape: + Exclude: + - 'spec/gherkin/stream/parser_message_stream_spec.rb' + +# Offense count: 69 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowMultipleReturnValues. +Style/RedundantReturn: + Exclude: + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/token_matcher.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +Style/RedundantSelf: + Exclude: + - 'lib/gherkin/gherkin_line.rb' + +# Offense count: 1620 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowAsExpressionSeparator. +Style/Semicolon: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: only_raise, only_fail, semantic +Style/SignalException: + Exclude: + - 'lib/gherkin/token_scanner.rb' + +# Offense count: 4 +# This cop supports unsafe auto-correction (--auto-correct-all). +Style/SlicingWithRange: + Exclude: + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/gherkin_line.rb' + - 'spec/gherkin/gherkin_spec.rb' + +# Offense count: 58 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowModifier. +Style/SoleNestedConditional: + Exclude: + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: RequireEnglish, EnforcedStyle. +# SupportedStyles: use_perl_names, use_english_names +Style/SpecialGlobalVars: + Exclude: + - 'Rakefile' + +# Offense count: 5 +# This cop supports unsafe auto-correction (--auto-correct-all). +# Configuration parameters: Mode. +Style/StringConcatenation: + Exclude: + - 'bin/gherkin-ruby' + - 'lib/gherkin/errors.rb' + - 'lib/gherkin/gherkin_line.rb' + - 'lib/gherkin/pickles/compiler.rb' + +# Offense count: 435 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Exclude: + - 'Gemfile' + - 'bin/gherkin' + - 'bin/gherkin-generate-tokens' + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/dialect.rb' + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/stream/parser_message_stream.rb' + - 'lib/gherkin/token.rb' + - 'lib/gherkin/token_formatter_builder.rb' + - 'lib/gherkin/token_matcher.rb' + - 'spec/gherkin/gherkin_line_spec.rb' + - 'spec/gherkin/gherkin_spec.rb' + - 'spec/gherkin/query_spec.rb' + - 'spec/gherkin/stream/parser_message_stream_spec.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiteralsInInterpolation: + Exclude: + - 'lib/gherkin/errors.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +Style/StructInheritance: + Exclude: + - 'lib/gherkin/gherkin_line.rb' + - 'lib/gherkin/token.rb' + +# Offense count: 3 +# This cop supports unsafe auto-correction (--auto-correct-all). +# Configuration parameters: AllowMethodsWithArguments, IgnoredMethods. +# IgnoredMethods: respond_to, define_method +Style/SymbolProc: + Exclude: + - 'lib/gherkin/ast_builder.rb' + - 'lib/gherkin/parser.rb' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle, AllowSafeAssignment. +# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex +Style/TernaryParentheses: + Exclude: + - 'lib/gherkin/errors.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInArguments: + Exclude: + - 'lib/gherkin/ast_builder.rb' + +# Offense count: 5 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInArrayLiteral: + Exclude: + - 'lib/gherkin/parser.rb' + - 'lib/gherkin/query.rb' + - 'spec/gherkin/query_spec.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInHashLiteral: + Exclude: + - 'lib/gherkin/pickles/compiler.rb' + - 'spec/gherkin/stream/parser_message_stream_spec.rb' + +# Offense count: 1 +# This cop supports unsafe auto-correction (--auto-correct-all). +Style/ZeroLengthPredicate: + Exclude: + - 'lib/gherkin/gherkin_line.rb' + +# Offense count: 123 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 177 diff --git a/ruby/CONTRIBUTING.md b/ruby/CONTRIBUTING.md index 6c48795a1..190129c27 100644 --- a/ruby/CONTRIBUTING.md +++ b/ruby/CONTRIBUTING.md @@ -8,8 +8,6 @@ to contribute. Just run `make` from this directory. -Even if you prefer `make` - run `rake` occasionally, as it reports better warnings. - ### Using rake Just run `rake` from this directory. diff --git a/ruby/Rakefile b/ruby/Rakefile index 85e0fc70a..c21069251 100644 --- a/ruby/Rakefile +++ b/ruby/Rakefile @@ -1,25 +1,12 @@ -# encoding: utf-8 require 'rubygems' require 'bundler' Bundler::GemHelper.install_tasks -$:.unshift File.expand_path("../lib", __FILE__) +$:.unshift File.expand_path('../lib', __FILE__) -Dir['./rake/*.rb'].each do |f| - require f -end +Dir['./rake/*.rb'].sort.each { |f| require f } -require "rspec/core/rake_task" +require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -require_relative 'spec/capture_warnings' -include CaptureWarnings -namespace :spec do - task :warnings do - report_warnings do - Rake::Task['spec'].invoke - end - end -end - -task default: ['spec:warnings'] +task default: :spec diff --git a/ruby/bin/gherkin b/ruby/bin/gherkin index 84c9e3249..6eda6f822 100755 --- a/ruby/bin/gherkin +++ b/ruby/bin/gherkin @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -$VERBOSE=nil # Shut up JRuby warnings on Travis + $LOAD_PATH.unshift(File.join(File.dirname(__FILE__),"../lib")) require 'optparse' @@ -15,17 +15,17 @@ options = { } OptionParser.new do |opts| - opts.on("--[no-]source", "Don't print source messages") do |v| - options[:include_source] = v + opts.on('--[no-]source', "Don't print source messages") do |value| + options[:include_source] = value end - opts.on("--[no-]ast", "Don't print ast messages") do |v| - options[:include_gherkin_document] = v + opts.on('--[no-]ast', "Don't print ast messages") do |value| + options[:include_gherkin_document] = value end - opts.on("--[no-]pickles", "Don't print pickle messages") do |v| - options[:include_pickles] = v + opts.on('--[no-]pickles', "Don't print pickle messages") do |value| + options[:include_pickles] = value end - opts.on("--predictable-ids", "Generate incrementing ids rather than UUIDs") do |v| - options[:id_generator] = Cucumber::Messages::IdGenerator::Incrementing.new if v + opts.on('--predictable-ids', 'Generate incrementing ids rather than UUIDs') do |value| + options[:id_generator] = Cucumber::Messages::Helpers::IdGenerator::Incrementing.new if value end end.parse! @@ -38,7 +38,7 @@ end if ARGV.empty? # Read from STDIN - messages = Cucumber::Messages::NdjsonToMessageEnumerator.new(STDIN) + messages = Cucumber::Messages::Helpers::NdjsonToMessageEnumerator.new(STDIN) else messages = Gherkin.from_paths(ARGV, options) end diff --git a/ruby/bin/gherkin-generate-tokens b/ruby/bin/gherkin-generate-tokens index 19f7a925f..5392ebbeb 100755 --- a/ruby/bin/gherkin-generate-tokens +++ b/ruby/bin/gherkin-generate-tokens @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -$VERBOSE=nil # Shut up JRuby warnings on Travis + $LOAD_PATH.unshift(File.join(File.dirname(__FILE__),"../lib")) require 'gherkin/parser' require 'gherkin/token_formatter_builder' diff --git a/ruby/cucumber-gherkin.gemspec b/ruby/cucumber-gherkin.gemspec index fe8e6cbbd..62e428c3e 100644 --- a/ruby/cucumber-gherkin.gemspec +++ b/ruby/cucumber-gherkin.gemspec @@ -10,7 +10,8 @@ Gem::Specification.new do |s| s.homepage = 'https://github.com/cucumber/gherkin' s.platform = Gem::Platform::RUBY s.license = 'MIT' - s.required_ruby_version = '>= 2.5' + s.required_ruby_version = '>= 3.0' + s.required_rubygems_version = '>= 3.2.8' s.metadata = { 'bug_tracker_uri' => 'https://github.com/cucumber/gherkin/issues', @@ -20,19 +21,14 @@ Gem::Specification.new do |s| 'source_code_uri' => 'https://github.com/cucumber/gherkin/blob/main/ruby' } - s.add_runtime_dependency 'cucumber-messages', '>= 19.1.4', '< 24' + s.add_runtime_dependency 'cucumber-messages', '> 25', '< 26' - s.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6' - s.add_development_dependency 'rspec', '~> 3.11', '>= 3.11.0' + s.add_development_dependency 'rake', '~> 13.1' + s.add_development_dependency 'rspec', '~> 3.13' + s.add_development_dependency 'rubocop', '~> 1.26.0' s.executables = %w[gherkin-ruby gherkin] - s.rubygems_version = '>= 1.6.1', '~> 0.8' - s.files = Dir[ - 'README.md', - 'LICENSE', - 'lib/**/*' - ] - s.test_files = Dir['spec/**/*'] + s.files = Dir['README.md', 'LICENSE', 'lib/**/*'] s.rdoc_options = ['--charset=UTF-8'] s.require_path = 'lib' end diff --git a/ruby/gherkin-ruby.razor b/ruby/gherkin-ruby.razor index 54ceab253..d99ba0732 100644 --- a/ruby/gherkin-ruby.razor +++ b/ruby/gherkin-ruby.razor @@ -54,7 +54,7 @@ module Gherkin class @Model.ParserClassName attr_accessor :stop_at_first_error - def initialize(ast_builder = AstBuilder.new(Cucumber::Messages::IdGenerator::UUID.new)) + def initialize(ast_builder = AstBuilder.new(Cucumber::Messages::Helpers::IdGenerator::UUID.new)) @@ast_builder = ast_builder end diff --git a/ruby/lib/gherkin/parser.rb b/ruby/lib/gherkin/parser.rb index a6bf40681..67c36b0bd 100644 --- a/ruby/lib/gherkin/parser.rb +++ b/ruby/lib/gherkin/parser.rb @@ -56,7 +56,7 @@ def initialize(token_scanner, token_matcher, token_queue, errors) class Parser attr_accessor :stop_at_first_error - def initialize(ast_builder = AstBuilder.new(Cucumber::Messages::IdGenerator::UUID.new)) + def initialize(ast_builder = AstBuilder.new(Cucumber::Messages::Helpers::IdGenerator::UUID.new)) @ast_builder = ast_builder end diff --git a/ruby/lib/gherkin/stream/parser_message_stream.rb b/ruby/lib/gherkin/stream/parser_message_stream.rb index c392c058f..1d67056bf 100644 --- a/ruby/lib/gherkin/stream/parser_message_stream.rb +++ b/ruby/lib/gherkin/stream/parser_message_stream.rb @@ -11,7 +11,7 @@ def initialize(paths, sources, options) @sources = sources @options = options - id_generator = options[:id_generator] || Cucumber::Messages::IdGenerator::UUID.new + id_generator = options[:id_generator] || Cucumber::Messages::Helpers::IdGenerator::UUID.new @parser = Parser.new(AstBuilder.new(id_generator)) @compiler = Pickles::Compiler.new(id_generator) end diff --git a/ruby/spec/capture_warnings.rb b/ruby/spec/capture_warnings.rb deleted file mode 100644 index 2315009db..000000000 --- a/ruby/spec/capture_warnings.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true -# With thanks to @myronmarston -# https://github.com/vcr/vcr/blob/master/spec/capture_warnings.rb - -module CaptureWarnings - def report_warnings(&block) - current_dir = Dir.pwd - warnings, errors = capture_error(&block).partition { |line| line.include?('warning') } - project_warnings, other_warnings = warnings.uniq.partition { |line| line.include?(current_dir) } - - if errors.any? - puts errors.join("\n") - end - - if other_warnings.any? - puts "#{ other_warnings.count } warnings detected, set VIEW_OTHER_WARNINGS=true to see them." - print_warnings('other', other_warnings) if ENV['VIEW_OTHER_WARNINGS'] - end - - # Until they fix https://bugs.ruby-lang.org/issues/10661 - if RUBY_VERSION == "2.2.0" - project_warnings = project_warnings.reject { |w| w =~ /warning: possible reference to past scope/ } - end - - if project_warnings.any? - puts "#{ project_warnings.count } warnings detected" - print_warnings('cucumber-expressions', project_warnings) - fail "Please remove all cucumber-expressions warnings." - end - - ensure_system_exit_if_required - end - - def capture_error(&block) - old_stderr = STDERR.clone - pipe_r, pipe_w = IO.pipe - pipe_r.sync = true - error = String.new - reader = Thread.new do - begin - loop do - error << pipe_r.readpartial(1024) - end - rescue EOFError - end - end - STDERR.reopen(pipe_w) - block.call - ensure - capture_system_exit - STDERR.reopen(old_stderr) - pipe_w.close - reader.join - return error.split("\n") - end - - def print_warnings(type, warnings) - puts - puts "-" * 30 + " #{type} warnings: " + "-" * 30 - puts - puts warnings.join("\n") - puts - puts "-" * 75 - puts - end - - def ensure_system_exit_if_required - raise @system_exit if @system_exit - end - - def capture_system_exit - @system_exit = $! - end -end diff --git a/ruby/spec/gherkin/dialect_spec.rb b/ruby/spec/gherkin/dialect_spec.rb index 6778cf131..1c444d0dc 100644 --- a/ruby/spec/gherkin/dialect_spec.rb +++ b/ruby/spec/gherkin/dialect_spec.rb @@ -1,7 +1,3 @@ -# coding: utf-8 -require 'rspec' -require 'gherkin/dialect' - module Gherkin describe Dialect do it 'provides an interface to the keywords of a dialect' do diff --git a/ruby/spec/gherkin/gherkin_line_spec.rb b/ruby/spec/gherkin/gherkin_line_spec.rb index 7a508d4ae..975fe61d2 100644 --- a/ruby/spec/gherkin/gherkin_line_spec.rb +++ b/ruby/spec/gherkin/gherkin_line_spec.rb @@ -1,6 +1,3 @@ -require 'rspec' -require 'gherkin/gherkin_line' - describe Gherkin::GherkinLine do context '#tags' do def tags(line) @@ -37,4 +34,4 @@ def cells_text(line) expect(cells_text("| a |\\")).to eq(['a']) end end -end \ No newline at end of file +end diff --git a/ruby/spec/gherkin/gherkin_spec.rb b/ruby/spec/gherkin/gherkin_spec.rb index cc6f114e5..154e4f212 100644 --- a/ruby/spec/gherkin/gherkin_spec.rb +++ b/ruby/spec/gherkin/gherkin_spec.rb @@ -1,6 +1,3 @@ -require 'rspec' -require 'gherkin' - describe Gherkin do it "can process feature file paths" do messages = Gherkin.from_paths( diff --git a/ruby/spec/gherkin/parser_spec.rb b/ruby/spec/gherkin/parser_spec.rb index 7565907f5..bd7610f31 100644 --- a/ruby/spec/gherkin/parser_spec.rb +++ b/ruby/spec/gherkin/parser_spec.rb @@ -1,10 +1,7 @@ -require 'rspec' -require 'gherkin' - describe Gherkin::Parser do - context '.new' do - it 'can be invoked with no args' do - Gherkin::Parser.new + describe '#initialize' do + it 'can be initialized with no arguments' do + expect { described_class.new }.not_to raise_error end end end diff --git a/ruby/spec/gherkin/query_spec.rb b/ruby/spec/gherkin/query_spec.rb index 75b85b497..b73c0d36b 100644 --- a/ruby/spec/gherkin/query_spec.rb +++ b/ruby/spec/gherkin/query_spec.rb @@ -1,9 +1,7 @@ -require 'rspec' -require 'gherkin' require 'gherkin/query' describe Gherkin::Query do - let(:subject) { Gherkin::Query.new } + subject(:query) { Gherkin::Query.new } def filter_messages_by_attribute(messages, attribute) messages.map do |message| @@ -20,11 +18,9 @@ def find_message_by_attribute(messages, attribute) let(:messages) do Gherkin.from_source( - "some/path", + 'some/path', feature_content, - { - include_gherkin_document: true - } + { include_gherkin_document: true } ).to_a end @@ -65,17 +61,13 @@ def find_message_by_attribute(messages, attribute) let(:feature_content) { '' } it 'does not fail' do - expect do - messages.each { |message| subject.update(message) } - end.not_to raise_exception + expect { messages.each { |message| query.update(message) } }.not_to raise_error end end end describe '#scenario_parent_locations' do - before do - messages.each { |message| subject.update(message) } - end + before { messages.each { |message| query.update(message) } } let(:background) { find_message_by_attribute(gherkin_document.feature.children, :background) } let(:scenarios) { filter_messages_by_attribute(gherkin_document.feature.children, :scenario) } @@ -84,7 +76,7 @@ def find_message_by_attribute(messages, attribute) let(:scenario) { scenarios.first } it 'provides the feature and background locations of a given scenario node id' do - expect(subject.scenario_parent_locations(scenario.id)).to eq([ + expect(query.scenario_parent_locations(scenario.id)).to eq([ gherkin_document.feature.location, background.location, ]) @@ -97,7 +89,7 @@ def find_message_by_attribute(messages, attribute) let(:scenario) { find_message_by_attribute(rule.children, :scenario) } it 'provides the feature, background, rule, and rule background locations of a given scenario node id' do - expect(subject.scenario_parent_locations(scenario.id)).to eq([ + expect(query.scenario_parent_locations(scenario.id)).to eq([ gherkin_document.feature.location, background.location, rule.location, @@ -110,7 +102,7 @@ def find_message_by_attribute(messages, attribute) let(:scenario) { scenarios.last } it 'provides the feature and background locations of a given scenario outline node id' do - expect(subject.scenario_parent_locations(scenario.id)).to eq([ + expect(query.scenario_parent_locations(scenario.id)).to eq([ gherkin_document.feature.location, background.location, ]) @@ -118,13 +110,13 @@ def find_message_by_attribute(messages, attribute) end it 'raises an exception if called with an invalid id' do - expect { subject.scenario_parent_locations("BAD") }.to raise_error(Gherkin::AstNodeNotLocatedException) + expect { query.scenario_parent_locations("BAD") }.to raise_error(Gherkin::AstNodeNotLocatedException) end end describe '#location' do before do - messages.each { |message| subject.update(message) } + messages.each { |message| query.update(message) } end let(:background) { find_message_by_attribute(gherkin_document.feature.children, :background) } @@ -133,16 +125,17 @@ def find_message_by_attribute(messages, attribute) let(:scenario) { scenarios.first } it 'raises an exception when the AST node ID is unknown' do - expect { subject.location("this-id-may-not-exist-for-real") }.to raise_exception(Gherkin::AstNodeNotLocatedException) + expect { query.location("this-id-may-not-exist-for-real") }.to raise_exception(Gherkin::AstNodeNotLocatedException) end it 'provides the location of a scenario' do - expect(subject.location(scenario.id)).to eq(scenario.location) + expect(query.location(scenario.id)).to eq(scenario.location) end it 'provides the location of an examples table row' do node = scenarios.last.examples.first.table_body.first - expect(subject.location(node.id)).to eq(node.location) + + expect(query.location(node.id)).to eq(node.location) end context 'when querying steps' do @@ -150,11 +143,11 @@ def find_message_by_attribute(messages, attribute) let(:scenario_step) { scenario.steps.first } it 'provides the location of a background step' do - expect(subject.location(background_step.id)).to eq(background_step.location) + expect(query.location(background_step.id)).to eq(background_step.location) end it 'provides the location of a scenario step' do - expect(subject.location(scenario_step.id)).to eq(scenario_step.location) + expect(query.location(scenario_step.id)).to eq(scenario_step.location) end end @@ -165,19 +158,19 @@ def find_message_by_attribute(messages, attribute) let(:examples_tag) { scenarios.last.examples.first.tags.first } it 'provides the location of a feature tags' do - expect(subject.location(feature_tag.id)).to eq(feature_tag.location) + expect(query.location(feature_tag.id)).to eq(feature_tag.location) end it 'provides the location of a scenario tags' do - expect(subject.location(scenario_tag.id)).to eq(scenario_tag.location) + expect(query.location(scenario_tag.id)).to eq(scenario_tag.location) end it 'provides the location of scenario examples tags' do - expect(subject.location(examples_tag.id)).to eq(examples_tag.location) + expect(query.location(examples_tag.id)).to eq(examples_tag.location) end it 'provides the location of a rule tag' do - expect(subject.location(rule_tag.id)).to eq(rule_tag.location) + expect(query.location(rule_tag.id)).to eq(rule_tag.location) end end @@ -189,19 +182,19 @@ def find_message_by_attribute(messages, attribute) let(:rule_scenario_tag) { rule_scenario.tags.first } it 'provides the location of a background step' do - expect(subject.location(rule_background_step.id)).to eq(rule_background_step.location) + expect(query.location(rule_background_step.id)).to eq(rule_background_step.location) end it 'provides the location of a scenario' do - expect(subject.location(rule_scenario.id)).to eq(rule_scenario.location) + expect(query.location(rule_scenario.id)).to eq(rule_scenario.location) end it 'provides the location of a scenario tag' do - expect(subject.location(rule_scenario_tag.id)).to eq(rule_scenario_tag.location) + expect(query.location(rule_scenario_tag.id)).to eq(rule_scenario_tag.location) end it 'provides the location of a scenario step' do - expect(subject.location(rule_scenario_step.id)).to eq(rule_scenario_step.location) + expect(query.location(rule_scenario_step.id)).to eq(rule_scenario_step.location) end end end diff --git a/ruby/spec/gherkin/stream/parser_message_stream_spec.rb b/ruby/spec/gherkin/stream/parser_message_stream_spec.rb index 2f7d38b6d..5d8e02aea 100644 --- a/ruby/spec/gherkin/stream/parser_message_stream_spec.rb +++ b/ruby/spec/gherkin/stream/parser_message_stream_spec.rb @@ -1,6 +1,3 @@ -require 'rspec' -require 'gherkin/stream/parser_message_stream' - module Gherkin module Stream describe ParserMessageStream do diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb new file mode 100644 index 000000000..3f8a30c53 --- /dev/null +++ b/ruby/spec/spec_helper.rb @@ -0,0 +1,3 @@ +require 'rspec' + +require 'gherkin'