From e8d5820a3b08eeca28de1a2b9c8a6ad2b9e6476c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20=26=20Yehuda=20Katz?= Date: Tue, 26 Oct 2010 12:41:00 -0200 Subject: [PATCH] Fix how UTF8 is handled inside I18n. --- ci/Gemfile.rails-3.x.lock | 4 ++-- lib/i18n/backend/base.rb | 41 +++++++++++++------------------------ test/backend/simple_test.rb | 22 ++++++++++++++++++++ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/ci/Gemfile.rails-3.x.lock b/ci/Gemfile.rails-3.x.lock index 3e55d161..c688deb5 100644 --- a/ci/Gemfile.rails-3.x.lock +++ b/ci/Gemfile.rails-3.x.lock @@ -25,7 +25,7 @@ PLATFORMS ruby DEPENDENCIES - activerecord (~> 3) - activesupport (~> 3) + activerecord (~> 3.0.0) + activesupport (~> 3.0.0) mocha sqlite3-ruby diff --git a/lib/i18n/backend/base.rb b/lib/i18n/backend/base.rb index 55a1ccf4..f780371d 100644 --- a/lib/i18n/backend/base.rb +++ b/lib/i18n/backend/base.rb @@ -150,25 +150,23 @@ def pluralize(locale, entry, count) def interpolate(locale, string, values = {}) return string unless string.is_a?(::String) && !values.empty? - preserve_encoding(string) do - string = string.gsub(DEPRECATED_INTERPOLATION_SYNTAX_PATTERN) do - escaped, key = $1, $2.to_sym - if escaped - "{{#{key}}}" - else - warn_syntax_deprecation!(locale, string) - "%{#{key}}" - end - end - - values.each do |key, value| - value = value.call(values) if interpolate_lambda?(value, string, key) - value = value.to_s unless value.is_a?(::String) - values[key] = value + string = string.gsub(DEPRECATED_INTERPOLATION_SYNTAX_PATTERN) do + escaped, key = $1, $2.to_sym + if escaped + "{{#{key}}}" + else + warn_syntax_deprecation!(locale, string) + "%{#{key}}" end + end - string % values + values.each do |key, value| + value = value.call(values) if interpolate_lambda?(value, string, key) + value = value.to_s unless value.is_a?(::String) + values[key] = value end + + string % values rescue KeyError => e if string =~ RESERVED_KEYS_PATTERN raise ReservedInterpolationKey.new($1.to_sym, string) @@ -177,17 +175,6 @@ def interpolate(locale, string, values = {}) end end - def preserve_encoding(string) - if string.respond_to?(:encoding) - encoding = string.encoding - result = yield - result.force_encoding(encoding) if result.respond_to?(:force_encoding) - result - else - yield - end - end - # returns true when the given value responds to :call and the key is # an interpolation placeholder in the given string def interpolate_lambda?(object, string, key) diff --git a/test/backend/simple_test.rb b/test/backend/simple_test.rb index 3a8f0935..3423988d 100644 --- a/test/backend/simple_test.rb +++ b/test/backend/simple_test.rb @@ -1,4 +1,5 @@ # encoding: utf-8 + $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../')); $:.uniq! require 'test_helper' @@ -78,4 +79,25 @@ def setup I18n.backend.reload! assert_equal I18n.backend.initialized?, false end + + # Encoding + if "string".respond_to?(:force_encoding) + test "ASCII strings in the backend should be encoded to UTF8 if interpolation options are in UTF8" do + I18n.backend.store_translations 'en', 'encoding' => ('%{who} let me go'.force_encoding("ASCII")) + result = I18n.t 'encoding', :who => "måmmå miå" + assert_equal Encoding::UTF_8, result.encoding + end + + test "UTF8 strings in the backend are still returned as UTF8" do + I18n.backend.store_translations 'en', 'encoding' => 'måmmå miå %{what}' + result = I18n.t 'encoding', :what => 'let me go'.force_encoding("ASCII") + assert_equal Encoding::UTF_8, result.encoding + end + + test "UTF8 strings in the backend are still returned as UTF8 even with numbers" do + I18n.backend.store_translations 'en', 'encoding' => '%{count} times: måmmå miå' + result = I18n.t 'encoding', :count => 3 + assert_equal Encoding::UTF_8, result.encoding + end + end end