diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..243bbb5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +# This workflow uses actions that are not certified by GitHub. They are +# provided by a third-party and are governed by separate terms of service, +# privacy policy, and support documentation. +# +# This workflow will install a prebuilt Ruby version, install dependencies, and +# run tests and linters. +name: "Ruby on Rails CI" +on: + push: + branches: [ "main", "develop", "staging" ] + pull_request: + branches: [ "main", "develop", "staging" ] +jobs: + test: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:11-alpine + ports: + - "5432:5432" + env: + POSTGRES_DB: rails_test + POSTGRES_USER: rails + POSTGRES_PASSWORD: password + env: + RAILS_ENV: test + DATABASE_URL: "postgres://rails:password@localhost:5432/rails_test" + steps: + - name: Checkout code + uses: actions/checkout@v4 + # Add or replace dependency steps here + - name: Install Ruby and gems + uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 + with: + bundler-cache: true + # Add or replace database setup steps here + - name: Set up database schema + run: bin/rails db:schema:load + # Add or replace test runners here + - name: Run tests + run: bundle exec rspec + + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Install Ruby and gems + uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 + with: + bundler-cache: true + # Add or replace any other lints here + - name: Security audit dependencies + run: bundle exec bundler-audit --update + - name: Security audit application code + run: bundle exec brakeman -q -w2 + - name: Lint Ruby files + run: bundle exec rubocop --parallel diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..208732d --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,5754 @@ +# Common configuration. +require: rubocop-rails + +AllCops: + SuggestExtensions: false + RubyInterpreters: + - ruby + - macruby + - rake + - jruby + - rbx + # Include common Ruby source files. + Include: + - '**/*.rb' + - '**/*.arb' + - '**/*.axlsx' + - '**/*.builder' + - '**/*.fcgi' + - '**/*.gemfile' + - '**/*.gemspec' + - '**/*.god' + - '**/*.jb' + - '**/*.jbuilder' + - '**/*.mspec' + - '**/*.opal' + - '**/*.pluginspec' + - '**/*.podspec' + - '**/*.rabl' + - '**/*.rake' + - '**/*.rbuild' + - '**/*.rbw' + - '**/*.rbx' + - '**/*.ru' + - '**/*.ruby' + - '**/*.schema' + - '**/*.spec' + - '**/*.thor' + - '**/*.watchr' + - '**/.irbrc' + - '**/.pryrc' + - '**/.simplecov' + - '**/buildfile' + - '**/Appraisals' + - '**/Berksfile' + - '**/Brewfile' + - '**/Buildfile' + - '**/Capfile' + - '**/Cheffile' + - '**/Dangerfile' + - '**/Deliverfile' + - '**/Fastfile' + - '**/*Fastfile' + - '**/Gemfile' + - '**/Guardfile' + - '**/Jarfile' + - '**/Mavenfile' + - '**/Podfile' + - '**/Puppetfile' + - '**/Rakefile' + - '**/rakefile' + - '**/Schemafile' + - '**/Snapfile' + - '**/Steepfile' + - '**/Thorfile' + - '**/Vagabondfile' + - '**/Vagrantfile' + Exclude: + - 'node_modules/**/*' + - 'tmp/**/*' + - 'vendor/**/*' + - '.git/**/*' + - bin/**/* + - db/schema.rb + - .gemspec/**/* + - .bundle/**/* + - vendor/**/* + - '**/dummy**/*' + - !ruby/regexp /old_and_unused\.rb$/ + # Default formatter will be used if no `-f/--format` option is given. + DefaultFormatter: progress + # Cop names are displayed in offense messages by default. Change behavior + # by overriding DisplayCopNames, or by giving the `--no-display-cop-names` + # option. + DisplayCopNames: true + # Style guide URLs are not displayed in offense messages by default. Change + # behavior by overriding `DisplayStyleGuide`, or by giving the + # `-S/--display-style-guide` option. + DisplayStyleGuide: false + # When specifying style guide URLs, any paths and/or fragments will be + # evaluated relative to the base URL. + StyleGuideBaseURL: https://rubystyle.guide + # Documentation URLs will be constructed using the base URL. + DocumentationBaseURL: https://docs.rubocop.org/rubocop + # Extra details are not displayed in offense messages by default. Change + # behavior by overriding ExtraDetails, or by giving the + # `-E/--extra-details` option. + ExtraDetails: false + # Additional cops that do not reference a style guide rule may be enabled by + # default. Change behavior by overriding `StyleGuideCopsOnly`, or by giving + # the `--only-guide-cops` option. + StyleGuideCopsOnly: false + # All cops except the ones configured `Enabled: false` in this file are enabled by default. + # Change this behavior by overriding either `DisabledByDefault` or `EnabledByDefault`. + # When `DisabledByDefault` is `true`, all cops in the default configuration + # are disabled, and only cops in user configuration are enabled. This makes + # cops opt-in instead of opt-out. Note that when `DisabledByDefault` is `true`, + # cops in user configuration will be enabled even if they don't set the + # Enabled parameter. + # When `EnabledByDefault` is `true`, all cops, even those configured `Enabled: false` + # in this file are enabled by default. Cops can still be disabled in user configuration. + # Note that it is invalid to set both EnabledByDefault and DisabledByDefault + # to true in the same configuration. + EnabledByDefault: false + DisabledByDefault: false + # New cops introduced between major versions are set to a special pending status + # and are not enabled by default with warning message. + # Change this behavior by overriding either `NewCops: enable` or `NewCops: disable`. + # When `NewCops` is `enable`, pending cops are enabled in bulk. Can be overridden by + # the `--enable-pending-cops` command-line option. + # When `NewCops` is `disable`, pending cops are disabled in bulk. Can be overridden by + # the `--disable-pending-cops` command-line option. + NewCops: pending + # Enables the result cache if `true`. Can be overridden by the `--cache` command + # line option. + UseCache: true + # Threshold for how many files can be stored in the result cache before some + # of the files are automatically removed. + MaxFilesInCache: 20000 + # The cache will be stored in "rubocop_cache" under this directory. If + # CacheRootDirectory is ~ (nil), which it is by default, the root will be + # taken from the environment variable `$XDG_CACHE_HOME` if it is set, or if + # `$XDG_CACHE_HOME` is not set, it will be `$HOME/.cache/`. + # The CacheRootDirectory can be overwritten by passing the `--cache-root` command + # line option or by setting `$RUBOCOP_CACHE_ROOT` environment variable. + CacheRootDirectory: ~ + # It is possible for a malicious user to know the location of RuboCop's cache + # directory by looking at CacheRootDirectory, and create a symlink in its + # place that could cause RuboCop to overwrite unintended files, or read + # malicious input. If you are certain that your cache location is secure from + # this kind of attack, and wish to use a symlinked cache location, set this + # value to "true". + AllowSymlinksInCacheRootDirectory: false + # What MRI version of the Ruby interpreter is the inspected code intended to + # run on? (If there is more than one, set this to the lowest version.) + # If a value is specified for TargetRubyVersion then it is used. Acceptable + # values are specified as a float (i.e. 3.0); the teeny version of Ruby + # should not be included. If the project specifies a Ruby version in the + # .tool-versions or .ruby-version files, Gemfile or gems.rb file, RuboCop will + # try to determine the desired version of Ruby by inspecting the + # .tool-versions file first, then .ruby-version, followed by the Gemfile.lock + # or gems.locked file. (Although the Ruby version is specified in the Gemfile + # or gems.rb file, RuboCop reads the final value from the lock file.) If the + # Ruby version is still unresolved, RuboCop will use the oldest officially + # supported Ruby version (currently Ruby 2.7). + TargetRubyVersion: ~ + # You can specify the parser engine. There are two options available: + # - `parser_whitequark` ... https://github.com/whitequark/parser + # - `parser_prism` ... https://github.com/ruby/prism (`Prism::Translation::Parser`) + # By default, `parser` is used. For the `TargetRubyVersion` value, `parser` can be specified for versions `2.0` and above. + # `parser_prism` can be specified for versions `3.3` and above. `parser_prism` is faster but still considered experimental. + ParserEngine: parser_whitequark + # Determines if a notification for extension libraries should be shown when + # rubocop is run. Keys are the name of the extension, and values are an array + # of gems in the Gemfile that the extension is suggested for, if not already + # included. + SuggestExtensions: + rubocop-rails: [rails] + rubocop-rspec: [rspec, rspec-rails] + rubocop-minitest: [minitest] + rubocop-sequel: [sequel] + rubocop-rake: [rake] + rubocop-graphql: [graphql] + rubocop-capybara: [capybara] + rubocop-factory_bot: [factory_bot, factory_bot_rails] + rubocop-rspec_rails: [rspec-rails] + # Enable/Disable checking the methods extended by Active Support. + ActiveSupportExtensionsEnabled: false + +#################### Bundler ############################### + +Bundler/DuplicatedGem: + Description: 'Checks for duplicate gem entries in Gemfile.' + Enabled: false + Severity: warning + VersionAdded: '0.46' + VersionChanged: '1.40' + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + +Bundler/DuplicatedGroup: + Description: 'Checks for duplicate group entries in Gemfile.' + Enabled: false + Severity: warning + VersionAdded: '1.56' + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + +Bundler/GemComment: + Description: 'Add a comment describing each gem.' + Enabled: false + VersionAdded: '0.59' + VersionChanged: '0.85' + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + IgnoredGems: [] + OnlyFor: [] + +Bundler/GemFilename: + Description: 'Enforces the filename for managing gems.' + Enabled: false + VersionAdded: '1.20' + EnforcedStyle: 'Gemfile' + SupportedStyles: + - 'Gemfile' + - 'gems.rb' + Include: + - '**/Gemfile' + - '**/gems.rb' + - '**/Gemfile.lock' + - '**/gems.locked' + +Bundler/GemVersion: + Description: 'Requires or forbids specifying gem versions.' + Enabled: false + VersionAdded: '1.14' + EnforcedStyle: 'required' + SupportedStyles: + - 'required' + - 'forbidden' + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + AllowedGems: [] + +Bundler/InsecureProtocolSource: + Description: >- + The source `:gemcutter`, `:rubygems` and `:rubyforge` are deprecated + because HTTP requests are insecure. Please change your source to + 'https://rubygems.org' if possible, or 'http://rubygems.org' if not. + Enabled: false + Severity: warning + VersionAdded: '0.50' + VersionChanged: '1.40' + AllowHttpProtocol: true + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + +Bundler/OrderedGems: + Description: >- + Gems within groups in the Gemfile should be alphabetically sorted. + Enabled: false + VersionAdded: '0.46' + VersionChanged: '0.47' + TreatCommentsAsGroupSeparators: true + # By default, "-" and "_" are ignored for order purposes. + # This can be overridden by setting this parameter to true. + ConsiderPunctuation: false + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + +#################### Gemspec ############################### + +Gemspec/AddRuntimeDependency: + Description: 'Prefer `add_dependency` over `add_runtime_dependency`.' + StyleGuide: '#add_dependency_vs_add_runtime_dependency' + Reference: https://github.com/rubygems/rubygems/issues/7799#issuecomment-2192720316 + Enabled: false + VersionAdded: '1.65' + Include: + - '**/*.gemspec' + +Gemspec/DependencyVersion: + Description: 'Requires or forbids specifying gem dependency versions.' + Enabled: false + VersionAdded: '1.29' + EnforcedStyle: 'required' + SupportedStyles: + - 'required' + - 'forbidden' + Include: + - '**/*.gemspec' + AllowedGems: [] + +Gemspec/DeprecatedAttributeAssignment: + Description: Checks that deprecated attribute assignments are not set in a gemspec file. + Enabled: false + Severity: warning + VersionAdded: '1.30' + VersionChanged: '1.40' + Include: + - '**/*.gemspec' + +Gemspec/DevelopmentDependencies: + Description: Checks that development dependencies are specified in Gemfile rather than gemspec. + Enabled: false + VersionAdded: '1.44' + EnforcedStyle: Gemfile + SupportedStyles: + - Gemfile + - gems.rb + - gemspec + AllowedGems: [] + Include: + - '**/*.gemspec' + - '**/Gemfile' + - '**/gems.rb' + +Gemspec/DuplicatedAssignment: + Description: 'An attribute assignment method calls should be listed only once in a gemspec.' + Enabled: false + Severity: warning + VersionAdded: '0.52' + VersionChanged: '1.40' + Include: + - '**/*.gemspec' + +Gemspec/OrderedDependencies: + Description: >- + Dependencies in the gemspec should be alphabetically sorted. + Enabled: false + VersionAdded: '0.51' + TreatCommentsAsGroupSeparators: true + # By default, "-" and "_" are ignored for order purposes. + # This can be overridden by setting this parameter to true. + ConsiderPunctuation: false + Include: + - '**/*.gemspec' + +Gemspec/RequireMFA: + Description: 'Checks that the gemspec has metadata to require Multi-Factor Authentication from RubyGems.' + Enabled: false + Severity: warning + VersionAdded: '1.23' + VersionChanged: '1.40' + Reference: + - https://guides.rubygems.org/mfa-requirement-opt-in/ + Include: + - '**/*.gemspec' + +Gemspec/RequiredRubyVersion: + Description: 'Checks that `required_ruby_version` of gemspec is specified and equal to `TargetRubyVersion` of .rubocop.yml.' + Enabled: false + Severity: warning + VersionAdded: '0.52' + VersionChanged: '1.40' + Include: + - '**/*.gemspec' + +Gemspec/RubyVersionGlobalsUsage: + Description: Checks usage of RUBY_VERSION in gemspec. + StyleGuide: '#no-ruby-version-in-the-gemspec' + Enabled: false + Severity: warning + VersionAdded: '0.72' + VersionChanged: '1.40' + Include: + - '**/*.gemspec' + +#################### Layout ########################### + +Layout/AccessModifierIndentation: + Description: Check indentation of private/protected visibility modifiers. + StyleGuide: '#indent-public-private-protected' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: indent + SupportedStyles: + - outdent + - indent + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/ArgumentAlignment: + Description: >- + Align the arguments of a method call if they span more + than one line. + StyleGuide: '#no-double-indent' + Enabled: false + VersionAdded: '0.68' + VersionChanged: '0.77' + # Alignment of arguments in multi-line method calls. + # + # The `with_first_argument` style aligns the following lines along the same + # column as the first parameter. + # + # method_call(a, + # b) + # + # The `with_fixed_indentation` style aligns the following lines with one + # level of indentation relative to the start of the line with the method call. + # + # method_call(a, + # b) + EnforcedStyle: with_first_argument + SupportedStyles: + - with_first_argument + - with_fixed_indentation + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/ArrayAlignment: + Description: >- + Align the elements of an array literal if they span more than + one line. + StyleGuide: '#no-double-indent' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.77' + # Alignment of elements of a multi-line array. + # + # The `with_first_parameter` style aligns the following lines along the same + # column as the first element. + # + # array = [1, 2, 3, + # 4, 5, 6] + # + # The `with_fixed_indentation` style aligns the following lines with one + # level of indentation relative to the start of the line with start of array. + # + # array = [1, 2, 3, + # 4, 5, 6] + EnforcedStyle: with_first_element + SupportedStyles: + - with_first_element + - with_fixed_indentation + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/AssignmentIndentation: + Description: >- + Checks the indentation of the first line of the + right-hand-side of a multi-line assignment. + Enabled: false + VersionAdded: '0.49' + VersionChanged: '1.45' + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/BeginEndAlignment: + Description: 'Align ends corresponding to begins correctly.' + Enabled: false + VersionAdded: '0.91' + # The value `start_of_line` means that `end` should be aligned the start of the line + # where the `begin` keyword is. + # The value `begin` means that `end` should be aligned with the `begin` keyword. + EnforcedStyleAlignWith: start_of_line + SupportedStylesAlignWith: + - start_of_line + - begin + Severity: warning + +Layout/BlockAlignment: + Description: 'Align block ends correctly.' + Enabled: false + VersionAdded: '0.53' + # The value `start_of_block` means that the `end` should be aligned with line + # where the `do` keyword appears. + # The value `start_of_line` means it should be aligned with the whole + # expression's starting line. + # The value `either` means both are allowed. + EnforcedStyleAlignWith: either + SupportedStylesAlignWith: + - either + - start_of_block + - start_of_line + +Layout/BlockEndNewline: + Description: 'Put end statement of multiline block on its own line.' + Enabled: false + VersionAdded: '0.49' + +Layout/CaseIndentation: + Description: 'Indentation of when in a case/(when|in)/[else/]end.' + StyleGuide: '#indent-when-to-case' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '1.16' + EnforcedStyle: case + SupportedStyles: + - case + - end + IndentOneStep: false + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + # This only matters if `IndentOneStep` is `true`. + IndentationWidth: ~ + +Layout/ClassStructure: + Description: 'Enforces a configured order of definitions within a class body.' + StyleGuide: '#consistent-classes' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.52' + VersionChanged: '1.53' + Categories: + module_inclusion: + - include + - prepend + - extend + ExpectedOrder: + - module_inclusion + - constants + - public_class_methods + - initializer + - public_methods + - protected_methods + - private_methods + +Layout/ClosingHeredocIndentation: + Description: 'Checks the indentation of here document closings.' + Enabled: false + VersionAdded: '0.57' + +Layout/ClosingParenthesisIndentation: + Description: 'Checks the indentation of hanging closing parentheses.' + Enabled: false + VersionAdded: '0.49' + +Layout/CommentIndentation: + Description: 'Indentation of comments.' + Enabled: false + # When true, allows comments to have extra indentation if that aligns them + # with a comment on the preceding line. + AllowForAlignment: false + VersionAdded: '0.49' + VersionChanged: '1.24' + +Layout/ConditionPosition: + Description: >- + Checks for condition placed in a confusing position relative to + the keyword. + StyleGuide: '#same-line-condition' + Enabled: false + VersionAdded: '0.53' + VersionChanged: '0.83' + +Layout/DefEndAlignment: + Description: 'Align ends corresponding to defs correctly.' + Enabled: false + VersionAdded: '0.53' + # The value `def` means that `end` should be aligned with the def keyword. + # The value `start_of_line` means that `end` should be aligned with method + # calls like `private`, `public`, etc, if present in front of the `def` + # keyword on the same line. + EnforcedStyleAlignWith: start_of_line + SupportedStylesAlignWith: + - start_of_line + - def + Severity: warning + +Layout/DotPosition: + Description: 'Checks the position of the dot in multi-line method calls.' + StyleGuide: '#consistent-multi-line-chains' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: leading + SupportedStyles: + - leading + - trailing + +Layout/ElseAlignment: + Description: 'Align elses and elsifs correctly.' + Enabled: false + VersionAdded: '0.49' + +Layout/EmptyComment: + Description: 'Checks empty comment.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.53' + VersionChanged: '1.61' + AllowBorderComment: true + AllowMarginComment: true + +Layout/EmptyLineAfterGuardClause: + Description: 'Add empty line after guard clause.' + Enabled: false + VersionAdded: '0.56' + VersionChanged: '0.59' + +Layout/EmptyLineAfterMagicComment: + Description: 'Add an empty line after magic comments to separate them from code.' + StyleGuide: '#separate-magic-comments-from-code' + Enabled: false + VersionAdded: '0.49' + +Layout/EmptyLineAfterMultilineCondition: + Description: 'Enforces empty line after multiline condition.' + # This is disabled, because this style is not very common in practice. + Enabled: false + VersionAdded: '0.90' + Reference: + - https://github.com/airbnb/ruby#multiline-if-newline + +Layout/EmptyLineBetweenDefs: + Description: 'Use empty lines between class/module/method defs.' + StyleGuide: '#empty-lines-between-methods' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '1.23' + EmptyLineBetweenMethodDefs: true + EmptyLineBetweenClassDefs: true + EmptyLineBetweenModuleDefs: true + # `DefLikeMacros` takes the name of any macro that you want to treat like a def. + DefLikeMacros: [] + # `AllowAdjacentOneLineDefs` means that single line method definitions don't + # need an empty line between them. `true` by default. + AllowAdjacentOneLineDefs: true + # Can be array to specify minimum and maximum number of empty lines, e.g. [1, 2] + NumberOfEmptyLines: 1 + +Layout/EmptyLines: + Description: "Don't use several empty lines in a row." + StyleGuide: '#two-or-more-empty-lines' + Enabled: false + VersionAdded: '0.49' + +Layout/EmptyLinesAroundAccessModifier: + Description: "Keep blank lines around access modifiers." + StyleGuide: '#empty-lines-around-access-modifier' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: around + SupportedStyles: + - around + - only_before + Reference: + # A reference to `EnforcedStyle: only_before`. + - https://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions + +Layout/EmptyLinesAroundArguments: + Description: "Keeps track of empty lines around method arguments." + Enabled: false + VersionAdded: '0.52' + +Layout/EmptyLinesAroundAttributeAccessor: + Description: "Keep blank lines around attribute accessors." + StyleGuide: '#empty-lines-around-attribute-accessor' + Enabled: false + VersionAdded: '0.83' + VersionChanged: '0.84' + AllowAliasSyntax: true + AllowedMethods: + - alias_method + - public + - protected + - private + +Layout/EmptyLinesAroundBeginBody: + Description: "Keeps track of empty lines around begin-end bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: false + VersionAdded: '0.49' + +Layout/EmptyLinesAroundBlockBody: + Description: "Keeps track of empty lines around block bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - no_empty_lines + +Layout/EmptyLinesAroundClassBody: + Description: "Keeps track of empty lines around class bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.53' + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - empty_lines_except_namespace + - empty_lines_special + - no_empty_lines + - beginning_only + - ending_only + +Layout/EmptyLinesAroundExceptionHandlingKeywords: + Description: "Keeps track of empty lines around exception handling keywords." + StyleGuide: '#empty-lines-around-bodies' + Enabled: false + VersionAdded: '0.49' + +Layout/EmptyLinesAroundMethodBody: + Description: "Keeps track of empty lines around method bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: false + VersionAdded: '0.49' + +Layout/EmptyLinesAroundModuleBody: + Description: "Keeps track of empty lines around module bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - empty_lines_except_namespace + - empty_lines_special + - no_empty_lines + +Layout/EndAlignment: + Description: 'Align ends correctly.' + Enabled: false + VersionAdded: '0.53' + # The value `keyword` means that `end` should be aligned with the matching + # keyword (`if`, `while`, etc.). + # The value `variable` means that in assignments, `end` should be aligned + # with the start of the variable on the left hand side of `=`. In all other + # situations, `end` should still be aligned with the keyword. + # The value `start_of_line` means that `end` should be aligned with the start + # of the line which the matching keyword appears on. + EnforcedStyleAlignWith: keyword + SupportedStylesAlignWith: + - keyword + - variable + - start_of_line + Severity: warning + +Layout/EndOfLine: + Description: 'Use Unix-style line endings.' + StyleGuide: '#crlf' + Enabled: false + VersionAdded: '0.49' + # The `native` style means that CR+LF (Carriage Return + Line Feed) is + # enforced on Windows, and LF is enforced on other platforms. The other styles + # mean LF and CR+LF, respectively. + EnforcedStyle: native + SupportedStyles: + - native + - lf + - crlf + +Layout/ExtraSpacing: + Description: 'Do not use unnecessary spacing.' + Enabled: false + VersionAdded: '0.49' + # When true, allows most uses of extra spacing if the intent is to align + # things with the previous or next line, not counting empty lines or comment + # lines. + AllowForAlignment: true + # When true, allows things like 'obj.meth(arg) # comment', + # rather than insisting on 'obj.meth(arg) # comment'. + # If done for alignment, either this OR AllowForAlignment will allow it. + AllowBeforeTrailingComments: false + # When true, forces the alignment of `=` in assignments on consecutive lines. + ForceEqualSignAlignment: false + +Layout/FirstArgumentIndentation: + Description: 'Checks the indentation of the first argument in a method call.' + Enabled: false + VersionAdded: '0.68' + VersionChanged: '0.77' + EnforcedStyle: special_for_inner_method_call_in_parentheses + SupportedStyles: + # The first parameter should always be indented one step more than the + # preceding line. + - consistent + # The first parameter should always be indented one level relative to the + # parent that is receiving the parameter + - consistent_relative_to_receiver + # The first parameter should normally be indented one step more than the + # preceding line, but if it's a parameter for a method call that is itself + # a parameter in a method call, then the inner parameter should be indented + # relative to the inner method. + - special_for_inner_method_call + # Same as `special_for_inner_method_call` except that the special rule only + # applies if the outer method call encloses its arguments in parentheses. + - special_for_inner_method_call_in_parentheses + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/FirstArrayElementIndentation: + Description: >- + Checks the indentation of the first element in an array + literal. + Enabled: false + VersionAdded: '0.68' + VersionChanged: '0.77' + # The value `special_inside_parentheses` means that array literals with + # brackets that have their opening bracket on the same line as a surrounding + # opening round parenthesis, shall have their first element indented relative + # to the first position inside the parenthesis. + # + # The value `consistent` means that the indentation of the first element shall + # always be relative to the first position of the line where the opening + # bracket is. + # + # The value `align_brackets` means that the indentation of the first element + # shall always be relative to the position of the opening bracket. + EnforcedStyle: special_inside_parentheses + SupportedStyles: + - special_inside_parentheses + - consistent + - align_brackets + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/FirstArrayElementLineBreak: + Description: >- + Checks for a line break before the first element in a + multi-line array. + Enabled: false + VersionAdded: '0.49' + AllowMultilineFinalElement: false + +Layout/FirstHashElementIndentation: + Description: 'Checks the indentation of the first key in a hash literal.' + Enabled: false + VersionAdded: '0.68' + VersionChanged: '0.77' + # The value `special_inside_parentheses` means that hash literals with braces + # that have their opening brace on the same line as a surrounding opening + # round parenthesis, shall have their first key indented relative to the + # first position inside the parenthesis. + # + # The value `consistent` means that the indentation of the first key shall + # always be relative to the first position of the line where the opening + # brace is. + # + # The value `align_braces` means that the indentation of the first key shall + # always be relative to the position of the opening brace. + EnforcedStyle: special_inside_parentheses + SupportedStyles: + - special_inside_parentheses + - consistent + - align_braces + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/FirstHashElementLineBreak: + Description: >- + Checks for a line break before the first element in a + multi-line hash. + Enabled: false + VersionAdded: '0.49' + AllowMultilineFinalElement: false + +Layout/FirstMethodArgumentLineBreak: + Description: >- + Checks for a line break before the first argument in a + multi-line method call. + Enabled: false + VersionAdded: '0.49' + AllowMultilineFinalElement: false + +Layout/FirstMethodParameterLineBreak: + Description: >- + Checks for a line break before the first parameter in a + multi-line method parameter definition. + Enabled: false + VersionAdded: '0.49' + AllowMultilineFinalElement: false + +Layout/FirstParameterIndentation: + Description: >- + Checks the indentation of the first parameter in a + method definition. + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.77' + EnforcedStyle: consistent + SupportedStyles: + - consistent + - align_parentheses + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/HashAlignment: + Description: >- + Align the elements of a hash literal if they span more than + one line. + Enabled: false + AllowMultipleStyles: true + VersionAdded: '0.49' + VersionChanged: '1.16' + # Alignment of entries using hash rocket as separator. Valid values are: + # + # key - left alignment of keys + # 'a' => 2 + # 'bb' => 3 + # separator - alignment of hash rockets, keys are right aligned + # 'a' => 2 + # 'bb' => 3 + # table - left alignment of keys, hash rockets, and values + # 'a' => 2 + # 'bb' => 3 + EnforcedHashRocketStyle: key + SupportedHashRocketStyles: + - key + - separator + - table + # Alignment of entries using colon as separator. Valid values are: + # + # key - left alignment of keys + # a: 0 + # bb: 1 + # separator - alignment of colons, keys are right aligned + # a: 0 + # bb: 1 + # table - left alignment of keys and values + # a: 0 + # bb: 1 + EnforcedColonStyle: key + SupportedColonStyles: + - key + - separator + - table + # Select whether hashes that are the last argument in a method call should be + # inspected? Valid values are: + # + # always_inspect - Inspect both implicit and explicit hashes. + # Registers an offense for: + # function(a: 1, + # b: 2) + # Registers an offense for: + # function({a: 1, + # b: 2}) + # always_ignore - Ignore both implicit and explicit hashes. + # Accepts: + # function(a: 1, + # b: 2) + # Accepts: + # function({a: 1, + # b: 2}) + # ignore_implicit - Ignore only implicit hashes. + # Accepts: + # function(a: 1, + # b: 2) + # Registers an offense for: + # function({a: 1, + # b: 2}) + # ignore_explicit - Ignore only explicit hashes. + # Accepts: + # function({a: 1, + # b: 2}) + # Registers an offense for: + # function(a: 1, + # b: 2) + EnforcedLastArgumentHashStyle: always_inspect + SupportedLastArgumentHashStyles: + - always_inspect + - always_ignore + - ignore_implicit + - ignore_explicit + +Layout/HeredocArgumentClosingParenthesis: + Description: >- + Checks for the placement of the closing parenthesis in a + method call that passes a HEREDOC string as an argument. + Enabled: false + StyleGuide: '#heredoc-argument-closing-parentheses' + VersionAdded: '0.68' + +Layout/HeredocIndentation: + Description: 'Checks the indentation of the here document bodies.' + StyleGuide: '#squiggly-heredocs' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.85' + +Layout/IndentationConsistency: + Description: 'Keep indentation straight.' + StyleGuide: '#spaces-indentation' + Enabled: false + VersionAdded: '0.49' + # The difference between `indented` and `normal` is that the `indented_internal_methods` + # style prescribes that in classes and modules the `protected` and `private` + # modifier keywords shall be indented the same as public methods and that + # protected and private members shall be indented one step more than the + # modifiers. Other than that, both styles mean that entities on the same + # logical depth shall have the same indentation. + EnforcedStyle: normal + SupportedStyles: + - normal + - indented_internal_methods + Reference: + # A reference to `EnforcedStyle: indented_internal_methods`. + - https://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions + +Layout/IndentationStyle: + Description: 'Consistent indentation either with tabs only or spaces only.' + StyleGuide: '#spaces-indentation' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.82' + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + # It is used during autocorrection to determine how many spaces should + # replace each tab. + IndentationWidth: ~ + EnforcedStyle: spaces + SupportedStyles: + - spaces + - tabs + +Layout/IndentationWidth: + Description: 'Use 2 spaces for indentation.' + StyleGuide: '#spaces-indentation' + Enabled: false + VersionAdded: '0.49' + # Number of spaces for each indentation level. + Width: 2 + AllowedPatterns: [] + +Layout/InitialIndentation: + Description: >- + Checks the indentation of the first non-blank non-comment line in a file. + Enabled: false + VersionAdded: '0.49' + +Layout/LeadingCommentSpace: + Description: 'Comments should start with a space.' + StyleGuide: '#hash-space' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.73' + AllowDoxygenCommentStyle: false + AllowGemfileRubyComment: false + +Layout/LeadingEmptyLines: + Description: Check for unnecessary blank lines at the beginning of a file. + Enabled: false + VersionAdded: '0.57' + VersionChanged: '0.77' + +Layout/LineContinuationLeadingSpace: + Description: >- + Use trailing spaces instead of leading spaces in strings + broken over multiple lines (by a backslash). + Enabled: false + VersionAdded: '1.31' + VersionChanged: '1.45' + EnforcedStyle: trailing + SupportedStyles: + - leading + - trailing + +Layout/LineContinuationSpacing: + Description: 'Checks the spacing in front of backslash in line continuations.' + Enabled: false + VersionAdded: '1.31' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + +Layout/LineEndStringConcatenationIndentation: + Description: >- + Checks the indentation of the next line after a line that + ends with a string literal and a backslash. + Enabled: false + VersionAdded: '1.18' + EnforcedStyle: aligned + SupportedStyles: + - aligned + - indented + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/LineLength: + Description: 'Checks that line length does not exceed the configured limit.' + StyleGuide: '#max-line-length' + Enabled: false + VersionAdded: '0.25' + VersionChanged: '1.4' + Max: 120 + # To make it possible to copy or click on URIs in the code, we allow lines + # containing a URI to be longer than Max. + AllowHeredoc: true + AllowURI: true + URISchemes: + - http + - https + # The IgnoreCopDirectives option causes the LineLength rule to ignore cop + # directives like '# rubocop: enable ...' when calculating a line's length. + IgnoreCopDirectives: true + # The AllowedPatterns option is a list of !ruby/regexp and/or string + # elements. Strings will be converted to Regexp objects. A line that matches + # any regular expression listed in this option will be ignored by LineLength. + AllowedPatterns: [] + +Layout/MultilineArrayBraceLayout: + Description: >- + Checks that the closing brace in an array literal is + either on the same line as the last array element, or + a new line. + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: symmetrical + SupportedStyles: + # symmetrical: closing brace is positioned in same way as opening brace + # new_line: closing brace is always on a new line + # same_line: closing brace is always on the same line as last element + - symmetrical + - new_line + - same_line + +Layout/MultilineArrayLineBreaks: + Description: >- + Checks that each item in a multi-line array literal + starts on a separate line. + Enabled: false + VersionAdded: '0.67' + AllowMultilineFinalElement: false + +Layout/MultilineAssignmentLayout: + Description: 'Check for a newline after the assignment operator in multi-line assignments.' + StyleGuide: '#indent-conditional-assignment' + Enabled: false + VersionAdded: '0.49' + # The types of assignments which are subject to this rule. + SupportedTypes: + - block + - case + - class + - if + - kwbegin + - module + EnforcedStyle: new_line + SupportedStyles: + # Ensures that the assignment operator and the rhs are on the same line for + # the set of supported types. + - same_line + # Ensures that the assignment operator and the rhs are on separate lines + # for the set of supported types. + - new_line + +Layout/MultilineBlockLayout: + Description: 'Ensures newlines after multiline block do statements.' + Enabled: false + VersionAdded: '0.49' + +Layout/MultilineHashBraceLayout: + Description: >- + Checks that the closing brace in a hash literal is + either on the same line as the last hash element, or + a new line. + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: symmetrical + SupportedStyles: + # symmetrical: closing brace is positioned in same way as opening brace + # new_line: closing brace is always on a new line + # same_line: closing brace is always on same line as last element + - symmetrical + - new_line + - same_line + +Layout/MultilineHashKeyLineBreaks: + Description: >- + Checks that each item in a multi-line hash literal + starts on a separate line. + Enabled: false + VersionAdded: '0.67' + AllowMultilineFinalElement: false + +Layout/MultilineMethodArgumentLineBreaks: + Description: >- + Checks that each argument in a multi-line method call + starts on a separate line. + Enabled: false + VersionAdded: '0.67' + AllowMultilineFinalElement: false + +Layout/MultilineMethodCallBraceLayout: + Description: >- + Checks that the closing brace in a method call is + either on the same line as the last method argument, or + a new line. + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: symmetrical + SupportedStyles: + # symmetrical: closing brace is positioned in same way as opening brace + # new_line: closing brace is always on a new line + # same_line: closing brace is always on the same line as last argument + - symmetrical + - new_line + - same_line + +Layout/MultilineMethodCallIndentation: + Description: >- + Checks indentation of method calls with the dot operator + that span more than one line. + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: aligned + SupportedStyles: + - aligned + - indented + - indented_relative_to_receiver + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/MultilineMethodDefinitionBraceLayout: + Description: >- + Checks that the closing brace in a method definition is + either on the same line as the last method parameter, or + a new line. + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: symmetrical + SupportedStyles: + # symmetrical: closing brace is positioned in same way as opening brace + # new_line: closing brace is always on a new line + # same_line: closing brace is always on the same line as last parameter + - symmetrical + - new_line + - same_line + +Layout/MultilineMethodParameterLineBreaks: + Description: >- + Checks that each parameter in a multi-line method definition + starts on a separate line. + Enabled: false + VersionAdded: '1.32' + AllowMultilineFinalElement: false + +Layout/MultilineOperationIndentation: + Description: >- + Checks indentation of binary operations that span more than + one line. + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: aligned + SupportedStyles: + - aligned + - indented + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/ParameterAlignment: + Description: >- + Align the parameters of a method definition if they span more + than one line. + StyleGuide: '#no-double-indent' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.77' + # Alignment of parameters in multi-line method calls. + # + # The `with_first_parameter` style aligns the following lines along the same + # column as the first parameter. + # + # def method_foo(a, + # b) + # + # The `with_fixed_indentation` style aligns the following lines with one + # level of indentation relative to the start of the line with the method call. + # + # def method_foo(a, + # b) + EnforcedStyle: with_first_parameter + SupportedStyles: + - with_first_parameter + - with_fixed_indentation + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/RedundantLineBreak: + Description: >- + Do not break up an expression into multiple lines when it fits + on a single line. + Enabled: false + InspectBlocks: false + VersionAdded: '1.13' + +Layout/RescueEnsureAlignment: + Description: 'Align rescues and ensures correctly.' + Enabled: false + VersionAdded: '0.49' + +Layout/SingleLineBlockChain: + Description: 'Put method call on a separate line if chained to a single line block.' + Enabled: false + VersionAdded: '1.14' + +Layout/SpaceAfterColon: + Description: 'Use spaces after colons.' + StyleGuide: '#spaces-operators' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceAfterComma: + Description: 'Use spaces after commas.' + StyleGuide: '#spaces-operators' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceAfterMethodName: + Description: >- + Do not put a space between a method name and the opening + parenthesis in a method definition. + StyleGuide: '#parens-no-spaces' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceAfterNot: + Description: Tracks redundant space after the ! operator. + StyleGuide: '#no-space-bang' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceAfterSemicolon: + Description: 'Use spaces after semicolons.' + StyleGuide: '#spaces-operators' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceAroundBlockParameters: + Description: 'Checks the spacing inside and after block parameters pipes.' + Enabled: false + VersionAdded: '0.49' + EnforcedStyleInsidePipes: no_space + SupportedStylesInsidePipes: + - space + - no_space + +Layout/SpaceAroundEqualsInParameterDefault: + Description: >- + Checks that the equals signs in parameter default assignments + have or don't have surrounding space depending on + configuration. + StyleGuide: '#spaces-around-equals' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + +Layout/SpaceAroundKeyword: + Description: 'Use a space around keywords if appropriate.' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceAroundMethodCallOperator: + Description: 'Checks method call operators to not have spaces around them.' + Enabled: false + VersionAdded: '0.82' + +Layout/SpaceAroundOperators: + Description: 'Use a single space around operators.' + StyleGuide: '#spaces-operators' + Enabled: false + VersionAdded: '0.49' + # When `true`, allows most uses of extra spacing if the intent is to align + # with an operator on the previous or next line, not counting empty lines + # or comment lines. + AllowForAlignment: true + EnforcedStyleForExponentOperator: no_space + SupportedStylesForExponentOperator: + - space + - no_space + EnforcedStyleForRationalLiterals: no_space + SupportedStylesForRationalLiterals: + - space + - no_space + +Layout/SpaceBeforeBlockBraces: + Description: >- + Checks that the left block brace has or doesn't have space + before it. + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + EnforcedStyleForEmptyBraces: space + SupportedStylesForEmptyBraces: + - space + - no_space + VersionChanged: '0.52' + +Layout/SpaceBeforeBrackets: + Description: 'Checks for receiver with a space before the opening brackets.' + StyleGuide: '#space-in-brackets-access' + Enabled: false + VersionAdded: '1.7' + +Layout/SpaceBeforeComma: + Description: 'No spaces before commas.' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceBeforeComment: + Description: >- + Checks for missing space between code and a comment on the + same line. + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceBeforeFirstArg: + Description: >- + Checks that exactly one space is used between a method name + and the first argument for method calls without parentheses. + Enabled: false + VersionAdded: '0.49' + # When `true`, allows most uses of extra spacing if the intent is to align + # things with the previous or next line, not counting empty lines or comment + # lines. + AllowForAlignment: true + +Layout/SpaceBeforeSemicolon: + Description: 'No spaces before semicolons.' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceInLambdaLiteral: + Description: 'Checks for spaces in lambda literals.' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: require_no_space + SupportedStyles: + - require_no_space + - require_space + +Layout/SpaceInsideArrayLiteralBrackets: + Description: 'Checks the spacing inside array literal brackets.' + Enabled: false + VersionAdded: '0.52' + EnforcedStyle: no_space + SupportedStyles: + - space + - no_space + # 'compact' normally requires a space inside the brackets, with the exception + # that successive left brackets or right brackets are collapsed together + - compact + EnforcedStyleForEmptyBrackets: no_space + SupportedStylesForEmptyBrackets: + - space + - no_space + +Layout/SpaceInsideArrayPercentLiteral: + Description: 'No unnecessary additional spaces between elements in %i/%w literals.' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceInsideBlockBraces: + Description: >- + Checks that block braces have or don't have surrounding space. + For blocks taking parameters, checks that the left brace has + or doesn't have trailing space. + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + EnforcedStyleForEmptyBraces: no_space + SupportedStylesForEmptyBraces: + - space + - no_space + # Space between `{` and `|`. Overrides `EnforcedStyle` if there is a conflict. + SpaceBeforeBlockParameters: true + +Layout/SpaceInsideHashLiteralBraces: + Description: "Use spaces inside hash literal braces - or don't." + StyleGuide: '#spaces-braces' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + # 'compact' normally requires a space inside hash braces, with the exception + # that successive left braces or right braces are collapsed together + - compact + EnforcedStyleForEmptyBraces: no_space + SupportedStylesForEmptyBraces: + - space + - no_space + + +Layout/SpaceInsideParens: + Description: 'No spaces after ( or before ).' + StyleGuide: '#spaces-braces' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '1.22' + EnforcedStyle: no_space + SupportedStyles: + - space + - compact + - no_space + +Layout/SpaceInsidePercentLiteralDelimiters: + Description: 'No unnecessary spaces inside delimiters of %i/%w/%x literals.' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceInsideRangeLiteral: + Description: 'No spaces inside range literals.' + StyleGuide: '#no-space-inside-range-literals' + Enabled: false + VersionAdded: '0.49' + +Layout/SpaceInsideReferenceBrackets: + Description: 'Checks the spacing inside referential brackets.' + Enabled: false + VersionAdded: '0.52' + VersionChanged: '0.53' + EnforcedStyle: no_space + SupportedStyles: + - space + - no_space + EnforcedStyleForEmptyBrackets: no_space + SupportedStylesForEmptyBrackets: + - space + - no_space + +Layout/SpaceInsideStringInterpolation: + Description: 'Checks for padding/surrounding spaces inside string interpolation.' + StyleGuide: '#string-interpolation' + Enabled: false + VersionAdded: '0.49' + EnforcedStyle: no_space + SupportedStyles: + - space + - no_space + +Layout/TrailingEmptyLines: + Description: 'Checks trailing blank lines and final newline.' + StyleGuide: '#newline-eof' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.77' + EnforcedStyle: final_newline + SupportedStyles: + - final_newline + - final_blank_line + +Layout/TrailingWhitespace: + Description: 'Avoid trailing whitespace.' + StyleGuide: '#no-trailing-whitespace' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '1.0' + AllowInHeredoc: false + +#################### Lint ################################## +### Warnings + +Lint/AmbiguousAssignment: + Description: 'Checks for mistyped shorthand assignments.' + Enabled: false + VersionAdded: '1.7' + +Lint/AmbiguousBlockAssociation: + Description: >- + Checks for ambiguous block association with method when param passed without + parentheses. + Enabled: false + VersionAdded: '0.48' + VersionChanged: '1.13' + AllowedMethods: [] + AllowedPatterns: [] + +Lint/AmbiguousOperator: + Description: >- + Checks for ambiguous operators in the first argument of a + method invocation without parentheses. + StyleGuide: '#method-invocation-parens' + Enabled: false + VersionAdded: '0.17' + VersionChanged: '0.83' + +Lint/AmbiguousOperatorPrecedence: + Description: >- + Checks for expressions containing multiple binary operations with + ambiguous precedence. + Enabled: false + VersionAdded: '1.21' + +Lint/AmbiguousRange: + Description: Checks for ranges with ambiguous boundaries. + Enabled: false + VersionAdded: '1.19' + SafeAutoCorrect: false + RequireParenthesesForMethodChains: false + +Lint/AmbiguousRegexpLiteral: + Description: >- + Checks for ambiguous regexp literals in the first argument of + a method invocation without parentheses. + Enabled: false + VersionAdded: '0.17' + VersionChanged: '0.83' + +Lint/AssignmentInCondition: + Description: "Don't use assignment in conditions." + StyleGuide: '#safe-assignment-in-condition' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.9' + VersionChanged: '1.45' + AllowSafeAssignment: true + +Lint/BigDecimalNew: + Description: '`BigDecimal.new()` is deprecated. Use `BigDecimal()` instead.' + Enabled: false + VersionAdded: '0.53' + +Lint/BinaryOperatorWithIdenticalOperands: + Description: 'Checks for places where binary operator has identical operands.' + Enabled: false + Safe: false + VersionAdded: '0.89' + VersionChanged: '1.7' + +Lint/BooleanSymbol: + Description: 'Check for `:true` and `:false` symbols.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.50' + VersionChanged: '1.22' + +Lint/CircularArgumentReference: + Description: "Default values in optional keyword arguments and optional ordinal arguments should not refer back to the name of the argument." + Enabled: false + VersionAdded: '0.33' + +Lint/ConstantDefinitionInBlock: + Description: 'Do not define constants within a block.' + StyleGuide: '#no-constant-definition-in-block' + Enabled: false + VersionAdded: '0.91' + VersionChanged: '1.3' + # `enums` for Typed Enums via T::Enum in Sorbet. + # https://sorbet.org/docs/tenum + AllowedMethods: + - enums + +Lint/ConstantOverwrittenInRescue: + Description: 'Checks for overwriting an exception with an exception result by use `rescue =>`.' + Enabled: false + VersionAdded: '1.31' + +Lint/ConstantResolution: + Description: 'Check that constants are fully qualified with `::`.' + Enabled: false + VersionAdded: '0.86' + # Restrict this cop to only looking at certain names + Only: [] + # Restrict this cop from only looking at certain names + Ignore: [] + +Lint/Debugger: + Description: 'Check for debugger calls.' + Enabled: false + VersionAdded: '0.14' + VersionChanged: '1.63' + DebuggerMethods: + # Groups are available so that a specific group can be disabled in + # a user's configuration, but are otherwise not significant. + Kernel: + - binding.irb + - Kernel.binding.irb + Byebug: + - byebug + - remote_byebug + - Kernel.byebug + - Kernel.remote_byebug + Capybara: + - page.save_and_open_page + - page.save_and_open_screenshot + - page.save_page + - page.save_screenshot + - save_and_open_page + - save_and_open_screenshot + - save_page + - save_screenshot + debug.rb: + - binding.b + - binding.break + - Kernel.binding.b + - Kernel.binding.break + Pry: + - binding.pry + - binding.remote_pry + - binding.pry_remote + - Kernel.binding.pry + - Kernel.binding.remote_pry + - Kernel.binding.pry_remote + - Pry.rescue + - pry + Rails: + - debugger + - Kernel.debugger + RubyJard: + - jard + WebConsole: + - binding.console + DebuggerRequires: + debug.rb: + - debug/open + - debug/start + +Lint/DeprecatedClassMethods: + Description: 'Check for deprecated class method calls.' + Enabled: false + VersionAdded: '0.19' + +Lint/DeprecatedConstants: + Description: 'Checks for deprecated constants.' + Enabled: false + VersionAdded: '1.8' + VersionChanged: '1.40' + # You can configure deprecated constants. + # If there is an alternative method, you can set alternative value as `Alternative`. + # And you can set the deprecated version as `DeprecatedVersion`. + # These options can be omitted if they are not needed. + # + # DeprecatedConstants: + # 'DEPRECATED_CONSTANT': + # Alternative: 'alternative_value' + # DeprecatedVersion: 'deprecated_version' + # + DeprecatedConstants: + 'NIL': + Alternative: 'nil' + DeprecatedVersion: '2.4' + 'TRUE': + Alternative: 'true' + DeprecatedVersion: '2.4' + 'FALSE': + Alternative: 'false' + DeprecatedVersion: '2.4' + 'Net::HTTPServerException': + Alternative: 'Net::HTTPClientException' + DeprecatedVersion: '2.6' + 'Random::DEFAULT': + Alternative: 'Random.new' + DeprecatedVersion: '3.0' + 'Struct::Group': + Alternative: 'Etc::Group' + DeprecatedVersion: '3.0' + 'Struct::Passwd': + Alternative: 'Etc::Passwd' + DeprecatedVersion: '3.0' + +Lint/DeprecatedOpenSSLConstant: + Description: "Don't use algorithm constants for `OpenSSL::Cipher` and `OpenSSL::Digest`." + Enabled: false + VersionAdded: '0.84' + +Lint/DisjunctiveAssignmentInConstructor: + Description: 'In constructor, plain assignment is preferred over disjunctive.' + Enabled: false + Safe: false + VersionAdded: '0.62' + VersionChanged: '0.88' + +Lint/DuplicateBranch: + Description: Checks that there are no repeated bodies within `if/unless`, `case-when` and `rescue` constructs. + Enabled: false + VersionAdded: '1.3' + VersionChanged: '1.7' + IgnoreLiteralBranches: false + IgnoreConstantBranches: false + +Lint/DuplicateCaseCondition: + Description: 'Do not repeat values in case conditionals.' + Enabled: false + VersionAdded: '0.45' + +Lint/DuplicateElsifCondition: + Description: 'Do not repeat conditions used in if `elsif`.' + Enabled: false + VersionAdded: '0.88' + +Lint/DuplicateHashKey: + Description: 'Check for duplicate keys in hash literals.' + Enabled: false + VersionAdded: '0.34' + VersionChanged: '0.77' + +Lint/DuplicateMagicComment: + Description: 'Check for duplicated magic comments.' + Enabled: false + VersionAdded: '1.37' + +Lint/DuplicateMatchPattern: + Description: 'Do not repeat patterns in `in` keywords.' + Enabled: false + VersionAdded: '1.50' + +Lint/DuplicateMethods: + Description: 'Check for duplicate method definitions.' + Enabled: false + VersionAdded: '0.29' + +Lint/DuplicateRegexpCharacterClassElement: + Description: 'Checks for duplicate elements in Regexp character classes.' + Enabled: false + VersionAdded: '1.1' + +Lint/DuplicateRequire: + Description: 'Check for duplicate `require`s and `require_relative`s.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.90' + VersionChanged: '1.28' + +Lint/DuplicateRescueException: + Description: 'Checks that there are no repeated exceptions used in `rescue` expressions.' + Enabled: false + VersionAdded: '0.89' + +Lint/EachWithObjectArgument: + Description: 'Check for immutable argument given to each_with_object.' + Enabled: false + VersionAdded: '0.31' + +Lint/ElseLayout: + Description: 'Check for odd code arrangement in an else block.' + Enabled: false + VersionAdded: '0.17' + VersionChanged: '1.2' + +Lint/EmptyBlock: + Description: 'Checks for blocks without a body.' + Enabled: false + VersionAdded: '1.1' + VersionChanged: '1.15' + AllowComments: true + AllowEmptyLambdas: true + +Lint/EmptyClass: + Description: 'Checks for classes and metaclasses without a body.' + Enabled: false + VersionAdded: '1.3' + AllowComments: false + +Lint/EmptyConditionalBody: + Description: 'Checks for the presence of `if`, `elsif` and `unless` branches without a body.' + Enabled: false + AutoCorrect: contextual + SafeAutoCorrect: false + AllowComments: true + VersionAdded: '0.89' + VersionChanged: '1.61' + +Lint/EmptyEnsure: + Description: 'Checks for empty ensure block.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.10' + VersionChanged: '1.61' + +Lint/EmptyExpression: + Description: 'Checks for empty expressions.' + Enabled: false + VersionAdded: '0.45' + +Lint/EmptyFile: + Description: 'Enforces that Ruby source files are not empty.' + Enabled: false + AllowComments: true + VersionAdded: '0.90' + +Lint/EmptyInPattern: + Description: 'Checks for the presence of `in` pattern branches without a body.' + Enabled: false + AllowComments: true + VersionAdded: '1.16' + +Lint/EmptyInterpolation: + Description: 'Checks for empty string interpolation.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.20' + VersionChanged: '1.61' + +Lint/EmptyWhen: + Description: 'Checks for `when` branches with empty bodies.' + Enabled: false + AllowComments: true + VersionAdded: '0.45' + VersionChanged: '0.83' + +Lint/EnsureReturn: + Description: 'Do not use return in an ensure block.' + StyleGuide: '#no-return-ensure' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.83' + +Lint/ErbNewArguments: + Description: 'Use `:trim_mode` and `:eoutvar` keyword arguments to `ERB.new`.' + Enabled: false + VersionAdded: '0.56' + +Lint/FlipFlop: + Description: 'Checks for flip-flops.' + StyleGuide: '#no-flip-flops' + Enabled: false + VersionAdded: '0.16' + +Lint/FloatComparison: + Description: 'Checks for the presence of precise comparison of floating point numbers.' + StyleGuide: '#float-comparison' + Enabled: false + VersionAdded: '0.89' + +Lint/FloatOutOfRange: + Description: >- + Catches floating-point literals too large or small for Ruby to + represent. + Enabled: false + VersionAdded: '0.36' + +Lint/FormatParameterMismatch: + Description: 'The number of parameters to format/sprint must match the fields.' + Enabled: false + VersionAdded: '0.33' + +Lint/HashCompareByIdentity: + Description: 'Prefer using `Hash#compare_by_identity` than using `object_id` for keys.' + StyleGuide: '#identity-comparison' + Enabled: false + Safe: false + VersionAdded: '0.93' + +Lint/HeredocMethodCallPosition: + Description: >- + Checks for the ordering of a method call where + the receiver of the call is a HEREDOC. + Enabled: false + StyleGuide: '#heredoc-method-calls' + VersionAdded: '0.68' + +Lint/IdentityComparison: + Description: 'Prefer `equal?` over `==` when comparing `object_id`.' + Enabled: false + StyleGuide: '#identity-comparison' + VersionAdded: '0.91' + +Lint/ImplicitStringConcatenation: + Description: >- + Checks for adjacent string literals on the same line, which + could better be represented as a single string literal. + Enabled: false + VersionAdded: '0.36' + +Lint/IncompatibleIoSelectWithFiberScheduler: + Description: 'Checks for `IO.select` that is incompatible with Fiber Scheduler.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.21' + VersionChanged: '1.24' + +Lint/IneffectiveAccessModifier: + Description: >- + Checks for attempts to use `private` or `protected` to set + the visibility of a class method, which does not work. + Enabled: false + VersionAdded: '0.36' + +Lint/InheritException: + Description: 'Avoid inheriting from the `Exception` class.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.41' + VersionChanged: '1.26' + # The default base class in favour of `Exception`. + EnforcedStyle: standard_error + SupportedStyles: + - standard_error + - runtime_error + +Lint/InterpolationCheck: + Description: 'Checks for interpolation in a single quoted string.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.50' + VersionChanged: '1.40' + +Lint/ItWithoutArgumentsInBlock: + Description: 'Checks uses of `it` calls without arguments in block.' + Reference: 'https://bugs.ruby-lang.org/issues/18980' + Enabled: false + VersionAdded: '1.59' + +Lint/LambdaWithoutLiteralBlock: + Description: 'Checks uses of lambda without a literal block.' + Enabled: false + VersionAdded: '1.8' + +Lint/LiteralAsCondition: + Description: 'Checks of literals used in conditions.' + Enabled: false + VersionAdded: '0.51' + +Lint/LiteralAssignmentInCondition: + Description: 'Checks for literal assignments in the conditions.' + Enabled: false + VersionAdded: '1.58' + +Lint/LiteralInInterpolation: + Description: 'Checks for literals used in interpolation.' + Enabled: false + VersionAdded: '0.19' + VersionChanged: '0.32' + +Lint/Loop: + Description: >- + Use Kernel#loop with break rather than begin/end/until or + begin/end/while for post-loop tests. + StyleGuide: '#loop-with-break' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.3' + Safe: false + +Lint/MissingCopEnableDirective: + Description: 'Checks for a `# rubocop:enable` after `# rubocop:disable`.' + Enabled: false + VersionAdded: '0.52' + # Maximum number of consecutive lines the cop can be disabled for. + # 0 allows only single-line disables + # 1 would mean the maximum allowed is the following: + # # rubocop:disable SomeCop + # a = 1 + # # rubocop:enable SomeCop + # .inf for any size + MaximumRangeSize: .inf + +Lint/MissingSuper: + Description: >- + Checks for the presence of constructors and lifecycle callbacks + without calls to `super`. + Enabled: false + AllowedParentClasses: [] + VersionAdded: '0.89' + VersionChanged: '1.4' + +Lint/MixedCaseRange: + Description: 'Checks for mixed-case character ranges since they include likely unintended characters.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.53' + +Lint/MixedRegexpCaptureTypes: + Description: 'Do not mix named captures and numbered captures in a Regexp literal.' + Enabled: false + VersionAdded: '0.85' + +Lint/MultipleComparison: + Description: "Use `&&` operator to compare multiple values." + Enabled: false + VersionAdded: '0.47' + VersionChanged: '1.1' + +Lint/NestedMethodDefinition: + Description: 'Do not use nested method definitions.' + StyleGuide: '#no-nested-methods' + Enabled: false + AllowedMethods: [] + AllowedPatterns: [] + VersionAdded: '0.32' + +Lint/NestedPercentLiteral: + Description: 'Checks for nested percent literals.' + Enabled: false + VersionAdded: '0.52' + +Lint/NextWithoutAccumulator: + Description: >- + Do not omit the accumulator when calling `next` + in a `reduce`/`inject` block. + Enabled: false + VersionAdded: '0.36' + +Lint/NoReturnInBeginEndBlocks: + Description: 'Do not `return` inside `begin..end` blocks in assignment contexts.' + Enabled: false + VersionAdded: '1.2' + +Lint/NonAtomicFileOperation: + Description: Checks for non-atomic file operations. + StyleGuide: '#atomic-file-operations' + Enabled: false + VersionAdded: '1.31' + SafeAutoCorrect: false + +Lint/NonDeterministicRequireOrder: + Description: 'Always sort arrays returned by Dir.glob when requiring files.' + Enabled: false + VersionAdded: '0.78' + Safe: false + +Lint/NonLocalExitFromIterator: + Description: 'Do not use return in iterator to cause non-local exit.' + Enabled: false + VersionAdded: '0.30' + +Lint/NumberConversion: + Description: 'Checks unsafe usage of number conversion methods.' + Enabled: false + VersionAdded: '0.53' + VersionChanged: '1.1' + SafeAutoCorrect: false + AllowedMethods: [] + AllowedPatterns: [] + IgnoredClasses: + - Time + - DateTime + +Lint/NumberedParameterAssignment: + Description: 'Checks for uses of numbered parameter assignment.' + Enabled: false + VersionAdded: '1.9' + +Lint/OrAssignmentToConstant: + Description: 'Checks unintended or-assignment to constant.' + Enabled: false + Safe: false + VersionAdded: '1.9' + +Lint/OrderedMagicComments: + Description: 'Checks the proper ordering of magic comments and whether a magic comment is not placed before a shebang.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.53' + VersionChanged: '1.37' + +Lint/OutOfRangeRegexpRef: + Description: 'Checks for out of range reference for Regexp because it always returns nil.' + Enabled: false + Safe: false + VersionAdded: '0.89' + +Lint/ParenthesesAsGroupedExpression: + Description: >- + Checks for method calls with a space before the opening + parenthesis. + StyleGuide: '#parens-no-spaces' + Enabled: false + VersionAdded: '0.12' + VersionChanged: '0.83' + +Lint/PercentStringArray: + Description: >- + Checks for unwanted commas and quotes in %w/%W literals. + Enabled: false + Safe: false + VersionAdded: '0.41' + +Lint/PercentSymbolArray: + Description: >- + Checks for unwanted commas and colons in %i/%I literals. + Enabled: false + VersionAdded: '0.41' + +Lint/RaiseException: + Description: Checks for `raise` or `fail` statements which are raising `Exception` class. + StyleGuide: '#raise-exception' + Enabled: false + Safe: false + VersionAdded: '0.81' + VersionChanged: '0.86' + AllowedImplicitNamespaces: + - 'Gem' + +Lint/RandOne: + Description: >- + Checks for `rand(1)` calls. Such calls always return `0` + and most likely a mistake. + Enabled: false + VersionAdded: '0.36' + +Lint/RedundantCopDisableDirective: + Description: >- + Checks for rubocop:disable comments that can be removed. + Note: this cop is not disabled when disabling all cops. + It must be explicitly disabled. + Enabled: false + VersionAdded: '0.76' + +Lint/RedundantCopEnableDirective: + Description: Checks for rubocop:enable comments that can be removed. + Enabled: false + VersionAdded: '0.76' + +Lint/RedundantDirGlobSort: + Description: 'Checks for redundant `sort` method to `Dir.glob` and `Dir[]`.' + Enabled: false + VersionAdded: '1.8' + VersionChanged: '1.26' + SafeAutoCorrect: false + +Lint/RedundantRegexpQuantifiers: + Description: 'Checks for redundant quantifiers in Regexps.' + Enabled: false + VersionAdded: '1.53' + +Lint/RedundantRequireStatement: + Description: 'Checks for unnecessary `require` statement.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.76' + VersionChanged: '1.57' + +Lint/RedundantSafeNavigation: + Description: 'Checks for redundant safe navigation calls.' + Enabled: false + VersionAdded: '0.93' + AllowedMethods: + - instance_of? + - kind_of? + - is_a? + - eql? + - respond_to? + - equal? + Safe: false + +Lint/RedundantSplatExpansion: + Description: 'Checks for splat unnecessarily being called on literals.' + Enabled: false + VersionAdded: '0.76' + VersionChanged: '1.7' + AllowPercentLiteralArrayArgument: true + +Lint/RedundantStringCoercion: + Description: 'Checks for Object#to_s usage in string interpolation.' + StyleGuide: '#no-to-s' + Enabled: false + VersionAdded: '0.19' + VersionChanged: '0.77' + +Lint/RedundantWithIndex: + Description: 'Checks for redundant `with_index`.' + Enabled: false + VersionAdded: '0.50' + +Lint/RedundantWithObject: + Description: 'Checks for redundant `with_object`.' + Enabled: false + VersionAdded: '0.51' + +Lint/RefinementImportMethods: + Description: 'Use `Refinement#import_methods` when using `include` or `prepend` in `refine` block.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.27' + +Lint/RegexpAsCondition: + Description: >- + Do not use regexp literal as a condition. + The regexp literal matches `$_` implicitly. + Enabled: false + VersionAdded: '0.51' + VersionChanged: '0.86' + +Lint/RequireParentheses: + Description: >- + Use parentheses in the method call to avoid confusion + about precedence. + Enabled: false + VersionAdded: '0.18' + +Lint/RequireRangeParentheses: + Description: 'Checks that a range literal is enclosed in parentheses when the end of the range is at a line break.' + Enabled: false + VersionAdded: '1.32' + +Lint/RequireRelativeSelfPath: + Description: 'Checks for uses a file requiring itself with `require_relative`.' + Enabled: false + VersionAdded: '1.22' + +Lint/RescueException: + Description: 'Avoid rescuing the Exception class.' + StyleGuide: '#no-blind-rescues' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.27' + +Lint/RescueType: + Description: 'Avoid rescuing from non constants that could result in a `TypeError`.' + Enabled: false + VersionAdded: '0.49' + +Lint/ReturnInVoidContext: + Description: 'Checks for return in void context.' + Enabled: false + VersionAdded: '0.50' + +Lint/SafeNavigationChain: + Description: 'Do not chain ordinary method call after safe navigation operator.' + Enabled: false + VersionAdded: '0.47' + VersionChanged: '0.77' + AllowedMethods: + - present? + - blank? + - presence + - try + - try! + - in? + +Lint/SafeNavigationConsistency: + Description: >- + Check to make sure that if safe navigation is used for a method + call in an `&&` or `||` condition that safe navigation is used + for all method calls on that same object. + Enabled: false + VersionAdded: '0.55' + VersionChanged: '0.77' + AllowedMethods: + - present? + - blank? + - presence + - try + - try! + +Lint/SafeNavigationWithEmpty: + Description: 'Avoid `foo&.empty?` in conditionals.' + Enabled: false + VersionAdded: '0.62' + VersionChanged: '0.87' + +Lint/ScriptPermission: + Description: 'Grant script file execute permission.' + Enabled: false + VersionAdded: '0.49' + VersionChanged: '0.50' + +Lint/SelfAssignment: + Description: 'Checks for self-assignments.' + Enabled: false + VersionAdded: '0.89' + +Lint/SendWithMixinArgument: + Description: 'Checks for `send` method when using mixin.' + Enabled: false + VersionAdded: '0.75' + +Lint/ShadowedArgument: + Description: 'Avoid reassigning arguments before they were used.' + Enabled: false + VersionAdded: '0.52' + IgnoreImplicitReferences: false + + +Lint/ShadowedException: + Description: >- + Avoid rescuing a higher level exception + before a lower level exception. + Enabled: false + VersionAdded: '0.41' + +Lint/ShadowingOuterLocalVariable: + Description: >- + Do not use the same name as outer local variable + for block arguments or block local variables. + Enabled: false + VersionAdded: '0.9' + +Lint/StructNewOverride: + Description: 'Disallow overriding the `Struct` built-in methods via `Struct.new`.' + Enabled: false + VersionAdded: '0.81' + +Lint/SuppressedException: + Description: "Don't suppress exceptions." + StyleGuide: '#dont-hide-exceptions' + Enabled: false + AllowComments: true + AllowNil: true + VersionAdded: '0.9' + VersionChanged: '1.12' + +Lint/SymbolConversion: + Description: 'Checks for unnecessary symbol conversions.' + Enabled: false + VersionAdded: '1.9' + VersionChanged: '1.16' + EnforcedStyle: strict + SupportedStyles: + - strict + - consistent + +Lint/Syntax: + Description: 'Checks for syntax errors.' + Enabled: true + VersionAdded: '0.9' + +Lint/ToEnumArguments: + Description: 'Ensures that `to_enum`/`enum_for`, called for the current method, has correct arguments.' + Enabled: false + VersionAdded: '1.1' + +Lint/ToJSON: + Description: 'Ensure #to_json includes an optional argument.' + Enabled: false + VersionAdded: '0.66' + +Lint/TopLevelReturnWithArgument: + Description: 'Detects top level return statements with argument.' + Enabled: false + VersionAdded: '0.89' + # These codes are `eval`-ed in method and their return values may be used. + Exclude: + - '**/*.jb' + +Lint/TrailingCommaInAttributeDeclaration: + Description: 'Checks for trailing commas in attribute declarations.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.90' + VersionChanged: '1.61' + +Lint/TripleQuotes: + Description: 'Checks for useless triple quote constructs.' + Enabled: false + VersionAdded: '1.9' + +Lint/UnderscorePrefixedVariableName: + Description: 'Do not use prefix `_` for a variable that is used.' + Enabled: false + VersionAdded: '0.21' + AllowKeywordBlockArguments: false + +Lint/UnexpectedBlockArity: + Description: 'Looks for blocks that have fewer arguments that the calling method expects.' + Enabled: false + Safe: false + VersionAdded: '1.5' + Methods: + chunk_while: 2 + each_with_index: 2 + each_with_object: 2 + inject: 2 + max: 2 + min: 2 + minmax: 2 + reduce: 2 + slice_when: 2 + sort: 2 + +Lint/UnifiedInteger: + Description: 'Use Integer instead of Fixnum or Bignum.' + Enabled: false + VersionAdded: '0.43' + +Lint/UnmodifiedReduceAccumulator: + Description: Checks for `reduce` or `inject` blocks that do not update the accumulator each iteration. + Enabled: false + VersionAdded: '1.1' + VersionChanged: '1.5' + +Lint/UnreachableCode: + Description: 'Unreachable code.' + Enabled: false + VersionAdded: '0.9' + +Lint/UnreachableLoop: + Description: 'Checks for loops that will have at most one iteration.' + Enabled: false + VersionAdded: '0.89' + VersionChanged: '1.7' + AllowedPatterns: + # RSpec uses `times` in its message expectations + # eg. `exactly(2).times` + - !ruby/regexp /(exactly|at_least|at_most)\(\d+\)\.times/ + +Lint/UnusedBlockArgument: + Description: 'Checks for unused block arguments.' + StyleGuide: '#underscore-unused-vars' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.21' + VersionChanged: '1.61' + IgnoreEmptyBlocks: true + AllowUnusedKeywordArguments: false + +Lint/UnusedMethodArgument: + Description: 'Checks for unused method arguments.' + StyleGuide: '#underscore-unused-vars' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.21' + VersionChanged: '1.61' + AllowUnusedKeywordArguments: false + IgnoreEmptyMethods: true + IgnoreNotImplementedMethods: true + +Lint/UriEscapeUnescape: + Description: >- + `URI.escape` method is obsolete and should not be used. Instead, use + `CGI.escape`, `URI.encode_www_form` or `URI.encode_www_form_component` + depending on your specific use case. + Also `URI.unescape` method is obsolete and should not be used. Instead, use + `CGI.unescape`, `URI.decode_www_form` or `URI.decode_www_form_component` + depending on your specific use case. + Enabled: false + VersionAdded: '0.50' + +Lint/UriRegexp: + Description: 'Use `URI::DEFAULT_PARSER.make_regexp` instead of `URI.regexp`.' + Enabled: false + VersionAdded: '0.50' + +Lint/UselessAccessModifier: + Description: 'Checks for useless access modifiers.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.20' + VersionChanged: '1.61' + ContextCreatingMethods: [] + MethodCreatingMethods: [] + +Lint/UselessAssignment: + Description: 'Checks for useless assignment to a local variable.' + StyleGuide: '#underscore-unused-vars' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.11' + VersionChanged: '1.61' + SafeAutoCorrect: false + +Lint/UselessElseWithoutRescue: + Description: 'Checks for useless `else` in `begin..end` without `rescue`.' + Enabled: false + VersionAdded: '0.17' + VersionChanged: '1.31' + +Lint/UselessMethodDefinition: + Description: 'Checks for useless method definitions.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.90' + VersionChanged: '1.61' + Safe: false + +Lint/UselessRescue: + Description: 'Checks for useless `rescue`s.' + Enabled: false + VersionAdded: '1.43' + +Lint/UselessRuby2Keywords: + Description: 'Finds unnecessary uses of `ruby2_keywords`.' + Enabled: false + VersionAdded: '1.23' + +Lint/UselessSetterCall: + Description: 'Checks for useless setter call to a local variable.' + Enabled: false + Safe: false + VersionAdded: '0.13' + VersionChanged: '1.2' + +Lint/UselessTimes: + Description: 'Checks for useless `Integer#times` calls.' + Enabled: false + Safe: false + AutoCorrect: contextual + VersionAdded: '0.91' + VersionChanged: '1.61' + +Lint/Void: + Description: 'Possible use of operator/literal/variable in void context.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.9' + VersionChanged: '1.61' + CheckForMethodsWithNoSideEffects: false + +#################### Metrics ############################### + +Metrics/AbcSize: + Description: >- + A calculated magnitude based on number of assignments, + branches, and conditions. + Reference: + - http://c2.com/cgi/wiki?AbcMetric + - https://en.wikipedia.org/wiki/ABC_Software_Metric + Enabled: false + VersionAdded: '0.27' + VersionChanged: '1.5' + # The ABC size is a calculated magnitude, so this number can be an Integer or + # a Float. + AllowedMethods: [] + AllowedPatterns: [] + CountRepeatedAttributes: true + Max: 17 + +Metrics/BlockLength: + Description: 'Avoid long blocks with many lines.' + Enabled: false + VersionAdded: '0.44' + VersionChanged: '1.5' + CountComments: false # count full line comments? + Max: 25 + CountAsOne: [] + AllowedMethods: + # By default, exclude the `#refine` method, as it tends to have larger + # associated blocks. + - refine + AllowedPatterns: [] + Exclude: + - '**/*.gemspec' + +Metrics/BlockNesting: + Description: 'Avoid excessive block nesting.' + StyleGuide: '#three-is-the-number-thou-shalt-count' + Enabled: false + VersionAdded: '0.25' + VersionChanged: '1.65' + CountBlocks: false + CountModifierForms: false + Max: 3 + +Metrics/ClassLength: + Description: 'Avoid classes longer than 100 lines of code.' + Enabled: false + VersionAdded: '0.25' + VersionChanged: '0.87' + CountComments: false # count full line comments? + Max: 100 + CountAsOne: [] + +Metrics/CollectionLiteralLength: + Description: 'Checks for `Array` or `Hash` literals with many entries.' + Enabled: false + VersionAdded: '1.47' + LengthThreshold: 250 + +# Avoid complex methods. +Metrics/CyclomaticComplexity: + Description: >- + A complexity metric that is strongly correlated to the number + of test cases needed to validate a method. + Enabled: false + VersionAdded: '0.25' + VersionChanged: '0.81' + AllowedMethods: [] + AllowedPatterns: [] + Max: 7 + +Metrics/MethodLength: + Description: 'Avoid methods longer than 10 lines of code.' + StyleGuide: '#short-methods' + Enabled: false + VersionAdded: '0.25' + VersionChanged: '1.5' + CountComments: false # count full line comments? + Max: 10 + CountAsOne: [] + AllowedMethods: [] + AllowedPatterns: [] + +Metrics/ModuleLength: + Description: 'Avoid modules longer than 100 lines of code.' + Enabled: false + VersionAdded: '0.31' + VersionChanged: '0.87' + CountComments: false # count full line comments? + Max: 100 + CountAsOne: [] + +Metrics/ParameterLists: + Description: 'Avoid parameter lists longer than three or four parameters.' + StyleGuide: '#too-many-params' + Enabled: false + VersionAdded: '0.25' + VersionChanged: '1.5' + Max: 5 + CountKeywordArgs: true + MaxOptionalParameters: 3 + +Metrics/PerceivedComplexity: + Description: >- + A complexity metric geared towards measuring complexity for a + human reader. + Enabled: false + VersionAdded: '0.25' + VersionChanged: '0.81' + AllowedMethods: [] + AllowedPatterns: [] + Max: 8 + +################## Migration ############################# + +Migration/DepartmentName: + Description: >- + Check that cop names in rubocop:disable (etc) comments are + given with department name. + Enabled: false + VersionAdded: '0.75' + +#################### Naming ############################## + +Naming/AccessorMethodName: + Description: Check the naming of accessor methods for get_/set_. + StyleGuide: '#accessor_mutator_method_names' + Enabled: false + VersionAdded: '0.50' + +Naming/AsciiIdentifiers: + Description: 'Use only ascii symbols in identifiers and constants.' + StyleGuide: '#english-identifiers' + Enabled: false + VersionAdded: '0.50' + VersionChanged: '0.87' + AsciiConstants: true + +Naming/BinaryOperatorParameterName: + Description: 'When defining binary operators, name the argument other.' + StyleGuide: '#other-arg' + Enabled: false + VersionAdded: '0.50' + VersionChanged: '1.2' + +Naming/BlockForwarding: + Description: 'Use anonymous block forwarding.' + StyleGuide: '#block-forwarding' + Enabled: false + VersionAdded: '1.24' + EnforcedStyle: anonymous + SupportedStyles: + - anonymous + - explicit + BlockForwardingName: block + +Naming/BlockParameterName: + Description: >- + Checks for block parameter names that contain capital letters, + end in numbers, or do not meet a minimal length. + Enabled: false + VersionAdded: '0.53' + VersionChanged: '0.77' + # Parameter names may be equal to or greater than this value + MinNameLength: 1 + AllowNamesEndingInNumbers: true + # Allowed names that will not register an offense + AllowedNames: [] + # Forbidden names that will register an offense + ForbiddenNames: [] + +Naming/ClassAndModuleCamelCase: + Description: 'Use CamelCase for classes and modules.' + StyleGuide: '#camelcase-classes' + Enabled: false + VersionAdded: '0.50' + VersionChanged: '0.85' + # Allowed class/module names can be specified here. + # These can be full or part of the name. + AllowedNames: + - module_parent + +Naming/ConstantName: + Description: 'Constants should use SCREAMING_SNAKE_CASE.' + StyleGuide: '#screaming-snake-case' + Enabled: false + VersionAdded: '0.50' + +Naming/FileName: + Description: 'Use snake_case for source file names.' + StyleGuide: '#snake-case-files' + Enabled: false + VersionAdded: '0.50' + VersionChanged: '1.23' + # Camel case file names listed in `AllCops:Include` and all file names listed + # in `AllCops:Exclude` are excluded by default. Add extra excludes here. + Exclude: + - Rakefile.rb + # When `true`, requires that each source file should define a class or module + # with a name which matches the file name (converted to ... case). + # It further expects it to be nested inside modules which match the names + # of subdirectories in its path. + ExpectMatchingDefinition: false + # When `false`, changes the behavior of ExpectMatchingDefinition to match only + # whether each source file's class or module name matches the file name -- + # not whether the nested module hierarchy matches the subdirectory path. + CheckDefinitionPathHierarchy: true + # paths that are considered root directories, for example "lib" in most ruby projects + # or "app/models" in rails projects + CheckDefinitionPathHierarchyRoots: + - lib + - spec + - test + - src + # If non-`nil`, expect all source file names to match the following regex. + # Only the file name itself is matched, not the entire file path. + # Use anchors as necessary if you want to match the entire name rather than + # just a part of it. + Regex: ~ + # With `IgnoreExecutableScripts` set to `true`, this cop does not + # report offending filenames for executable scripts (i.e. source + # files with a shebang in the first line). + IgnoreExecutableScripts: true + AllowedAcronyms: + - CLI + - DSL + - ACL + - API + - ASCII + - CPU + - CSS + - DNS + - EOF + - GUID + - HTML + - HTTP + - HTTPS + - ID + - IP + - JSON + - LHS + - QPS + - RAM + - RHS + - RPC + - SLA + - SMTP + - SQL + - SSH + - TCP + - TLS + - TTL + - UDP + - UI + - UID + - UUID + - URI + - URL + - UTF8 + - VM + - XML + - XMPP + - XSRF + - XSS + +Naming/HeredocDelimiterCase: + Description: 'Use configured case for heredoc delimiters.' + StyleGuide: '#heredoc-delimiters' + Enabled: false + VersionAdded: '0.50' + VersionChanged: '1.2' + EnforcedStyle: uppercase + SupportedStyles: + - lowercase + - uppercase + +Naming/HeredocDelimiterNaming: + Description: 'Use descriptive heredoc delimiters.' + StyleGuide: '#heredoc-delimiters' + Enabled: false + VersionAdded: '0.50' + ForbiddenDelimiters: + - !ruby/regexp '/(^|\s)(EO[A-Z]{1}|END)(\s|$)/i' + +Naming/InclusiveLanguage: + Description: 'Recommend the use of inclusive language instead of problematic terms.' + Enabled: false + VersionAdded: '1.18' + VersionChanged: '1.49' + CheckIdentifiers: true + CheckConstants: true + CheckVariables: true + CheckStrings: false + CheckSymbols: true + CheckComments: true + CheckFilepaths: true + FlaggedTerms: + whitelist: + Regex: !ruby/regexp '/white[-_\s]?list/' + Suggestions: + - allowlist + - permit + blacklist: + Regex: !ruby/regexp '/black[-_\s]?list/' + Suggestions: + - denylist + - block + slave: + WholeWord: true + Suggestions: ['replica', 'secondary', 'follower'] + +Naming/MemoizedInstanceVariableName: + Description: >- + Memoized method name should match memo instance variable name. + Enabled: false + VersionAdded: '0.53' + VersionChanged: '1.2' + EnforcedStyleForLeadingUnderscores: disallowed + SupportedStylesForLeadingUnderscores: + - disallowed + - required + - optional + Safe: false + +Naming/MethodName: + Description: 'Use the configured style when naming methods.' + StyleGuide: '#snake-case-symbols-methods-vars' + Enabled: false + VersionAdded: '0.50' + EnforcedStyle: snake_case + SupportedStyles: + - snake_case + - camelCase + # Method names matching patterns are always allowed. + # + # AllowedPatterns: + # - '\A\s*onSelectionBulkChange\s*' + # - '\A\s*onSelectionCleared\s*' + # + AllowedPatterns: [] + +Naming/MethodParameterName: + Description: >- + Checks for method parameter names that contain capital letters, + end in numbers, or do not meet a minimal length. + Enabled: false + VersionAdded: '0.53' + VersionChanged: '0.77' + # Parameter names may be equal to or greater than this value + MinNameLength: 3 + AllowNamesEndingInNumbers: true + # Allowed names that will not register an offense + AllowedNames: + - as + - at + - by + - cc + - db + - id + - if + - in + - io + - ip + - of + - 'on' + - os + - pp + - to + # Forbidden names that will register an offense + ForbiddenNames: [] + +Naming/PredicateName: + Description: 'Check the names of predicate methods.' + StyleGuide: '#bool-methods-qmark' + Enabled: false + VersionAdded: '0.50' + VersionChanged: '0.77' + # Predicate name prefixes. + NamePrefix: + - is_ + - has_ + - have_ + # Predicate name prefixes that should be removed. + ForbiddenPrefixes: + - is_ + - has_ + - have_ + # Predicate names which, despite having a forbidden prefix, or no `?`, + # should still be accepted + AllowedMethods: + - is_a? + # Method definition macros for dynamically generated methods. + MethodDefinitionMacros: + - define_method + - define_singleton_method + # Exclude Rspec specs because there is a strong convention to write spec + # helpers in the form of `have_something` or `be_something`. + Exclude: + - 'spec/**/*' + +Naming/RescuedExceptionsVariableName: + Description: 'Use consistent rescued exceptions variables naming.' + Enabled: false + VersionAdded: '0.67' + VersionChanged: '0.68' + PreferredName: e + +Naming/VariableName: + Description: 'Use the configured style when naming variables.' + StyleGuide: '#snake-case-symbols-methods-vars' + Enabled: false + VersionAdded: '0.50' + VersionChanged: '1.8' + EnforcedStyle: snake_case + SupportedStyles: + - snake_case + - camelCase + AllowedIdentifiers: [] + AllowedPatterns: [] + +Naming/VariableNumber: + Description: 'Use the configured style when numbering symbols, methods and variables.' + StyleGuide: '#snake-case-symbols-methods-vars-with-numbers' + Enabled: false + VersionAdded: '0.50' + VersionChanged: '1.4' + EnforcedStyle: normalcase + SupportedStyles: + - snake_case + - normalcase + - non_integer + CheckMethodNames: true + CheckSymbols: true + AllowedIdentifiers: + - capture3 # Open3.capture3 + - iso8601 # Time#iso8601 + - rfc1123_date # CGI.rfc1123_date + - rfc822 # Time#rfc822 + - rfc2822 # Time#rfc2822 + - rfc3339 # DateTime.rfc3339 + - x86_64 # Allowed by default as an underscore separated CPU architecture name + AllowedPatterns: [] + +#################### Security ############################## + +Security/CompoundHash: + Description: 'When overwriting Object#hash to combine values, prefer delegating to Array#hash over writing a custom implementation.' + Enabled: false + Safe: false + VersionAdded: '1.28' + VersionChanged: '1.51' + +Security/Eval: + Description: 'The use of eval represents a serious security risk.' + Enabled: false + VersionAdded: '0.47' + +Security/IoMethods: + Description: >- + Checks for the first argument to `IO.read`, `IO.binread`, `IO.write`, `IO.binwrite`, + `IO.foreach`, and `IO.readlines`. + Enabled: false + Safe: false + VersionAdded: '1.22' + +Security/JSONLoad: + Description: >- + Prefer usage of `JSON.parse` over `JSON.load` due to potential + security issues. See reference for more information. + Reference: 'https://ruby-doc.org/stdlib-2.7.0/libdoc/json/rdoc/JSON.html#method-i-load' + Enabled: false + VersionAdded: '0.43' + VersionChanged: '1.22' + # Autocorrect here will change to a method that may cause crashes depending + # on the value of the argument. + SafeAutoCorrect: false + +Security/MarshalLoad: + Description: >- + Avoid using of `Marshal.load` or `Marshal.restore` due to potential + security issues. See reference for more information. + Reference: 'https://ruby-doc.org/core-2.7.0/Marshal.html#module-Marshal-label-Security+considerations' + Enabled: false + VersionAdded: '0.47' + +Security/Open: + Description: 'The use of `Kernel#open` and `URI.open` represent a serious security risk.' + Enabled: false + VersionAdded: '0.53' + VersionChanged: '1.0' + Safe: false + +Security/YAMLLoad: + Description: >- + Prefer usage of `YAML.safe_load` over `YAML.load` due to potential + security issues. See reference for more information. + Reference: 'https://ruby-doc.org/stdlib-2.7.0/libdoc/yaml/rdoc/YAML.html#module-YAML-label-Security' + Enabled: false + VersionAdded: '0.47' + SafeAutoCorrect: false + +#################### Style ############################### + +Style/AccessModifierDeclarations: + Description: 'Checks style of how access modifiers are used.' + Enabled: false + VersionAdded: '0.57' + VersionChanged: '0.81' + EnforcedStyle: group + SupportedStyles: + - inline + - group + AllowModifiersOnSymbols: true + AllowModifiersOnAttrs: true + SafeAutoCorrect: false + +Style/AccessorGrouping: + Description: 'Checks for grouping of accessors in `class` and `module` bodies.' + Enabled: false + VersionAdded: '0.87' + EnforcedStyle: grouped + SupportedStyles: + # separated: each accessor goes in a separate statement. + # grouped: accessors are grouped into a single statement. + - separated + - grouped + +Style/Alias: + Description: 'Use alias instead of alias_method.' + StyleGuide: '#alias-method-lexically' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.36' + EnforcedStyle: prefer_alias + SupportedStyles: + - prefer_alias + - prefer_alias_method + +Style/AndOr: + Description: 'Use &&/|| instead of and/or.' + StyleGuide: '#no-and-or-or' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.9' + VersionChanged: '1.21' + # Whether `and` and `or` are banned only in conditionals (conditionals) + # or completely (always). + EnforcedStyle: conditionals + SupportedStyles: + - always + - conditionals + +Style/ArgumentsForwarding: + Description: 'Use arguments forwarding.' + StyleGuide: '#arguments-forwarding' + Enabled: false + UseAnonymousForwarding: true + RedundantRestArgumentNames: + - args + - arguments + RedundantKeywordRestArgumentNames: + - kwargs + - options + - opts + RedundantBlockArgumentNames: + - blk + - block + - proc + VersionAdded: '1.1' + VersionChanged: '1.58' + +Style/ArrayCoercion: + Description: >- + Use Array() instead of explicit Array check or [*var], when dealing + with a variable you want to treat as an Array, but you're not certain it's an array. + StyleGuide: '#array-coercion' + Safe: false + Enabled: false + VersionAdded: '0.88' + +Style/ArrayFirstLast: + Description: 'Use `arr.first` and `arr.last` instead of `arr[0]` and `arr[-1]`.' + Reference: '#first-and-last' + Enabled: false + VersionAdded: '1.58' + Safe: false + +Style/ArrayIntersect: + Description: 'Use `array1.intersect?(array2)` instead of `(array1 & array2).any?`.' + Enabled: 'pending' + Safe: false + VersionAdded: '1.40' + +Style/ArrayJoin: + Description: 'Use Array#join instead of Array#*.' + StyleGuide: '#array-join' + Enabled: false + VersionAdded: '0.20' + VersionChanged: '0.31' + +Style/AsciiComments: + Description: 'Use only ascii symbols in comments.' + StyleGuide: '#english-comments' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.21' + AllowedChars: + - © + +Style/Attr: + Description: 'Checks for uses of Module#attr.' + StyleGuide: '#attr' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.12' + +Style/AutoResourceCleanup: + Description: 'Suggests the usage of an auto resource cleanup version of a method (if available).' + Enabled: false + VersionAdded: '0.30' + +Style/BarePercentLiterals: + Description: 'Checks if usage of %() or %Q() matches configuration.' + StyleGuide: '#percent-q-shorthand' + Enabled: false + VersionAdded: '0.25' + EnforcedStyle: bare_percent + SupportedStyles: + - percent_q + - bare_percent + +Style/BeginBlock: + Description: 'Avoid the use of BEGIN blocks.' + StyleGuide: '#no-BEGIN-blocks' + Enabled: false + VersionAdded: '0.9' + +Style/BisectedAttrAccessor: + Description: >- + Checks for places where `attr_reader` and `attr_writer` + for the same method can be combined into single `attr_accessor`. + Enabled: false + VersionAdded: '0.87' + +Style/BlockComments: + Description: 'Do not use block comments.' + StyleGuide: '#no-block-comments' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.23' + +Style/BlockDelimiters: + Description: >- + Avoid using {...} for multi-line blocks (multiline chaining is + always ugly). + Prefer {...} over do...end for single-line blocks. + StyleGuide: '#single-line-blocks' + Enabled: false + VersionAdded: '0.30' + VersionChanged: '0.35' + EnforcedStyle: line_count_based + SupportedStyles: + # The `line_count_based` style enforces braces around single line blocks and + # do..end around multi-line blocks. + - line_count_based + # The `semantic` style enforces braces around functional blocks, where the + # primary purpose of the block is to return a value and do..end for + # multi-line procedural blocks, where the primary purpose of the block is + # its side-effects. Single-line procedural blocks may only use do-end, + # unless AllowBracesOnProceduralOneLiners has a truthy value (see below). + # + # This looks at the usage of a block's method to determine its type (e.g. is + # the result of a `map` assigned to a variable or passed to another + # method) but exceptions are permitted in the `ProceduralMethods`, + # `FunctionalMethods` and `AllowedMethods` sections below. + - semantic + # The `braces_for_chaining` style enforces braces around single line blocks + # and do..end around multi-line blocks, except for multi-line blocks whose + # return value is being chained with another method (in which case braces + # are enforced). + - braces_for_chaining + # The `always_braces` style always enforces braces. + - always_braces + ProceduralMethods: + # Methods that are known to be procedural in nature but look functional from + # their usage, e.g. + # + # time = Benchmark.realtime do + # foo.bar + # end + # + # Here, the return value of the block is discarded but the return value of + # `Benchmark.realtime` is used. + - benchmark + - bm + - bmbm + - create + - each_with_object + - measure + - new + - realtime + - tap + - with_object + FunctionalMethods: + # Methods that are known to be functional in nature but look procedural from + # their usage, e.g. + # + # let(:foo) { Foo.new } + # + # Here, the return value of `Foo.new` is used to define a `foo` helper but + # doesn't appear to be used from the return value of `let`. + - let + - let! + - subject + - watch + AllowedMethods: + # Methods that can be either procedural or functional and cannot be + # categorised from their usage alone, e.g. + # + # foo = lambda do |x| + # puts "Hello, #{x}" + # end + # + # foo = lambda do |x| + # x * 100 + # end + # + # Here, it is impossible to tell from the return value of `lambda` whether + # the inner block's return value is significant. + - lambda + - proc + - it + AllowedPatterns: [] + # The AllowBracesOnProceduralOneLiners option is ignored unless the + # EnforcedStyle is set to `semantic`. If so: + # + # If AllowBracesOnProceduralOneLiners is unspecified, or set to any + # falsey value, then semantic purity is maintained, so one-line + # procedural blocks must use do-end, not braces. + # + # # bad + # collection.each { |element| puts element } + # + # # good + # collection.each do |element| puts element end + # + # If AllowBracesOnProceduralOneLiners is set to any truthy value, + # then one-line procedural blocks may use either style. + # + # # good + # collection.each { |element| puts element } + # + # # also good + # collection.each do |element| puts element end + AllowBracesOnProceduralOneLiners: false + # The BracesRequiredMethods overrides all other configurations except + # AllowedMethods. It can be used to enforce that all blocks for specific + # methods use braces. For example, you can use this to enforce Sorbet + # signatures use braces even when the rest of your codebase enforces + # the `line_count_based` style. + BracesRequiredMethods: [] + +Style/CaseEquality: + Description: 'Avoid explicit use of the case equality operator(===).' + StyleGuide: '#no-case-equality' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.89' + # If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of + # the case equality operator is a constant. + # + # # bad + # /string/ === "string" + # + # # good + # String === "string" + AllowOnConstant: false + # If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of + # the case equality operator is `self.class`. + # + # # bad + # some_class === object + # + # # good + # self.class === object + AllowOnSelfClass: false + +Style/CaseLikeIf: + Description: 'Identifies places where `if-elsif` constructions can be replaced with `case-when`.' + StyleGuide: '#case-vs-if-else' + Enabled: false + Safe: false + VersionAdded: '0.88' + VersionChanged: '1.48' + # `MinBranchesCount` defines the number of branches `if` needs to have to trigger this cop. + MinBranchesCount: 3 + +Style/CharacterLiteral: + Description: 'Checks for uses of character literals.' + StyleGuide: '#no-character-literals' + Enabled: false + VersionAdded: '0.9' + +Style/ClassAndModuleChildren: + Description: 'Checks style of children classes and modules.' + StyleGuide: '#namespace-definition' + # Moving from compact to nested children requires knowledge of whether the + # outer parent is a module or a class. Moving from nested to compact requires + # verification that the outer parent is defined elsewhere. RuboCop does not + # have the knowledge to perform either operation safely and thus requires + # manual oversight. + SafeAutoCorrect: false + Enabled: false + VersionAdded: '0.19' + # + # Basically there are two different styles: + # + # `nested` - have each child on a separate line + # class Foo + # class Bar + # end + # end + # + # `compact` - combine definitions as much as possible + # class Foo::Bar + # end + # + # The compact style is only forced, for classes or modules with one child. + EnforcedStyle: nested + SupportedStyles: + - nested + - compact + +Style/ClassCheck: + Description: 'Enforces consistent use of `Object#is_a?` or `Object#kind_of?`.' + StyleGuide: '#is-a-vs-kind-of' + Enabled: false + VersionAdded: '0.24' + EnforcedStyle: is_a? + SupportedStyles: + - is_a? + - kind_of? + +Style/ClassEqualityComparison: + Description: 'Enforces the use of `Object#instance_of?` instead of class comparison for equality.' + StyleGuide: '#instance-of-vs-class-comparison' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.93' + VersionChanged: '1.57' + AllowedMethods: + - == + - equal? + - eql? + AllowedPatterns: [] + +Style/ClassMethods: + Description: 'Use self when defining module/class methods.' + StyleGuide: '#def-self-class-methods' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.20' + +Style/ClassMethodsDefinitions: + Description: 'Enforces using `def self.method_name` or `class << self` to define class methods.' + StyleGuide: '#def-self-class-methods' + Enabled: false + VersionAdded: '0.89' + EnforcedStyle: def_self + SupportedStyles: + - def_self + - self_class + +Style/ClassVars: + Description: 'Avoid the use of class variables.' + StyleGuide: '#no-class-vars' + Enabled: false + VersionAdded: '0.13' + +Style/CollectionCompact: + Description: 'Use `{Array,Hash}#{compact,compact!}` instead of custom logic to reject nils.' + Enabled: false + Safe: false + VersionAdded: '1.2' + VersionChanged: '1.3' + AllowedReceivers: [] + +# Align with the style guide. +Style/CollectionMethods: + Description: 'Preferred collection methods.' + StyleGuide: '#map-find-select-reduce-include-size' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.7' + Safe: false + # Mapping from undesired method to desired method + # e.g. to use `detect` over `find`: + # + # Style/CollectionMethods: + # PreferredMethods: + # find: detect + PreferredMethods: + collect: 'map' + collect!: 'map!' + collect_concat: 'flat_map' + inject: 'reduce' + detect: 'find' + find_all: 'select' + member?: 'include?' + # Methods in this array accept a final symbol as an implicit block + # eg. `inject(:+)` + MethodsAcceptingSymbol: + - inject + - reduce + +Style/ColonMethodCall: + Description: 'Do not use :: for method call.' + StyleGuide: '#double-colons' + Enabled: false + VersionAdded: '0.9' + +Style/ColonMethodDefinition: + Description: 'Do not use :: for defining class methods.' + StyleGuide: '#colon-method-definition' + Enabled: false + VersionAdded: '0.52' + +Style/CombinableLoops: + Description: >- + Checks for places where multiple consecutive loops over the same data + can be combined into a single loop. + Enabled: false + Safe: false + VersionAdded: '0.90' + +Style/CommandLiteral: + Description: 'Use `` or %x around command literals.' + StyleGuide: '#percent-x' + Enabled: false + VersionAdded: '0.30' + EnforcedStyle: backticks + # backticks: Always use backticks. + # percent_x: Always use `%x`. + # mixed: Use backticks on single-line commands, and `%x` on multi-line commands. + SupportedStyles: + - backticks + - percent_x + - mixed + # If `false`, the cop will always recommend using `%x` if one or more backticks + # are found in the command string. + AllowInnerBackticks: false + +# Checks formatting of special comments +Style/CommentAnnotation: + Description: >- + Checks formatting of special comments + (TODO, FIXME, OPTIMIZE, HACK, REVIEW, NOTE). + StyleGuide: '#annotate-keywords' + Enabled: false + VersionAdded: '0.10' + VersionChanged: '1.20' + Keywords: + - TODO + - FIXME + - OPTIMIZE + - HACK + - REVIEW + - NOTE + RequireColon: true + +Style/CommentedKeyword: + Description: 'Do not place comments on the same line as certain keywords.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.51' + VersionChanged: '1.19' + +Style/ComparableClamp: + Description: 'Enforces the use of `Comparable#clamp` instead of comparison by minimum and maximum.' + Enabled: false + VersionAdded: '1.44' + +Style/ConcatArrayLiterals: + Description: 'Enforces the use of `Array#push(item)` instead of `Array#concat([item])` to avoid redundant array literals.' + Enabled: false + Safe: false + VersionAdded: '1.41' + +Style/ConditionalAssignment: + Description: >- + Use the return value of `if` and `case` statements for + assignment to a variable and variable comparison instead + of assigning that variable inside of each branch. + Enabled: false + VersionAdded: '0.36' + VersionChanged: '0.47' + EnforcedStyle: assign_to_condition + SupportedStyles: + - assign_to_condition + - assign_inside_condition + # When configured to `assign_to_condition`, `SingleLineConditionsOnly` + # will only register an offense when all branches of a condition are + # a single line. + # When configured to `assign_inside_condition`, `SingleLineConditionsOnly` + # will only register an offense for assignment to a condition that has + # at least one multiline branch. + SingleLineConditionsOnly: true + IncludeTernaryExpressions: true + +Style/ConstantVisibility: + Description: >- + Check that class- and module constants have + visibility declarations. + Enabled: false + VersionAdded: '0.66' + VersionChanged: '1.10' + IgnoreModules: false + +# Checks that you have put a copyright in a comment before any code. +# +# You can override the default Notice in your .rubocop.yml file. +# +# In order to use autocorrect, you must supply a value for the +# `AutocorrectNotice` key that matches the regexp Notice. A blank +# `AutocorrectNotice` will cause an error during autocorrect. +# +# Autocorrect will add a copyright notice in a comment at the top +# of the file immediately after any shebang or encoding comments. +# +# Example rubocop.yml: +# +# Style/Copyright: +# Enabled: false +# Notice: 'Copyright (\(c\) )?2015 Yahoo! Inc' +# AutocorrectNotice: '# Copyright (c) 2015 Yahoo! Inc.' +# +Style/Copyright: + Description: 'Include a copyright notice in each file before any code.' + Enabled: false + VersionAdded: '0.30' + Notice: '^Copyright (\(c\) )?2[0-9]{3} .+' + AutocorrectNotice: '' + +Style/DataInheritance: + Description: 'Checks for inheritance from Data.define.' + StyleGuide: '#no-extend-data-define' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.49' + VersionChanged: '1.51' + +Style/DateTime: + Description: 'Use Time over DateTime.' + StyleGuide: '#date-time' + Enabled: false + VersionAdded: '0.51' + VersionChanged: '0.92' + SafeAutoCorrect: false + AllowCoercion: false + +Style/DefWithParentheses: + Description: 'Use def with parentheses when there are arguments.' + StyleGuide: '#method-parens' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.12' + +Style/Dir: + Description: >- + Use the `__dir__` method to retrieve the canonicalized + absolute path to the current file. + Enabled: false + VersionAdded: '0.50' + +Style/DirEmpty: + Description: >- + Prefer to use `Dir.empty?('path/to/dir')` when checking if a directory is empty. + Enabled: false + VersionAdded: '1.48' + +Style/DisableCopsWithinSourceCodeDirective: + Description: >- + Forbids disabling/enabling cops within source code. + Enabled: false + VersionAdded: '0.82' + VersionChanged: '1.9' + AllowedCops: [] + +Style/DocumentDynamicEvalDefinition: + Description: >- + When using `class_eval` (or other `eval`) with string interpolation, + add a comment block showing its appearance if interpolated. + StyleGuide: '#eval-comment-docs' + Enabled: false + VersionAdded: '1.1' + VersionChanged: '1.3' + +Style/Documentation: + Description: 'Document classes and non-namespace modules.' + Enabled: false + VersionAdded: '0.9' + AllowedConstants: [] + Exclude: + - 'spec/**/*' + - 'test/**/*' + +Style/DocumentationMethod: + Description: 'Checks for missing documentation comment for public methods.' + Enabled: false + VersionAdded: '0.43' + AllowedMethods: [] + Exclude: + - 'spec/**/*' + - 'test/**/*' + RequireForNonPublicMethods: false + +Style/DoubleCopDisableDirective: + Description: 'Checks for double rubocop:disable comments on a single line.' + Enabled: false + VersionAdded: '0.73' + +Style/DoubleNegation: + Description: 'Checks for uses of double negation (!!).' + StyleGuide: '#no-bang-bang' + Enabled: false + VersionAdded: '0.19' + VersionChanged: '1.2' + EnforcedStyle: allowed_in_returns + SafeAutoCorrect: false + SupportedStyles: + - allowed_in_returns + - forbidden + +Style/EachForSimpleLoop: + Description: >- + Use `Integer#times` for a simple loop which iterates a fixed + number of times. + Enabled: false + VersionAdded: '0.41' + +Style/EachWithObject: + Description: 'Prefer `each_with_object` over `inject` or `reduce`.' + Enabled: false + VersionAdded: '0.22' + VersionChanged: '0.42' + +Style/EmptyBlockParameter: + Description: 'Omit pipes for empty block parameters.' + Enabled: false + VersionAdded: '0.52' + +Style/EmptyCaseCondition: + Description: 'Avoid empty condition in case statements.' + Enabled: false + VersionAdded: '0.40' + +Style/EmptyElse: + Description: 'Avoid empty else-clauses.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.28' + VersionChanged: '1.61' + EnforcedStyle: both + # empty - warn only on empty `else` + # nil - warn on `else` with nil in it + # both - warn on empty `else` and `else` with `nil` in it + SupportedStyles: + - empty + - nil + - both + AllowComments: false + +Style/EmptyHeredoc: + Description: 'Checks for using empty heredoc to reduce redundancy.' + Enabled: false + AutoCorrect: contextual + VersionAdded: '1.32' + VersionChanged: '1.61' + +Style/EmptyLambdaParameter: + Description: 'Omit parens for empty lambda parameters.' + Enabled: false + VersionAdded: '0.52' + +Style/EmptyLiteral: + Description: 'Prefer literals to Array.new/Hash.new/String.new.' + StyleGuide: '#literal-array-hash' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.12' + +Style/EmptyMethod: + Description: 'Checks the formatting of empty method definitions.' + StyleGuide: '#no-single-line-methods' + Enabled: false + AutoCorrect: contextual + VersionAdded: '0.46' + VersionChanged: '1.61' + EnforcedStyle: compact + SupportedStyles: + - compact + - expanded + +Style/Encoding: + Description: 'Use UTF-8 as the source file encoding.' + StyleGuide: '#utf-8' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.50' + +Style/EndBlock: + Description: 'Avoid the use of END blocks.' + StyleGuide: '#no-END-blocks' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.81' + +Style/EndlessMethod: + Description: 'Avoid the use of multi-lined endless method definitions.' + StyleGuide: '#endless-methods' + Enabled: false + VersionAdded: '1.8' + EnforcedStyle: allow_single_line + SupportedStyles: + - allow_single_line + - allow_always + - disallow + +Style/EnvHome: + Description: "Checks for consistent usage of `ENV['HOME']`." + Enabled: false + Safe: false + VersionAdded: '1.29' + +Style/EvalWithLocation: + Description: 'Pass `__FILE__` and `__LINE__` to `eval` method, as they are used by backtraces.' + Enabled: false + VersionAdded: '0.52' + +Style/EvenOdd: + Description: 'Favor the use of `Integer#even?` && `Integer#odd?`.' + StyleGuide: '#predicate-methods' + Enabled: false + VersionAdded: '0.12' + VersionChanged: '0.29' + +Style/ExactRegexpMatch: + Description: 'Checks for exact regexp match inside Regexp literals.' + Enabled: false + VersionAdded: '1.51' + +Style/ExpandPathArguments: + Description: "Use `expand_path(__dir__)` instead of `expand_path('..', __FILE__)`." + Enabled: false + VersionAdded: '0.53' + +Style/ExplicitBlockArgument: + Description: >- + Consider using explicit block argument to avoid writing block literal + that just passes its arguments to another block. + StyleGuide: '#block-argument' + Enabled: false + VersionAdded: '0.89' + VersionChanged: '1.8' + +Style/ExponentialNotation: + Description: 'When using exponential notation, favor a mantissa between 1 (inclusive) and 10 (exclusive).' + StyleGuide: '#exponential-notation' + Enabled: false + VersionAdded: '0.82' + EnforcedStyle: scientific + SupportedStyles: + - scientific + - engineering + - integral + +Style/FetchEnvVar: + Description: >- + Suggests `ENV.fetch` for the replacement of `ENV[]`. + Reference: + - https://rubystyle.guide/#hash-fetch-defaults + Enabled: false + VersionAdded: '1.28' + # Environment variables to be excluded from the inspection. + AllowedVars: [] + +Style/FileEmpty: + Description: >- + Prefer to use `File.empty?('path/to/file')` when checking if a file is empty. + Enabled: false + Safe: false + VersionAdded: '1.48' + +Style/FileRead: + Description: 'Favor `File.(bin)read` convenience methods.' + StyleGuide: '#file-read' + Enabled: false + VersionAdded: '1.24' + +Style/FileWrite: + Description: 'Favor `File.(bin)write` convenience methods.' + StyleGuide: '#file-write' + Enabled: false + VersionAdded: '1.24' + +Style/FloatDivision: + Description: 'For performing float division, coerce one side only.' + StyleGuide: '#float-division' + Reference: 'https://blog.rubystyle.guide/ruby/2019/06/21/float-division.html' + Enabled: false + VersionAdded: '0.72' + VersionChanged: '1.9' + Safe: false + EnforcedStyle: single_coerce + SupportedStyles: + - left_coerce + - right_coerce + - single_coerce + - fdiv + +Style/For: + Description: 'Checks use of for or each in multiline loops.' + StyleGuide: '#no-for-loops' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.13' + VersionChanged: '1.26' + EnforcedStyle: each + SupportedStyles: + - each + - for + +Style/FormatString: + Description: 'Enforce the use of Kernel#sprintf, Kernel#format or String#%.' + StyleGuide: '#sprintf' + Enabled: false + VersionAdded: '0.19' + VersionChanged: '0.49' + EnforcedStyle: format + SupportedStyles: + - format + - sprintf + - percent + +Style/FormatStringToken: + Description: 'Use a consistent style for format string tokens.' + Enabled: false + EnforcedStyle: annotated + SupportedStyles: + # Prefer tokens which contain a sprintf like type annotation like + # `%s`, `%d`, `%f` + - annotated + # Prefer simple looking "template" style tokens like `%{name}`, `%{age}` + - template + - unannotated + # `MaxUnannotatedPlaceholdersAllowed` defines the number of `unannotated` + # style token in a format string to be allowed when enforced style is not + # `unannotated`. + MaxUnannotatedPlaceholdersAllowed: 1 + VersionAdded: '0.49' + VersionChanged: '1.0' + AllowedMethods: [] + AllowedPatterns: [] + +Style/FrozenStringLiteralComment: + Description: >- + Add the frozen_string_literal comment to the top of files + to help transition to frozen string literals by default. + Enabled: false + VersionAdded: '0.36' + VersionChanged: '0.79' + EnforcedStyle: always + SupportedStyles: + # `always` will always add the frozen string literal comment to a file + # regardless of the Ruby version or if `freeze` or `<<` are called on a + # string literal. It is possible that this will create errors. + - always + # `always_true` will add the frozen string literal comment to a file, + # similarly to the `always` style, but will also change any disabled + # comments (e.g. `# frozen_string_literal: false`) to be enabled. + - always_true + # `never` will enforce that the frozen string literal comment does not + # exist in a file. + - never + SafeAutoCorrect: false + +Style/GlobalStdStream: + Description: 'Enforces the use of `$stdout/$stderr/$stdin` instead of `STDOUT/STDERR/STDIN`.' + StyleGuide: '#global-stdout' + Enabled: false + VersionAdded: '0.89' + SafeAutoCorrect: false + +Style/GlobalVars: + Description: 'Do not introduce global variables.' + StyleGuide: '#instance-vars' + Reference: 'https://www.zenspider.com/ruby/quickref.html' + Enabled: false + VersionAdded: '0.13' + # Built-in global variables are allowed by default. + AllowedVariables: [] + +Style/GuardClause: + Description: 'Check for conditionals that can be replaced with guard clauses.' + StyleGuide: '#no-nested-conditionals' + Enabled: false + VersionAdded: '0.20' + VersionChanged: '1.31' + # `MinBodyLength` defines the number of lines of the a body of an `if` or `unless` + # needs to have to trigger this cop + MinBodyLength: 1 + AllowConsecutiveConditionals: false + +Style/HashAsLastArrayItem: + Description: >- + Checks for presence or absence of braces around hash literal as a last + array item depending on configuration. + StyleGuide: '#hash-literal-as-last-array-item' + Enabled: false + VersionAdded: '0.88' + EnforcedStyle: braces + SupportedStyles: + - braces + - no_braces + +Style/HashConversion: + Description: 'Avoid Hash[] in favor of ary.to_h or literal hashes.' + StyleGuide: '#avoid-hash-constructor' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.10' + VersionChanged: '1.55' + AllowSplatArgument: true + +Style/HashEachMethods: + Description: 'Use Hash#each_key and Hash#each_value.' + StyleGuide: '#hash-each' + Enabled: false + Safe: false + VersionAdded: '0.80' + VersionChanged: '1.16' + AllowedReceivers: + - Thread.current + +Style/HashExcept: + Description: >- + Checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods + that can be replaced with `Hash#except` method. + Enabled: false + Safe: false + VersionAdded: '1.7' + VersionChanged: '1.39' + +Style/HashLikeCase: + Description: >- + Checks for places where `case-when` represents a simple 1:1 + mapping and can be replaced with a hash lookup. + Enabled: false + VersionAdded: '0.88' + # `MinBranchesCount` defines the number of branches `case` needs to have + # to trigger this cop + MinBranchesCount: 3 + +Style/HashSyntax: + Description: >- + Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax + { :a => 1, :b => 2 }. + StyleGuide: '#hash-literals' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.24' + EnforcedStyle: ruby19 + SupportedStyles: + # checks for 1.9 syntax (e.g. {a: 1}) for all symbol keys + - ruby19 + # checks for hash rocket syntax for all hashes + - hash_rockets + # forbids mixed key syntaxes (e.g. {a: 1, :b => 2}) + - no_mixed_keys + # enforces both ruby19 and no_mixed_keys styles + - ruby19_no_mixed_keys + # Force hashes that have a hash value omission + EnforcedShorthandSyntax: always + SupportedShorthandSyntax: + # forces use of the 3.1 syntax (e.g. {foo:}) when the hash key and value are the same. + - always + # forces use of explicit hash literal value. + - never + # accepts both shorthand and explicit use of hash literal value. + - either + # forces use of the 3.1 syntax only if all values can be omitted in the hash. + - consistent + # allow either (implicit or explicit) syntax but enforce consistency within a single hash + - either_consistent + # Force hashes that have a symbol value to use hash rockets + UseHashRocketsWithSymbolValues: false + # Do not suggest { a?: 1 } over { :a? => 1 } in ruby19 style + PreferHashRocketsForNonAlnumEndingSymbols: false + +Style/HashTransformKeys: + Description: 'Prefer `transform_keys` over `each_with_object`, `map`, or `to_h`.' + Enabled: false + VersionAdded: '0.80' + VersionChanged: '0.90' + Safe: false + +Style/HashTransformValues: + Description: 'Prefer `transform_values` over `each_with_object`, `map`, or `to_h`.' + Enabled: false + VersionAdded: '0.80' + VersionChanged: '0.90' + Safe: false + +Style/IdenticalConditionalBranches: + Description: >- + Checks that conditional statements do not have an identical + line at the end of each branch, which can validly be moved + out of the conditional. + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.36' + VersionChanged: '1.19' + +Style/IfInsideElse: + Description: 'Finds if nodes inside else, which can be converted to elsif.' + Enabled: false + AllowIfModifier: false + VersionAdded: '0.36' + VersionChanged: '1.3' + +Style/IfUnlessModifier: + Description: >- + Favor modifier if/unless usage when you have a + single-line body. + StyleGuide: '#if-as-a-modifier' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.30' + +Style/IfUnlessModifierOfIfUnless: + Description: >- + Avoid modifier if/unless usage on conditionals. + Enabled: false + VersionAdded: '0.39' + VersionChanged: '0.87' + +Style/IfWithBooleanLiteralBranches: + Description: 'Checks for redundant `if` with boolean literal branches.' + Enabled: false + VersionAdded: '1.9' + SafeAutoCorrect: false + AllowedMethods: + - nonzero? + +Style/IfWithSemicolon: + Description: 'Do not use if x; .... Use the ternary operator instead.' + StyleGuide: '#no-semicolon-ifs' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.83' + +Style/ImplicitRuntimeError: + Description: >- + Use `raise` or `fail` with an explicit exception class and + message, rather than just a message. + Enabled: false + VersionAdded: '0.41' + +Style/InPatternThen: + Description: 'Checks for `in;` uses in `case` expressions.' + StyleGuide: '#no-in-pattern-semicolons' + Enabled: false + VersionAdded: '1.16' + +Style/InfiniteLoop: + Description: >- + Use Kernel#loop for infinite loops. + This cop is unsafe if the body may raise a `StopIteration` exception. + Safe: false + StyleGuide: '#infinite-loop' + Enabled: false + VersionAdded: '0.26' + VersionChanged: '0.61' + +Style/InlineComment: + Description: 'Avoid trailing inline comments.' + Enabled: false + VersionAdded: '0.23' + +Style/InverseMethods: + Description: >- + Use the inverse method instead of `!.method` + if an inverse method is defined. + Enabled: false + Safe: false + VersionAdded: '0.48' + # `InverseMethods` are methods that can be inverted by a not (`not` or `!`) + # The relationship of inverse methods only needs to be defined in one direction. + # Keys and values both need to be defined as symbols. + InverseMethods: + :any?: :none? + :even?: :odd? + :==: :!= + :=~: :!~ + :<: :>= + :>: :<= + # `InverseBlocks` are methods that are inverted by inverting the return + # of the block that is passed to the method + InverseBlocks: + :select: :reject + :select!: :reject! + +Style/InvertibleUnlessCondition: + Description: 'Favor `if` with inverted condition over `unless`.' + Enabled: false + Safe: false + VersionAdded: '1.44' + VersionChanged: '1.50' + # `InverseMethods` are methods that can be inverted in a `unless` condition. + # The relationship of inverse methods needs to be defined in both directions. + # Keys and values both need to be defined as symbols. + InverseMethods: + :!=: :== + :>: :<= + :<=: :> + :<: :>= + :>=: :< + :!~: :=~ + :zero?: :nonzero? + :nonzero?: :zero? + :any?: :none? + :none?: :any? + :even?: :odd? + :odd?: :even? + +Style/IpAddresses: + Description: "Don't include literal IP addresses in code." + Enabled: false + VersionAdded: '0.58' + VersionChanged: '0.91' + # Allow addresses to be permitted + AllowedAddresses: + - "::" + # :: is a valid IPv6 address, but could potentially be legitimately in code + Exclude: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + - '**/*.gemspec' + +Style/KeywordParametersOrder: + Description: 'Enforces that optional keyword parameters are placed at the end of the parameters list.' + StyleGuide: '#keyword-parameters-order' + Enabled: false + VersionAdded: '0.90' + VersionChanged: '1.7' + +Style/Lambda: + Description: 'Use the new lambda literal syntax for single-line blocks.' + StyleGuide: '#lambda-multi-line' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.40' + EnforcedStyle: line_count_dependent + SupportedStyles: + - line_count_dependent + - lambda + - literal + +Style/LambdaCall: + Description: 'Use lambda.call(...) instead of lambda.(...).' + StyleGuide: '#proc-call' + Enabled: false + VersionAdded: '0.13' + VersionChanged: '0.14' + EnforcedStyle: call + SupportedStyles: + - call + - braces + +Style/LineEndConcatenation: + Description: >- + Use \ instead of + or << to concatenate two string literals at + line end. + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.18' + VersionChanged: '0.64' + +Style/MagicCommentFormat: + Description: 'Use a consistent style for magic comments.' + Enabled: false + VersionAdded: '1.35' + EnforcedStyle: snake_case + SupportedStyles: + # `snake` will enforce the magic comment is written + # in snake case (words separated by underscores). + # Eg: froze_string_literal: true + - snake_case + # `kebab` will enforce the magic comment is written + # in kebab case (words separated by hyphens). + # Eg: froze-string-literal: true + - kebab_case + DirectiveCapitalization: lowercase + ValueCapitalization: ~ + SupportedCapitalizations: + - lowercase + - uppercase + +Style/MapCompactWithConditionalBlock: + Description: 'Prefer `select` or `reject` over `map { ... }.compact`.' + Enabled: false + VersionAdded: '1.30' + +Style/MapIntoArray: + Description: 'Checks for usages of `each` with `<<`, `push`, or `append` which can be replaced by `map`.' + StyleGuide: '#functional-code' + Enabled: false + VersionAdded: '1.63' + Safe: false + +Style/MapToHash: + Description: 'Prefer `to_h` with a block over `map.to_h`.' + Enabled: false + VersionAdded: '1.24' + Safe: false + +Style/MapToSet: + Description: 'Prefer `to_set` with a block over `map.to_set`.' + Enabled: false + Safe: false + VersionAdded: '1.42' + +Style/MethodCallWithArgsParentheses: + Description: 'Use parentheses for method calls with arguments.' + StyleGuide: '#method-invocation-parens' + Enabled: false + VersionAdded: '0.47' + VersionChanged: '1.7' + IgnoreMacros: true + AllowedMethods: [] + AllowedPatterns: [] + IncludedMacros: [] + AllowParenthesesInMultilineCall: false + AllowParenthesesInChaining: false + AllowParenthesesInCamelCaseMethod: false + AllowParenthesesInStringInterpolation: false + EnforcedStyle: require_parentheses + SupportedStyles: + - require_parentheses + - omit_parentheses + +Style/MethodCallWithoutArgsParentheses: + Description: 'Do not use parentheses for method calls with no arguments.' + StyleGuide: '#method-invocation-parens' + Enabled: false + AllowedMethods: [] + AllowedPatterns: [] + VersionAdded: '0.47' + VersionChanged: '0.55' + +Style/MethodCalledOnDoEndBlock: + Description: 'Avoid chaining a method call on a do...end block.' + StyleGuide: '#single-line-blocks' + Enabled: false + VersionAdded: '0.14' + +Style/MethodDefParentheses: + Description: >- + Checks if the method definitions have or don't have + parentheses. + StyleGuide: '#method-parens' + Enabled: false + VersionAdded: '0.16' + VersionChanged: '1.7' + EnforcedStyle: require_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + - require_no_parentheses_except_multiline + +Style/MinMax: + Description: >- + Use `Enumerable#minmax` instead of `Enumerable#min` + and `Enumerable#max` in conjunction. + Enabled: false + VersionAdded: '0.50' + +Style/MinMaxComparison: + Description: 'Enforces the use of `max` or `min` instead of comparison for greater or less.' + Enabled: false + Safe: false + VersionAdded: '1.42' + +Style/MissingElse: + Description: >- + Require if/case expressions to have an else branches. + If enabled, it is recommended that + Style/UnlessElse and Style/EmptyElse be enabled. + This will conflict with Style/EmptyElse if + Style/EmptyElse is configured to style "both". + Enabled: false + VersionAdded: '0.30' + VersionChanged: '0.38' + EnforcedStyle: both + SupportedStyles: + # if - warn when an if expression is missing an else branch + # case - warn when a case expression is missing an else branch + # both - warn when an if or case expression is missing an else branch + - if + - case + - both + +Style/MissingRespondToMissing: + Description: >- + Checks if `method_missing` is implemented + without implementing `respond_to_missing`. + StyleGuide: '#no-method-missing' + Enabled: false + VersionAdded: '0.56' + +Style/MixinGrouping: + Description: 'Checks for grouping of mixins in `class` and `module` bodies.' + StyleGuide: '#mixin-grouping' + Enabled: false + VersionAdded: '0.48' + VersionChanged: '0.49' + EnforcedStyle: separated + SupportedStyles: + # separated: each mixed in module goes in a separate statement. + # grouped: mixed in modules are grouped into a single statement. + - separated + - grouped + +Style/MixinUsage: + Description: 'Checks that `include`, `extend` and `prepend` exists at the top level.' + Enabled: false + VersionAdded: '0.51' + +Style/ModuleFunction: + Description: 'Checks for usage of `extend self` in modules.' + StyleGuide: '#module-function' + Enabled: false + VersionAdded: '0.11' + VersionChanged: '0.65' + EnforcedStyle: module_function + SupportedStyles: + - module_function + - extend_self + - forbidden + Autocorrect: false + SafeAutoCorrect: false + +Style/MultilineBlockChain: + Description: 'Avoid multi-line chains of blocks.' + StyleGuide: '#single-line-blocks' + Enabled: false + VersionAdded: '0.13' + +Style/MultilineIfModifier: + Description: 'Only use if/unless modifiers on single line statements.' + StyleGuide: '#no-multiline-if-modifiers' + Enabled: false + VersionAdded: '0.45' + +Style/MultilineIfThen: + Description: 'Do not use then for multi-line if/unless.' + StyleGuide: '#no-then' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.26' + +Style/MultilineInPatternThen: + Description: 'Do not use `then` for multi-line `in` statement.' + StyleGuide: '#no-then' + Enabled: false + VersionAdded: '1.16' + +Style/MultilineMemoization: + Description: 'Wrap multiline memoizations in a `begin` and `end` block.' + Enabled: false + VersionAdded: '0.44' + VersionChanged: '0.48' + EnforcedStyle: keyword + SupportedStyles: + - keyword + - braces + +Style/MultilineMethodSignature: + Description: 'Avoid multi-line method signatures.' + Enabled: false + VersionAdded: '0.59' + VersionChanged: '1.7' + +Style/MultilineTernaryOperator: + Description: >- + Avoid multi-line ?: (the ternary operator); + use if/unless instead. + StyleGuide: '#no-multiline-ternary' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.86' + +Style/MultilineWhenThen: + Description: 'Do not use then for multi-line when statement.' + StyleGuide: '#no-then' + Enabled: false + VersionAdded: '0.73' + +Style/MultipleComparison: + Description: >- + Avoid comparing a variable with multiple items in a conditional, + use Array#include? instead. + Enabled: false + VersionAdded: '0.49' + VersionChanged: '1.1' + AllowMethodComparison: true + ComparisonsThreshold: 2 + +Style/MutableConstant: + Description: 'Do not assign mutable objects to constants.' + Enabled: false + VersionAdded: '0.34' + VersionChanged: '1.8' + SafeAutoCorrect: false + EnforcedStyle: literals + SupportedStyles: + # literals: freeze literals assigned to constants + # strict: freeze all constants + # Strict mode is considered an experimental feature. It has not been updated + # with an exhaustive list of all methods that will produce frozen objects so + # there is a decent chance of getting some false positives. Luckily, there is + # no harm in freezing an already frozen object. + - literals + - strict + +Style/NegatedIf: + Description: >- + Favor unless over if for negative conditions + (or control flow or). + StyleGuide: '#unless-for-negatives' + Enabled: false + VersionAdded: '0.20' + VersionChanged: '0.48' + EnforcedStyle: both + SupportedStyles: + # both: prefix and postfix negated `if` should both use `unless` + # prefix: only use `unless` for negated `if` statements positioned before the body of the statement + # postfix: only use `unless` for negated `if` statements positioned after the body of the statement + - both + - prefix + - postfix + +Style/NegatedIfElseCondition: + Description: >- + Checks for uses of `if-else` and ternary operators with a negated condition + which can be simplified by inverting condition and swapping branches. + Enabled: false + VersionAdded: '1.2' + +Style/NegatedUnless: + Description: 'Favor if over unless for negative conditions.' + StyleGuide: '#if-for-negatives' + Enabled: false + VersionAdded: '0.69' + EnforcedStyle: both + SupportedStyles: + # both: prefix and postfix negated `unless` should both use `if` + # prefix: only use `if` for negated `unless` statements positioned before the body of the statement + # postfix: only use `if` for negated `unless` statements positioned after the body of the statement + - both + - prefix + - postfix + +Style/NegatedWhile: + Description: 'Favor until over while for negative conditions.' + StyleGuide: '#until-for-negatives' + Enabled: false + VersionAdded: '0.20' + +Style/NestedFileDirname: + Description: 'Checks for nested `File.dirname`.' + Enabled: false + VersionAdded: '1.26' + +Style/NestedModifier: + Description: 'Avoid using nested modifiers.' + StyleGuide: '#no-nested-modifiers' + Enabled: false + VersionAdded: '0.35' + +Style/NestedParenthesizedCalls: + Description: >- + Parenthesize method calls which are nested inside the + argument list of another parenthesized method call. + Enabled: false + VersionAdded: '0.36' + VersionChanged: '0.77' + AllowedMethods: + - be + - be_a + - be_an + - be_between + - be_falsey + - be_kind_of + - be_instance_of + - be_truthy + - be_within + - eq + - eql + - end_with + - include + - match + - raise_error + - respond_to + - start_with + +Style/NestedTernaryOperator: + Description: 'Use one expression per branch in a ternary operator.' + StyleGuide: '#no-nested-ternary' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.86' + +Style/Next: + Description: 'Use `next` to skip iteration instead of a condition at the end.' + StyleGuide: '#no-nested-conditionals' + Enabled: false + VersionAdded: '0.22' + VersionChanged: '0.35' + # With `always` all conditions at the end of an iteration needs to be + # replaced by next - with `skip_modifier_ifs` the modifier if like this one + # are ignored: [1, 2].each { |a| return 'yes' if a == 1 } + EnforcedStyle: skip_modifier_ifs + # `MinBodyLength` defines the number of lines of the a body of an `if` or `unless` + # needs to have to trigger this cop + MinBodyLength: 3 + SupportedStyles: + - skip_modifier_ifs + - always + +Style/NilComparison: + Description: 'Prefer x.nil? to x == nil.' + StyleGuide: '#predicate-methods' + Enabled: false + VersionAdded: '0.12' + VersionChanged: '0.59' + EnforcedStyle: predicate + SupportedStyles: + - predicate + - comparison + +Style/NilLambda: + Description: 'Prefer `-> {}` to `-> { nil }`.' + Enabled: false + VersionAdded: '1.3' + VersionChanged: '1.15' + +Style/NonNilCheck: + Description: 'Checks for redundant nil checks.' + StyleGuide: '#no-non-nil-checks' + Enabled: false + VersionAdded: '0.20' + VersionChanged: '0.22' + # With `IncludeSemanticChanges` set to `true`, this cop reports offenses for + # `!x.nil?` and autocorrects that and `x != nil` to solely `x`, which is + # **usually** OK, but might change behavior. + # + # With `IncludeSemanticChanges` set to `false`, this cop does not report + # offenses for `!x.nil?` and does no changes that might change behavior. + IncludeSemanticChanges: false + +Style/Not: + Description: 'Use ! instead of not.' + StyleGuide: '#bang-not-not' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.20' + +Style/NumberedParameters: + Description: 'Restrict the usage of numbered parameters.' + Enabled: false + VersionAdded: '1.22' + EnforcedStyle: allow_single_line + SupportedStyles: + - allow_single_line + - disallow + +Style/NumberedParametersLimit: + Description: 'Avoid excessive numbered params in a single block.' + Enabled: false + VersionAdded: '1.22' + Max: 1 + +Style/NumericLiteralPrefix: + Description: 'Use smallcase prefixes for numeric literals.' + StyleGuide: '#numeric-literal-prefixes' + Enabled: false + VersionAdded: '0.41' + EnforcedOctalStyle: zero_with_o + SupportedOctalStyles: + - zero_with_o + - zero_only + +Style/NumericLiterals: + Description: >- + Add underscores to large numeric literals to improve their + readability. + StyleGuide: '#underscores-in-numerics' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.48' + MinDigits: 5 + Strict: false + # You can specify allowed numbers. (e.g. port number 3000, 8080, and etc) + AllowedNumbers: [] + AllowedPatterns: [] + +Style/NumericPredicate: + Description: >- + Checks for the use of predicate- or comparison methods for + numeric comparisons. + StyleGuide: '#predicate-methods' + # This will change to a new method call which isn't guaranteed to be on the + # object. Switching these methods has to be done with knowledge of the types + # of the variables which rubocop doesn't have. + Safe: false + Enabled: false + VersionAdded: '0.42' + VersionChanged: '0.59' + EnforcedStyle: predicate + SupportedStyles: + - predicate + - comparison + AllowedMethods: [] + AllowedPatterns: [] + # Exclude RSpec specs because assertions like `expect(1).to be > 0` cause + # false positives. + Exclude: + - 'spec/**/*' + +Style/ObjectThen: + Description: 'Enforces the use of consistent method names `Object#yield_self` or `Object#then`.' + StyleGuide: '#object-yield-self-vs-object-then' + Enabled: false + VersionAdded: '1.28' + # Use `Object#yield_self` or `Object#then`? + # Prefer `Object#yield_self` to `Object#then` (yield_self) + # Prefer `Object#then` to `Object#yield_self` (then) + EnforcedStyle: 'then' + SupportedStyles: + - then + - yield_self + +Style/OneLineConditional: + Description: >- + Favor the ternary operator (?:) or multi-line constructs over + single-line if/then/else/end constructs. + StyleGuide: '#ternary-operator' + Enabled: false + AlwaysCorrectToMultiline: false + VersionAdded: '0.9' + VersionChanged: '0.90' + +Style/OpenStructUse: + Description: >- + Avoid using OpenStruct. As of Ruby 3.0, use is officially discouraged due to performance, + version compatibility, and potential security issues. + Reference: + - https://docs.ruby-lang.org/en/3.0.0/OpenStruct.html#class-OpenStruct-label-Caveats + + Enabled: false + Safe: false + VersionAdded: '1.23' + VersionChanged: '1.51' + +Style/OperatorMethodCall: + Description: 'Checks for redundant dot before operator method call.' + StyleGuide: '#operator-method-call' + Enabled: false + VersionAdded: '1.37' + +Style/OptionHash: + Description: "Don't use option hashes when you can use keyword arguments." + StyleGuide: '#keyword-arguments-vs-option-hashes' + Enabled: false + VersionAdded: '0.33' + VersionChanged: '0.34' + # A list of parameter names that will be flagged by this cop. + SuspiciousParamNames: + - options + - opts + - args + - params + - parameters + Allowlist: [] + +Style/OptionalArguments: + Description: >- + Checks for optional arguments that do not appear at the end + of the argument list. + StyleGuide: '#optional-arguments' + Enabled: false + Safe: false + VersionAdded: '0.33' + VersionChanged: '0.83' + +Style/OptionalBooleanParameter: + Description: 'Use keyword arguments when defining method with boolean argument.' + StyleGuide: '#boolean-keyword-arguments' + Enabled: false + Safe: false + VersionAdded: '0.89' + AllowedMethods: + - respond_to_missing? + +Style/OrAssignment: + Description: 'Recommend usage of double pipe equals (||=) where applicable.' + StyleGuide: '#double-pipe-for-uninit' + Enabled: false + VersionAdded: '0.50' + +Style/ParallelAssignment: + Description: >- + Check for simple usages of parallel assignment. + It will only warn when the number of variables + matches on both sides of the assignment. + StyleGuide: '#parallel-assignment' + Enabled: false + VersionAdded: '0.32' + +Style/ParenthesesAroundCondition: + Description: >- + Don't use parentheses around the condition of an + if/unless/while. + StyleGuide: '#no-parens-around-condition' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.56' + AllowSafeAssignment: true + AllowInMultilineConditions: false + +Style/PercentLiteralDelimiters: + Description: 'Use `%`-literal delimiters consistently.' + StyleGuide: '#percent-literal-braces' + Enabled: false + VersionAdded: '0.19' + # Specify the default preferred delimiter for all types with the 'default' key + # Override individual delimiters (even with default specified) by specifying + # an individual key + PreferredDelimiters: + default: () + '%i': '[]' + '%I': '[]' + '%r': '{}' + '%w': '[]' + '%W': '[]' + VersionChanged: '0.48' + +Style/PercentQLiterals: + Description: 'Checks if uses of %Q/%q match the configured preference.' + Enabled: false + VersionAdded: '0.25' + EnforcedStyle: lower_case_q + SupportedStyles: + - lower_case_q # Use `%q` when possible, `%Q` when necessary + - upper_case_q # Always use `%Q` + +Style/PerlBackrefs: + Description: 'Avoid Perl-style regex back references.' + StyleGuide: '#no-perl-regexp-last-matchers' + Enabled: false + VersionAdded: '0.13' + +Style/PreferredHashMethods: + Description: 'Checks use of `has_key?` and `has_value?` Hash methods.' + StyleGuide: '#hash-key' + Enabled: false + Safe: false + VersionAdded: '0.41' + VersionChanged: '0.70' + EnforcedStyle: short + SupportedStyles: + - short + - verbose + +Style/Proc: + Description: 'Use proc instead of Proc.new.' + StyleGuide: '#proc' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.18' + +Style/QuotedSymbols: + Description: 'Use a consistent style for quoted symbols.' + Enabled: false + VersionAdded: '1.16' + EnforcedStyle: same_as_string_literals + SupportedStyles: + - same_as_string_literals + - single_quotes + - double_quotes + +Style/RaiseArgs: + Description: 'Checks the arguments passed to raise/fail.' + StyleGuide: '#exception-class-messages' + Enabled: false + Safe: false + VersionAdded: '0.14' + VersionChanged: '1.61' + EnforcedStyle: exploded + SupportedStyles: + - compact # raise Exception.new(msg) + - exploded # raise Exception, msg + AllowedCompactTypes: [] + +Style/RandomWithOffset: + Description: >- + Prefer to use ranges when generating random numbers instead of + integers with offsets. + StyleGuide: '#random-numbers' + Enabled: false + VersionAdded: '0.52' + +Style/RedundantArgument: + Description: 'Check for a redundant argument passed to certain methods.' + Enabled: false + Safe: false + VersionAdded: '1.4' + VersionChanged: '1.55' + Methods: + # Array#join + join: '' + # Array#sum + sum: 0 + # Kernel.#exit + exit: true + # Kernel.#exit! + exit!: false + # String#split + split: ' ' + # String#chomp + chomp: "\n" + # String#chomp! + chomp!: "\n" + +Style/RedundantArrayConstructor: + Description: 'Checks for the instantiation of array using redundant `Array` constructor.' + Enabled: false + VersionAdded: '1.52' + +Style/RedundantAssignment: + Description: 'Checks for redundant assignment before returning.' + Enabled: false + VersionAdded: '0.87' + +Style/RedundantBegin: + Description: "Don't use begin blocks when they are not needed." + StyleGuide: '#begin-implicit' + Enabled: false + VersionAdded: '0.10' + VersionChanged: '0.21' + +Style/RedundantCapitalW: + Description: 'Checks for %W when interpolation is not needed.' + Enabled: false + VersionAdded: '0.76' + +Style/RedundantCondition: + Description: 'Checks for unnecessary conditional expressions.' + Enabled: false + VersionAdded: '0.76' + +Style/RedundantConditional: + Description: "Don't return true/false from a conditional." + Enabled: false + VersionAdded: '0.50' + +Style/RedundantConstantBase: + Description: Avoid redundant `::` prefix on constant. + Enabled: false + VersionAdded: '1.40' + +Style/RedundantCurrentDirectoryInPath: + Description: 'Checks for uses a redundant current directory in path.' + Enabled: false + VersionAdded: '1.53' + +Style/RedundantDoubleSplatHashBraces: + Description: 'Checks for redundant uses of double splat hash braces.' + Enabled: false + VersionAdded: '1.41' + +Style/RedundantEach: + Description: 'Checks for redundant `each`.' + Enabled: false + Safe: false + VersionAdded: '1.38' + +Style/RedundantException: + Description: "Checks for an obsolete RuntimeException argument in raise/fail." + StyleGuide: '#no-explicit-runtimeerror' + Enabled: false + VersionAdded: '0.14' + VersionChanged: '0.29' + +Style/RedundantFetchBlock: + Description: >- + Use `fetch(key, value)` instead of `fetch(key) { value }` + when value has Numeric, Rational, Complex, Symbol or String type, `false`, `true`, `nil` or is a constant. + Reference: 'https://github.com/fastruby/fast-ruby#hashfetch-with-argument-vs-hashfetch--block-code' + Enabled: false + Safe: false + # If enabled, this cop will autocorrect usages of + # `fetch` being called with block returning a constant. + # This can be dangerous since constants will not be defined at that moment. + SafeForConstants: false + VersionAdded: '0.86' + +Style/RedundantFileExtensionInRequire: + Description: >- + Checks for the presence of superfluous `.rb` extension in + the filename provided to `require` and `require_relative`. + StyleGuide: '#no-explicit-rb-to-require' + Enabled: false + VersionAdded: '0.88' + +Style/RedundantFilterChain: + Description: >- + Identifies usages of `any?`, `empty?`, `none?` or `one?` predicate methods chained to + `select`/`filter`/`find_all` and change them to use predicate method instead. + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.52' + VersionChanged: '1.57' + +Style/RedundantFreeze: + Description: "Checks usages of Object#freeze on immutable objects." + Enabled: false + VersionAdded: '0.34' + VersionChanged: '0.66' + +Style/RedundantHeredocDelimiterQuotes: + Description: 'Checks for redundant heredoc delimiter quotes.' + Enabled: false + VersionAdded: '1.45' + +Style/RedundantInitialize: + Description: 'Checks for redundant `initialize` methods.' + Enabled: false + AutoCorrect: contextual + Safe: false + AllowComments: true + VersionAdded: '1.27' + VersionChanged: '1.61' + +Style/RedundantInterpolation: + Description: 'Checks for strings that are just an interpolated expression.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.76' + VersionChanged: '1.30' + +Style/RedundantLineContinuation: + Description: 'Check for redundant line continuation.' + Enabled: false + VersionAdded: '1.49' + +Style/RedundantParentheses: + Description: "Checks for parentheses that seem not to serve any purpose." + Enabled: false + VersionAdded: '0.36' + +Style/RedundantPercentQ: + Description: 'Checks for %q/%Q when single quotes or double quotes would do.' + StyleGuide: '#percent-q' + Enabled: false + VersionAdded: '0.76' + +Style/RedundantRegexpArgument: + Description: 'Identifies places where argument can be replaced from a deterministic regexp to a string.' + Enabled: false + VersionAdded: '1.53' + +Style/RedundantRegexpCharacterClass: + Description: 'Checks for unnecessary single-element Regexp character classes.' + Enabled: false + VersionAdded: '0.85' + +Style/RedundantRegexpConstructor: + Description: 'Checks for the instantiation of regexp using redundant `Regexp.new` or `Regexp.compile`.' + Enabled: false + VersionAdded: '1.52' + +Style/RedundantRegexpEscape: + Description: 'Checks for redundant escapes in Regexps.' + Enabled: false + VersionAdded: '0.85' + +Style/RedundantReturn: + Description: "Don't use return where it's not required." + StyleGuide: '#no-explicit-return' + Enabled: false + VersionAdded: '0.10' + VersionChanged: '0.14' + # When `true` allows code like `return x, y`. + AllowMultipleReturnValues: false + +Style/RedundantSelf: + Description: "Don't use self where it's not needed." + StyleGuide: '#no-self-unless-required' + Enabled: false + VersionAdded: '0.10' + VersionChanged: '0.13' + +Style/RedundantSelfAssignment: + Description: 'Checks for places where redundant assignments are made for in place modification methods.' + Enabled: false + Safe: false + VersionAdded: '0.90' + +Style/RedundantSelfAssignmentBranch: + Description: 'Checks for places where conditional branch makes redundant self-assignment.' + Enabled: false + VersionAdded: '1.19' + +Style/RedundantSort: + Description: >- + Use `min` instead of `sort.first`, + `max_by` instead of `sort_by...last`, etc. + Enabled: false + VersionAdded: '0.76' + VersionChanged: '1.22' + Safe: false + +Style/RedundantSortBy: + Description: 'Use `sort` instead of `sort_by { |x| x }`.' + Enabled: false + VersionAdded: '0.36' + +Style/RedundantStringEscape: + Description: 'Checks for redundant escapes in string literals.' + Enabled: false + VersionAdded: '1.37' + +Style/RegexpLiteral: + Description: 'Use / or %r around regular expressions.' + StyleGuide: '#percent-r' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.30' + EnforcedStyle: slashes + # slashes: Always use slashes. + # percent_r: Always use `%r`. + # mixed: Use slashes on single-line regexes, and `%r` on multi-line regexes. + SupportedStyles: + - slashes + - percent_r + - mixed + # If `false`, the cop will always recommend using `%r` if one or more slashes + # are found in the regexp string. + AllowInnerSlashes: false + +Style/RequireOrder: + Description: Sort `require` and `require_relative` in alphabetical order. + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.40' + +Style/RescueModifier: + Description: 'Avoid using rescue in its modifier form.' + StyleGuide: '#no-rescue-modifiers' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.34' + +Style/RescueStandardError: + Description: 'Avoid rescuing without specifying an error class.' + Enabled: false + VersionAdded: '0.52' + EnforcedStyle: explicit + # implicit: Do not include the error class, `rescue` + # explicit: Require an error class `rescue StandardError` + SupportedStyles: + - implicit + - explicit + +Style/ReturnNil: + Description: 'Use return instead of return nil.' + Enabled: false + EnforcedStyle: return + SupportedStyles: + - return + - return_nil + VersionAdded: '0.50' + +Style/ReturnNilInPredicateMethodDefinition: + Description: 'Checks if uses of `return` or `return nil` in predicate method definition.' + StyleGuide: '#bool-methods-qmark' + Enabled: false + SafeAutoCorrect: false + AllowedMethods: [] + AllowedPatterns: [] + VersionAdded: '1.53' + +Style/SafeNavigation: + Description: >- + Transforms usages of a method call safeguarded by + a check for the existence of the object to + safe navigation (`&.`). + Autocorrection is unsafe as it assumes the object will + be `nil` or truthy, but never `false`. + Enabled: false + VersionAdded: '0.43' + VersionChanged: '1.27' + # Safe navigation may cause a statement to start returning `nil` in addition + # to whatever it used to return. + ConvertCodeThatCanStartToReturnNil: false + AllowedMethods: + - present? + - blank? + - presence + - try + - try! + SafeAutoCorrect: false + # Maximum length of method chains for register an offense. + MaxChainLength: 2 + +Style/Sample: + Description: >- + Use `sample` instead of `shuffle.first`, + `shuffle.last`, and `shuffle[Integer]`. + Reference: 'https://github.com/fastruby/fast-ruby#arrayshufflefirst-vs-arraysample-code' + Enabled: false + VersionAdded: '0.30' + +Style/SelectByRegexp: + Description: 'Prefer grep/grep_v to select/reject with a regexp match.' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.22' + +Style/SelfAssignment: + Description: >- + Checks for places where self-assignment shorthand should have + been used. + StyleGuide: '#self-assignment' + Enabled: false + VersionAdded: '0.19' + VersionChanged: '0.29' + +Style/Semicolon: + Description: "Don't use semicolons to terminate expressions." + StyleGuide: '#no-semicolon' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.19' + # Allow `;` to separate several expressions on the same line. + AllowAsExpressionSeparator: false + +Style/Send: + Description: 'Prefer `Object#__send__` or `Object#public_send` to `send`, as `send` may overlap with existing methods.' + StyleGuide: '#prefer-public-send' + Enabled: false + VersionAdded: '0.33' + +Style/SendWithLiteralMethodName: + Description: 'Detects the use of the `public_send` method with a static method name argument.' + Enabled: false + Safe: false + AllowSend: true + VersionAdded: '1.64' + +Style/SignalException: + Description: 'Checks for proper usage of fail and raise.' + StyleGuide: '#prefer-raise-over-fail' + Enabled: false + VersionAdded: '0.11' + VersionChanged: '0.37' + EnforcedStyle: only_raise + SupportedStyles: + - only_raise + - only_fail + - semantic + +Style/SingleArgumentDig: + Description: 'Avoid using single argument dig method.' + Enabled: false + VersionAdded: '0.89' + Safe: false + +Style/SingleLineBlockParams: + Description: 'Enforces the names of some block params.' + Enabled: false + VersionAdded: '0.16' + VersionChanged: '1.6' + Methods: + - reduce: + - acc + - elem + - inject: + - acc + - elem + +Style/SingleLineDoEndBlock: + Description: 'Checks for single-line `do`...`end` blocks.' + StyleGuide: '#single-line-do-end-block' + Enabled: false + VersionAdded: '1.57' + +Style/SingleLineMethods: + Description: 'Avoid single-line methods.' + StyleGuide: '#no-single-line-methods' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.8' + AllowIfMethodIsEmpty: true + +Style/SlicingWithRange: + Description: 'Checks array slicing is done with redundant, endless, and beginless ranges when suitable.' + StyleGuide: '#slicing-with-ranges' + Enabled: false + VersionAdded: '0.83' + Safe: false + +Style/SoleNestedConditional: + Description: >- + Finds sole nested conditional nodes + which can be merged into outer conditional node. + Enabled: false + VersionAdded: '0.89' + VersionChanged: '1.5' + AllowModifier: false + +Style/SpecialGlobalVars: + Description: 'Avoid Perl-style global variables.' + StyleGuide: '#no-cryptic-perlisms' + Enabled: false + VersionAdded: '0.13' + VersionChanged: '0.36' + SafeAutoCorrect: false + RequireEnglish: true + EnforcedStyle: use_english_names + SupportedStyles: + - use_perl_names + - use_english_names + - use_builtin_english_names + +Style/StabbyLambdaParentheses: + Description: 'Check for the usage of parentheses around stabby lambda arguments.' + StyleGuide: '#stabby-lambda-with-args' + Enabled: false + VersionAdded: '0.35' + EnforcedStyle: require_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + +Style/StaticClass: + Description: 'Prefer modules to classes with only class methods.' + StyleGuide: '#modules-vs-classes' + Enabled: false + Safe: false + VersionAdded: '1.3' + +Style/StderrPuts: + Description: 'Use `warn` instead of `$stderr.puts`.' + StyleGuide: '#warn' + Enabled: false + VersionAdded: '0.51' + +Style/StringChars: + Description: 'Checks for uses of `String#split` with empty string or regexp literal argument.' + StyleGuide: '#string-chars' + Enabled: false + Safe: false + VersionAdded: '1.12' + +Style/StringConcatenation: + Description: 'Checks for places where string concatenation can be replaced with string interpolation.' + StyleGuide: '#string-interpolation' + Enabled: false + Safe: false + VersionAdded: '0.89' + VersionChanged: '1.18' + Mode: aggressive + +Style/StringHashKeys: + Description: 'Prefer symbols instead of strings as hash keys.' + StyleGuide: '#symbols-as-keys' + Enabled: false + VersionAdded: '0.52' + VersionChanged: '0.75' + Safe: false + +Style/StringLiterals: + Description: 'Checks if uses of quotes match the configured preference.' + StyleGuide: '#consistent-string-literals' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.36' + EnforcedStyle: single_quotes + SupportedStyles: + - single_quotes + - double_quotes + # If `true`, strings which span multiple lines using `\` for continuation must + # use the same type of quotes on each line. + ConsistentQuotesInMultiline: false + +Style/StringLiteralsInInterpolation: + Description: >- + Checks if uses of quotes inside expressions in interpolated + strings match the configured preference. + Enabled: false + VersionAdded: '0.27' + EnforcedStyle: single_quotes + SupportedStyles: + - single_quotes + - double_quotes + +Style/StringMethods: + Description: 'Checks if configured preferred methods are used over non-preferred.' + Enabled: false + VersionAdded: '0.34' + VersionChanged: '0.34' + # Mapping from undesired method to desired_method + # e.g. to use `to_sym` over `intern`: + # + # StringMethods: + # PreferredMethods: + # intern: to_sym + PreferredMethods: + intern: to_sym + +Style/Strip: + Description: 'Use `strip` instead of `lstrip.rstrip`.' + Enabled: false + VersionAdded: '0.36' + +Style/StructInheritance: + Description: 'Checks for inheritance from Struct.new.' + StyleGuide: '#no-extend-struct-new' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.29' + VersionChanged: '1.20' + +Style/SuperArguments: + Description: 'Call `super` without arguments and parentheses when the signature is identical.' + Enabled: false + VersionAdded: '1.64' + +Style/SuperWithArgsParentheses: + Description: 'Use parentheses for `super` with arguments.' + StyleGuide: '#super-with-args' + Enabled: false + VersionAdded: '1.58' + +Style/SwapValues: + Description: 'Enforces the use of shorthand-style swapping of 2 variables.' + StyleGuide: '#values-swapping' + Enabled: false + VersionAdded: '1.1' + SafeAutoCorrect: false + +Style/SymbolArray: + Description: 'Use %i or %I for arrays of symbols.' + StyleGuide: '#percent-i' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.49' + EnforcedStyle: percent + MinSize: 2 + SupportedStyles: + - percent + - brackets + +Style/SymbolLiteral: + Description: 'Use plain symbols instead of string symbols when possible.' + Enabled: false + VersionAdded: '0.30' + +Style/SymbolProc: + Description: 'Use symbols as procs instead of blocks when possible.' + Enabled: false + Safe: false + VersionAdded: '0.26' + VersionChanged: '1.64' + AllowMethodsWithArguments: false + # A list of method names to be always allowed by the check. + # The names should be fairly unique, otherwise you'll end up ignoring lots of code. + AllowedMethods: + - define_method + AllowedPatterns: [] + AllowComments: false + +Style/TernaryParentheses: + Description: 'Checks for use of parentheses around ternary conditions.' + Enabled: false + VersionAdded: '0.42' + VersionChanged: '0.46' + EnforcedStyle: require_no_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + - require_parentheses_when_complex + AllowSafeAssignment: true + +Style/TopLevelMethodDefinition: + Description: 'Looks for top-level method definitions.' + StyleGuide: '#top-level-methods' + Enabled: false + VersionAdded: '1.15' + +Style/TrailingBodyOnClass: + Description: 'Class body goes below class statement.' + Enabled: false + VersionAdded: '0.53' + +Style/TrailingBodyOnMethodDefinition: + Description: 'Method body goes below definition.' + Enabled: false + VersionAdded: '0.52' + +Style/TrailingBodyOnModule: + Description: 'Module body goes below module statement.' + Enabled: false + VersionAdded: '0.53' + +Style/TrailingCommaInArguments: + Description: 'Checks for trailing comma in argument lists.' + StyleGuide: '#no-trailing-params-comma' + Enabled: false + VersionAdded: '0.36' + # If `comma`, the cop requires a comma after the last argument, but only for + # parenthesized method calls where each argument is on its own line. + # If `consistent_comma`, the cop requires a comma after the last argument, + # for all parenthesized method calls with arguments. + EnforcedStyleForMultiline: no_comma + SupportedStylesForMultiline: + - comma + - consistent_comma + - no_comma + +Style/TrailingCommaInArrayLiteral: + Description: 'Checks for trailing comma in array literals.' + StyleGuide: '#no-trailing-array-commas' + Enabled: false + VersionAdded: '0.53' + # If `comma`, the cop requires a comma after the last item in an array, + # but only when each item is on its own line. + # If `consistent_comma`, the cop requires a comma after the last item of all + # non-empty, multiline array literals. + EnforcedStyleForMultiline: no_comma + SupportedStylesForMultiline: + - comma + - consistent_comma + - no_comma + +Style/TrailingCommaInBlockArgs: + Description: 'Checks for useless trailing commas in block arguments.' + Enabled: false + Safe: false + VersionAdded: '0.81' + +Style/TrailingCommaInHashLiteral: + Description: 'Checks for trailing comma in hash literals.' + Enabled: false + # If `comma`, the cop requires a comma after the last item in a hash, + # but only when each item is on its own line. + # If `consistent_comma`, the cop requires a comma after the last item of all + # non-empty, multiline hash literals. + EnforcedStyleForMultiline: no_comma + SupportedStylesForMultiline: + - comma + - consistent_comma + - no_comma + VersionAdded: '0.53' + +Style/TrailingMethodEndStatement: + Description: 'Checks for trailing end statement on line of method body.' + Enabled: false + VersionAdded: '0.52' + +Style/TrailingUnderscoreVariable: + Description: >- + Checks for the usage of unneeded trailing underscores at the + end of parallel variable assignment. + AllowNamedUnderscoreVariables: true + Enabled: false + VersionAdded: '0.31' + VersionChanged: '0.35' + +# `TrivialAccessors` requires exact name matches and doesn't allow +# predicated methods by default. +Style/TrivialAccessors: + Description: 'Prefer attr_* methods to trivial readers/writers.' + StyleGuide: '#attr_family' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.15' + # When set to `false` the cop will suggest the use of accessor methods + # in situations like: + # + # def name + # @other_name + # end + # + # This way you can uncover "hidden" attributes in your code. + ExactNameMatch: true + AllowPredicates: true + # Allows trivial writers that don't end in an equal sign. e.g. + # + # def on_exception(action) + # @on_exception=action + # end + # on_exception :restart + # + # Commonly used in DSLs + AllowDSLWriters: true + IgnoreClassMethods: false + AllowedMethods: + - to_ary + - to_a + - to_c + - to_enum + - to_h + - to_hash + - to_i + - to_int + - to_io + - to_open + - to_path + - to_proc + - to_r + - to_regexp + - to_str + - to_s + - to_sym + +Style/UnlessElse: + Description: >- + Do not use unless with else. Rewrite these with the positive + case first. + StyleGuide: '#no-else-with-unless' + Enabled: false + VersionAdded: '0.9' + +Style/UnlessLogicalOperators: + Description: >- + Checks for use of logical operators in an unless condition. + Enabled: false + VersionAdded: '1.11' + EnforcedStyle: forbid_mixed_logical_operators + SupportedStyles: + - forbid_mixed_logical_operators + - forbid_logical_operators + +Style/UnpackFirst: + Description: >- + Checks for accessing the first element of `String#unpack` + instead of using `unpack1`. + Enabled: false + VersionAdded: '0.54' + +Style/VariableInterpolation: + Description: >- + Don't interpolate global, instance and class variables + directly in strings. + StyleGuide: '#curlies-interpolate' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.20' + +Style/WhenThen: + Description: 'Use when x then ... for one-line cases.' + StyleGuide: '#no-when-semicolons' + Enabled: false + VersionAdded: '0.9' + +Style/WhileUntilDo: + Description: 'Checks for redundant do after while or until.' + StyleGuide: '#no-multiline-while-do' + Enabled: false + VersionAdded: '0.9' + +Style/WhileUntilModifier: + Description: >- + Favor modifier while/until usage when you have a + single-line body. + StyleGuide: '#while-as-a-modifier' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '0.30' + +Style/WordArray: + Description: 'Use %w or %W for arrays of words.' + StyleGuide: '#percent-w' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.19' + EnforcedStyle: percent + SupportedStyles: + # percent style: %w(word1 word2) + - percent + # bracket style: ['word1', 'word2'] + - brackets + # The `MinSize` option causes the `WordArray` rule to be ignored for arrays + # smaller than a certain size. The rule is only applied to arrays + # whose element count is greater than or equal to `MinSize`. + MinSize: 2 + # The regular expression `WordRegex` decides what is considered a word. + WordRegex: !ruby/regexp '/\A(?:\p{Word}|\p{Word}-\p{Word}|\n|\t)+\z/' + +Style/YAMLFileRead: + Description: 'Checks for the use of `YAML.load`, `YAML.safe_load`, and `YAML.parse` with `File.read` argument.' + Enabled: false + VersionAdded: '1.53' + +Style/YodaCondition: + Description: 'Forbid or enforce yoda conditions.' + Reference: 'https://en.wikipedia.org/wiki/Yoda_conditions' + Enabled: false + EnforcedStyle: forbid_for_all_comparison_operators + SupportedStyles: + # check all comparison operators + - forbid_for_all_comparison_operators + # check only equality operators: `!=` and `==` + - forbid_for_equality_operators_only + # enforce yoda for all comparison operators + - require_for_all_comparison_operators + # enforce yoda only for equality operators: `!=` and `==` + - require_for_equality_operators_only + Safe: false + VersionAdded: '0.49' + VersionChanged: '0.75' + +Style/YodaExpression: + Description: 'Forbid the use of yoda expressions.' + Enabled: false + Safe: false + VersionAdded: '1.42' + VersionChanged: '1.43' + SupportedOperators: + - '*' + - '+' + - '&' + - '|' + - '^' + +Style/ZeroLengthPredicate: + Description: 'Use #empty? when testing for objects of length 0.' + Enabled: false + Safe: false + VersionAdded: '0.37' + VersionChanged: '0.39' \ No newline at end of file diff --git a/Gemfile b/Gemfile index 269b363..61fb330 100644 --- a/Gemfile +++ b/Gemfile @@ -1,63 +1,83 @@ -source "https://rubygems.org" +source 'https://rubygems.org' -ruby "3.2.2" +ruby '3.2.2' -# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.1.3", ">= 7.1.3.4" +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main' +gem 'rails', '~> 7.1.3', '>= 7.1.3.4' # Use postgresql as the database for Active Record -gem "pg", "~> 1.1" +gem 'pg', '~> 1.1' # Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" +gem 'puma', '>= 5.0' # Build JSON APIs with ease [https://github.com/rails/jbuilder] -# gem "jbuilder" +# gem 'jbuilder' # Use Redis adapter to run Action Cable in production -# gem "redis", ">= 4.0.1" +# gem 'redis', '>= 4.0.1' # Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] -# gem "kredis" +# gem 'kredis' # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" +# gem 'bcrypt', '~> 3.1.7' # Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[ windows jruby ] +gem 'tzinfo-data', platforms: %i[ windows jruby ] # Reduces boot times through caching; required in config/boot.rb -gem "bootsnap", require: false +gem 'bootsnap','~> 1.18.3', require: false # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] -# gem "image_processing", "~> 1.2" +# gem 'image_processing', '~> 1.2' # Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin Ajax possible -gem "rack-cors" +gem 'rack-cors', '~> 2.0.2' -group :development, :test do - # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[ mri windows ] +group :development, :test do + # Speed up commands on slow machines / big apps [https://github.com/rails/spring] + # gem 'spring' + gem 'pry', '~> 0.14.2' + gem 'pry-rails', '~> 0.3.11' + gem 'pry-byebug', '~> 3.10.1' + gem 'bundler-audit', '~> 0.9.1' + gem 'brakeman', '~> 6.1.2' + gem 'rubocop', '~> 1.65.0', require: false + # gem 'rubocop-capybara', '~> 2.21.0' + # gem 'rubocop-factory_bot', '~> 2.26.1' + gem 'rubocop-rails', '~> 2.25.1', require: false + # gem 'rubocop-rspec', '~> 3.0.3' + # gem 'rubocop-rspec_rails', '~> 2.30.0' end -group :development do - # Speed up commands on slow machines / big apps [https://github.com/rails/spring] - # gem "spring" - gem 'pry' - gem 'pry-rails' - gem 'pry-byebug' - gem 'rspec-rails' - gem "factory_bot_rails" - gem 'capybara' - gem 'database_cleaner' - gem "faker" +group :test do + gem 'rspec-rails', '~> 6.1.3' + gem 'factory_bot_rails', '~> 6.4.3' + gem 'capybara', '~> 3.40.0' + gem 'database_cleaner', '~> 2.0.2' + gem 'faker', '~> 3.4.1' + gem 'shoulda-matchers', '~> 6.2.0' + # gem 'route_mechanic', github: 'ohbarye/route_mechanic' end + # Use Json Web Token (JWT) for token based authentication -gem 'jwt' +gem 'jwt', '~> 2.8.2' # Use ActiveModel has_secure_password -gem 'bcrypt' +gem 'bcrypt', '~> 3.1.20' # Shim to load environment variables from .env into ENV in development. -gem 'dotenv' \ No newline at end of file +gem 'dotenv', '~> 3.1.2' + +# A fast JSON parser and Object marshaller as a Ruby gem. +gem 'oj', '~> 3.16.4' +# JSON Serializer for response +gem 'panko_serializer', '~> 0.8.2' + +# for image processing. Used by ActiveStorage +gem 'image_processing', '~> 1.12.2' + +# Fix security issue: URL: https://github.com/rack/rack/security/advisories/GHSA-cj83-2ww7-mvq7 +gem 'rack', '~> 3.1.7' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 2611080..afeb2b0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,12 +77,18 @@ GEM tzinfo (~> 2.0) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) + ast (2.4.2) base64 (0.2.0) bcrypt (3.1.20) bigdecimal (3.1.8) bootsnap (1.18.3) msgpack (~> 1.2) + brakeman (6.1.2) + racc builder (3.3.0) + bundler-audit (0.9.1) + bundler (>= 1.2.0, < 3) + thor (~> 1.0) byebug (11.1.3) capybara (3.40.0) addressable @@ -104,9 +110,6 @@ GEM database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) date (3.3.4) - debug (1.9.2) - irb (~> 1.10) - reline (>= 0.3.8) diff-lcs (1.5.1) dotenv (3.1.2) drb (2.2.1) @@ -118,16 +121,27 @@ GEM railties (>= 5.0.0) faker (3.4.1) i18n (>= 1.8.11, < 2) + ffi (1.17.0-aarch64-linux-gnu) + ffi (1.17.0-arm-linux-gnu) + ffi (1.17.0-arm64-darwin) + ffi (1.17.0-x86-linux-gnu) + ffi (1.17.0-x86_64-darwin) + ffi (1.17.0-x86_64-linux-gnu) globalid (1.2.1) activesupport (>= 6.1) i18n (1.14.5) concurrent-ruby (~> 1.0) + image_processing (1.12.2) + mini_magick (>= 4.9.5, < 5) + ruby-vips (>= 2.0.17, < 3) io-console (0.7.2) irb (1.13.2) rdoc (>= 4.0.0) reline (>= 0.4.2) + json (2.7.2) jwt (2.8.2) base64 + language_server-protocol (3.17.0.3) loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -139,6 +153,7 @@ GEM marcel (1.0.4) matrix (0.4.2) method_source (1.1.0) + mini_magick (4.13.2) mini_mime (1.1.5) minitest (5.24.0) msgpack (1.7.2) @@ -165,6 +180,15 @@ GEM racc (~> 1.4) nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) + oj (3.16.4) + bigdecimal (>= 3.0) + panko_serializer (0.8.2) + activesupport + oj (> 3.11.0, < 4.0.0) + parallel (1.25.1) + parser (3.3.4.0) + ast (~> 2.4.1) + racc pg (1.5.6) pry (0.14.2) coderay (~> 1.1) @@ -180,7 +204,7 @@ GEM puma (6.4.2) nio4r (~> 2.0) racc (1.8.0) - rack (3.1.3) + rack (3.1.7) rack-cors (2.0.2) rack (>= 2.0.0) rack-session (2.0.0) @@ -219,12 +243,15 @@ GEM rake (>= 12.2) thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) + rainbow (3.1.1) rake (13.2.1) rdoc (6.7.0) psych (>= 4.0.0) regexp_parser (2.9.2) reline (0.5.9) io-console (~> 0.5) + rexml (3.3.2) + strscan rspec-core (3.13.0) rspec-support (~> 3.13.0) rspec-expectations (3.13.1) @@ -242,11 +269,36 @@ GEM rspec-mocks (~> 3.13) rspec-support (~> 3.13) rspec-support (3.13.1) + rubocop (1.65.0) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.4, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.31.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) + rubocop-rails (2.25.1) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + ruby-progressbar (1.13.0) + ruby-vips (2.2.1) + ffi (~> 1.12) + shoulda-matchers (6.2.0) + activesupport (>= 5.2.0) stringio (3.1.1) + strscan (3.1.0) thor (1.3.1) timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) + unicode-display_width (2.5.0) webrick (1.8.1) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) @@ -264,23 +316,31 @@ PLATFORMS x86_64-linux DEPENDENCIES - bcrypt - bootsnap - capybara - database_cleaner - debug - dotenv - factory_bot_rails - faker - jwt + bcrypt (~> 3.1.20) + bootsnap (~> 1.18.3) + brakeman (~> 6.1.2) + bundler-audit (~> 0.9.1) + capybara (~> 3.40.0) + database_cleaner (~> 2.0.2) + dotenv (~> 3.1.2) + factory_bot_rails (~> 6.4.3) + faker (~> 3.4.1) + image_processing (~> 1.12.2) + jwt (~> 2.8.2) + oj (~> 3.16.4) + panko_serializer (~> 0.8.2) pg (~> 1.1) - pry - pry-byebug - pry-rails + pry (~> 0.14.2) + pry-byebug (~> 3.10.1) + pry-rails (~> 0.3.11) puma (>= 5.0) - rack-cors + rack (~> 3.1.7) + rack-cors (~> 2.0.2) rails (~> 7.1.3, >= 7.1.3.4) - rspec-rails + rspec-rails (~> 6.1.3) + rubocop (~> 1.65.0) + rubocop-rails (~> 2.25.1) + shoulda-matchers (~> 6.2.0) tzinfo-data RUBY VERSION diff --git a/app/controllers/api/v1/authentication_controller.rb b/app/controllers/api/v1/authentication_controller.rb index 43a8ab6..58798b4 100644 --- a/app/controllers/api/v1/authentication_controller.rb +++ b/app/controllers/api/v1/authentication_controller.rb @@ -3,9 +3,9 @@ class Api::V1::AuthenticationController < ApplicationController # POST /auth/login def login - @user = User.find_by_email(params[:email]) + @user = User.find_by(email: params[:email]) if @user&.authenticate(params[:password]) - time = Time.now + 24.hours.to_i + time = Time.zone.now + 24.hours.to_i token = JsonWebToken.encode({user_id: @user.id}, time) render json: { token: token, exp: time.strftime("%m-%d-%Y %H:%M"), username: @user.username,name: @user.name }, status: :ok diff --git a/app/controllers/api/v1/comments_controller.rb b/app/controllers/api/v1/comments_controller.rb new file mode 100644 index 0000000..19cb40f --- /dev/null +++ b/app/controllers/api/v1/comments_controller.rb @@ -0,0 +1,61 @@ +class Api::V1::CommentsController < ApplicationController + before_action :authorize_request + before_action :set_post + before_action :set_comment, only: %i[ show update destroy ] + + # GET /comments + def index + @comments = @post.comments + render json: Panko::ArraySerializer.new(@comments, each_serializer: CommentSerializer).to_json + end + + # GET /comments/1 + def show + render json: CommentSerializer.new.serialize(@comment).to_json + end + + # POST /comments + def create + @comment = @post.comments.build(comment_params) + @comment.user_id = @current_user.id + + if @comment.save + render json: CommentSerializer.new.serialize(@comment).to_json, status: :created + else + render json: @comment.errors, status: :unprocessable_entity + end + end + + # PATCH/PUT /comments/1 + def update + if @comment.update(comment_params) + render json: CommentSerializer.new.serialize(@comment).to_json + else + render json: @comment.errors, status: :unprocessable_entity + end + end + + # DELETE /comments/1 + def destroy + if @comment.destroy + render json: CommentSerializer.new.serialize(@comment).to_json + else + render json: @comment.errors, status: :unprocessable_entity + end + end + + private + + def set_post + @post = Post.find(params[:post_id]) + end + # Use callbacks to share common setup or constraints between actions. + def set_comment + @comment = Comment.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def comment_params + params.require(:comment).permit(:body, :user_id, :post_id) + end +end diff --git a/app/controllers/api/v1/posts_controller.rb b/app/controllers/api/v1/posts_controller.rb new file mode 100644 index 0000000..86fb57a --- /dev/null +++ b/app/controllers/api/v1/posts_controller.rb @@ -0,0 +1,61 @@ +class Api::V1::PostsController < ApplicationController + before_action :authorize_request + before_action :set_post, only: %i[ show update destroy ] + + # GET /posts + def index + @posts = Post.includes(:comments, :user) + + render json: Panko::ArraySerializer.new(@posts, each_serializer: PostSerializer).to_json + end + + # GET /posts/1 + def show + render json: PostSerializer.new.serialize(@post).to_json + end + + # POST /posts + def create + @post = Post.new(post_params) + @post.user_id = @current_user.id + @post.medias.attach(post_params[:medias]) + + if @post.save + render json: PostSerializer.new.serialize(@post).to_json, status: :created + else + render json: @post.errors, status: :unprocessable_entity + end + end + + # PATCH/PUT /posts/1 + def update + @post.medias.attach(post_params[:medias]) + + if @post.update(post_params) + render json: PostSerializer.new.serialize(@post).to_json + else + render json: @post.errors, status: :unprocessable_entity + end + end + + # DELETE /posts/1 + def destroy + + if @post.destroy + render json: PostSerializer.new.serialize(@post).to_json + else + render json: @post.errors, status: :unprocessable_entity + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_post + @post = Post.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def post_params + params.require(:post).permit(:title, :description, medias:[]) + end +end diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index 4cf1809..5d1e7d7 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -5,19 +5,20 @@ class Api::V1::UsersController < ApplicationController # GET /users def index @users = User.all - render json: @users, status: :ok + + render json: Panko::ArraySerializer.new(@users, each_serializer: UserSerializer).to_json, status: :ok end # GET /users/{username} def show - render json: @user, status: :ok + render json: UserSerializer.new.serialize(@user).to_json, status: :ok end # POST /users def create @user = User.new(user_params) if @user.save - render json: {user: @user, message: 'User created Successfully!'}, status: 200 + render json: {user: UserSerializer.new.serialize(@user).to_json, message: 'User created Successfully!'}, status: :ok else render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity @@ -27,7 +28,7 @@ def create # PUT /users/{username} def update if @user.update(user_params) - render json: {user: @user, message: 'User Updated Successfully!'}, status: 200 + render json: {user: UserSerializer.new.serialize(@user).to_json, message: 'User Updated Successfully!'}, status: :ok else render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity @@ -37,7 +38,7 @@ def update # DELETE /users/{username} def destroy if @user.destroy - render json: {user: @user, message: 'User deleted Successfully!'}, status: 200 + render json: {user: UserSerializer.new.serialize(@user).to_json, message: 'User deleted Successfully!'}, status: :ok else render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e29138a..6ed95b8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,14 +1,50 @@ class ApplicationController < ActionController::API - def not_found - render json: { error: 'not_found' } + private + + rescue_from Exception do |exception| + render_error(exception) + end + + def get_exception_status_code(exception) + status_number = 500 + + error_classes_404 = [ + ActiveRecord::RecordNotFound, + ActionController::RoutingError, + AbstractController::ActionNotFound + ] + error_classes_500 = [ + NameError + ] + + if error_classes_404.include?(exception.class) + status_number = 404 + end + + return status_number.to_i + end + + def render_error(exception_obj = Exception.new("Error occurred!"), options = {}) + + if exception_obj.is_a?(Exception) + error_msg = exception_obj.message + Rails.logger.error exception_obj.message + Rails.logger.error exception_obj.backtrace.join("\n") + elsif exception_obj.is_a?(String) + error_msg = exception_obj + else + error_msg = "Error occurred!" + end + + render json: {error: error_msg}, status: get_exception_status_code(exception_obj) end def authorize_request token = request.headers['x-token'] begin @decoded = JsonWebToken.decode(token) - @current_user = User.find(@decoded[:user_id]) + @current_user = User.find(@decoded["user_id"]) rescue ActiveRecord::RecordNotFound => e render json: { errors: e.message }, status: :unauthorized rescue JWT::DecodeError => e diff --git a/app/models/comment.rb b/app/models/comment.rb new file mode 100644 index 0000000..e739c8d --- /dev/null +++ b/app/models/comment.rb @@ -0,0 +1,5 @@ +class Comment < ApplicationRecord + belongs_to :user + belongs_to :commentable, polymorphic: true + validates :body, presence: true +end diff --git a/app/models/post.rb b/app/models/post.rb new file mode 100644 index 0000000..9b467ac --- /dev/null +++ b/app/models/post.rb @@ -0,0 +1,6 @@ +class Post < ApplicationRecord + belongs_to :user + has_many :comments, as: :commentable, dependent: :destroy + has_many_attached :medias + validates :title, :description, presence: true +end diff --git a/app/models/user.rb b/app/models/user.rb index 972b47f..093d326 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,8 @@ class User < ApplicationRecord has_secure_password + has_many :posts, dependent: :destroy + has_many :comments, dependent: :destroy + validates :email, presence: true, uniqueness: true validates :email, format: { with: URI::MailTo::EMAIL_REGEXP } validates :username, presence: true, uniqueness: true diff --git a/app/serializers/comment_serializer.rb b/app/serializers/comment_serializer.rb new file mode 100644 index 0000000..3c81e03 --- /dev/null +++ b/app/serializers/comment_serializer.rb @@ -0,0 +1,5 @@ +class CommentSerializer < Panko::Serializer + + attributes :id, :body, :user_id + has_one :user, serializer: UserSerializer +end \ No newline at end of file diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb new file mode 100644 index 0000000..2499a61 --- /dev/null +++ b/app/serializers/post_serializer.rb @@ -0,0 +1,15 @@ +class PostSerializer < Panko::Serializer + include Rails.application.routes.url_helpers + + attributes :id, :title, :description, :medias + + has_many :comments, serializer: CommentSerializer + has_one :user, serializer: UserSerializer + + def medias + object.medias.map do |_medias| + # rails_blob_path(_medias , only_path: true) if object.medias.attached? + rails_blob_url(_medias) + end + end +end \ No newline at end of file diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb new file mode 100644 index 0000000..dbf696e --- /dev/null +++ b/app/serializers/user_serializer.rb @@ -0,0 +1,3 @@ +class UserSerializer < Panko::Serializer + attributes :id, :email, :username +end \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index f962d9f..fba8e0c 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -68,4 +68,8 @@ # Raise error when a before_action's only/except options reference missing actions config.action_controller.raise_on_missing_callback_actions = true + + config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } + self.default_url_options = config.action_mailer.default_url_options + end diff --git a/config/initializers/oj_init.rb b/config/initializers/oj_init.rb new file mode 100644 index 0000000..a58f11f --- /dev/null +++ b/config/initializers/oj_init.rb @@ -0,0 +1 @@ +Oj.optimize_rails() \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 03946bd..d700145 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,16 +3,17 @@ # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to verify that the app is live. - get "up" => "rails/health#show", as: :rails_health_check + # get "up" => "rails/health#show", as: :rails_health_check # Defines the root path route ("/") # root "posts#index" namespace :api do namespace :v1 do resources :users - post '/auth/login', to: 'authentication#login' - get '/*a', to: 'application#not_found' + resources :posts do + resources :comments + end + post '/auth/login', to: 'authentication#login' end end - -end +end \ No newline at end of file diff --git a/config/service.yml b/config/service.yml new file mode 100644 index 0000000..8d6d3ac --- /dev/null +++ b/config/service.yml @@ -0,0 +1,14 @@ +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +amazon: + service: S3 + access_key_id: "" + secret_access_key: "" + bucket: "" + region: "" # e.g. 'us-east-1' \ No newline at end of file diff --git a/db/migrate/20240710074107_create_posts.rb b/db/migrate/20240710074107_create_posts.rb new file mode 100644 index 0000000..e17ce22 --- /dev/null +++ b/db/migrate/20240710074107_create_posts.rb @@ -0,0 +1,11 @@ +class CreatePosts < ActiveRecord::Migration[7.1] + def change + create_table :posts do |t| + t.string :title + t.string :description + t.belongs_to :user, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20240712121342_create_comments.rb b/db/migrate/20240712121342_create_comments.rb new file mode 100644 index 0000000..b2b88ee --- /dev/null +++ b/db/migrate/20240712121342_create_comments.rb @@ -0,0 +1,11 @@ +class CreateComments < ActiveRecord::Migration[7.1] + def change + create_table :comments do |t| + t.string :body + t.belongs_to :user, null: false, foreign_key: true + t.belongs_to :post, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20240715144922_create_active_storage_tables.active_storage.rb b/db/migrate/20240715144922_create_active_storage_tables.active_storage.rb new file mode 100644 index 0000000..e4706aa --- /dev/null +++ b/db/migrate/20240715144922_create_active_storage_tables.active_storage.rb @@ -0,0 +1,57 @@ +# This migration comes from active_storage (originally 20170806125915) +class CreateActiveStorageTables < ActiveRecord::Migration[7.0] + def change + # Use Active Record's configured type for primary and foreign keys + primary_key_type, foreign_key_type = primary_and_foreign_key_types + + create_table :active_storage_blobs, id: primary_key_type do |t| + t.string :key, null: false + t.string :filename, null: false + t.string :content_type + t.text :metadata + t.string :service_name, null: false + t.bigint :byte_size, null: false + t.string :checksum + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :key ], unique: true + end + + create_table :active_storage_attachments, id: primary_key_type do |t| + t.string :name, null: false + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + t.references :blob, null: false, type: foreign_key_type + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + + create_table :active_storage_variant_records, id: primary_key_type do |t| + t.belongs_to :blob, null: false, index: false, type: foreign_key_type + t.string :variation_digest, null: false + + t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_and_foreign_key_types + config = Rails.configuration.generators + setting = config.options[config.orm][:primary_key_type] + primary_key_type = setting || :primary_key + foreign_key_type = setting || :bigint + [primary_key_type, foreign_key_type] + end +end diff --git a/db/migrate/20240716133052_add_commentable_fields_to_comments.rb b/db/migrate/20240716133052_add_commentable_fields_to_comments.rb new file mode 100644 index 0000000..4809b3b --- /dev/null +++ b/db/migrate/20240716133052_add_commentable_fields_to_comments.rb @@ -0,0 +1,12 @@ +class AddCommentableFieldsToComments < ActiveRecord::Migration[7.1] + def change + # add_column :comments, :commentable_id, :integer + # add_column :comments, :commentable_type, :string + change_table :comments, bulk: true do |t| + t.integer :commentable_id + t.string :commentable_type + t.index :commentable_id + t.index :commentable_type + end + end +end diff --git a/db/migrate/20240719091803_add_unique_index_for_table.rb b/db/migrate/20240719091803_add_unique_index_for_table.rb new file mode 100644 index 0000000..ae5ba45 --- /dev/null +++ b/db/migrate/20240719091803_add_unique_index_for_table.rb @@ -0,0 +1,6 @@ +class AddUniqueIndexForTable < ActiveRecord::Migration[7.1] + def change + add_index :users, :email, unique: true + add_index :users, :username, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index b6c5e59..f73e5de 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,10 +10,57 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_06_24_195012) do +ActiveRecord::Schema[7.1].define(version: 2024_07_19_091803) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "active_storage_attachments", force: :cascade do |t| + t.string "name", null: false + t.string "record_type", null: false + t.bigint "record_id", null: false + t.bigint "blob_id", null: false + t.datetime "created_at", null: false + t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" + t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true + end + + create_table "active_storage_blobs", force: :cascade do |t| + t.string "key", null: false + t.string "filename", null: false + t.string "content_type" + t.text "metadata" + t.string "service_name", null: false + t.bigint "byte_size", null: false + t.string "checksum" + t.datetime "created_at", null: false + t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true + end + + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + + create_table "comments", force: :cascade do |t| + t.string "body" + t.bigint "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "commentable_id" + t.string "commentable_type" + t.index ["user_id"], name: "index_comments_on_user_id" + end + + create_table "posts", force: :cascade do |t| + t.string "title" + t.string "description" + t.bigint "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_posts_on_user_id" + end + create_table "users", force: :cascade do |t| t.string "name" t.string "username" @@ -21,6 +68,12 @@ t.string "password_digest" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["email"], name: "index_users_on_email", unique: true + t.index ["username"], name: "index_users_on_username", unique: true end + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" + add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "comments", "users" + add_foreign_key "posts", "users" end diff --git a/lib/tasks/update_db.rake b/lib/tasks/update_db.rake new file mode 100644 index 0000000..6471b18 --- /dev/null +++ b/lib/tasks/update_db.rake @@ -0,0 +1,13 @@ + +namespace :update_db do + + desc 'Update Comments with commentable data' + task comments: :environment do + Comment.in_batches.each do |comments| + comments_with_group = comments.group_by{|c| c.post_id } + comments_with_group.each do |post_id, comments| + Comment.where(id: comments.mpa(&:id).compact.uniq).update(commentable_id: post_id, commentable_type: 'Post') + end + end + end +end \ No newline at end of file diff --git a/spec/controllers/api/v1/comments_controller_spec.rb b/spec/controllers/api/v1/comments_controller_spec.rb new file mode 100644 index 0000000..9f2d302 --- /dev/null +++ b/spec/controllers/api/v1/comments_controller_spec.rb @@ -0,0 +1,112 @@ +# spec/controllers/api/v1/comments_controller_spec.rb +require 'rails_helper' + +RSpec.describe Api::V1::CommentsController, type: :controller do + let(:user) { create(:user) } + let(:post_obj) { create(:post, user: user) } + let(:valid_attributes) { { body: 'Sample Comment' } } + let(:invalid_attributes) { { body: '' } } + let!(:comment) { create(:comment, commentable: post_obj, user: user) } + let(:token) { JsonWebToken.encode({user_id: user.id}, (Time.zone.now + 24.hours.to_i) ) } + let(:valid_headers) { {'x-token': token} } + + before do + request.headers.merge!(valid_headers) + allow(JsonWebToken).to receive(:decode).and_return({ 'user_id' => user.id }) + end + + describe 'GET #index' do + it 'returns a success response' do + get :index, params: { post_id: post_obj.id } + expect(response).to have_http_status(:ok) + end + + it 'returns all comments for the post' do + get :index, params: { post_id: post_obj.id } + expect(JSON.parse(response.body).size).to eq(post_obj.comments.count) + end + end + + describe 'GET #show' do + context 'when the comment exists' do + it 'returns a success response' do + get :show, params: { post_id: post_obj.id, id: comment.to_param } + expect(response).to have_http_status(:ok) + end + + it 'returns the comment' do + get :show, params: { post_id: post_obj.id, id: comment.to_param } + expect(JSON.parse(response.body)['id']).to eq(comment.id) + end + end + + context 'when the comment does not exist' do + it 'returns a not found response' do + get :show, params: { post_id: post_obj.id, id: 0 } + expect(response).to have_http_status(:not_found) + end + end + end + + describe 'POST #create' do + context 'with valid params' do + it 'creates a new comment' do + expect { + post :create, params: { post_id: post_obj.id, comment: valid_attributes } + }.to change(Comment, :count).by(1) + expect(response).to have_http_status(:created) + end + end + + context 'with invalid params' do + it 'does not create a new comment' do + expect { + post :create, params: { post_id: post_obj.id, comment: invalid_attributes } + }.to change(Comment, :count).by(0) + end + + it 'returns an unprocessable entity response' do + post :create, params: { post_id: post_obj.id, comment: invalid_attributes } + + expect(response).to have_http_status(:unprocessable_entity) + end + end + end + + describe 'PATCH/PUT #update' do + context 'with valid params' do + let(:new_attributes) { { body: 'Updated Comment' } } + + it 'updates the requested comment' do + put :update, params: { post_id: post_obj.id, id: comment.id, comment: new_attributes } + comment.reload + expect(comment.body).to eq('Updated Comment') + end + + it 'returns a success response' do + put :update, params: { post_id: post_obj.id, id: comment.id, comment: new_attributes } + expect(response).to have_http_status(:ok) + end + end + + context 'with invalid params' do + it 'returns an unprocessable entity response' do + put :update, params: { post_id: post_obj.id, id: comment.id, comment: invalid_attributes } + expect(response).to have_http_status(:unprocessable_entity) + end + end + end + + describe 'DELETE #destroy' do + it 'destroys the requested comment' do + expect { + delete :destroy, params: { post_id: post_obj.id, id: comment.id } + }.to change(Comment, :count).by(-1) + end + + it 'returns a success response' do + delete :destroy, params: { post_id: post_obj.id, id: comment.id } + expect(response).to have_http_status(:ok) + end + end +end diff --git a/spec/controllers/api/v1/posts_controller_spec.rb b/spec/controllers/api/v1/posts_controller_spec.rb new file mode 100644 index 0000000..6e898d6 --- /dev/null +++ b/spec/controllers/api/v1/posts_controller_spec.rb @@ -0,0 +1,114 @@ +# spec/controllers/api/v1/posts_controller_spec.rb +require 'rails_helper' + +RSpec.describe Api::V1::PostsController, type: :controller do + let(:user) { create(:user) } + let(:valid_attributes) { { title: 'Sample Title', description: 'Sample Description' } } + let(:invalid_attributes) { { title: '', description: '' } } + let!(:post_obj) { create(:post, user: user) } + let(:token) { JsonWebToken.encode({user_id: user.id}, (Time.zone.now + 24.hours.to_i) ) } + let(:valid_headers) { {'x-token': token} } + + before do + request.headers.merge!(valid_headers) + allow(JsonWebToken).to receive(:decode).and_return({ 'user_id' => user.id }) + end + + describe 'GET #index' do + it 'returns a success response' do + get :index + expect(response).to have_http_status(:ok) + end + + it 'returns all posts' do + get :index + expect(JSON.parse(response.body).size).to eq(Post.count) + end + end + + describe 'GET #show' do + context 'when the post exists' do + it 'returns a success response' do + get :show, params: { id: post_obj.to_param } + expect(response).to have_http_status(:ok) + end + + it 'returns the post' do + get :show, params: { id: post_obj.to_param } + expect(JSON.parse(response.body)['id']).to eq(post_obj.id) + end + end + + context 'when the post does not exist' do + it 'returns a not found response' do + get :show, params: { id: 0 } + expect(response).to have_http_status(:not_found) + end + end + end + + describe 'POST #create' do + context 'with valid params' do + it 'creates a new post' do + expect { + post :create, params: { post: valid_attributes } + }.to change(Post, :count).by(1) + end + + it 'returns a created response' do + post :create, params: { post: valid_attributes } + expect(response).to have_http_status(:created) + end + end + + context 'with invalid params' do + it 'does not create a new post' do + expect { + post :create, params: { post: invalid_attributes } + }.to change(Post, :count).by(0) + end + + it 'returns an unprocessable entity response' do + post :create, params: { post: invalid_attributes } + expect(response).to have_http_status(:unprocessable_entity) + end + end + end + + describe 'PATCH/PUT #update' do + context 'with valid params' do + let(:new_attributes) { { title: 'Updated Title' } } + + it 'updates the requested post' do + put :update, params: { id: post_obj.id, post: new_attributes } + post_obj.reload + expect(post_obj.title).to eq('Updated Title') + end + + it 'returns a success response' do + put :update, params: { id: post_obj.to_param, post: new_attributes } + expect(response).to have_http_status(:ok) + end + end + + context 'with invalid params' do + it 'returns an unprocessable entity response' do + put :update, params: { id: post_obj.to_param, post: invalid_attributes } + expect(response).to have_http_status(:unprocessable_entity) + end + end + end + + describe 'DELETE #destroy' do + it 'destroys the requested post' do + expect { + delete :destroy, params: { id: post_obj.to_param } + }.to change(Post, :count).by(-1) + end + + it 'returns a no content response' do + delete :destroy, params: { id: post_obj.to_param } + expect(response).to have_http_status(:ok) + end + end +end diff --git a/spec/controllers/api/v1/users_controller_spec.rb b/spec/controllers/api/v1/users_controller_spec.rb index ffec178..c9781ab 100644 --- a/spec/controllers/api/v1/users_controller_spec.rb +++ b/spec/controllers/api/v1/users_controller_spec.rb @@ -58,7 +58,7 @@ it 'returns a created response' do post :create, params: valid_attributes - expect(response).to have_http_status(:created) + expect(response).to have_http_status(200) end end @@ -131,7 +131,7 @@ it 'returns a no content response' do delete :destroy, params: { id: user.to_param } - expect(response).to have_http_status(:no_content) + expect(response).to have_http_status(200) end context 'when the user does not exist' do diff --git a/spec/factories.rb b/spec/factories.rb index cb1f44c..ccb0a1b 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,5 +1,17 @@ require 'faker' FactoryBot.define do + factory :comment do + body { "MyString" } + user { nil } + commentable { nil } + end + + factory :post do + title { "MyString" } + description { "MyString" } + user { nil } + end + factory(:user) do email { Faker::Internet.email } username {Faker::Internet.username } diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb new file mode 100644 index 0000000..6e6497a --- /dev/null +++ b/spec/models/comment_spec.rb @@ -0,0 +1,34 @@ +# spec/models/comment_spec.rb +require 'rails_helper' + +RSpec.describe Comment, type: :model do + let(:user) { create(:user) } + let(:post) { create(:post, user: user) } + + describe 'associations' do + it { should belong_to(:user) } + it { should belong_to(:commentable) } + end + + describe 'validations' do + it 'is valid with valid attributes' do + comment = Comment.new(body: 'This is a comment', user: user, commentable: post) + expect(comment).to be_valid + end + + it 'is not valid without a body' do + comment = Comment.new(body: nil, user: user, commentable: post) + expect(comment).not_to be_valid + end + + it 'is not valid without a user' do + comment = Comment.new(body: 'This is a comment', user: nil, commentable: post) + expect(comment).not_to be_valid + end + + it 'is not valid without a post' do + comment = Comment.new(body: 'This is a comment', user: user, commentable: nil) + expect(comment).not_to be_valid + end + end +end diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb new file mode 100644 index 0000000..d8c144b --- /dev/null +++ b/spec/models/post_spec.rb @@ -0,0 +1,39 @@ +# spec/models/post_spec.rb +require 'rails_helper' + +RSpec.describe Post, type: :model do + let(:user) { create(:user) } + let(:valid_attributes) { { title: 'Sample Title', description: 'Sample Description', user: user } } + + context 'validations' do + it 'is valid with valid attributes' do + post = Post.new(valid_attributes) + expect(post).to be_valid + end + + it 'is invalid without a user' do + post = Post.new(valid_attributes.except(:user)) + expect(post).not_to be_valid + expect(post.errors[:user]).to include('must exist') + end + + it 'is invalid without a title' do + post = Post.new(valid_attributes.except(:title)) + expect(post).not_to be_valid + expect(post.errors[:title]).to include("can't be blank") + end + + it 'is invalid without a description' do + post = Post.new(valid_attributes.except(:description)) + expect(post).not_to be_valid + expect(post.errors[:description]).to include("can't be blank") + end + end + + context 'associations' do + it 'belongs to a user' do + assoc = Post.reflect_on_association(:user) + expect(assoc.macro).to eq :belongs_to + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 66a4c5d..eb0095f 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -66,3 +66,10 @@ # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") end + +Shoulda::Matchers.configure do |config| + config.integrate do |with| + with.test_framework :rspec + with.library :rails + end +end \ No newline at end of file diff --git a/spec/requests/comments_spec.rb b/spec/requests/comments_spec.rb new file mode 100644 index 0000000..df1606d --- /dev/null +++ b/spec/requests/comments_spec.rb @@ -0,0 +1,105 @@ +require 'rails_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to test the controller code that +# was generated by Rails when you ran the scaffold generator. +# +# It assumes that the implementation code is generated by the rails scaffold +# generator. If you are using any extension libraries to generate different +# controller code, this generated spec may or may not pass. +# +# It only uses APIs available in rails and/or rspec-rails. There are a number +# of tools you can use to make these specs even more expressive, but we're +# sticking to rails and rspec-rails APIs to keep things simple and stable. + +RSpec.describe "/comments", type: :request do + let(:user) { create(:user) } + let(:post_obj) { create(:post, user: user) } + let(:valid_attributes) { { body: 'Sample Comment' } } + let(:invalid_attributes) { { body: ''} } + let!(:comment) { create(:comment, commentable: post_obj, user: user) } + let(:valid_headers) { {'x-token': JsonWebToken.encode({user_id: user.id}, (Time.zone.now + 24.hours.to_i) )} } + let(:new_attributes) { { body: 'Sample Comment Update' } } + + describe "GET /index" do + it "renders a successful response" do + get api_v1_post_comments_url(post_id: post_obj.id), headers: valid_headers, as: :json + expect(response).to be_successful + end + end + + describe "GET /show" do + it "renders a successful response" do + get api_v1_post_comment_path(post_id: post_obj.id, id: comment.id), headers: valid_headers, as: :json + expect(response).to be_successful + end + end + + describe "POST /create" do + context "with valid parameters" do + it 'creates a new Comment' do + expect { + post api_v1_post_comments_path(post_id: post_obj.id), params: { comment: valid_attributes }, headers: valid_headers, as: :json + }.to change(Comment, :count).by(1) + end + + it "renders a JSON response with the new comment" do + post api_v1_post_comments_url(post_id: post_obj.id), params: { comment: valid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:created) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + + context "with invalid parameters" do + it "does not create a new Comment" do + expect { + post api_v1_post_comments_url(post_id: post_obj.id), + params: { comment: invalid_attributes }, as: :json + }.to change(Comment, :count).by(0) + end + + it "renders a JSON response with errors for the new comment" do + post api_v1_post_comments_url(post_id: post_obj.id), + params: { comment: invalid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + end + + describe "PATCH /update" do + context "with valid parameters" do + + it "updates the requested comment" do + patch api_v1_post_comment_url(post_id: post_obj.id, id: comment.id), + params: { comment: new_attributes }, headers: valid_headers, as: :json + comment.reload + expect(comment.body).to match(new_attributes[:body]) + end + + it "renders a JSON response with the comment" do + patch api_v1_post_comment_url(post_id: post_obj.id, id: comment.id), + params: { comment: new_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:ok) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + + context "with invalid parameters" do + it "renders a JSON response with errors for the comment" do + patch api_v1_post_comment_url(post_id: post_obj.id, id: comment.id), + params: { comment: invalid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + end + + describe "DELETE /destroy" do + it "destroys the requested comment" do + expect { + delete api_v1_post_comment_url(post_id: post_obj.id, id: comment.id), headers: valid_headers, as: :json + }.to change(Comment, :count).by(-1) + end + end +end diff --git a/spec/requests/posts_spec.rb b/spec/requests/posts_spec.rb new file mode 100644 index 0000000..bac886f --- /dev/null +++ b/spec/requests/posts_spec.rb @@ -0,0 +1,110 @@ +require 'rails_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to test the controller code that +# was generated by Rails when you ran the scaffold generator. +# +# It assumes that the implementation code is generated by the rails scaffold +# generator. If you are using any extension libraries to generate different +# controller code, this generated spec may or may not pass. +# +# It only uses APIs available in rails and/or rspec-rails. There are a number +# of tools you can use to make these specs even more expressive, but we're +# sticking to rails and rspec-rails APIs to keep things simple and stable. + +RSpec.describe "/posts", type: :request do + # This should return the minimal set of attributes required to create a valid + # Post. As you add validations to Post, be sure to + # adjust the attributes here as well. + let(:user) { create(:user) } + let(:post_obj) {create(:post, user_id: user.id)} + let(:valid_attributes) { { title: 'Sample Title', description: 'Sample Description' } } + let(:invalid_attributes) { { title: '', description: '' } } + let(:token) { JsonWebToken.encode({user_id: user.id}, (Time.zone.now + 24.hours.to_i) ) } + let(:valid_headers) { {'x-token': token} } + let(:new_attributes) { { title: 'Sample Title Update' } } + + describe "GET /index" do + it "renders a successful response" do + get api_v1_posts_path, headers: valid_headers, as: :json + expect(response).to be_successful + end + end + + describe "GET /show" do + it "renders a successful response" do + get api_v1_posts_path(post_obj), headers: valid_headers, as: :json + expect(response).to be_successful + end + end + + describe "POST /create" do + context "with valid parameters" do + it "creates a new Post" do + expect { + post api_v1_posts_path, + params: { post: valid_attributes }, headers: valid_headers, as: :json + }.to change(Post, :count).by(1) + end + + it "renders a JSON response with the new post" do + post api_v1_posts_path, + params: { post: valid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:created) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + + context "with invalid parameters" do + it "does not create a new Post" do + expect { + post api_v1_posts_path, + params: { post: invalid_attributes }, as: :json + }.to change(Post, :count).by(0) + end + + it "renders a JSON response with errors for the new post" do + post api_v1_posts_path, + params: { post: invalid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + end + + describe "PATCH /update" do + context "with valid parameters" do + + it "updates the requested post" do + patch api_v1_post_path(post_obj), + params: { post: new_attributes }, headers: valid_headers, as: :json + post_obj.reload + expect(post_obj.title).to match(new_attributes[:title]) + end + + it "renders a JSON response with the post" do + patch api_v1_post_path(post_obj), + params: { post: new_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:ok) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + + context "with invalid parameters" do + it "renders a JSON response with errors for the post" do + patch api_v1_post_path(post_obj), + params: { post: invalid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + end + + describe "DELETE /destroy" do + it "destroys the requested post" do + expect { + delete api_v1_post_path(post_obj), headers: valid_headers, as: :json + }.to change(Post, :count).by(0) + end + end +end diff --git a/spec/routing/application_routing_spec.rb b/spec/routing/application_routing_spec.rb new file mode 100644 index 0000000..1b3f553 --- /dev/null +++ b/spec/routing/application_routing_spec.rb @@ -0,0 +1,7 @@ +# This is from route_mechanic which tests your all routes +RSpec.describe 'Rails.application', type: :routing do + + it "fails if application does not have valid routes" do + # expect(Rails.application).to have_valid_routes + end +end \ No newline at end of file