diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..cc32da4 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1 @@ +inherit_from: .rubocop_todo.yml diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..93ebac5 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,69 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2017-10-13 16:58:50 -0700 using RuboCop version 0.49.1. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. +# Offense count: 4 +Metrics/AbcSize: + Max: 31 + +# Offense count: 5 +# Configuration parameters: CountComments, ExcludedMethods. +Metrics/BlockLength: + Max: 68 + +# Offense count: 1 +# Configuration parameters: CountComments. +Metrics/ClassLength: + Max: 106 + +# Offense count: 3 +Metrics/CyclomaticComplexity: + Max: 8 + +# Offense count: 86 +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# URISchemes: http, https +Metrics/LineLength: + Max: 174 + +# Offense count: 6 +# Configuration parameters: CountComments. +Metrics/MethodLength: + Max: 26 + +# Offense count: 2 +Metrics/PerceivedComplexity: + Max: 8 + +# Offense count: 2 +Style/Documentation: + Exclude: + - 'spec/**/*' + - 'test/**/*' + - 'lib/rubocop/cop/i18n/gettext.rb' + - 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb' + +# Offense count: 1 +# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms. +# 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 +Style/FileName: + Exclude: + - 'lib/rubocop-i18n.rb' + +# Offense count: 7 +# Configuration parameters: SupportedStyles. +# SupportedStyles: annotated, template +Style/FormatStringToken: + EnforcedStyle: template + +# Offense count: 4 +# Configuration parameters: MinBodyLength. +Style/GuardClause: + Exclude: + - 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb' + - 'lib/rubocop/cop/i18n/gettext/decorate_string.rb' + - 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb' + - 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb' diff --git a/CHANGELOG.md b/CHANGELOG.md index c1730d0..9933524 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## master (unreleased) + * Code restructure (no API changes) + * RuboCop lint fixes + ### 1.1.0 * Added support for DecorateStringFormattingUsingPercent diff --git a/Rakefile b/Rakefile index b7e9ed5..b618cfb 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,12 @@ -require "bundler/gem_tasks" -require "rspec/core/rake_task" +require 'bundler/gem_tasks' +require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -task :default => :spec +task default: :test + +task test: %i[rubocop spec] + +task :rubocop do + sh 'rubocop -P' +end diff --git a/bin/console b/bin/console index 11d498d..0404354 100755 --- a/bin/console +++ b/bin/console @@ -1,7 +1,7 @@ #!/usr/bin/env ruby -require "bundler/setup" -require "rubocop/i18n" +require 'bundler/setup' +require 'rubocop/i18n' # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. @@ -10,5 +10,5 @@ require "rubocop/i18n" # require "pry" # Pry.start -require "irb" +require 'irb' IRB.start(__FILE__) diff --git a/lib/rubocop/cop/i18n/gettext.rb b/lib/rubocop/cop/i18n/gettext.rb index 8180ee8..0211e3a 100644 --- a/lib/rubocop/cop/i18n/gettext.rb +++ b/lib/rubocop/cop/i18n/gettext.rb @@ -4,6 +4,41 @@ module RuboCop module Cop module I18n module GetText + def self.supported_methods + %w[raise fail] + end + + # Supports decorators from + # * mutoh/gettext https://github.com/mutoh/gettext/blob/master/lib/gettext.rb + # * grosser/fast_gettext https://github.com/grosser/fast_gettext/blob/master/lib/fast_gettext/translation.rb + def self.supported_decorators + %w[ + _ + n_ + np_ + ns_ + N_ + Nn_ + D_ + Dn_ + Ds_ + Dns_ + d_ + dn_ + ds_ + dns_ + p_ + s_ + ] + end + + def self.supported_method?(method_name) + supported_methods.include?(method_name) + end + + def self.supported_decorator?(decorator_name) + supported_decorators.include?(decorator_name) + end end end end diff --git a/lib/rubocop/cop/i18n/gettext/decorate_function_message.rb b/lib/rubocop/cop/i18n/gettext/decorate_function_message.rb index 1a15d9c..68b06d5 100644 --- a/lib/rubocop/cop/i18n/gettext/decorate_function_message.rb +++ b/lib/rubocop/cop/i18n/gettext/decorate_function_message.rb @@ -3,19 +3,16 @@ module Cop module I18n module GetText class DecorateFunctionMessage < Cop - SUPPORTED_METHODS = ['raise', 'fail'] - SUPPORTED_DECORATORS = ['_', 'n_', 'N_'] - def on_send(node) method_name = node.loc.selector.source - return if !supported_method_name?(method_name) + return unless GetText.supported_method?(method_name) _, method_name, *arg_nodes = *node if !arg_nodes.empty? && !already_decorated?(node) && (contains_string?(arg_nodes) || string_constant?(arg_nodes)) - if string_constant?(arg_nodes) - message_section = arg_nodes[1] - else - message_section = arg_nodes[0] - end + message_section = if string_constant?(arg_nodes) + arg_nodes[1] + else + arg_nodes[0] + end detect_and_report(node, message_section, method_name) end @@ -23,15 +20,11 @@ def on_send(node) private - def supported_method_name?(method_name) - SUPPORTED_METHODS.include?(method_name) - end - def already_decorated?(node, parent = nil) parent ||= node if node.respond_to?(:loc) && node.loc.respond_to?(:selector) - return true if SUPPORTED_DECORATORS.include?(node.loc.selector.source) + return true if GetText.supported_decorator?(node.loc.selector.source) end return false unless node.respond_to?(:children) @@ -44,10 +37,10 @@ def string_constant?(nodes) end def contains_string?(nodes) - nodes[0].inspect.include?(":str") || nodes[0].inspect.include?(":dstr") + nodes[0].inspect.include?(':str') || nodes[0].inspect.include?(':dstr') end - def detect_and_report(node, message_section, method_name) + def detect_and_report(_node, message_section, method_name) errors = how_bad_is_it(message_section) return if errors.empty? error_message = "'#{method_name}' function, " @@ -68,7 +61,7 @@ def how_bad_is_it(message_section) errors.push :multiline if message_section.multiline? errors.push :concatenation if concatenation_offense?(message_section) errors.push :interpolation if interpolation_offense?(message_section) - errors.push :no_decoration if !already_decorated?(message_section) + errors.push :no_decoration unless already_decorated?(message_section) # only display no_decoration, if that is the only problem. if errors.size > 1 && errors.include?(:no_decoration) @@ -92,7 +85,7 @@ def concatenation_offense?(node, parent = nil) def interpolation_offense?(node, parent = nil) parent ||= node - return true if node.class == RuboCop::AST::Node && node.dstr_type? + return true if node.class == RuboCop::AST::Node && node.dstr_type? return false unless node.respond_to?(:children) @@ -103,52 +96,51 @@ def autocorrect(node) if node.str_type? single_string_correct(node) elsif interpolation_offense?(node) -# interpolation_correct(node) + # interpolation_correct(node) end end def single_string_correct(node) - ->(corrector) { - corrector.insert_before(node.source_range , "_(") - corrector.insert_after(node.source_range , ")") } + lambda { |corrector| + corrector.insert_before(node.source_range, '_(') + corrector.insert_after(node.source_range, ')') + } end def interpolation_correct(node) - interpolated_values_string = "" + interpolated_values_string = '' count = 0 - ->(corrector) { + lambda { |corrector| node.children.each do |child| # dstrs are split into "str" segments and other segments. # The "other" segments are the interpolated values. - if child.type == :begin - value = child.children[0] - hash_key = "value" - if value.type == :lvar - # Use the variable's name as the format key - hash_key = value.loc.name.source - else - # These are placeholders that will manually need to be given - # a descriptive name - hash_key << "#{count}" - count += 1 - end - if interpolated_values_string.empty? - interpolated_values_string << "{ " - end - interpolated_values_string << "#{hash_key}: #{value.loc.expression.source}, " - - # Replace interpolation with format string - corrector.replace(child.loc.expression, "%{#{hash_key}}") + next unless child.type == :begin + value = child.children[0] + hash_key = 'value' + if value.type == :lvar + # Use the variable's name as the format key + hash_key = value.loc.name.source + else + # These are placeholders that will manually need to be given + # a descriptive name + hash_key << count.to_s + count += 1 + end + if interpolated_values_string.empty? + interpolated_values_string << '{ ' end + interpolated_values_string << "#{hash_key}: #{value.loc.expression.source}, " + + # Replace interpolation with format string + corrector.replace(child.loc.expression, "%{#{hash_key}}") end - if !interpolated_values_string.empty? - interpolated_values_string << "}" + unless interpolated_values_string.empty? + interpolated_values_string << '}' end corrector.insert_before(node.source_range, '_(') corrector.insert_after(node.source_range, ") % #{interpolated_values_string}") } end - end end end diff --git a/lib/rubocop/cop/i18n/gettext/decorate_string.rb b/lib/rubocop/cop/i18n/gettext/decorate_string.rb index 44995d7..d9c661c 100644 --- a/lib/rubocop/cop/i18n/gettext/decorate_string.rb +++ b/lib/rubocop/cop/i18n/gettext/decorate_string.rb @@ -21,9 +21,9 @@ module GetText class DecorateString < Cop def on_str(node) str = node.children[0] - #ignore strings with no whitespace - are typically keywords or interpolation statements and cover the above commented-out statements + # ignore strings with no whitespace - are typically keywords or interpolation statements and cover the above commented-out statements if str !~ /^\S*$/ - add_offense(node, :expression, "decorator is missing around sentence") if node.loc.respond_to?(:begin) + add_offense(node, :expression, 'decorator is missing around sentence') if node.loc.respond_to?(:begin) end end @@ -32,7 +32,6 @@ def on_str(node) def message(node) node.receiver ? MSG_DEFAULT : MSG_SELF end - end end end diff --git a/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb b/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb index e9748d1..29aaa3b 100644 --- a/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb +++ b/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb @@ -3,8 +3,9 @@ module Cop module I18n module GetText # When using an decorated string to support I18N, any strings inside the decoration should not contain - # the '#{}' interpolation string as this makes it hard to translate the strings. This cop checks the - # decorators listed in SUPPORTED_DECORATORS + # the '#{}' interpolation string as this makes it hard to translate the strings. + # + # Check GetText.supported_decorators for a list of decorators that can be used. # # @example # @@ -20,12 +21,9 @@ module GetText # _("result is %{detail}" % {detail: message}) # class DecorateStringFormattingUsingInterpolation < Cop - - SUPPORTED_DECORATORS = ['_', 'n_', 'N_'] - def on_send(node) decorator_name = node.loc.selector.source - return if !supported_decorator_name?(decorator_name) + return unless GetText.supported_decorator?(decorator_name) _, method_name, *arg_nodes = *node if !arg_nodes.empty? && contains_string_formatting_with_interpolation?(arg_nodes) message_section = arg_nodes[0] @@ -35,10 +33,6 @@ def on_send(node) private - def supported_decorator_name?(decorator_name) - SUPPORTED_DECORATORS.include?(decorator_name) - end - def string_contains_interpolation_format?(str) str.match(/\#{[^}]+}/) end @@ -49,7 +43,7 @@ def contains_string_formatting_with_interpolation?(node) end if node.respond_to?(:type) - if node.type == :str or node.type == :dstr + if node.type == :str || node.type == :dstr return string_contains_interpolation_format?(node.source) end end @@ -57,9 +51,8 @@ def contains_string_formatting_with_interpolation?(node) if node.respond_to?(:children) return node.children.any? { |child| contains_string_formatting_with_interpolation?(child) } end - return false + false end - end end end diff --git a/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb b/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb index fe8d4de..e280540 100644 --- a/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb +++ b/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb @@ -4,7 +4,7 @@ module I18n module GetText # When using a decorated string to support I18N, any strings inside the decoration should not contain sprintf # style formatting as this makes it hard to translate the string. This cop checks the decorators listed in - # SUPPORTED_DECORATORS and checks for each of the formats in SUPPORTED_FORMATS. NOTE: this cop does not + # GetText.supported_decorators and checks for each of the formats in SUPPORTED_FORMATS. NOTE: this cop does not # check for all possible sprintf formats. # # @example @@ -22,13 +22,11 @@ module GetText # _("result is %{detail}" % {detail: message}) # class DecorateStringFormattingUsingPercent < Cop - - SUPPORTED_DECORATORS = ['_', 'n_', 'N_'] - SUPPORTED_FORMATS = %w[b B d i o u x X e E f g G a A c p s] + SUPPORTED_FORMATS = %w[b B d i o u x X e E f g G a A c p s].freeze def on_send(node) decorator_name = node.loc.selector.source - return if !supported_decorator_name?(decorator_name) + return unless GetText.supported_decorator?(decorator_name) _, method_name, *arg_nodes = *node if !arg_nodes.empty? && contains_string_with_percent_format?(arg_nodes) message_section = arg_nodes[0] @@ -38,10 +36,6 @@ def on_send(node) private - def supported_decorator_name?(decorator_name) - SUPPORTED_DECORATORS.include?(decorator_name) - end - def string_contains_percent_format?(str) SUPPORTED_FORMATS.any? { |format| str.match(/%([-+])?[0-9]*(\.[0-9]*)?#{format}/) } end @@ -52,7 +46,7 @@ def contains_string_with_percent_format?(node) end if node.respond_to?(:type) - if node.type == :str or node.type == :dstr + if node.type == :str || node.type == :dstr return string_contains_percent_format?(node.source) end end @@ -62,7 +56,6 @@ def contains_string_with_percent_format?(node) end false end - end end end diff --git a/rubocop-i18n.gemspec b/rubocop-i18n.gemspec index b39c183..2b85226 100644 --- a/rubocop-i18n.gemspec +++ b/rubocop-i18n.gemspec @@ -1,29 +1,32 @@ # coding: utf-8 + lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +rubocop_version = '~> 0.49.0' Gem::Specification.new do |spec| - spec.name = "rubocop-i18n" - spec.version = '1.1.0' - spec.authors = ["Puppet", "Brandon High", "TP Honey", "Helen Campbell"] - spec.email = ["team-modules@puppet.com", "brandon.high@puppet.com", "tp@puppet.com", "helen@puppet.com"] + spec.name = 'rubocop-i18n' + spec.version = '1.2.0' + spec.authors = ['Puppet', 'Brandon High', 'TP Honey', 'Helen Campbell'] + spec.email = ['team-modules@puppet.com', 'brandon.high@puppet.com', 'tp@puppet.com', 'helen@puppet.com'] - spec.summary = %q{RuboCop rules for i18n} - spec.description = %q{RuboCop rules for detecting and autocorrecting undecorated strings for i18n} - spec.homepage = "https://github.com/puppetlabs/rubocop-i18n" + spec.summary = 'RuboCop rules for i18n' + spec.description = 'RuboCop rules for detecting and autocorrecting undecorated strings for i18n' + spec.homepage = 'https://github.com/puppetlabs/rubocop-i18n' spec.license = 'Apache-2' spec.files = `git ls-files -z`.split("\x0").reject do |f| f.match(%r{^(test|spec|features)/}) end - spec.bindir = "exe" + spec.bindir = 'exe' spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ["lib"] + spec.require_paths = ['lib'] - spec.add_development_dependency "bundler", "~> 1.14" - spec.add_development_dependency "rake", "~> 10.0" - spec.add_development_dependency "rspec", "~> 3.0" - spec.add_development_dependency "rb-readline" - spec.add_development_dependency "pry" - spec.add_runtime_dependency "rubocop", "~> 0.49" + spec.add_development_dependency 'bundler', '~> 1.14' + spec.add_development_dependency 'rake', '~> 10.0' + spec.add_development_dependency 'rspec', '~> 3.0' + spec.add_development_dependency 'rb-readline' + spec.add_development_dependency 'pry' + spec.add_development_dependency 'rubocop', rubocop_version + spec.add_runtime_dependency 'rubocop', rubocop_version end diff --git a/spec/rubocop/cop/i18n/gettext/decorate_function_message_spec.rb b/spec/rubocop/cop/i18n/gettext/decorate_function_message_spec.rb index 85f15e5..5421ad7 100644 --- a/spec/rubocop/cop/i18n/gettext/decorate_function_message_spec.rb +++ b/spec/rubocop/cop/i18n/gettext/decorate_function_message_spec.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true + require 'spec_helper' describe RuboCop::Cop::I18n::GetText::DecorateFunctionMessage do let(:config) { RuboCop::Config.new } subject(:cop) { described_class.new(config) } - before(:each) { + before(:each) do investigate(cop, source) - } + end - functions = ['fail', 'raise'] - functions.each do |function| + RuboCop::Cop::I18n::GetText.supported_methods.each do |function| context "#{function} with undecorated double-quote message" do it_behaves_like 'a_detecting_cop', "#{function}(\"a string\")", function, 'message string should be decorated' it_behaves_like 'a_fixing_cop', "#{function}(\"a string\")", "#{function}(_(\"a string\"))", function @@ -33,7 +33,7 @@ end context "#{function} with interpolated string" do it_behaves_like 'a_detecting_cop', "#{function}(\"a string \#{var}\")", function, 'message should use correctly formatted interpolation' - #it_behaves_like 'a_fixing_cop', "#{function}(\"a string \#{var}\")", "#{function}(_(\"a string %{value0}\") % { value0: var, })", function + # it_behaves_like 'a_fixing_cop', "#{function}(\"a string \#{var}\")", "#{function}(_(\"a string %{value0}\") % { value0: var, })", function it_behaves_like 'a_no_cop_required', "#{function}(_(\"a string %{value0}\")) % { value0: var, }", function it_behaves_like 'a_no_cop_required', "#{function}(N_(\"a string %s\"))", function end @@ -47,15 +47,17 @@ expect(cop.offenses.size).to eq(0) end end - context "#{function} with the n_ decorator" do - it_behaves_like 'a_no_cop_required', "#{function}(n_(\"a string\"))", function - it_behaves_like 'a_no_cop_required', "#{function}(n_('a string'))", function - it_behaves_like 'a_no_cop_required', "#{function}(CONSTANT, n_('a string'))", function - it_behaves_like 'a_no_cop_required', "#{function}(n_(\"a string %{value0}\")) % { value0: var, }", function + RuboCop::Cop::I18n::GetText.supported_decorators.each do |decorator| + context "#{function} with the #{decorator} decorator" do + it_behaves_like 'a_no_cop_required', "#{function}(#{decorator}(\"a string\"))", function + it_behaves_like 'a_no_cop_required', "#{function}(#{decorator}('a string'))", function + it_behaves_like 'a_no_cop_required', "#{function}(CONSTANT, #{decorator}('a string'))", function + it_behaves_like 'a_no_cop_required', "#{function}(#{decorator}(\"a string %{value0}\")) % { value0: var, }", function + end end end - context "real life examples," do - context "message is multiline with interpolated" do + context 'real life examples,' do + context 'message is multiline with interpolated' do let(:source) { "raise(Puppet::ParseError, \"mysql_password(): Wrong number of arguments \" \\\n \"given (\#{args.size} for 1)\")" } it 'has the correct error message' do @@ -69,8 +71,8 @@ end it 'autocorrects', broken: true do - corrected = autocorrect_source( "raise(Puppet::ParseError, \"mysql_password(): Wrong number of arguments \" \\ \"given (\#{args.size} for 1)\")" ) - expect(corrected).to eq("raise(Puppet::ParseError, _(\"a string %{value0}\") % { value0: var, })") + corrected = autocorrect_source("raise(Puppet::ParseError, \"mysql_password(): Wrong number of arguments \" \\ \"given (\#{args.size} for 1)\")") + expect(corrected).to eq('raise(Puppet::ParseError, _("a string %{value0}") % { value0: var, })') end end end diff --git a/spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation_spec.rb b/spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation_spec.rb index dfd0836..e8bc0f0 100644 --- a/spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation_spec.rb +++ b/spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation_spec.rb @@ -1,18 +1,17 @@ # frozen_string_literal: true + require 'spec_helper' describe RuboCop::Cop::I18n::GetText::DecorateStringFormattingUsingInterpolation do - let(:config) {RuboCop::Config.new} - subject(:cop) {described_class.new(config)} - before(:each) { + let(:config) { RuboCop::Config.new } + subject(:cop) { described_class.new(config) } + before(:each) do investigate(cop, source) - } - - decorators = ['_', 'n_', 'N_'] - decorators.each do |decorator| + end + RuboCop::Cop::I18n::GetText.supported_decorators.each do |decorator| context "#{decorator} decoration not used" do - it_behaves_like 'a_no_cop_required', "thing(\"a #{true} that is not decorated\")" + it_behaves_like 'a_no_cop_required', 'thing("a \#{true} that is not decorated")' end context "#{decorator} decoration used but strings contain no \#{}" do @@ -39,5 +38,4 @@ it_behaves_like 'a_detecting_cop', "#{decorator}(CONSTANT, \"a \#{true}\")", '_', 'function, message string should not contain #{} formatting' end end - end diff --git a/spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent_spec.rb b/spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent_spec.rb index 93ee114..56f91d4 100644 --- a/spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent_spec.rb +++ b/spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent_spec.rb @@ -1,18 +1,17 @@ # frozen_string_literal: true + require 'spec_helper' describe RuboCop::Cop::I18n::GetText::DecorateStringFormattingUsingPercent do - let(:config) {RuboCop::Config.new} - subject(:cop) {described_class.new(config)} - before(:each) { + let(:config) { RuboCop::Config.new } + subject(:cop) { described_class.new(config) } + before(:each) do investigate(cop, source) - } - - decorators = ['_', 'n_', 'N_'] - decorators.each do |decorator| + end + RuboCop::Cop::I18n::GetText.supported_decorators.each do |decorator| context "#{decorator} decoration not used" do - it_behaves_like 'a_no_cop_required', "thing(\"a %s that is not decorated\")" + it_behaves_like 'a_no_cop_required', 'thing("a %s that is not decorated")' end context "#{decorator} decoration used but strings contain no % format" do @@ -29,7 +28,6 @@ formats = %w[b B d i o u x X e E f g G a A c p s] formats.each do |format| - context "#{decorator} decoration with string % format" do it_behaves_like 'a_detecting_cop', "#{decorator}(\"a %#{format} string\")", '_', 'message string should not contain sprintf style formatting' it_behaves_like 'a_detecting_cop', "#{decorator}(\"a %#{format} string\" % [\"thing\"])", '_', 'message string should not contain sprintf style formatting' diff --git a/spec/rubocop/cop/i18n/gettext/decorate_string_spec.rb b/spec/rubocop/cop/i18n/gettext/decorate_string_spec.rb index d3523ca..3225614 100644 --- a/spec/rubocop/cop/i18n/gettext/decorate_string_spec.rb +++ b/spec/rubocop/cop/i18n/gettext/decorate_string_spec.rb @@ -1,19 +1,17 @@ # frozen_string_literal: true + require 'spec_helper' describe RuboCop::Cop::I18n::GetText::DecorateString do let(:config) { RuboCop::Config.new } subject(:cop) { described_class.new(config) } - # For some reason, this string isn't considered decorated. - #it_behaves_like 'accepts', '_("a string")' - context 'undecorated string' do - let(:source) { -<<-RUBY -"a string" -RUBY - } + let(:source) do + <<-RUBY + "a string" + RUBY + end it 'rejects' do investigate(cop, source) diff --git a/spec/shared_examples.rb b/spec/shared_examples.rb index 9c8e976..dc06075 100644 --- a/spec/shared_examples.rb +++ b/spec/shared_examples.rb @@ -7,8 +7,8 @@ end end -shared_examples 'a_detecting_cop' do |unfixed, function, expected_warning| - let(:source) { "#{unfixed}" } +shared_examples 'a_detecting_cop' do |unfixed, _function, expected_warning| + let(:source) { unfixed.to_s } it 'has the correct rubocop warning' do expect(cop.offenses[0]).not_to be_nil expect(cop.offenses[0].message).to include(expected_warning) @@ -19,15 +19,15 @@ end end -shared_examples 'a_no_cop_required' do |fixed, function| - let(:source) { "#{fixed}" } +shared_examples 'a_no_cop_required' do |fixed, _function| + let(:source) { fixed.to_s } it 'has no offenses found' do - expect(cop.offenses).to be_empty + expect(cop.offenses).to be_empty end end -shared_examples 'a_fixing_cop' do |unfixed, fixed, function| - let(:source) { "#{unfixed}" } +shared_examples 'a_fixing_cop' do |unfixed, fixed, _function| + let(:source) { unfixed.to_s } it 'autocorrects' do corrected = autocorrect_source(unfixed) expect(corrected).to eq(fixed) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8b8a4fe..ff8332d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,11 +1,10 @@ -require "bundler/setup" -require "shared_functions" -require "shared_examples" +require 'bundler/setup' +require 'shared_functions' +require 'shared_examples' require 'rubocop/cop/i18n' require 'rubocop/rspec/cop_helper' RSpec.configure do |config| - # These two settings work together to allow you to limit a spec run # to individual examples or groups you care about by tagging them with # `:focus` metadata. When nothing is tagged with `:focus`, all examples