kirushik/critical_chain

View on GitHub
app/controllers/estimation_items_controller.rb

Summary

Maintainability
A
1 hr
Test Coverage

Method has too many lines. [28/10]
Open

  def update
    @estimation = Estimation.find(params[:estimation_id]).decorate
    @estimation_item = EstimationItem.find(params[:id])

    authorize @estimation, :update?

Checks if the length of a method exceeds some maximum value. Comment lines can optionally be allowed. The maximum allowed length is configurable.

You can set constructs you want to fold with CountAsOne. Available are: 'array', 'hash', 'heredoc', and 'method_call'. Each construct will be counted as one line regardless of its actual size.

NOTE: The ExcludedMethods and IgnoredMethods configuration is deprecated and only kept for backwards compatibility. Please use AllowedMethods and AllowedPatterns instead. By default, there are no methods to allowed.

Example: CountAsOne: ['array', 'heredoc', 'method_call']

def m
  array = [       # +1
    1,
    2
  ]

  hash = {        # +3
    key: 'value'
  }

  <<~HEREDOC      # +1
    Heredoc
    content.
  HEREDOC

  foo(            # +1
    1,
    2
  )
end               # 6 points

Method update has 28 lines of code (exceeds 25 allowed). Consider refactoring.
Open

  def update
    @estimation = Estimation.find(params[:estimation_id]).decorate
    @estimation_item = EstimationItem.find(params[:id])

    authorize @estimation, :update?
