tulul/lycantulul_bot

View on GitHub
lib/lycantulul_bot/lycantulul/statistics.rb

Summary

Maintainability
C
7 hrs
Test Coverage

Assignment Branch Condition size for get_stats is too high. [170.7/15]
Open

    def self.get_stats(stat)
      stats = ["Statistik #{stat}"]
      case stat
      when '/stats'
        stats << "Current stats:"

This cop 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

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

    def self.get_stats(stat)
      stats = ["Statistik #{stat}"]
      case stat
      when '/stats'
        stats << "Current stats:"

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

Method get_stats has 69 lines of code (exceeds 25 allowed). Consider refactoring.
Open

    def self.get_stats(stat)
      stats = ["Statistik #{stat}"]
      case stat
      when '/stats'
        stats << "Current stats:"
Severity: Major
Found in lib/lycantulul_bot/lycantulul/statistics.rb - About 2 hrs to fix

    Cyclomatic complexity for get_stats is too high. [10/6]
    Open

        def self.get_stats(stat)
          stats = ["Statistik #{stat}"]
          case stat
          when '/stats'
            stats << "Current stats:"

    This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.

    An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.

    Method get_stats has a Cognitive Complexity of 11 (exceeds 5 allowed). Consider refactoring.
    Open

        def self.get_stats(stat)
          stats = ["Statistik #{stat}"]
          case stat
          when '/stats'
            stats << "Current stats:"
    Severity: Minor
    Found in lib/lycantulul_bot/lycantulul/statistics.rb - About 1 hr to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Similar blocks of code found in 3 locations. Consider refactoring.
    Open

            stats << "Last 24|4|1 hours: #{Lycantulul::Game.where(:created_at.gte => 24.hours.ago).count} | #{Lycantulul::Game.where(:created_at.gte => 4.hours.ago).count} | #{Lycantulul::Game.where(:created_at.gte => 1.hour.ago).count}"
    Severity: Major
    Found in lib/lycantulul_bot/lycantulul/statistics.rb and 2 other locations - About 55 mins to fix
    lib/lycantulul_bot/lycantulul/statistics.rb on lines 12..12
    lib/lycantulul_bot/lycantulul/statistics.rb on lines 16..16

    Duplicated Code

    Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

    Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

    When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

    Tuning

    This issue has a mass of 38.

    We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

    The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

    If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

    See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

    Refactorings

    Further Reading

    Similar blocks of code found in 3 locations. Consider refactoring.
    Open

            stats << "Last 24|4|1 hours: #{Lycantulul::Group.where(:created_at.gte => 24.hours.ago).count} | #{Lycantulul::Group.where(:created_at.gte => 4.hours.ago).count} | #{Lycantulul::Group.where(:created_at.gte => 1.hour.ago).count}"
    Severity: Major
    Found in lib/lycantulul_bot/lycantulul/statistics.rb and 2 other locations - About 55 mins to fix
    lib/lycantulul_bot/lycantulul/statistics.rb on lines 12..12
    lib/lycantulul_bot/lycantulul/statistics.rb on lines 19..19

    Duplicated Code

    Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

    Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

    When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

    Tuning

    This issue has a mass of 38.

    We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

    The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

    If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

    See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

    Refactorings

    Further Reading

    Similar blocks of code found in 3 locations. Consider refactoring.
    Open

            stats << "Last 24|4|1 hours: #{Lycantulul::RegisteredPlayer.where(:created_at.gte => 24.hours.ago).count} | #{Lycantulul::RegisteredPlayer.where(:created_at.gte => 4.hours.ago).count} | #{Lycantulul::RegisteredPlayer.where(:created_at.gte => 1.hour.ago).count}"
    Severity: Major
    Found in lib/lycantulul_bot/lycantulul/statistics.rb and 2 other locations - About 55 mins to fix
    lib/lycantulul_bot/lycantulul/statistics.rb on lines 16..16
    lib/lycantulul_bot/lycantulul/statistics.rb on lines 19..19

    Duplicated Code

    Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

    Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

    When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

    Tuning

    This issue has a mass of 38.

    We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

    The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

    If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

    See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

    Refactorings

    Further Reading

    Similar blocks of code found in 2 locations. Consider refactoring.
    Open

            stats << "Villager victory: #{v = Lycantulul::Group.all.sum(&:village_victory)} (#{"%.2f\%" % (v * 100.0 / g)})"
    Severity: Minor
    Found in lib/lycantulul_bot/lycantulul/statistics.rb and 1 other location - About 20 mins to fix
    lib/lycantulul_bot/lycantulul/statistics.rb on lines 22..22

    Duplicated Code

    Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

    Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

    When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

    Tuning

    This issue has a mass of 21.

    We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

    The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

    If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

    See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

    Refactorings

    Further Reading

    Similar blocks of code found in 2 locations. Consider refactoring.
    Open

            stats << "Werewolf victory: #{w = Lycantulul::Group.all.sum(&:werewolf_victory)} (#{"%.2f\%" % (w * 100.0 / g)})"
    Severity: Minor
    Found in lib/lycantulul_bot/lycantulul/statistics.rb and 1 other location - About 20 mins to fix
    lib/lycantulul_bot/lycantulul/statistics.rb on lines 23..23

    Duplicated Code

    Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

    Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

    When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

    Tuning

    This issue has a mass of 21.

    We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

    The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

    If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

    See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

    Refactorings

    Further Reading

    Favor format over String#%.
    Open

            stats << "Werewolf victory: #{w = Lycantulul::Group.all.sum(&:werewolf_victory)} (#{"%.2f\%" % (w * 100.0 / g)})"

    This cop enforces the use of a single string formatting utility. Valid options include Kernel#format, Kernel#sprintf and String#%.

    The detection of String#% cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal.

    Example: EnforcedStyle: format(default)

    # bad
    puts sprintf('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts format('%10s', 'hoge')

    Example: EnforcedStyle: sprintf

    # bad
    puts format('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts sprintf('%10s', 'hoge')

    Example: EnforcedStyle: percent

    # bad
    puts format('%10s', 'hoge')
    puts sprintf('%10s', 'hoge')
    
    # good
    puts '%10s' % 'hoge'

    Line is too long. [89/80]
    Open

              stats << "Round #{g.round}, #{g.living_players.count}/#{g.players.count} alive"

    Favor format over String#%.
    Open

            stats << "Villager victory: #{v = Lycantulul::Group.all.sum(&:village_victory)} (#{"%.2f\%" % (v * 100.0 / g)})"

    This cop enforces the use of a single string formatting utility. Valid options include Kernel#format, Kernel#sprintf and String#%.

    The detection of String#% cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal.

    Example: EnforcedStyle: format(default)

    # bad
    puts sprintf('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts format('%10s', 'hoge')

    Example: EnforcedStyle: sprintf

    # bad
    puts format('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts sprintf('%10s', 'hoge')

    Example: EnforcedStyle: percent

    # bad
    puts format('%10s', 'hoge')
    puts sprintf('%10s', 'hoge')
    
    # good
    puts '%10s' % 'hoge'

    Favor format over String#%.
    Open

              stats << "#{"%3d" % x.game} #{x.title.gsub(/[<>]/, '') rescue ''}"

    This cop enforces the use of a single string formatting utility. Valid options include Kernel#format, Kernel#sprintf and String#%.

    The detection of String#% cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal.

    Example: EnforcedStyle: format(default)

    # bad
    puts sprintf('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts format('%10s', 'hoge')

    Example: EnforcedStyle: sprintf

    # bad
    puts format('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts sprintf('%10s', 'hoge')

    Example: EnforcedStyle: percent

    # bad
    puts format('%10s', 'hoge')
    puts sprintf('%10s', 'hoge')
    
    # good
    puts '%10s' % 'hoge'

    Shadowing outer local variable - v.
    Open

            tot.sort_by{ |_, v| v }.reverse.each do |role, count|

    This cop looks for use of the same name as outer local variables for block arguments or block local variables. This is a mimic of the warning "shadowing outer local variable - foo" from ruby -cw.

    Example:

    # bad
    
    def some_method
      foo = 1
    
      2.times do |foo| # shadowing outer `foo`
        do_something(foo)
      end
    end

    Example:

    # good
    
    def some_method
      foo = 1
    
      2.times do |bar|
        do_something(bar)
      end
    end

    Line is too long. [95/80]
    Open

            stats << "Blocking players: #{Lycantulul::RegisteredPlayer.where(blocked: true).count}"

    Line is too long. [88/80]
    Open

              stats << "N|D|V time: #{g.night_time}, #{g.discussion_time}, #{g.voting_time}"

    Prefer single-quoted strings inside interpolations.
    Open

              stats << "<code>#{"%5.2f%" % (count * 100.0 / sum)}</code> #{g.get_role(g.class.const_get(role.upcase))}"

    This cop checks that quotes inside the string interpolation match the configured preference.

    Example: EnforcedStyle: single_quotes (default)

    # bad
    result = "Tests #{success ? "PASS" : "FAIL"}"
    
    # good
    result = "Tests #{success ? 'PASS' : 'FAIL'}"

    Example: EnforcedStyle: double_quotes

    # bad
    result = "Tests #{success ? 'PASS' : 'FAIL'}"
    
    # good
    result = "Tests #{success ? "PASS" : "FAIL"}"

    Shadowing outer local variable - g.
    Open

            Lycantulul::Game.running.each do |g|

    This cop looks for use of the same name as outer local variables for block arguments or block local variables. This is a mimic of the warning "shadowing outer local variable - foo" from ruby -cw.

    Example:

    # bad
    
    def some_method
      foo = 1
    
      2.times do |foo| # shadowing outer `foo`
        do_something(foo)
      end
    end

    Example:

    # good
    
    def some_method
      foo = 1
    
      2.times do |bar|
        do_something(bar)
      end
    end

    Space missing to the left of {.
    Open

            tot.sort_by{ |_, v| v }.reverse.each do |role, count|

    Checks that block braces have or don't have a space before the opening brace depending on configuration.

    Example:

    # bad
    foo.map{ |a|
      a.bar.to_s
    }
    
    # good
    foo.map { |a|
      a.bar.to_s
    }

    Favor format over String#%.
    Open

              stats << "<code>#{"%5.2f%" % (count * 100.0 / sum)}</code> #{g.get_role(g.class.const_get(role.upcase))}"

    This cop enforces the use of a single string formatting utility. Valid options include Kernel#format, Kernel#sprintf and String#%.

    The detection of String#% cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal.

    Example: EnforcedStyle: format(default)

    # bad
    puts sprintf('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts format('%10s', 'hoge')

    Example: EnforcedStyle: sprintf

    # bad
    puts format('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts sprintf('%10s', 'hoge')

    Example: EnforcedStyle: percent

    # bad
    puts format('%10s', 'hoge')
    puts sprintf('%10s', 'hoge')
    
    # good
    puts '%10s' % 'hoge'

    Favor format over String#%.
    Open

              stats << "#{"%3d" % x.game} #{x.full_name}"

    This cop enforces the use of a single string formatting utility. Valid options include Kernel#format, Kernel#sprintf and String#%.

    The detection of String#% cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal.

    Example: EnforcedStyle: format(default)

    # bad
    puts sprintf('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts format('%10s', 'hoge')

    Example: EnforcedStyle: sprintf

    # bad
    puts format('%10s', 'hoge')
    puts '%10s' % 'hoge'
    
    # good
    puts sprintf('%10s', 'hoge')

    Example: EnforcedStyle: percent

    # bad
    puts format('%10s', 'hoge')
    puts sprintf('%10s', 'hoge')
    
    # good
    puts '%10s' % 'hoge'

    Avoid using rescue in its modifier form.
    Open

              stats << "===== #{g.title.gsub(/[<>]/, '') rescue ''} ====="

    This cop checks for uses of rescue in its modifier form.

    Example:

    # bad
    some_method rescue handle_error
    
    # good
    begin
      some_method
    rescue
      handle_error
    end

    Prefer single-quoted strings inside interpolations.
    Open

              stats << "#{"%3d" % x.game} #{x.title.gsub(/[<>]/, '') rescue ''}"

    This cop checks that quotes inside the string interpolation match the configured preference.

    Example: EnforcedStyle: single_quotes (default)

    # bad
    result = "Tests #{success ? "PASS" : "FAIL"}"
    
    # good
    result = "Tests #{success ? 'PASS' : 'FAIL'}"

    Example: EnforcedStyle: double_quotes

    # bad
    result = "Tests #{success ? 'PASS' : 'FAIL'}"
    
    # good
    result = "Tests #{success ? "PASS" : "FAIL"}"

    Line is too long. [236/80]
    Open

            stats << "Last 24|4|1 hours: #{Lycantulul::Group.where(:created_at.gte => 24.hours.ago).count} | #{Lycantulul::Group.where(:created_at.gte => 4.hours.ago).count} | #{Lycantulul::Group.where(:created_at.gte => 1.hour.ago).count}"

    Line is too long. [121/80]
    Open

            stats << "Werewolf victory: #{w = Lycantulul::Group.all.sum(&:werewolf_victory)} (#{"%.2f\%" % (w * 100.0 / g)})"

    Shadowing outer local variable - g.
    Open

            Lycantulul::Game.running.each do |g|

    This cop looks for use of the same name as outer local variables for block arguments or block local variables. This is a mimic of the warning "shadowing outer local variable - foo" from ruby -cw.

    Example:

    # bad
    
    def some_method
      foo = 1
    
      2.times do |foo| # shadowing outer `foo`
        do_something(foo)
      end
    end

    Example:

    # good
    
    def some_method
      foo = 1
    
      2.times do |bar|
        do_something(bar)
      end
    end

    Avoid using rescue in its modifier form.
    Open

              stats << "===== #{g.title.gsub(/[<>]/, '') rescue ''} ====="

    This cop checks for uses of rescue in its modifier form.

    Example:

    # bad
    some_method rescue handle_error
    
    # good
    begin
      some_method
    rescue
      handle_error
    end

    Extra empty line detected at class body beginning.
    Open

    
        def self.get_stats(stat)

    This cops checks if empty lines around the bodies of classes match the configuration.

    Example: EnforcedStyle: empty_lines

    # good
    
    class Foo
    
      def bar
        # ...
      end
    
    end

    Example: EnforcedStyle: emptylinesexcept_namespace

    # good
    
    class Foo
      class Bar
    
        # ...
    
      end
    end

    Example: EnforcedStyle: emptylinesspecial

    # good
    class Foo
    
      def bar; end
    
    end

    Example: EnforcedStyle: noemptylines (default)

    # good
    
    class Foo
      def bar
        # ...
      end
    end

    Line is too long. [120/80]
    Open

            stats << "Villager victory: #{v = Lycantulul::Group.all.sum(&:village_victory)} (#{"%.2f\%" % (v * 100.0 / g)})"

    Missing magic comment # frozen_string_literal: true.
    Open

    module Lycantulul

    This cop is designed to help upgrade to Ruby 3.0. It will add the comment # frozen_string_literal: true to the top of files to enable frozen string literals. Frozen string literals may be default in Ruby 3.0. The comment will be added below a shebang and encoding comment. The frozen string literal comment is only valid in Ruby 2.3+.

    Example: EnforcedStyle: when_needed (default)

    # The `when_needed` style will add the frozen string literal comment
    # to files only when the `TargetRubyVersion` is set to 2.3+.
    # bad
    module Foo
      # ...
    end
    
    # good
    # frozen_string_literal: true
    
    module Foo
      # ...
    end

    Example: EnforcedStyle: always

    # 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

    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

    Avoid using rescue in its modifier form.
    Open

              stats << "#{"%3d" % x.game} #{x.title.gsub(/[<>]/, '') rescue ''}"

    This cop checks for uses of rescue in its modifier form.

    Example:

    # bad
    some_method rescue handle_error
    
    # good
    begin
      some_method
    rescue
      handle_error
    end

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

            stats << "Role frequency statistics"

    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"

    Missing top-level class documentation comment.
    Open

      class Statistics

    This cop 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, or constant definitions.

    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
    
    # good
    # Description/Explanation of Person class
    class Person
      # ...
    end

    Line is too long. [115/80]
    Open

              stats << "<code>#{"%5.2f%" % (count * 100.0 / sum)}</code> #{g.get_role(g.class.const_get(role.upcase))}"

    Prefer single-quoted strings inside interpolations.
    Open

              stats << "#{"%3d" % x.game} #{x.full_name}"

    This cop checks that quotes inside the string interpolation match the configured preference.

    Example: EnforcedStyle: single_quotes (default)

    # bad
    result = "Tests #{success ? "PASS" : "FAIL"}"
    
    # good
    result = "Tests #{success ? 'PASS' : 'FAIL'}"

    Example: EnforcedStyle: double_quotes

    # bad
    result = "Tests #{success ? 'PASS' : 'FAIL'}"
    
    # good
    result = "Tests #{success ? "PASS" : "FAIL"}"

    Line is too long. [269/80]
    Open

            stats << "Last 24|4|1 hours: #{Lycantulul::RegisteredPlayer.where(:created_at.gte => 24.hours.ago).count} | #{Lycantulul::RegisteredPlayer.where(:created_at.gte => 4.hours.ago).count} | #{Lycantulul::RegisteredPlayer.where(:created_at.gte => 1.hour.ago).count}"

    Line is too long. [233/80]
    Open

            stats << "Last 24|4|1 hours: #{Lycantulul::Game.where(:created_at.gte => 24.hours.ago).count} | #{Lycantulul::Game.where(:created_at.gte => 4.hours.ago).count} | #{Lycantulul::Game.where(:created_at.gte => 1.hour.ago).count}"

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

            stats << "Current stats:"

    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