File: interpolation.rb

package info (click to toggle)
libi18n-ruby 0.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 576 kB
  • ctags: 619
  • sloc: ruby: 4,655; makefile: 5
file content (108 lines) | stat: -rw-r--r-- 5,522 bytes parent folder | download
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