theoooo-i18n 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,98 @@
1
+ require 'i18n/locale/tag'
2
+
3
+ # Locale Fallbacks
4
+ #
5
+ # Extends the I18n module to hold a fallbacks instance which is set to an
6
+ # instance of I18n::Locale::Fallbacks by default but can be swapped with a
7
+ # different implementation.
8
+ #
9
+ # Locale fallbacks will compute a number of fallback locales for a given locale.
10
+ # For example:
11
+ #
12
+ # <pre><code>
13
+ # I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] </code></pre>
14
+ #
15
+ # Locale fallbacks always fall back to
16
+ #
17
+ # * all parent locales of a given locale (e.g. :es for :"es-MX") first,
18
+ # * the current default locales and all of their parents second
19
+ #
20
+ # The default locales are set to [I18n.default_locale] by default but can be
21
+ # set to something else.
22
+ #
23
+ # One can additionally add any number of additional fallback locales manually.
24
+ # These will be added before the default locales to the fallback chain. For
25
+ # example:
26
+ #
27
+ # # using the default locale as default fallback locale
28
+ #
29
+ # I18n.default_locale = :"en-US"
30
+ # I18n.fallbacks = I18n::Fallbacks.new(:"de-AT" => :"de-DE")
31
+ # I18n.fallbacks[:"de-AT"] # => [:"de-AT", :"de-DE", :de, :"en-US", :en]
32
+ #
33
+ # # using a custom locale as default fallback locale
34
+ #
35
+ # I18n.fallbacks = I18n::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de)
36
+ # I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en]
37
+ # I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en]
38
+ #
39
+ # # mapping fallbacks to an existing instance
40
+ #
41
+ # # people speaking Catalan also speak Spanish as spoken in Spain
42
+ # fallbacks = I18n.fallbacks
43
+ # fallbacks.map(:ca => :"es-ES")
44
+ # fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en]
45
+ #
46
+ # # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel
47
+ # fallbacks.map(:"ar-PS" => :"he-IL")
48
+ # fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en]
49
+ # fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en]
50
+ #
51
+ # # people speaking Sami as spoken in Finnland also speak Swedish and Finnish as spoken in Finnland
52
+ # fallbacks.map(:sms => [:"se-FI", :"fi-FI"])
53
+ # fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en]
54
+
55
+ module I18n
56
+ module Locale
57
+ class Fallbacks < Hash
58
+ def initialize(*mappings)
59
+ @map = {}
60
+ map(mappings.pop) if mappings.last.is_a?(Hash)
61
+ self.defaults = mappings.empty? ? [I18n.default_locale.to_sym] : mappings
62
+ end
63
+
64
+ def defaults=(defaults)
65
+ @defaults = defaults.map { |default| compute(default, false) }.flatten
66
+ end
67
+ attr_reader :defaults
68
+
69
+ def [](locale)
70
+ raise InvalidLocale.new(locale) if locale.nil?
71
+ locale = locale.to_sym
72
+ super || store(locale, compute(locale))
73
+ end
74
+
75
+ def map(mappings)
76
+ mappings.each do |from, to|
77
+ from, to = from.to_sym, Array(to)
78
+ to.each do |to|
79
+ @map[from] ||= []
80
+ @map[from] << to.to_sym
81
+ end
82
+ end
83
+ end
84
+
85
+ protected
86
+
87
+ def compute(tags, include_defaults = true)
88
+ result = Array(tags).collect do |tag|
89
+ tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym }
90
+ tags.each { |tag| tags += compute(@map[tag]) if @map[tag] }
91
+ tags
92
+ end.flatten
93
+ result.push(*defaults) if include_defaults
94
+ result.uniq
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,22 @@
1
+ module I18n
2
+ module Locale
3
+ module Tag
4
+ module Parents
5
+ def parent
6
+ @parent ||= begin
7
+ segs = to_a.compact
8
+ segs.length > 1 ? self.class.tag(*segs[0..(segs.length-2)].join('-')) : nil
9
+ end
10
+ end
11
+
12
+ def self_and_parents
13
+ @self_and_parents ||= [self] + parents
14
+ end
15
+
16
+ def parents
17
+ @parents ||= ([parent] + (parent ? parent.parents : [])).compact
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,76 @@
1
+ # RFC 4646/47 compliant Locale tag implementation that parses locale tags to
2
+ # subtags such as language, script, region, variant etc.
3
+ #
4
+ # For more information see by http://en.wikipedia.org/wiki/IETF_language_tag
5
+ #
6
+ # Rfc4646::Parser does not implement grandfathered tags.
7
+
8
+ require 'i18n/locale/tag/parents'
9
+
10
+ module I18n
11
+ module Locale
12
+ module Tag
13
+ RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ]
14
+ RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase }
15
+
16
+ class Rfc4646 < Struct.new(*RFC4646_SUBTAGS)
17
+ class << self
18
+ # Parses the given tag and returns a Tag instance if it is valid.
19
+ # Returns false if the given tag is not valid according to RFC 4646.
20
+ def tag(tag)
21
+ matches = parser.match(tag)
22
+ new(*matches) if matches
23
+ end
24
+
25
+ def parser
26
+ @@parser ||= Rfc4646::Parser
27
+ end
28
+
29
+ def parser=(parser)
30
+ @@parser = parser
31
+ end
32
+ end
33
+
34
+ include Parents
35
+
36
+ RFC4646_FORMATS.each do |name, format|
37
+ define_method(name) { self[name].send(format) unless self[name].nil? }
38
+ end
39
+
40
+ def to_sym
41
+ to_s.to_sym
42
+ end
43
+
44
+ def to_s
45
+ @tag ||= to_a.compact.join("-")
46
+ end
47
+
48
+ def to_a
49
+ members.collect { |attr| self.send(attr) }
50
+ end
51
+
52
+ module Parser
53
+ PATTERN = %r{\A(?:
54
+ ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
55
+ (?:-([a-z]{4}))? # script
56
+ (?:-([a-z]{2}|\d{3}))? # region
57
+ (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant
58
+ (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension
59
+ (?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag
60
+ (x(?:-[0-9a-z]{1,8})+)| # privateuse tag
61
+ /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered
62
+ )\z}xi
63
+
64
+ class << self
65
+ def match(tag)
66
+ c = PATTERN.match(tag.to_s).captures
67
+ c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here?
68
+ rescue
69
+ false
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,42 @@
1
+ require 'i18n/locale/tag/parents'
2
+
3
+ # Simple Locale tag implementation that computes subtags by simply splitting
4
+ # the locale tag at '-' occurences.
5
+
6
+ module I18n
7
+ module Locale
8
+ module Tag
9
+ class Simple
10
+ class << self
11
+ def tag(tag)
12
+ new(tag)
13
+ end
14
+ end
15
+
16
+ include Parents
17
+
18
+ attr_reader :tag
19
+
20
+ def initialize(*tag)
21
+ @tag = tag.join('-').to_sym
22
+ end
23
+
24
+ def subtags
25
+ @subtags = tag.to_s.split('-').map { |subtag| subtag.to_s }
26
+ end
27
+
28
+ def to_sym
29
+ tag
30
+ end
31
+
32
+ def to_s
33
+ tag.to_s
34
+ end
35
+
36
+ def to_a
37
+ subtags
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,25 @@
1
+ require 'i18n/locale/tag/simple'
2
+ require 'i18n/locale/tag/rfc4646'
3
+
4
+ module I18n
5
+ module Locale
6
+ module Tag
7
+ class << self
8
+ # Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+.
9
+ def implementation
10
+ @@implementation ||= Simple
11
+ end
12
+
13
+ # Sets the current locale tag implementation. Use this to set a different locale tag implementation.
14
+ def implementation=(implementation)
15
+ @@implementation = implementation
16
+ end
17
+
18
+ # Factory method for locale tags. Delegates to the current locale tag implementation.
19
+ def tag(tag)
20
+ implementation.tag(tag)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+ require 'i18n/backend/cache'
3
+ require 'activesupport'
4
+
5
+ class I18nCacheBackendTest < Test::Unit::TestCase
6
+ def setup
7
+ super
8
+ I18n.backend.meta_class.send(:include, I18n::Backend::Cache)
9
+ I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
10
+ end
11
+
12
+ def teardown
13
+ I18n.cache_store = nil
14
+ end
15
+
16
+ define_method :"test translate hits the backend and caches the response" do
17
+ I18n.backend.expects(:lookup).returns('Foo')
18
+ assert_equal 'Foo', I18n.t(:foo)
19
+
20
+ I18n.backend.expects(:lookup).never
21
+ assert_equal 'Foo', I18n.t(:foo)
22
+
23
+ I18n.backend.expects(:lookup).returns('Bar')
24
+ assert_equal 'Bar', I18n.t(:bar)
25
+ end
26
+
27
+ define_method :"test still raises MissingTranslationData but also caches it" do
28
+ I18n.backend.expects(:lookup).returns(nil)
29
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
30
+ I18n.backend.expects(:lookup).never
31
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
32
+ end
33
+
34
+ define_method :"test uses 'i18n' as a cache key namespace by default" do
35
+ assert_equal 0, I18n.backend.send(:cache_key, :foo).index('i18n')
36
+ end
37
+
38
+ define_method :"test adds a custom cache key namespace" do
39
+ with_cache_namespace('bar') do
40
+ assert_equal 0, I18n.backend.send(:cache_key, :foo).index('i18n-bar')
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ def with_cache_namespace(namespace)
47
+ I18n.cache_namespace = namespace
48
+ yield
49
+ I18n.cache_namespace = nil
50
+ end
51
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+ require 'i18n/backend/chain'
3
+
4
+ module ChainSetup
5
+ def setup
6
+ super
7
+ first = I18n::Backend::Simple.new
8
+ # first.store_translations(:en, translations)
9
+ I18n.backend = I18n::Backend::Chain.new(first, I18n.backend)
10
+ end
11
+ end
12
+
13
+ class I18nChainBackendApiBasicsTest < Test::Unit::TestCase
14
+ include ChainSetup
15
+ include Tests::Backend::Api::Basics
16
+ end
17
+
18
+ class I18nChainBackendApiTranslateTest < Test::Unit::TestCase
19
+ include Tests::Backend::Simple::Setup::Base
20
+ include ChainSetup
21
+ include Tests::Backend::Api::Translation
22
+ end
23
+
24
+ class I18nChainBackendApiInterpolateTest < Test::Unit::TestCase
25
+ include Tests::Backend::Simple::Setup::Base
26
+ include ChainSetup
27
+ include Tests::Backend::Api::Interpolation
28
+ end
29
+
30
+ class I18nChainBackendApiLambdaTest < Test::Unit::TestCase
31
+ include Tests::Backend::Simple::Setup::Base
32
+ include ChainSetup
33
+ include Tests::Backend::Api::Lambda
34
+ end
35
+
36
+ class I18nChainBackendApiTranslateLinkedTest < Test::Unit::TestCase
37
+ include Tests::Backend::Simple::Setup::Base
38
+ include ChainSetup
39
+ include Tests::Backend::Api::Link
40
+ end
41
+
42
+ class I18nChainBackendApiPluralizationTest < Test::Unit::TestCase
43
+ include Tests::Backend::Simple::Setup::Base
44
+ include ChainSetup
45
+ include Tests::Backend::Api::Pluralization
46
+ end
47
+
48
+ class I18nChainBackendApiLocalizeDateTest < Test::Unit::TestCase
49
+ include ChainSetup
50
+ include Tests::Backend::Simple::Setup::Localization
51
+ include Tests::Backend::Api::Localization::Date
52
+ end
53
+
54
+ class I18nChainBackendApiLocalizeDateTimeTest < Test::Unit::TestCase
55
+ include ChainSetup
56
+ include Tests::Backend::Simple::Setup::Localization
57
+ include Tests::Backend::Api::Localization::DateTime
58
+ end
59
+
60
+ class I18nChainBackendApiLocalizeTimeTest < Test::Unit::TestCase
61
+ include ChainSetup
62
+ include Tests::Backend::Simple::Setup::Localization
63
+ include Tests::Backend::Api::Localization::Time
64
+ end
65
+
66
+ class I18nChainBackendApiLocalizeLambdaTest < Test::Unit::TestCase
67
+ include ChainSetup
68
+ include Tests::Backend::Simple::Setup::Localization
69
+ include Tests::Backend::Api::Localization::Lambda
70
+ end
71
+
@@ -0,0 +1,62 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+ require 'i18n/backend/chain'
3
+
4
+ class I18nChainBackendTest < Test::Unit::TestCase
5
+ def setup
6
+ @first = backend(:en => {
7
+ :foo => 'Foo', :formats => { :short => 'short' }, :plural_1 => { :one => '{{count}}' }
8
+ })
9
+ @second = backend(:en => {
10
+ :bar => 'Bar', :formats => { :long => 'long' }, :plural_2 => { :one => 'one' }
11
+ })
12
+ @chain = I18n.backend = I18n::Backend::Chain.new(@first, @second)
13
+ end
14
+
15
+ define_method "test: looks up translations from the first chained backend" do
16
+ assert_equal 'Foo', @first.send(:translations)[:en][:foo]
17
+ assert_equal 'Foo', I18n.t(:foo)
18
+ end
19
+
20
+ define_method "test: looks up translations from the second chained backend" do
21
+ assert_equal 'Bar', @second.send(:translations)[:en][:bar]
22
+ assert_equal 'Bar', I18n.t(:bar)
23
+ end
24
+
25
+ define_method "test: defaults only apply to lookups on the last backend in the chain" do
26
+ assert_equal 'Foo', I18n.t(:foo, :default => 'Bah')
27
+ assert_equal 'Bar', I18n.t(:bar, :default => 'Bah')
28
+ assert_equal 'Bah', I18n.t(:bah, :default => 'Bah') # default kicks in only here
29
+ end
30
+
31
+ define_method "test: default" do
32
+ assert_equal 'Fuh', I18n.t(:default => 'Fuh')
33
+ assert_equal 'Zero', I18n.t(:default => { :zero => 'Zero' }, :count => 0)
34
+ assert_equal({ :zero => 'Zero' }, I18n.t(:default => { :zero => 'Zero' }))
35
+ assert_equal 'Foo', I18n.t(:default => :foo)
36
+ end
37
+
38
+ define_method "test: namespace lookup collects results from all backends" do
39
+ assert_equal({ :short => 'short', :long => 'long' }, I18n.t(:formats))
40
+ end
41
+
42
+ define_method "test: namespace lookup with only the first backend returning a result" do
43
+ assert_equal({ :one => '{{count}}' }, I18n.t(:plural_1))
44
+ end
45
+
46
+ define_method "test: pluralization still works" do
47
+ assert_equal '1', I18n.t(:plural_1, :count => 1)
48
+ assert_equal 'one', I18n.t(:plural_2, :count => 1)
49
+ end
50
+
51
+ define_method "test: bulk lookup collects results from all backends" do
52
+ assert_equal ['Foo', 'Bar'], I18n.t([:foo, :bar])
53
+ end
54
+
55
+ protected
56
+
57
+ def backend(translations)
58
+ backend = I18n::Backend::Simple.new
59
+ translations.each { |locale, translations| backend.store_translations(locale, translations) }
60
+ backend
61
+ end
62
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+ require 'i18n/backend/fallbacks'
3
+
4
+ module FallbacksSetup
5
+ def setup
6
+ super
7
+ I18n.backend.meta_class.send(:include, I18n::Backend::Fallbacks)
8
+ end
9
+ end
10
+
11
+ class I18nFallbacksBackendApiBasicsTest < Test::Unit::TestCase
12
+ include FallbacksSetup
13
+ include Tests::Backend::Api::Basics
14
+ end
15
+
16
+ class I18nFallbacksBackendApiTranslateTest < Test::Unit::TestCase
17
+ include Tests::Backend::Simple::Setup::Base
18
+ include FallbacksSetup
19
+ include Tests::Backend::Api::Translation
20
+ end
21
+
22
+ class I18nFallbacksBackendApiInterpolateTest < Test::Unit::TestCase
23
+ include Tests::Backend::Simple::Setup::Base
24
+ include FallbacksSetup
25
+ include Tests::Backend::Api::Interpolation
26
+ end
27
+
28
+ class I18nFallbacksBackendApiLambdaTest < Test::Unit::TestCase
29
+ include Tests::Backend::Simple::Setup::Base
30
+ include FallbacksSetup
31
+ include Tests::Backend::Api::Lambda
32
+ end
33
+
34
+ class I18nFallbacksBackendApiTranslateLinkedTest < Test::Unit::TestCase
35
+ include Tests::Backend::Simple::Setup::Base
36
+ include FallbacksSetup
37
+ include Tests::Backend::Api::Link
38
+ end
39
+
40
+ class I18nFallbacksBackendApiPluralizationTest < Test::Unit::TestCase
41
+ include Tests::Backend::Simple::Setup::Base
42
+ include FallbacksSetup
43
+ include Tests::Backend::Api::Pluralization
44
+ end
45
+
46
+ class I18nFallbacksBackendApiLocalizeDateTest < Test::Unit::TestCase
47
+ include FallbacksSetup
48
+ include Tests::Backend::Simple::Setup::Localization
49
+ include Tests::Backend::Api::Localization::Date
50
+ end
51
+
52
+ class I18nFallbacksBackendApiLocalizeDateTimeTest < Test::Unit::TestCase
53
+ include FallbacksSetup
54
+ include Tests::Backend::Simple::Setup::Localization
55
+ include Tests::Backend::Api::Localization::DateTime
56
+ end
57
+
58
+ class I18nFallbacksBackendApiLocalizeTimeTest < Test::Unit::TestCase
59
+ include FallbacksSetup
60
+ include Tests::Backend::Simple::Setup::Localization
61
+ include Tests::Backend::Api::Localization::Time
62
+ end
63
+
64
+ class I18nFallbacksBackendApiLocalizeLambdaTest < Test::Unit::TestCase
65
+ include FallbacksSetup
66
+ include Tests::Backend::Simple::Setup::Localization
67
+ include Tests::Backend::Api::Localization::Lambda
68
+ end
69
+
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+ require 'i18n/backend/fallbacks'
3
+
4
+ class I18nFallbacksBackendTest < Test::Unit::TestCase
5
+ def setup
6
+ I18n.backend = I18n::Backend::Simple.new
7
+ I18n.backend.meta_class.send(:include, I18n::Backend::Fallbacks)
8
+ backend_store_translations(:en, :foo => 'Foo')
9
+ end
10
+
11
+ define_method "test: fallbacks for :de are [:de, :en]" do
12
+ assert_equal [:de, :en], I18n.fallbacks[:de]
13
+ end
14
+
15
+ define_method "test: still returns the English translation as usual" do
16
+ assert_equal 'Foo', I18n.t(:foo, :locale => :en)
17
+ end
18
+
19
+ define_method "test: returns the English translation for a missing German translation" do
20
+ assert_equal 'Foo', I18n.t(:foo, :locale => :de)
21
+ end
22
+
23
+ define_method "test: raises I18n::MissingTranslationData exception when no translation was found" do
24
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:bar, :locale => :en, :raise => true) }
25
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:bar, :locale => :de, :raise => true) }
26
+ end
27
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+ require 'i18n/backend/pluralization'
3
+
4
+ module PluralizationSetup
5
+ def setup
6
+ super
7
+ I18n.backend.meta_class.send(:include, I18n::Backend::Pluralization)
8
+ I18n.load_path << locales_dir + '/plurals.rb'
9
+ end
10
+ end
11
+
12
+ class I18nPluralizationBackendApiBasicsTest < Test::Unit::TestCase
13
+ include PluralizationSetup
14
+ include Tests::Backend::Api::Basics
15
+ end
16
+
17
+ class I18nPluralizationBackendApiTranslateTest < Test::Unit::TestCase
18
+ include Tests::Backend::Simple::Setup::Base
19
+ include PluralizationSetup
20
+ include Tests::Backend::Api::Translation
21
+ end
22
+
23
+ class I18nPluralizationBackendApiInterpolateTest < Test::Unit::TestCase
24
+ include Tests::Backend::Simple::Setup::Base
25
+ include PluralizationSetup
26
+ include Tests::Backend::Api::Interpolation
27
+ end
28
+
29
+ class I18nPluralizationBackendApiLambdaTest < Test::Unit::TestCase
30
+ include Tests::Backend::Simple::Setup::Base
31
+ include PluralizationSetup
32
+ include Tests::Backend::Api::Lambda
33
+ end
34
+
35
+ class I18nPluralizationBackendApiTranslateLinkedTest < Test::Unit::TestCase
36
+ include Tests::Backend::Simple::Setup::Base
37
+ include PluralizationSetup
38
+ include Tests::Backend::Api::Link
39
+ end
40
+
41
+ class I18nPluralizationBackendApiPluralizeTest < Test::Unit::TestCase
42
+ include PluralizationSetup
43
+ include Tests::Backend::Simple::Setup::Base
44
+ include Tests::Backend::Api::Pluralization
45
+ end
46
+
47
+ class I18nPluralizationBackendApiLocalizeDateTest < Test::Unit::TestCase
48
+ include PluralizationSetup
49
+ include Tests::Backend::Simple::Setup::Localization
50
+ include Tests::Backend::Api::Localization::Date
51
+ end
52
+
53
+ class I18nPluralizationBackendApiLocalizeDateTimeTest < Test::Unit::TestCase
54
+ include PluralizationSetup
55
+ include Tests::Backend::Simple::Setup::Localization
56
+ include Tests::Backend::Api::Localization::DateTime
57
+ end
58
+
59
+ class I18nPluralizationBackendApiLocalizeTimeTest < Test::Unit::TestCase
60
+ include PluralizationSetup
61
+ include Tests::Backend::Simple::Setup::Localization
62
+ include Tests::Backend::Api::Localization::Time
63
+ end
64
+
65
+ class I18nPluralizationBackendApiLocalizeLambdaTest < Test::Unit::TestCase
66
+ include PluralizationSetup
67
+ include Tests::Backend::Simple::Setup::Localization
68
+ include Tests::Backend::Api::Localization::Lambda
69
+ end
70
+
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+ require 'i18n/backend/pluralization'
3
+
4
+ class I18nPluralizationBackendTest < Test::Unit::TestCase
5
+ def setup
6
+ I18n.backend = I18n::Backend::Simple.new
7
+ I18n.backend.meta_class.send(:include, I18n::Backend::Pluralization)
8
+ @pluralizer = lambda { |n| n == 1 ? :one : n == 0 || (2..10).include?(n % 100) ? :few : (11..19).include?(n % 100) ? :many : :other }
9
+ backend_store_translations(:foo, :i18n => { :pluralize => @pluralizer })
10
+ @entry = { :zero => 'zero', :one => 'one', :few => 'few', :many => 'many', :other => 'other' }
11
+ end
12
+
13
+ define_method :"test: pluralization picks a pluralizer from :'i18n.pluralize'" do
14
+ assert_equal @pluralizer, I18n.backend.send(:pluralizer, :foo)
15
+ end
16
+
17
+ define_method :"test: pluralization picks :one for 1" do
18
+ assert_equal 'one', I18n.t(:count => 1, :default => @entry, :locale => :foo)
19
+ end
20
+
21
+ define_method :"test: pluralization picks :few for 2" do
22
+ assert_equal 'few', I18n.t(:count => 2, :default => @entry, :locale => :foo)
23
+ end
24
+
25
+ define_method :"test: pluralization picks :many for 11" do
26
+ assert_equal 'many', I18n.t(:count => 11, :default => @entry, :locale => :foo)
27
+ end
28
+
29
+ define_method :"test: pluralization picks zero for 0 if the key is contained in the data" do
30
+ assert_equal 'zero', I18n.t(:count => 0, :default => @entry, :locale => :foo)
31
+ end
32
+
33
+ define_method :"test: pluralization picks few for 0 if the key is not contained in the data" do
34
+ @entry.delete(:zero)
35
+ assert_equal 'few', I18n.t(:count => 0, :default => @entry, :locale => :foo)
36
+ end
37
+ end