Severity: Minor
Found in app/controllers/estimation_items_controller.rb - About 1 hr to fix

    EstimationItemsController#create has approx 6 statements
    Open

      def create

    A method with Too Many Statements is any method that has a large number of lines.

    Too Many Statements warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements counts +1 for every simple statement in a method and +1 for every statement within a control structure (if, else, case, when, for, while, until, begin, rescue) but it doesn't count the control structure itself.

    So the following method would score +6 in Reek's statement-counting algorithm:

    def parse(arg, argv, &error)
      if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
        return nil, block, nil                                         # +1
      end
      opt = (val = parse_arg(val, &error))[1]                          # +2
      val = conv_arg(*val)                                             # +3
      if opt and !arg
        argv.shift                                                     # +4
      else
        val[0] = nil                                                   # +5
      end
      val                                                              # +6
    end

    (You might argue that the two assignments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)

    EstimationItemsController#update has approx 10 statements
    Open

      def update

    A method with Too Many Statements is any method that has a large number of lines.

    Too Many Statements warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements counts +1 for every simple statement in a method and +1 for every statement within a control structure (if, else, case, when, for, while, until, begin, rescue) but it doesn't count the control structure itself.

    So the following method would score +6 in Reek's statement-counting algorithm:

    def parse(arg, argv, &error)
      if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
        return nil, block, nil                                         # +1
      end
      opt = (val = parse_arg(val, &error))[1]                          # +2
      val = conv_arg(*val)                                             # +3
      if opt and !arg
        argv.shift                                                     # +4
      else
        val[0] = nil                                                   # +5
      end
      val                                                              # +6
    end

    (You might argue that the two assignments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)

    EstimationItemsController tests 'request.xhr?' at least 3 times
    Open

        redirect_to estimation_path(@estimation) unless request.xhr?
      end
    
      def destroy
        @estimation = Estimation.find(params[:estimation_id]).decorate

    Repeated Conditional is a special case of Simulated Polymorphism. Basically it means you are checking the same value throughout a single class and take decisions based on this.

    Example

    Given

    class RepeatedConditionals
      attr_accessor :switch
    
      def repeat_1
        puts "Repeat 1!" if switch
      end
    
      def repeat_2
        puts "Repeat 2!" if switch
      end
    
      def repeat_3
        puts "Repeat 3!" if switch
      end
    end

    Reek would emit the following warning:

    test.rb -- 4 warnings:
      [5, 9, 13]:RepeatedConditionals tests switch at least 3 times (RepeatedConditional)

    If you get this warning then you are probably not using the right abstraction or even more probable, missing an additional abstraction.

    EstimationItemsController assumes too much for instance variable '@estimation_item'
    Open

    class EstimationItemsController < ApplicationController

    Classes should not assume that instance variables are set or present outside of the current class definition.

    Good:

    class Foo
      def initialize
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Good as well:

    class Foo
      def foo?
        bar == :foo
      end
    
      def bar
        @bar ||= :foo
      end
    end

    Bad:

    class Foo
      def go_foo!
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Example

    Running Reek on:

    class Dummy
      def test
        @ivar
      end
    end

    would report:

    [1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar

    Note that this example would trigger this smell warning as well:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        @omg
      end
    end

    The way to address the smell warning is that you should create an attr_reader to use @omg in the subclass and not access @omg directly like this:

    class Parent
      attr_reader :omg
    
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Directly accessing instance variables is considered a smell because it breaks encapsulation and makes it harder to reason about code.

    If you don't want to expose those methods as public API just make them private like this:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    
      private
      attr_reader :omg
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Current Support in Reek

    An instance variable must:

    • be set in the constructor
    • or be accessed through a method with lazy initialization / memoization.

    If not, Instance Variable Assumption will be reported.

    EstimationItemsController assumes too much for instance variable '@estimation'
    Open

    class EstimationItemsController < ApplicationController

    Classes should not assume that instance variables are set or present outside of the current class definition.

    Good:

    class Foo
      def initialize
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Good as well:

    class Foo
      def foo?
        bar == :foo
      end
    
      def bar
        @bar ||= :foo
      end
    end

    Bad:

    class Foo
      def go_foo!
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Example

    Running Reek on:

    class Dummy
      def test
        @ivar
      end
    end

    would report:

    [1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar

    Note that this example would trigger this smell warning as well:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        @omg
      end
    end

    The way to address the smell warning is that you should create an attr_reader to use @omg in the subclass and not access @omg directly like this:

    class Parent
      attr_reader :omg
    
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Directly accessing instance variables is considered a smell because it breaks encapsulation and makes it harder to reason about code.

    If you don't want to expose those methods as public API just make them private like this:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    
      private
      attr_reader :omg
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Current Support in Reek

    An instance variable must:

    • be set in the constructor
    • or be accessed through a method with lazy initialization / memoization.

    If not, Instance Variable Assumption will be reported.

    Assignment Branch Condition size for update is too high. [<4, 31, 2> 31.32/17]
    Open

      def update
        @estimation = Estimation.find(params[:estimation_id]).decorate
        @estimation_item = EstimationItem.find(params[:id])
    
        authorize @estimation, :update?

    Checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric and https://en.wikipedia.org/wiki/ABC_Software_Metric.

    Interpreting ABC size:

    • <= 17 satisfactory
    • 18..30 unsatisfactory
    • > 30 dangerous

    You can have repeated "attributes" calls count as a single "branch". For this purpose, attributes are any method with no argument; no attempt is meant to distinguish actual attr_reader from other methods.

    Example: CountRepeatedAttributes: false (default is true)

    # `model` and `current_user`, referenced 3 times each,
     # are each counted as only 1 branch each if
     # `CountRepeatedAttributes` is set to 'false'
    
     def search
       @posts = model.active.visible_by(current_user)
                 .search(params[:q])
       @posts = model.some_process(@posts, current_user)
       @posts = model.another_process(@posts, current_user)
    
       render 'pages/search/page'
     end

    This cop also takes into account AllowedMethods (defaults to []) And AllowedPatterns (defaults to [])

    Missing top-level documentation comment for class EstimationItemsController.
    Open

    class EstimationItemsController < ApplicationController

    Checks for missing top-level documentation of classes and modules. Classes with no body are exempt from the check and so are namespace modules - modules that have nothing in their bodies except classes, other modules, constant definitions or constant visibility declarations.

    The documentation requirement is annulled if the class or module has a #:nodoc: comment next to it. Likewise, #:nodoc: all does the same for all its children.

    Example:

    # bad
    class Person
      # ...
    end
    
    module Math
    end
    
    # good
    # Description/Explanation of Person class
    class Person
      # ...
    end
    
    # allowed
      # Class without body
      class Person
      end
    
      # Namespace - A namespace can be a class or a module
      # Containing a class
      module Namespace
        # Description/Explanation of Person class
        class Person
          # ...
        end
      end
    
      # Containing constant visibility declaration
      module Namespace
        class Private
        end
    
        private_constant :Private
      end
    
      # Containing constant definition
      module Namespace
        Public = Class.new
      end
    
      # Macro calls
      module Namespace
        extend Foo
      end

    Example: AllowedConstants: ['ClassMethods']

    # good
     module A
       module ClassMethods
         # ...
       end
      end

    Prefer string interpolation to string concatenation.
    Open

                    item: "#" + dom_id(@estimation_item),

    Checks for places where string concatenation can be replaced with string interpolation.

    The cop can autocorrect simple cases but will skip autocorrecting more complex cases where the resulting code would be harder to read. In those cases, it might be useful to extract statements to local variables or methods which you can then interpolate in a string.

    NOTE: When concatenation between two strings is broken over multiple lines, this cop does not register an offense; instead, Style/LineEndConcatenation will pick up the offense if enabled.

    Two modes are supported: 1. aggressive style checks and corrects all occurrences of + where either the left or right side of + is a string literal. 2. conservative style on the other hand, checks and corrects only if left side (receiver of + method call) is a string literal. This is useful when the receiver is some expression that returns string like Pathname instead of a string literal.

    Safety:

    This cop is unsafe in aggressive mode, as it cannot be guaranteed that the receiver is actually a string, which can result in a false positive.

    Example: Mode: aggressive (default)

    # bad
    email_with_name = user.name + ' <' + user.email + '>'
    Pathname.new('/') + 'test'
    
    # good
    email_with_name = "#{user.name} <#{user.email}>"
    email_with_name = format('%s <%s>', user.name, user.email)
    "#{Pathname.new('/')}test"
    
    # accepted, line-end concatenation
    name = 'First' +
      'Last'

    Example: Mode: conservative

    # bad
    'Hello' + user.name
    
    # good
    "Hello #{user.name}"
    user.name + '!!'
    Pathname.new('/') + 'test'

    Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.
    Open

                  sum: @estimation.sum,

    Checks the indentation of the first key in a hash literal where the opening brace and the first key are on separate lines. The other keys' indentations are handled by the HashAlignment cop.

    By default, Hash literals that are arguments in a method call with parentheses, and where the opening curly brace of the hash is on the same line as the opening parenthesis of the method call, shall have their first key indented one step (two spaces) more than the position inside the opening parenthesis.

    Other hash literals shall have their first key indented one step more than the start of the line where the opening curly brace is.

    This default style is called 'specialinsideparentheses'. Alternative styles are 'consistent' and 'align_braces'. Here are examples:

    Example: EnforcedStyle: specialinsideparentheses (default)

    # The `special_inside_parentheses` style enforces that the first key
    # in a hash literal where the opening brace and the first key are on
    # separate lines is indented one step (two spaces) more than the
    # position inside the opening parentheses.
    
    # bad
    hash = {
      key: :value
    }
    and_in_a_method_call({
      no: :difference
                         })
    takes_multi_pairs_hash(x: {
      a: 1,
      b: 2
    },
                           y: {
                             c: 1,
                             d: 2
                           })
    
    # good
    special_inside_parentheses
    hash = {
      key: :value
    }
    but_in_a_method_call({
                           its_like: :this
                         })
    takes_multi_pairs_hash(x: {
                             a: 1,
                             b: 2
                           },
                           y: {
                             c: 1,
                             d: 2
                           })

    Example: EnforcedStyle: consistent

    # The `consistent` style enforces that the first key in a hash
    # literal where the opening brace and the first key are on
    # separate lines is indented the same as a hash literal which is not
    # defined inside a method call.
    
    # bad
    hash = {
      key: :value
    }
    but_in_a_method_call({
                           its_like: :this
                          })
    
    # good
    hash = {
      key: :value
    }
    and_in_a_method_call({
      no: :difference
    })

    Example: EnforcedStyle: align_braces

    # The `align_brackets` style enforces that the opening and closing
    # braces are indented to the same position.
    
    # bad
    and_now_for_something = {
                              completely: :different
    }
    takes_multi_pairs_hash(x: {
      a: 1,
      b: 2
    },
                            y: {
                                 c: 1,
                                 d: 2
                               })
    
    # good
    and_now_for_something = {
                              completely: :different
                            }
    takes_multi_pairs_hash(x: {
                                a: 1,
                                b: 2
                              },
                           y: {
                                c: 1,
                                d: 2
                              })

    Avoid comma after the last item of a hash.
    Open

                  },

    Checks for trailing comma in hash literals. The configuration options are:

    • consistent_comma: Requires a comma after the last item of all non-empty, multiline hash literals.
    • comma: Requires a comma after the last item in a hash, but only when each item is on its own line.
    • no_comma: Does not require a comma after the last item in a hash

    Example: EnforcedStyleForMultiline: consistent_comma

    # bad
    a = { foo: 1, bar: 2, }
    
    # good
    a = { foo: 1, bar: 2 }
    
    # good
    a = {
      foo: 1, bar: 2,
      qux: 3,
    }
    
    # good
    a = {
      foo: 1, bar: 2, qux: 3,
    }
    
    # good
    a = {
      foo: 1,
      bar: 2,
    }

    Example: EnforcedStyleForMultiline: comma

    # bad
    a = { foo: 1, bar: 2, }
    
    # good
    a = { foo: 1, bar: 2 }
    
    # bad
    a = {
      foo: 1, bar: 2,
      qux: 3,
    }
    
    # good
    a = {
      foo: 1, bar: 2,
      qux: 3
    }
    
    # bad
    a = {
      foo: 1, bar: 2, qux: 3,
    }
    
    # good
    a = {
      foo: 1, bar: 2, qux: 3
    }
    
    # good
    a = {
      foo: 1,
      bar: 2,
    }

    Example: EnforcedStyleForMultiline: no_comma (default)

    # bad
    a = { foo: 1, bar: 2, }
    
    # good
    a = {
      foo: 1,
      bar: 2
    }

    Avoid comma after the last item of a hash.
    Open

                    total: @estimation_item.total,

    Checks for trailing comma in hash literals. The configuration options are:

    • consistent_comma: Requires a comma after the last item of all non-empty, multiline hash literals.
    • comma: Requires a comma after the last item in a hash, but only when each item is on its own line.
    • no_comma: Does not require a comma after the last item in a hash

    Example: EnforcedStyleForMultiline: consistent_comma

    # bad
    a = { foo: 1, bar: 2, }
    
    # good
    a = { foo: 1, bar: 2 }
    
    # good
    a = {
      foo: 1, bar: 2,
      qux: 3,
    }
    
    # good
    a = {
      foo: 1, bar: 2, qux: 3,
    }
    
    # good
    a = {
      foo: 1,
      bar: 2,
    }

    Example: EnforcedStyleForMultiline: comma

    # bad
    a = { foo: 1, bar: 2, }
    
    # good
    a = { foo: 1, bar: 2 }
    
    # bad
    a = {
      foo: 1, bar: 2,
      qux: 3,
    }
    
    # good
    a = {
      foo: 1, bar: 2,
      qux: 3
    }
    
    # bad
    a = {
      foo: 1, bar: 2, qux: 3,
    }
    
    # good
    a = {
      foo: 1, bar: 2, qux: 3
    }
    
    # good
    a = {
      foo: 1,
      bar: 2,
    }

    Example: EnforcedStyleForMultiline: no_comma (default)

    # bad
    a = { foo: 1, bar: 2, }
    
    # good
    a = {
      foo: 1,
      bar: 2
    }

    Align the keys of a hash literal if they span more than one line.
    Open

                       msg: @estimation_item.errors.full_messages.first,

    Check that the keys, separators, and values of a multi-line hash literal are aligned according to configuration. The configuration options are:

    • key (left align keys, one space before hash rockets and values)
    • separator (align hash rockets and colons, right align keys)
    • table (left align keys, hash rockets, and values)

    The treatment of hashes passed as the last argument to a method call can also be configured. The options are:

    • always_inspect
    • always_ignore
    • ignore_implicit (without curly braces)

    Alternatively you can specify multiple allowed styles. That's done by passing a list of styles to EnforcedStyles.

    Example: EnforcedHashRocketStyle: key (default)

    # bad
    {
      :foo => bar,
       :ba => baz
    }
    {
      :foo => bar,
      :ba  => baz
    }
    
    # good
    {
      :foo => bar,
      :ba => baz
    }

    Example: EnforcedHashRocketStyle: separator

    # bad
    {
      :foo => bar,
      :ba => baz
    }
    {
      :foo => bar,
      :ba  => baz
    }
    
    # good
    {
      :foo => bar,
       :ba => baz
    }

    Example: EnforcedHashRocketStyle: table

    # bad
    {
      :foo => bar,
       :ba => baz
    }
    
    # good
    {
      :foo => bar,
      :ba  => baz
    }

    Example: EnforcedColonStyle: key (default)

    # bad
    {
      foo: bar,
       ba: baz
    }
    {
      foo: bar,
      ba:  baz
    }
    
    # good
    {
      foo: bar,
      ba: baz
    }

    Example: EnforcedColonStyle: separator

    # bad
    {
      foo: bar,
      ba: baz
    }
    
    # good
    {
      foo: bar,
       ba: baz
    }

    Example: EnforcedColonStyle: table

    # bad
    {
      foo: bar,
      ba: baz
    }
    
    # good
    {
      foo: bar,
      ba:  baz
    }

    Example: EnforcedLastArgumentHashStyle: always_inspect (default)

    # Inspect both implicit and explicit hashes.
    
    # bad
    do_something(foo: 1,
      bar: 2)
    
    # bad
    do_something({foo: 1,
      bar: 2})
    
    # good
    do_something(foo: 1,
                 bar: 2)
    
    # good
    do_something(
      foo: 1,
      bar: 2
    )
    
    # good
    do_something({foo: 1,
                  bar: 2})
    
    # good
    do_something({
      foo: 1,
      bar: 2
    })

    Example: EnforcedLastArgumentHashStyle: always_ignore

    # Ignore both implicit and explicit hashes.
    
    # good
    do_something(foo: 1,
      bar: 2)
    
    # good
    do_something({foo: 1,
      bar: 2})

    Example: EnforcedLastArgumentHashStyle: ignore_implicit

    # Ignore only implicit hashes.
    
    # bad
    do_something({foo: 1,
      bar: 2})
    
    # good
    do_something(foo: 1,
      bar: 2)

    Example: EnforcedLastArgumentHashStyle: ignore_explicit

    # Ignore only explicit hashes.
    
    # bad
    do_something(foo: 1,
      bar: 2)
    
    # good
    do_something({foo: 1,
      bar: 2})

    Align the keys of a hash literal if they span more than one line.
    Open

                       additionalValues: {
                  sum: @estimation.sum,
                  buffer: @estimation.buffer,
                  total: @estimation.total,
                  actual_sum: @estimation.actual_sum,

    Check that the keys, separators, and values of a multi-line hash literal are aligned according to configuration. The configuration options are:

    • key (left align keys, one space before hash rockets and values)
    • separator (align hash rockets and colons, right align keys)
    • table (left align keys, hash rockets, and values)

    The treatment of hashes passed as the last argument to a method call can also be configured. The options are:

    • always_inspect
    • always_ignore
    • ignore_implicit (without curly braces)

    Alternatively you can specify multiple allowed styles. That's done by passing a list of styles to EnforcedStyles.

    Example: EnforcedHashRocketStyle: key (default)

    # bad
    {
      :foo => bar,
       :ba => baz
    }
    {
      :foo => bar,
      :ba  => baz
    }
    
    # good
    {
      :foo => bar,
      :ba => baz
    }

    Example: EnforcedHashRocketStyle: separator

    # bad
    {
      :foo => bar,
      :ba => baz
    }
    {
      :foo => bar,
      :ba  => baz
    }
    
    # good
    {
      :foo => bar,
       :ba => baz
    }

    Example: EnforcedHashRocketStyle: table

    # bad
    {
      :foo => bar,
       :ba => baz
    }
    
    # good
    {
      :foo => bar,
      :ba  => baz
    }

    Example: EnforcedColonStyle: key (default)

    # bad
    {
      foo: bar,
       ba: baz
    }
    {
      foo: bar,
      ba:  baz
    }
    
    # good
    {
      foo: bar,
      ba: baz
    }

    Example: EnforcedColonStyle: separator

    # bad
    {
      foo: bar,
      ba: baz
    }
    
    # good
    {
      foo: bar,
       ba: baz
    }

    Example: EnforcedColonStyle: table

    # bad
    {
      foo: bar,
      ba: baz
    }
    
    # good
    {
      foo: bar,
      ba:  baz
    }

    Example: EnforcedLastArgumentHashStyle: always_inspect (default)

    # Inspect both implicit and explicit hashes.
    
    # bad
    do_something(foo: 1,
      bar: 2)
    
    # bad
    do_something({foo: 1,
      bar: 2})
    
    # good
    do_something(foo: 1,
                 bar: 2)
    
    # good
    do_something(
      foo: 1,
      bar: 2
    )
    
    # good
    do_something({foo: 1,
                  bar: 2})
    
    # good
    do_something({
      foo: 1,
      bar: 2
    })

    Example: EnforcedLastArgumentHashStyle: always_ignore

    # Ignore both implicit and explicit hashes.
    
    # good
    do_something(foo: 1,
      bar: 2)
    
    # good
    do_something({foo: 1,
      bar: 2})

    Example: EnforcedLastArgumentHashStyle: ignore_implicit

    # Ignore only implicit hashes.
    
    # bad
    do_something({foo: 1,
      bar: 2})
    
    # good
    do_something(foo: 1,
      bar: 2)

    Example: EnforcedLastArgumentHashStyle: ignore_explicit

    # Ignore only explicit hashes.
    
    # bad
    do_something(foo: 1,
      bar: 2)
    
    # good
    do_something({foo: 1,
      bar: 2})

    Missing frozen string literal comment.
    Open

    # == Schema Information

    Helps you transition from mutable string literals to frozen string literals. It will add the # frozen_string_literal: true magic comment to the top of files to enable frozen string literals. Frozen string literals may be default in future Ruby. The comment will be added below a shebang and encoding comment. The frozen string literal comment is only valid in Ruby 2.3+.

    Note that the cop will accept files where the comment exists but is set to false instead of true.

    To require a blank line after this comment, please see Layout/EmptyLineAfterMagicComment cop.

    Safety:

    This cop's autocorrection is unsafe since any strings mutations will change from being accepted to raising FrozenError, as all strings will become frozen by default, and will need to be manually refactored.

    Example: EnforcedStyle: always (default)

    # The `always` style 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.
    # bad
    module Bar
      # ...
    end
    
    # good
    # frozen_string_literal: true
    
    module Bar
      # ...
    end
    
    # good
    # frozen_string_literal: false
    
    module Bar
      # ...
    end

    Example: EnforcedStyle: never

    # The `never` will enforce that the frozen string literal comment does
    # not exist in a file.
    # bad
    # frozen_string_literal: true
    
    module Baz
      # ...
    end
    
    # good
    module Baz
      # ...
    end

    Example: EnforcedStyle: always_true

    # The `always_true` style enforces that the frozen string literal
    # comment is set to `true`. This is a stricter option than `always`
    # and forces projects to use frozen string literals.
    # bad
    # frozen_string_literal: false
    
    module Baz
      # ...
    end
    
    # bad
    module Baz
      # ...
    end
    
    # good
    # frozen_string_literal: true
    
    module Bar
      # ...
    end

    Indent the right brace the same as the start of the line where the left brace is.
    Open

                } }

    Checks the indentation of the first key in a hash literal where the opening brace and the first key are on separate lines. The other keys' indentations are handled by the HashAlignment cop.

    By default, Hash literals that are arguments in a method call with parentheses, and where the opening curly brace of the hash is on the same line as the opening parenthesis of the method call, shall have their first key indented one step (two spaces) more than the position inside the opening parenthesis.

    Other hash literals shall have their first key indented one step more than the start of the line where the opening curly brace is.

    This default style is called 'specialinsideparentheses'. Alternative styles are 'consistent' and 'align_braces'. Here are examples:

    Example: EnforcedStyle: specialinsideparentheses (default)

    # The `special_inside_parentheses` style enforces that the first key
    # in a hash literal where the opening brace and the first key are on
    # separate lines is indented one step (two spaces) more than the
    # position inside the opening parentheses.
    
    # bad
    hash = {
      key: :value
    }
    and_in_a_method_call({
      no: :difference
                         })
    takes_multi_pairs_hash(x: {
      a: 1,
      b: 2
    },
                           y: {
                             c: 1,
                             d: 2
                           })
    
    # good
    special_inside_parentheses
    hash = {
      key: :value
    }
    but_in_a_method_call({
                           its_like: :this
                         })
    takes_multi_pairs_hash(x: {
                             a: 1,
                             b: 2
                           },
                           y: {
                             c: 1,
                             d: 2
                           })

    Example: EnforcedStyle: consistent

    # The `consistent` style enforces that the first key in a hash
    # literal where the opening brace and the first key are on
    # separate lines is indented the same as a hash literal which is not
    # defined inside a method call.
    
    # bad
    hash = {
      key: :value
    }
    but_in_a_method_call({
                           its_like: :this
                          })
    
    # good
    hash = {
      key: :value
    }
    and_in_a_method_call({
      no: :difference
    })

    Example: EnforcedStyle: align_braces

    # The `align_brackets` style enforces that the opening and closing
    # braces are indented to the same position.
    
    # bad
    and_now_for_something = {
                              completely: :different
    }
    takes_multi_pairs_hash(x: {
      a: 1,
      b: 2
    },
                            y: {
                                 c: 1,
                                 d: 2
                               })
    
    # good
    and_now_for_something = {
                              completely: :different
                            }
    takes_multi_pairs_hash(x: {
                                a: 1,
                                b: 2
                              },
                           y: {
                                c: 1,
                                d: 2
                              })

    Prefer single-quoted strings when you don't need string interpolation or special symbols.
    Open

                    item: "#" + dom_id(@estimation_item),

    Checks if uses of quotes match the configured preference.

    Example: EnforcedStyle: single_quotes (default)

    # bad
    "No special symbols"
    "No string interpolation"
    "Just text"
    
    # good
    'No special symbols'
    'No string interpolation'
    'Just text'
    "Wait! What's #{this}!"

    Example: EnforcedStyle: double_quotes

    # bad
    'Just some text'
    'No special chars or interpolation'
    
    # good
    "Just some text"
    "No special chars or interpolation"
    "Every string in #{project} uses double_quotes"

    There are no issues that match your filters.

    Category
    Status