forked from puppetlabs/rubocop-i18n
/
decorate_string.rb
83 lines (72 loc) · 2.34 KB
/
decorate_string.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# frozen_string_literal: true
module RuboCop
module Cop
module I18n
module GetText
# This cop is looks for strings that appear to be sentences but are not decorated.
# Sentences are determined by the STRING_REGEXP. (Upper case character, at least one space,
# and sentence punctuation at the end)
#
# @example
#
# # bad
#
# "Result is bad."
#
# @example
#
# # good
#
# _("Result is good.")
class DecorateString < Base
extend AutoCorrector
STRING_REGEXP = /^\s*[[:upper:]][[:alpha:]]*[[:blank:]]+.*[.!?]$/.freeze
def on_dstr(node)
check_for_parent_decorator(node) if dstr_contains_sentence?(node)
end
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
def sentence?(node)
child = node.children[0]
if child.is_a?(String)
if child.valid_encoding?
child.encode(Encoding::UTF_8).chomp =~ STRING_REGEXP
else
false
end
elsif child.respond_to?(:type) && child.str_type?
sentence?(child)
else
false
end
end
def dstr_contains_sentence?(node)
node.children.any? { |child| sentence?(child) }
end
def check_for_parent_decorator(node)
parent = node.parent
if parent.respond_to?(:type) && parent.send_type?
method_name = parent.loc.selector.source
return if GetText.supported_decorator?(method_name)
elsif parent.respond_to?(:method_name) && parent.method?(:[])
return
end
add_offense(node, message: 'decorator is missing around sentence') do |corrector|
single_string_correct(corrector, node) if node.str_type?
end
end
def single_string_correct(corrector, node)
corrector.wrap(node.source_range, '_(', ')')
end
end
end
end
end
end