Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
make sure String#% supports escaped % signs correctly
  • Loading branch information
clemens committed Jan 23, 2010
1 parent 17e923d commit bd74060
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
8 changes: 6 additions & 2 deletions lib/i18n/core_ext/string/interpolate.rb
Expand Up @@ -31,11 +31,15 @@ class String
alias :interpolate_without_ruby_19_syntax :% # :nodoc:

INTERPOLATION_PATTERN = Regexp.union(
/%%/,
/%\{(\w+)\}/, # matches placeholders like "%{foo}"
/%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
)

INTERPOLATION_PATTERN_WITH_ESCAPE = Regexp.union(
/%%/,
INTERPOLATION_PATTERN
)

# % uses self (i.e. the String) as a format specification and returns the
# result of applying it to the given arguments. In other words it interpolates
# the given arguments to the string according to the formats the string
Expand Down Expand Up @@ -75,7 +79,7 @@ class String
# # => "10, 43.3"
def %(args)
if args.kind_of?(Hash)
dup.gsub(INTERPOLATION_PATTERN) do |match|
dup.gsub(INTERPOLATION_PATTERN_WITH_ESCAPE) do |match|
if match == '%%'
'%'
else
Expand Down
7 changes: 6 additions & 1 deletion test/core_ext/string/interpolate_test.rb
Expand Up @@ -83,10 +83,15 @@ class I18nCoreExtStringInterpolationTest < Test::Unit::TestCase
assert_equal("%{num} %<num>d", "%%{num} %%<num>d" % {:num => 1})
end

test "% can be used in Ruby's own sprintf behavior" do
assert_equal "70%", "%d%%" % 70
assert_equal "70-100%", "%d-%d%%" % [70, 100]
end

def test_sprintf_mix_unformatted_and_formatted_named_placeholders
assert_equal("foo 1.000000", "%{name} %<num>f" % {:name => "foo", :num => 1.0})
end

def test_string_interpolation_raises_an_argument_error_when_mixing_named_and_unnamed_placeholders
assert_raise(ArgumentError) { "%{name} %f" % [1.0] }
assert_raise(ArgumentError) { "%{name} %f" % [1.0, 2.0] }
Expand Down

0 comments on commit bd74060

Please sign in to comment.