i18n 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of i18n might be problematic. Click here for more details.

@@ -0,0 +1,93 @@
1
+ =begin
2
+ heavily based on Masao Mutoh's gettext String interpolation extension
3
+ http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
4
+ Copyright (C) 2005-2009 Masao Mutoh
5
+ You may redistribute it and/or modify it under the same license terms as Ruby.
6
+ =end
7
+
8
+ if RUBY_VERSION < '1.9'
9
+
10
+ # KeyError is raised by String#% when the string contains a named placeholder
11
+ # that is not contained in the given arguments hash. Ruby 1.9 includes and
12
+ # raises this exception natively. We define it to mimic Ruby 1.9's behaviour
13
+ # in Ruby 1.8.x
14
+
15
+ class KeyError < IndexError
16
+ def initialize(message = nil)
17
+ super(message || "key not found")
18
+ end
19
+ end unless defined?(KeyError)
20
+
21
+ # Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
22
+ #
23
+ # String#% method which accept "named argument". The translator can know
24
+ # the meaning of the msgids using "named argument" instead of %s/%d style.
25
+
26
+ class String
27
+ # For older ruby versions, such as ruby-1.8.5
28
+ alias :bytesize :size unless instance_methods.find {|m| m.to_s == 'bytesize'}
29
+ alias :interpolate_without_ruby_19_syntax :% # :nodoc:
30
+
31
+ INTERPOLATION_PATTERN = Regexp.union(
32
+ /%%/,
33
+ /%\{(\w+)\}/, # matches placeholders like "%{foo}"
34
+ /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
35
+ )
36
+
37
+ # % uses self (i.e. the String) as a format specification and returns the
38
+ # result of applying it to the given arguments. In other words it interpolates
39
+ # the given arguments to the string according to the formats the string
40
+ # defines.
41
+ #
42
+ # There are three ways to use it:
43
+ #
44
+ # * Using a single argument or Array of arguments.
45
+ #
46
+ # This is the default behaviour of the String class. See Kernel#sprintf for
47
+ # more details about the format string.
48
+ #
49
+ # Example:
50
+ #
51
+ # "%d %s" % [1, "message"]
52
+ # # => "1 message"
53
+ #
54
+ # * Using a Hash as an argument and unformatted, named placeholders.
55
+ #
56
+ # When you pass a Hash as an argument and specify placeholders with %{foo}
57
+ # it will interpret the hash values as named arguments.
58
+ #
59
+ # Example:
60
+ #
61
+ # "%{firstname}, %{lastname}" % {:firstname => "Masao", :lastname => "Mutoh"}
62
+ # # => "Masao Mutoh"
63
+ #
64
+ # * Using a Hash as an argument and formatted, named placeholders.
65
+ #
66
+ # When you pass a Hash as an argument and specify placeholders with %<foo>d
67
+ # it will interpret the hash values as named arguments and format the value
68
+ # according to the formatting instruction appended to the closing >.
69
+ #
70
+ # Example:
71
+ #
72
+ # "%<integer>d, %<float>.1f" % { :integer => 10, :float => 43.4 }
73
+ # # => "10, 43.3"
74
+ def %(args)
75
+ if args.kind_of?(Hash)
76
+ dup.gsub(INTERPOLATION_PATTERN) do |match|
77
+ if match == '%%'
78
+ '%'
79
+ else
80
+ key = ($1 || $2).to_sym
81
+ raise KeyError unless args.has_key?(key)
82
+ $3 ? sprintf("%#{$3}", args[key]) : args[key]
83
+ end
84
+ end
85
+ elsif self =~ INTERPOLATION_PATTERN
86
+ raise ArgumentError.new('one hash required')
87
+ else
88
+ result = gsub(/%([{<])/, '%%\1')
89
+ result.send :'interpolate_without_ruby_19_syntax', args
90
+ end
91
+ end
92
+ end
93
+ end
@@ -1,5 +1,3 @@
1
- dir = File.dirname(__FILE__)
2
- require dir + '/i18n_test.rb'
3
- require dir + '/simple_backend_test.rb'
4
- require dir + '/i18n_exceptions_test.rb'
5
- # require dir + '/custom_backend_test.rb'
1
+ Dir[File.dirname(__FILE__) + '/**/*_test.rb'].each do |file|
2
+ require file
3
+ end
@@ -0,0 +1,13 @@
1
+ module Tests
2
+ module Backend
3
+ module Api
4
+ module Basics
5
+ def test_available_locales
6
+ backend_store_translations 'de', :foo => 'bar'
7
+ backend_store_translations 'en', :foo => 'foo'
8
+ assert_equal ['de', 'en'], I18n.backend.available_locales.map{|locale| locale.to_s }.sort
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,63 @@
1
+ module Tests
2
+ module Backend
3
+ module Api
4
+ module Interpolation
5
+ def interpolate(options)
6
+ I18n.backend.translate('en', nil, options)
7
+ end
8
+
9
+ def test_interpolation_given_no_interpolation_values_it_does_not_alter_the_string
10
+ assert_equal 'Hi {{name}}!', interpolate(:default => 'Hi {{name}}!')
11
+ end
12
+
13
+ def test_interpolation_given_interpolation_values_it_interpolates_the_values_to_the_string
14
+ assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => 'David')
15
+ end
16
+
17
+ def test_interpolation_given_interpolation_values_with_nil_values_it_interpolates_the_values_to_the_string
18
+ assert_equal 'Hi !', interpolate(:default => 'Hi {{name}}!', :name => nil)
19
+ end
20
+
21
+ def test_interpolate_with_ruby_1_9_syntax
22
+ assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
23
+ end
24
+
25
+ def test_interpolate_given_a_value_hash_interpolates_into_unicode_string
26
+ assert_equal 'Häi David!', interpolate(:default => 'Häi {{name}}!', :name => 'David')
27
+ end
28
+
29
+ def test_interpolate_given_a_unicode_value_hash_interpolates_to_the_string
30
+ assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi {{name}}!', :name => 'ゆきひろ')
31
+ end
32
+
33
+ def test_interpolate_given_a_unicode_value_hash_interpolates_into_unicode_string
34
+ assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、{{name}}さん!', :name => 'ゆきひろ')
35
+ end
36
+
37
+ if Kernel.const_defined?(:Encoding)
38
+ def test_interpolate_given_a_non_unicode_multibyte_value_hash_interpolates_into_a_string_with_the_same_encoding
39
+ assert_equal euc_jp('Hi ゆきひろ!'), interpolate(:default => 'Hi {{name}}!', :name => euc_jp('ゆきひろ'))
40
+ end
41
+
42
+ def test_interpolate_given_a_unicode_value_hash_into_a_non_unicode_multibyte_string_raises_encoding_compatibility_error
43
+ assert_raises(Encoding::CompatibilityError) do
44
+ interpolate(:default => euc_jp('こんにちは、{{name}}さん!'), :name => 'ゆきひろ')
45
+ end
46
+ end
47
+
48
+ def test_interpolate_given_a_non_unicode_multibyte_value_hash_into_an_unicode_string_raises_encoding_compatibility_error
49
+ assert_raises(Encoding::CompatibilityError) do
50
+ interpolate(:default => 'こんにちは、{{name}}さん!', :name => euc_jp('ゆきひろ'))
51
+ end
52
+ end
53
+ end
54
+
55
+ def test_interpolate_given_a_string_containing_a_reserved_key_raises_reserved_interpolation_key
56
+ assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{default}}', :foo => :bar) }
57
+ assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{scope}}', :foo => :bar) }
58
+ assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{separator}}', :foo => :bar) }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,50 @@
1
+ module Tests
2
+ module Backend
3
+ module Api
4
+ module Lambda
5
+ def test_translate_simple_proc
6
+ setup_proc_translations
7
+ assert_equal 'bar=bar, baz=baz, foo=foo', I18n.backend.translate('en', :a_lambda, :foo => 'foo', :bar => 'bar', :baz => 'baz')
8
+ end
9
+
10
+ def test_translate_proc_in_defaults
11
+ setup_proc_translations
12
+ assert_equal 'bar=bar, baz=baz, foo=foo', I18n.backend.translate('en', :does_not_exist, :default => :a_lambda, :foo => 'foo', :bar => 'bar', :baz => 'baz')
13
+ assert_equal 'bar=bar, baz=baz, foo=foo', I18n.backend.translate('en', :does_not_exist, :default => [:does_not_exist_2, :does_not_exist_3, :a_lambda], :foo => 'foo', :bar => 'bar', :baz => 'baz')
14
+ end
15
+
16
+ def test_translate_proc_with_pluralize
17
+ setup_proc_translations
18
+ params = { :zero => 'zero', :one => 'one', :other => 'other' }
19
+ assert_equal 'zero', I18n.backend.translate('en', :lambda_for_pluralize, params.merge(:count => 0))
20
+ assert_equal 'one', I18n.backend.translate('en', :lambda_for_pluralize, params.merge(:count => 1))
21
+ assert_equal 'other', I18n.backend.translate('en', :lambda_for_pluralize, params.merge(:count => 2))
22
+ end
23
+
24
+ def test_translate_proc_with_interpolate
25
+ setup_proc_translations
26
+ assert_equal 'bar baz foo', I18n.backend.translate('en', :lambda_for_interpolate, :foo => 'foo', :bar => 'bar', :baz => 'baz')
27
+ end
28
+
29
+ def test_translate_with_proc_as_default
30
+ expected = 'result from lambda'
31
+ assert_equal expected, I18n.backend.translate(:en, :'does not exist', :default => lambda { |key, values| expected })
32
+ end
33
+
34
+ private
35
+
36
+ def setup_proc_translations
37
+ I18n.backend.store_translations 'en', {
38
+ :a_lambda => lambda { |key, values|
39
+ values.keys.sort_by(&:to_s).collect { |key| "#{key}=#{values[key]}"}.join(', ')
40
+ },
41
+ :lambda_for_pluralize => lambda { |key, values| values },
42
+ :lambda_for_interpolate => lambda { |key, values|
43
+ "{{#{values.keys.sort_by(&:to_s).join('}} {{')}}}"
44
+ }
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,45 @@
1
+ module Tests
2
+ module Backend
3
+ module Api
4
+ module Link
5
+ def test_translate_calls_translate_if_resolves_to_a_symbol
6
+ setup_linked_translations
7
+ assert_equal 'foo', I18n.backend.translate('en', :link_to_foo)
8
+ end
9
+
10
+ def test_translate_calls_translate_if_resolves_to_a_symbol2
11
+ setup_linked_translations
12
+ assert_equal('baz', I18n.backend.translate('en', :link_to_baz))
13
+ end
14
+
15
+ def test_translate_calls_translate_if_resolves_to_a_symbol3
16
+ setup_linked_translations
17
+ assert I18n.backend.translate('en', :link_to_bar).key?(:baz)
18
+ end
19
+
20
+ def test_translate_calls_translate_if_resolves_to_a_symbol_with_scope_1
21
+ setup_linked_translations
22
+ assert_equal('baz', I18n.backend.translate('en', :link_to_baz, :scope => :bar))
23
+ end
24
+
25
+ def test_translate_calls_translate_if_resolves_to_a_symbol_with_scope_1
26
+ setup_linked_translations
27
+ assert_equal('buz', I18n.backend.translate('en', :'bar.link_to_buz'))
28
+ end
29
+
30
+ private
31
+
32
+ def setup_linked_translations
33
+ I18n.backend.store_translations 'en', {
34
+ :foo => 'foo',
35
+ :bar => { :baz => 'baz', :link_to_baz => :baz, :link_to_buz => :'boz.buz' },
36
+ :boz => { :buz => 'buz' },
37
+ :link_to_foo => :foo,
38
+ :link_to_bar => :bar,
39
+ :link_to_baz => :'bar.baz'
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ module Tests
2
+ module Backend
3
+ module Api
4
+ module Localization
5
+ module Date
6
+ # TODO should be Mrz, shouldn't it?
7
+ def test_localize_given_the_short_format_it_uses_it
8
+ assert_equal '01. Mar', I18n.backend.localize('de', date, :short)
9
+ end
10
+
11
+ def test_localize_given_the_long_format_it_uses_it
12
+ assert_equal '01. März 2008', I18n.backend.localize('de', date, :long)
13
+ end
14
+
15
+ def test_localize_given_the_default_format_it_uses_it
16
+ assert_equal '01.03.2008', I18n.backend.localize('de', date, :default)
17
+ end
18
+
19
+ def test_localize_given_a_day_name_format_it_returns_a_day_name
20
+ assert_equal 'Samstag', I18n.backend.localize('de', date, '%A')
21
+ end
22
+
23
+ def test_localize_given_an_abbr_day_name_format_it_returns_an_abbrevated_day_name
24
+ assert_equal 'Sa', I18n.backend.localize('de', date, '%a')
25
+ end
26
+
27
+ def test_localize_given_a_month_name_format_it_returns_a_month_name
28
+ assert_equal 'März', I18n.backend.localize('de', date, '%B')
29
+ end
30
+
31
+ # TODO should be Mrz, shouldn't it?
32
+ def test_localize_given_an_abbr_month_name_format_it_returns_an_abbrevated_month_name
33
+ assert_equal 'Mar', I18n.backend.localize('de', date, '%b')
34
+ end
35
+
36
+ def test_localize_given_a_format_specified_as_a_proc
37
+ assert_equal '1ter März 2008', I18n.backend.localize('de', date, :long_ordinalized)
38
+ end
39
+
40
+ def test_localize_given_a_format_specified_as_a_proc_with_additional_options
41
+ assert_equal '1ter März 2008 (MEZ)', I18n.backend.localize('de', date, :long_ordinalized, :timezone => 'MEZ')
42
+ end
43
+
44
+ def test_localize_given_no_format_it_does_not_fail
45
+ assert_nothing_raised{ I18n.backend.localize 'de', date }
46
+ end
47
+
48
+ def test_localize_given_an_unknown_format_it_does_not_fail
49
+ assert_nothing_raised{ I18n.backend.localize 'de', date, '%x' }
50
+ end
51
+
52
+ def test_localize_nil_raises_argument_error
53
+ assert_raises(I18n::ArgumentError) { I18n.backend.localize 'de', nil }
54
+ end
55
+
56
+ def test_localize_object_raises_argument_error
57
+ assert_raises(I18n::ArgumentError) { I18n.backend.localize 'de', Object.new }
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,61 @@
1
+ module Tests
2
+ module Backend
3
+ module Api
4
+ module Localization
5
+ module DateTime
6
+ # TODO should be Mrz, shouldn't it?
7
+ def test_localize_given_the_short_format_it_uses_it
8
+ assert_equal '01. Mar 06:00', I18n.backend.localize('de', morning_datetime, :short)
9
+ end
10
+
11
+ def test_localize_given_the_long_format_it_uses_it
12
+ assert_equal '01. März 2008 06:00', I18n.backend.localize('de', morning_datetime, :long)
13
+ end
14
+
15
+ # TODO should be Mrz, shouldn't it?
16
+ def test_localize_given_the_default_format_it_uses_it
17
+ assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.backend.localize('de', morning_datetime, :default)
18
+ end
19
+
20
+ def test_localize_given_a_day_name_format_it_returns_the_correct_day_name
21
+ assert_equal 'Samstag', I18n.backend.localize('de', morning_datetime, '%A')
22
+ end
23
+
24
+ def test_localize_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name
25
+ assert_equal 'Sa', I18n.backend.localize('de', morning_datetime, '%a')
26
+ end
27
+
28
+ def test_localize_given_a_month_name_format_it_returns_the_correct_month_name
29
+ assert_equal 'März', I18n.backend.localize('de', morning_datetime, '%B')
30
+ end
31
+
32
+ # TODO should be Mrz, shouldn't it?
33
+ def test_localize_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name
34
+ assert_equal 'Mar', I18n.backend.localize('de', morning_datetime, '%b')
35
+ end
36
+
37
+ def test_localize_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator
38
+ assert_equal 'am', I18n.backend.localize('de', morning_datetime, '%p')
39
+ assert_equal 'pm', I18n.backend.localize('de', evening_datetime, '%p')
40
+ end
41
+
42
+ def test_localize_given_a_format_specified_as_a_proc
43
+ assert_equal '1ter März 2008, 06:00 Uhr', I18n.backend.localize('de', morning_datetime, :long_ordinalized)
44
+ end
45
+
46
+ def test_localize_given_a_format_specified_as_a_proc_with_additional_options
47
+ assert_equal '1ter März 2008, 06:00 Uhr (MEZ)', I18n.backend.localize('de', morning_datetime, :long_ordinalized, :timezone => 'MEZ')
48
+ end
49
+
50
+ def test_localize_given_no_format_it_does_not_fail
51
+ assert_nothing_raised{ I18n.backend.localize 'de', morning_datetime }
52
+ end
53
+
54
+ def test_localize_given_an_unknown_format_it_does_not_fail
55
+ assert_nothing_raised{ I18n.backend.localize 'de', morning_datetime, '%x' }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,24 @@
1
+ module Tests
2
+ module Backend
3
+ module Api
4
+ module Localization
5
+ module Lambda
6
+ def test_localize_uses_lambda_day_names
7
+ assert_match /Суббота/, I18n.backend.localize('ru', time, "%A, %d %B")
8
+ assert_match /суббота/, I18n.backend.localize('ru', time, "%d %B (%A)")
9
+ end
10
+
11
+ def test_localize_uses_lambda_month_names
12
+ assert_match /марта/, I18n.backend.localize('ru', time, "%d %B %Y")
13
+ assert_match /Март/, I18n.backend.localize('ru', time, "%B %Y")
14
+ end
15
+
16
+ def test_localize_uses_lambda_abbr_day_names
17
+ assert_match /марта/, I18n.backend.localize('ru', time, "%d %b %Y")
18
+ assert_match /март/, I18n.backend.localize('ru', time, "%b %Y")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,61 @@
1
+ module Tests
2
+ module Backend
3
+ module Api
4
+ module Localization
5
+ module Time
6
+ # TODO should be Mrz, shouldn't it?
7
+ def test_localize_given_the_short_format_it_uses_it
8
+ assert_equal '01. Mar 06:00', I18n.backend.localize('de', morning_time, :short)
9
+ end
10
+
11
+ def test_localize_given_the_long_format_it_uses_it
12
+ assert_equal '01. März 2008 06:00', I18n.backend.localize('de', morning_time, :long)
13
+ end
14
+
15
+ # TODO Seems to break on Windows because ENV['TZ'] is ignored. What's a better way to do this?
16
+ # def test_localize_given_the_default_format_it_uses_it
17
+ # assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.backend.localize('de', morning_time, :default)
18
+ # end
19
+
20
+ def test_localize_given_a_day_name_format_it_returns_the_correct_day_name
21
+ assert_equal 'Samstag', I18n.backend.localize('de', morning_time, '%A')
22
+ end
23
+
24
+ def test_localize_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name
25
+ assert_equal 'Sa', I18n.backend.localize('de', morning_time, '%a')
26
+ end
27
+
28
+ def test_localize_given_a_month_name_format_it_returns_the_correct_month_name
29
+ assert_equal 'März', I18n.backend.localize('de', morning_time, '%B')
30
+ end
31
+
32
+ # TODO should be Mrz, shouldn't it?
33
+ def test_localize_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name
34
+ assert_equal 'Mar', I18n.backend.localize('de', morning_time, '%b')
35
+ end
36
+
37
+ def test_localize_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator
38
+ assert_equal 'am', I18n.backend.localize('de', morning_time, '%p')
39
+ assert_equal 'pm', I18n.backend.localize('de', evening_time, '%p')
40
+ end
41
+
42
+ def test_localize_given_a_format_specified_as_a_proc
43
+ assert_equal '1ter März 2008, 06:00 Uhr', I18n.backend.localize('de', morning_time, :long_ordinalized)
44
+ end
45
+
46
+ def test_localize_given_a_format_specified_as_a_proc_with_additional_options
47
+ assert_equal '1ter März 2008, 06:00 Uhr (MEZ)', I18n.backend.localize('de', morning_time, :long_ordinalized, :timezone => 'MEZ')
48
+ end
49
+
50
+ def test_localize_given_no_format_it_does_not_fail
51
+ assert_nothing_raised{ I18n.backend.localize 'de', morning_time }
52
+ end
53
+
54
+ def test_localize_given_an_unknown_format_it_does_not_fail
55
+ assert_nothing_raised{ I18n.backend.localize 'de', morning_time, '%x' }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end