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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
# encoding: utf-8
module Tests
module Api
module Interpolation
def interpolate(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
key = args.pop
I18n.backend.translate('en', key, options)
end
# If no interpolation parameter is not given, I18n should not alter the string.
# This behavior is due to three reasons:
#
# * Checking interpolation keys in all strings hits performance, badly;
#
# * This allows us to retrieve untouched values through I18n. For example
# I could have a middleware that returns I18n lookup results in JSON
# to be processed through Javascript. Leaving the keys untouched allows
# the interpolation to happen at the javascript level;
#
# * Security concerns: if I allow users to translate a web site, they can
# insert %{} in messages causing the I18n lookup to fail in every request.
#
define_method "test interpolation: given no values it does not alter the string" do
assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!')
end
define_method "test interpolation: given values it interpolates them into the string" do
assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
end
define_method "test interpolation: given a nil value it still interpolates it into the string" do
assert_equal 'Hi !', interpolate(:default => 'Hi %{name}!', :name => nil)
end
define_method "test interpolation: given a lambda as a value it calls it if the string contains the key" do
assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => lambda { |*args| 'David' })
end
define_method "test interpolation: given a lambda as a value it does not call it if the string does not contain the key" do
assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { |*args| raise 'fail' }) }
end
define_method "test interpolation: given values but missing a key it raises I18n::MissingInterpolationArgument" do
assert_raise(I18n::MissingInterpolationArgument) do
interpolate(:default => '%{foo}', :bar => 'bar')
end
end
define_method "test interpolation: it does not raise I18n::MissingInterpolationArgument for escaped variables" do
assert_nothing_raised(I18n::MissingInterpolationArgument) do
assert_equal 'Barr %{foo}', interpolate(:default => '%{bar} %%{foo}', :bar => 'Barr')
end
end
define_method "test interpolation: it does not change the original, stored translation string" do
I18n.backend.store_translations(:en, :interpolate => 'Hi %{name}!')
assert_equal 'Hi David!', interpolate(:interpolate, :name => 'David')
assert_equal 'Hi Yehuda!', interpolate(:interpolate, :name => 'Yehuda')
end
define_method "test interpolation: works with the deprecated syntax" do
deprecation = capture(:stderr) do
assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => 'David')
end
assert_match "The {{key}} interpolation syntax in I18n messages is deprecated", deprecation
end
define_method "test interpolation: given the translation is in utf-8 it still works" do
assert_equal 'Häi David!', interpolate(:default => 'Häi %{name}!', :name => 'David')
end
define_method "test interpolation: given the value is in utf-8 it still works" do
assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi %{name}!', :name => 'ゆきひろ')
end
define_method "test interpolation: given the translation and the value are in utf-8 it still works" do
assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、%{name}さん!', :name => 'ゆきひろ')
end
if Kernel.const_defined?(:Encoding)
define_method "test interpolation: given a euc-jp translation and a utf-8 value it raises Encoding::CompatibilityError" do
assert_raise(Encoding::CompatibilityError) do
interpolate(:default => euc_jp('こんにちは、%{name}さん!'), :name => 'ゆきひろ')
end
end
# define_method "test interpolation: given a utf-8 translation and a euc-jp value it returns a translation in euc-jp" do
# assert_equal euc_jp('Hi ゆきひろ!'), interpolate(:default => 'Hi %{name}!', :name => euc_jp('ゆきひろ'))
# end
#
# TODO should better explain how this relates to the test above with the simpler utf-8 default string
define_method "test interpolation: given a utf-8 translation and a euc-jp value it raises Encoding::CompatibilityError" do
assert_raise(Encoding::CompatibilityError) do
interpolate(:default => 'こんにちは、%{name}さん!', :name => euc_jp('ゆきひろ'))
end
end
end
define_method "test interpolation: given a translations containing a reserved key it raises I18n::ReservedInterpolationKey" do
assert_raise(I18n::ReservedInterpolationKey) { interpolate(:default => '%{default}', :foo => :bar) }
assert_raise(I18n::ReservedInterpolationKey) { interpolate(:default => '%{scope}', :foo => :bar) }
assert_raise(I18n::ReservedInterpolationKey) { interpolate(:default => '%{separator}', :foo => :bar) }
end
end
end
end
|