class RuboCop::Cop::I18n::RailsI18n::DecorateString

This cop is looks for strings that appear to be sentences but are not decorated. Sentences are determined by the SENTENCE_REGEXP. (Upper case character, at least one space, and sentence punctuation at the end)

@example

# bad

"Result is bad."

@example

# good

t("result_is_good")
I18n.t("result_is_good")

There are several options for configuration.

@example IgnoreExceptions: true

# OK

raise "Some string sentence"

@example EnforcedSentenceType: sentence

# bad

"Result is bad."

# good

t("result_is_good")
I18n.t("result_is_good")

@example EnforcedSentenceType: fragmented_sentence

# bad

"Result is bad"   # Contains a capital to start
"result is bad."  # Ends in punctuation

# good

t("result_is_good")
I18n.t("result_is_good")

@example EnforcedSentenceType: fragment

# bad

"result is bad"   # A series of words

# good

t("result_is_good")
I18n.t("result_is_good")

@example Regexp: ^only-this-text$

# bad

"only-this-text"

# good

"Any other string is fine now"
t("only_this_text")

Constants

FRAGMENTED_SENTENCE_REGEXP
FRAGMENT_REGEXP
SENTENCE_REGEXP
SUPPORTED_DECORATORS

Public Instance Methods

on_dstr(node) click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 84
def on_dstr(node)
  check_for_parent_decorator(node) if dstr_contains_sentence?(node)
end
on_str(node) click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 88
def on_str(node)
  return unless sentence?(node)

  parent = node.parent
  if parent.respond_to?(:type)
    return if parent.regexp_type? || parent.dstr_type?
  end

  check_for_parent_decorator(node)
end

Private Instance Methods

check_for_parent_decorator(node) click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 138
def check_for_parent_decorator(node)
  return if parent_is_translator?(node.parent)
  return if parent_is_indexer?(node.parent)
  return if ignoring_raised_parent?(node.parent)

  add_offense(node, message: 'decorator is missing around sentence')
end
dstr_contains_sentence?(node) click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 134
def dstr_contains_sentence?(node)
  node.children.any? { |child| sentence?(child) }
end
ignoring_raised_parent?(parent) click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 146
def ignoring_raised_parent?(parent)
  return false unless cop_config['IgnoreExceptions']

  return true if parent.respond_to?(:method_name) && %i[raise fail].include?(parent.method_name)

  # Commonly exceptions are initialized manually.
  return ignoring_raised_parent?(parent.parent) if parent.respond_to?(:method_name) && parent.method?(:new)

  false
end
parent_is_indexer?(parent) click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 157
def parent_is_indexer?(parent)
  parent.respond_to?(:method_name) && parent.method?(:[])
end
parent_is_translator?(parent) click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 161
def parent_is_translator?(parent)
  if parent.respond_to?(:type) && parent.send_type?
    method_name = parent.loc.selector.source
    if RailsI18n.supported_decorator?(method_name)
      # Implicit receiver is assumed correct.
      return true if parent.receiver.nil?
      return true if parent.receiver.children == [nil, :I18n]
    end
  end
  false
end
regexp() click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 116
def regexp
  @regexp ||= regexp_from_config || regexp_from_string_type
end
regexp_from_config() click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 130
def regexp_from_config
  Regexp.new(cop_config['Regexp']) if cop_config['Regexp']
end
regexp_from_string_type() click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 120
def regexp_from_string_type
  case cop_config['EnforcedSentenceType'].to_s.downcase
  when 'sentence'            then SENTENCE_REGEXP
  when 'fragmented_sentence' then FRAGMENTED_SENTENCE_REGEXP
  when 'fragment'            then FRAGMENT_REGEXP
  else
    SENTENCE_REGEXP
  end
end
sentence?(node) click to toggle source
# File lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb, line 101
def sentence?(node)
  child = node.children[0]
  if child.is_a?(String)
    if child.valid_encoding?
      child.encode(Encoding::UTF_8).chomp =~ regexp
    else
      false
    end
  elsif child.respond_to?(:type) && child.str_type?
    sentence?(child)
  else
    false
  end
end